mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 08:57:44 +00:00
Merged master to SQL_REWRITE_OWN
This commit is contained in:
commit
8d6bc11dfd
41 changed files with 1420 additions and 403 deletions
|
@ -37,7 +37,8 @@ include( "cmake/compiler.cmake" )
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||||
git_describe(VERSION --tags --dirty=-d)
|
git_describe(VERSION --tags --dirty=-d)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp" @ONLY)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp.in"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp" @ONLY)
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# Common include folders
|
# Common include folders
|
||||||
|
@ -56,5 +57,10 @@ link_directories(${SERVER_COMMON_DIR})
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader)
|
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader)
|
||||||
|
|
||||||
add_subdirectory("src/servers")
|
add_subdirectory("src/servers")
|
||||||
|
|
||||||
add_subdirectory("src/libraries/sapphire/datReader")
|
add_subdirectory("src/libraries/sapphire/datReader")
|
||||||
add_subdirectory("src/libraries/sapphire/mysqlConnector")
|
add_subdirectory("src/libraries/sapphire/mysqlConnector")
|
||||||
|
|
||||||
|
add_subdirectory("src/tools/exd_common_gen")
|
||||||
|
add_subdirectory("src/tools/quest_parser")
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body scroll="no">
|
||||||
<div id="TopDiv"></div>
|
<div id="TopDiv"></div>
|
||||||
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
||||||
<div class="container" id="Conttwo">
|
<div class="container" id="Conttwo">
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body scroll="no">
|
||||||
<div id="TopDiv"></div>
|
<div id="TopDiv"></div>
|
||||||
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
||||||
<div class="container" id="Conttwo">
|
<div class="container" id="Conttwo">
|
||||||
|
|
|
@ -228,6 +228,9 @@ global CURRENCY_TOMESTONELORE = 0X0E
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Skill handle types
|
// Skill handle types
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
global STD_DAMAGE = 0X00
|
global STD_DAMAGE = 0X03
|
||||||
global STD_HEAL = 0X01
|
global STD_HEAL = 0X04
|
||||||
global STD_DOT = 0X02
|
global STD_MP_LOSS = 0X0A
|
||||||
|
global STD_MP_GAIN = 0X0B
|
||||||
|
global STD_TP_LOSS = 0X0C
|
||||||
|
global STD_TP_GAIN = 0X0D
|
|
@ -34,7 +34,7 @@ class OpeningGridaniaDef
|
||||||
|
|
||||||
def Scene00000( player )
|
def Scene00000( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 0, 0x2001, 0, 1,
|
player.eventPlay( this.id, 0, 0x04AC05, 0, 1,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.setOpeningSequence( 1 );
|
player.setOpeningSequence( 1 );
|
||||||
|
|
|
@ -72,7 +72,6 @@ class OpeningLimsaLominsaDef
|
||||||
player.eventPlay( this.id, 40, 1, 2, 1,
|
player.eventPlay( this.id, 40, 1, 2, 1,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.eventFinish( eventId, UNLOCK );
|
|
||||||
if( player.getOpeningSequence() == 2 )
|
if( player.getOpeningSequence() == 2 )
|
||||||
{
|
{
|
||||||
// update the instance boundaries
|
// update the instance boundaries
|
||||||
|
|
|
@ -35,7 +35,7 @@ class OpeningUldahDef
|
||||||
|
|
||||||
def Scene00000( player )
|
def Scene00000( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 0, 0x2001, 0, 1,
|
player.eventPlay( this.id, 0, 0x04AC05, 0, 1,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.setOpeningSequence( 1 );
|
player.setOpeningSequence( 1 );
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
// Start NPC: 1001140
|
// Start NPC: 1001140
|
||||||
// End NPC: 1000100
|
// End NPC: 1000100
|
||||||
|
|
||||||
class ManFst003Def
|
class ManFst003Def
|
||||||
{
|
{
|
||||||
def ManFst003Def()
|
def ManFst003Def()
|
||||||
{
|
{
|
||||||
// Basic quest information
|
// Basic quest information
|
||||||
this.name = "Close to Home";
|
this.name = "Close to Home";
|
||||||
this.id = 65659;
|
this.id = 65659;
|
||||||
|
|
||||||
|
@ -24,13 +24,13 @@ class ManFst003Def
|
||||||
// GetQuestUI8BL
|
// GetQuestUI8BL
|
||||||
// GetQuestUI8CH
|
// GetQuestUI8CH
|
||||||
|
|
||||||
// Steps in this quest ( 0 is before accepting,
|
// Steps in this quest ( 0 is before accepting,
|
||||||
// 1 is first, 255 means ready for turning it in
|
// 1 is first, 255 means ready for turning it in
|
||||||
this.SEQ_0 = 0;
|
this.SEQ_0 = 0;
|
||||||
this.SEQ_1 = 1;
|
this.SEQ_1 = 1;
|
||||||
this.SEQ_FINISH = 255;
|
this.SEQ_FINISH = 255;
|
||||||
|
|
||||||
// Quest rewards
|
// Quest rewards
|
||||||
this.RewardExpFactor = 100;
|
this.RewardExpFactor = 100;
|
||||||
this.RewardGil = 107;
|
this.RewardGil = 107;
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ class ManFst003Def
|
||||||
def checkQuestCompletion( player, varIdx )
|
def checkQuestCompletion( player, varIdx )
|
||||||
{
|
{
|
||||||
|
|
||||||
print( varIdx );
|
|
||||||
if (varIdx == 3)
|
if (varIdx == 3)
|
||||||
{
|
{
|
||||||
player.questMessage(this.id, 1, 0, 0, 0 );
|
player.questMessage(this.id, 1, 0, 0, 0 );
|
||||||
|
@ -118,8 +117,8 @@ class ManFst003Def
|
||||||
player.eventPlay( this.id, 1, 0x0EFB/*flags*/, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 1, 0x0EFB/*flags*/, 0/*unk*/, 0/*unk*/,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.setQuestUI8AL( ManFst004.id, 1 );
|
player.setQuestUI8AL( ManFst003.id, 1 );
|
||||||
ManFst003.checkQuestCompletion( player, 1 );
|
ManFst003.checkQuestCompletion( player, 0 );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +127,7 @@ class ManFst003Def
|
||||||
player.eventPlay( this.id, 2, 0, 0, 0,
|
player.eventPlay( this.id, 2, 0, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.setQuestUI8BH( ManFst004.id, 1 );
|
player.setQuestUI8BH( ManFst003.id, 1 );
|
||||||
ManFst003.checkQuestCompletion( player, 3 );
|
ManFst003.checkQuestCompletion( player, 3 );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -207,8 +206,8 @@ class ManFst003Def
|
||||||
player.eventPlay( this.id, 100, 0x0EFB, 0, 0,
|
player.eventPlay( this.id, 100, 0x0EFB, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.setQuestUI8CH( ManFst004.id, 0 ); // remove key item, since we have just traded it
|
player.setQuestUI8CH( ManFst003.id, 0 ); // remove key item, since we have just traded it
|
||||||
player.setQuestUI8BL( ManFst004.id, 1 );
|
player.setQuestUI8BL( ManFst003.id, 1 );
|
||||||
ManFst003.checkQuestCompletion(player, 2 );
|
ManFst003.checkQuestCompletion(player, 2 );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -237,7 +236,6 @@ class ManFst003Def
|
||||||
},
|
},
|
||||||
fun( player, eventId, additional ) {},
|
fun( player, eventId, additional ) {},
|
||||||
eventId );
|
eventId );
|
||||||
player.unlock();
|
|
||||||
}
|
}
|
||||||
else if( actor == this.ACTOR2 )
|
else if( actor == this.ACTOR2 )
|
||||||
{
|
{
|
||||||
|
@ -257,4 +255,3 @@ class ManFst003Def
|
||||||
};
|
};
|
||||||
|
|
||||||
GLOBAL ManFst003 = ManFst003Def();
|
GLOBAL ManFst003 = ManFst003Def();
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,12 @@ class ManSea001Def
|
||||||
// Available Scenes in this quest, not necessarly all are used
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
def Scene00000( player )
|
def Scene00000( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 0, HIDE_HOTBAR, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 0, 0x2000, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
if( param2 == 1 )
|
if( param2 == 1 )
|
||||||
{
|
{
|
||||||
|
player.setOpeningSequence( 2 );
|
||||||
ManSea001.Scene00001( player );
|
ManSea001.Scene00001( player );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -63,7 +64,7 @@ class ManSea001Def
|
||||||
|
|
||||||
def Scene00001( player )
|
def Scene00001( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 1, HIDE_HOTBAR, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 1, 0xF8482EFB, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
ManSea001.Scene00002( player );
|
ManSea001.Scene00002( player );
|
||||||
|
@ -81,13 +82,13 @@ class ManSea001Def
|
||||||
|
|
||||||
def Scene00003( player )
|
def Scene00003( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 3, NONE, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 3, NONE, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.questUpdate( ManSea001.id, 0x01 ); // add quest to player.
|
player.questUpdate( ManSea001.id, 0x01 ); // add quest to player.
|
||||||
|
|
||||||
// update the instance boundaries, call to the opening event
|
// update the instance boundaries, call to the opening event
|
||||||
//player.eventPlay( ManSea001.OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR, 1, 0);
|
player.eventPlay( ManSea001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 1, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +108,7 @@ class ManSea001Def
|
||||||
|
|
||||||
def Scene00006( player )
|
def Scene00006( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 6, NONE, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 6, 0x20, 0/*unk*/, 0/*unk*/,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
if( param2 == 1 )
|
if( param2 == 1 )
|
||||||
|
@ -141,7 +142,7 @@ class ManSea001Def
|
||||||
|
|
||||||
def Scene00011( player )
|
def Scene00011( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 11, NONE, 0, 0,
|
player.eventPlay( this.id, 11, 0x2c02, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
ManSea001.Scene00012( player );
|
ManSea001.Scene00012( player );
|
||||||
|
@ -150,7 +151,7 @@ class ManSea001Def
|
||||||
|
|
||||||
def Scene00012( player )
|
def Scene00012( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 12, NONE, 0, 0,
|
player.eventPlay( this.id, 12, 0x20, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
if( param2 == 1 )
|
if( param2 == 1 )
|
||||||
|
|
|
@ -9,25 +9,25 @@
|
||||||
// Start NPC: 1003987
|
// Start NPC: 1003987
|
||||||
// End NPC: 1003988
|
// End NPC: 1003988
|
||||||
|
|
||||||
class ManWil001Def
|
class ManWil001Def
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// default ctor
|
// default ctor
|
||||||
def ManWil001Def()
|
def ManWil001Def()
|
||||||
{
|
{
|
||||||
// Basic quest information
|
// Basic quest information
|
||||||
this.name = "Coming to Ul'dah";
|
this.name = "Coming to Ul'dah";
|
||||||
this.id = 66130;
|
this.id = 66130;
|
||||||
|
|
||||||
// Quest vars / flags used
|
// Quest vars / flags used
|
||||||
// GetQuestUI8AL
|
// GetQuestUI8AL
|
||||||
|
|
||||||
// Steps in this quest ( 0 is before accepting,
|
// Steps in this quest ( 0 is before accepting,
|
||||||
// 1 is first, 255 means ready for turning it in
|
// 1 is first, 255 means ready for turning it in
|
||||||
this.SEQ_0 = 0;
|
this.SEQ_0 = 0;
|
||||||
this.SEQ_FINISH = 255;
|
this.SEQ_FINISH = 255;
|
||||||
|
|
||||||
// Quest rewards
|
// Quest rewards
|
||||||
this.RewardExpFactor = 50;
|
this.RewardExpFactor = 50;
|
||||||
this.RewardGil = 103;
|
this.RewardGil = 103;
|
||||||
|
|
||||||
|
@ -49,11 +49,12 @@ class ManWil001Def
|
||||||
// Available Scenes in this quest, not necessarly all are used
|
// Available Scenes in this quest, not necessarly all are used
|
||||||
def Scene00000( player )
|
def Scene00000( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 0, 0, 0, 0,
|
player.eventPlay( this.id, 0, 0x2000, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
if( param2 == 1 ) // accept quest
|
if( param2 == 1 ) // accept quest
|
||||||
{
|
{
|
||||||
|
player.setOpeningSequence( 2 );
|
||||||
ManWil001.Scene00001( player );
|
ManWil001.Scene00001( player );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -61,7 +62,7 @@ class ManWil001Def
|
||||||
|
|
||||||
def Scene00001( player )
|
def Scene00001( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 1, 0, 0, 0,
|
player.eventPlay( this.id, 1, 0xF8482EFB, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
ManWil001.Scene00002( player );
|
ManWil001.Scene00002( player );
|
||||||
|
@ -70,11 +71,11 @@ class ManWil001Def
|
||||||
|
|
||||||
def Scene00002( player )
|
def Scene00002( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 2, 0, 0, 0,
|
player.eventPlay( this.id, 2, NONE, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
player.questUpdate( ManWil001.id, ManWil001Obj.SEQ_FINISH );// add quest to player.
|
player.questUpdate( ManWil001.id, ManWil001.SEQ_FINISH );// add quest to player.
|
||||||
player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 );
|
player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ class ManWil001Def
|
||||||
|
|
||||||
def Scene00004( player )
|
def Scene00004( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 4, 0, 0, 0,
|
player.eventPlay( this.id, 4, 0x2c02, 0, 0,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
ManWil001.Scene00005( player );
|
ManWil001.Scene00005( player );
|
||||||
|
@ -94,7 +95,7 @@ class ManWil001Def
|
||||||
|
|
||||||
def Scene00005( player )
|
def Scene00005( player )
|
||||||
{
|
{
|
||||||
player.eventPlay( this.id, 5, 0/*flags*/, 0/*unk*/, 0/*unk*/,
|
player.eventPlay( this.id, 5, 0x20/*flags*/, 0/*unk*/, 0/*unk*/,
|
||||||
fun( player, eventId, param1, param2, param3 )
|
fun( player, eventId, param1, param2, param3 )
|
||||||
{
|
{
|
||||||
if( param2 == 1 ) // clicked finish button
|
if( param2 == 1 ) // clicked finish button
|
||||||
|
|
18
scripts/chai/skill/thm/skillDef_147.chai
Normal file
18
scripts/chai/skill/thm/skillDef_147.chai
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Skill Name: Fire II
|
||||||
|
// Skill ID: 147
|
||||||
|
|
||||||
|
class skillDef_147Def
|
||||||
|
{
|
||||||
|
def skillDef_147Def()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
def onFinish( player, target )
|
||||||
|
{
|
||||||
|
player.handleScriptSkill( STD_DAMAGE, 147, 80, 0, target );
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
GLOBAL skillDef_147 = skillDef_147Def();
|
|
@ -383,6 +383,29 @@ namespace Core {
|
||||||
instance,
|
instance,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TerritoryIntendedUseType : uint8_t //ToDo: Add The Rest of The Territory Types and Have Better Names For Them
|
||||||
|
{
|
||||||
|
Town = 0,
|
||||||
|
OpenWorld = 1,
|
||||||
|
Inn = 2,
|
||||||
|
Dungeon = 3,
|
||||||
|
JailArea = 5,
|
||||||
|
OpeningArea = 6,
|
||||||
|
BeforeTrialDung = 7,
|
||||||
|
AllianceRaid = 8,
|
||||||
|
OpenWorldInstanceBattle = 9,
|
||||||
|
Trial = 10,
|
||||||
|
HousingArea = 13,
|
||||||
|
HousingPrivateArea = 14,
|
||||||
|
MSQPrivateArea = 15,
|
||||||
|
Raids = 16,
|
||||||
|
RaidFights = 17,
|
||||||
|
ChocoboTutorial = 21,
|
||||||
|
Wedding = 22,
|
||||||
|
BeginnerTutorial = 27,
|
||||||
|
PalaceOfTheDead = 31,
|
||||||
|
};
|
||||||
|
|
||||||
enum CharaLook : uint8_t
|
enum CharaLook : uint8_t
|
||||||
{
|
{
|
||||||
Race = 0x00,
|
Race = 0x00,
|
||||||
|
@ -548,7 +571,7 @@ namespace Core {
|
||||||
Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical
|
Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct ActionType : int8_t
|
enum class ActionType : int8_t
|
||||||
{
|
{
|
||||||
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
|
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
|
||||||
Unknown_0 = 0,
|
Unknown_0 = 0,
|
||||||
|
@ -581,7 +604,7 @@ namespace Core {
|
||||||
GpGain = 14
|
GpGain = 14
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ActionHitSeverityType : uint8_t
|
enum class ActionHitSeverityType : uint8_t
|
||||||
{
|
{
|
||||||
NormalDamage = 0,
|
NormalDamage = 0,
|
||||||
CritHeal = 0,
|
CritHeal = 0,
|
||||||
|
@ -591,6 +614,19 @@ namespace Core {
|
||||||
CritDirectHitDamage = 3
|
CritDirectHitDamage = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ActionCollisionType : uint8_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
SingleTarget,
|
||||||
|
Circle,
|
||||||
|
Cone,
|
||||||
|
Box,
|
||||||
|
Unknown,
|
||||||
|
Unknown2,
|
||||||
|
PersistentArea, // for when you set aoe like asylum
|
||||||
|
Unknown3
|
||||||
|
};
|
||||||
|
|
||||||
enum HandleActionType : uint8_t
|
enum HandleActionType : uint8_t
|
||||||
{
|
{
|
||||||
Event,
|
Event,
|
||||||
|
@ -605,8 +641,16 @@ namespace Core {
|
||||||
StdDot,
|
StdDot,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum InvincibilityType : uint8_t
|
||||||
|
{
|
||||||
|
InvincibilityNone,
|
||||||
|
InvincibilityRefill,
|
||||||
|
InvincibilityStayAlive,
|
||||||
|
};
|
||||||
|
|
||||||
enum struct PlayerStateFlag : uint8_t
|
enum struct PlayerStateFlag : uint8_t
|
||||||
{
|
{
|
||||||
|
SomeFlag,
|
||||||
NoCombat,
|
NoCombat,
|
||||||
Combat,
|
Combat,
|
||||||
Casting,
|
Casting,
|
||||||
|
@ -614,9 +658,9 @@ namespace Core {
|
||||||
StatusAffliction1,
|
StatusAffliction1,
|
||||||
Occupied,
|
Occupied,
|
||||||
Occupied1,
|
Occupied1,
|
||||||
|
|
||||||
Occupied2,
|
Occupied2,
|
||||||
Occupied3,
|
Occupied3,
|
||||||
|
|
||||||
BoundByDuty,
|
BoundByDuty,
|
||||||
Occupied4,
|
Occupied4,
|
||||||
DuelingArea,
|
DuelingArea,
|
||||||
|
@ -627,6 +671,7 @@ namespace Core {
|
||||||
PreparingToCraft,
|
PreparingToCraft,
|
||||||
Gathering,
|
Gathering,
|
||||||
Fishing,
|
Fishing,
|
||||||
|
|
||||||
BeingRaised,
|
BeingRaised,
|
||||||
BetweenAreas,
|
BetweenAreas,
|
||||||
Stealthed,
|
Stealthed,
|
||||||
|
@ -637,9 +682,9 @@ namespace Core {
|
||||||
BetweenAreas1,
|
BetweenAreas1,
|
||||||
SystemError,
|
SystemError,
|
||||||
LoggingOut,
|
LoggingOut,
|
||||||
|
|
||||||
InvalidLocation,
|
InvalidLocation,
|
||||||
WaitingForDuty,
|
WaitingForDuty,
|
||||||
|
|
||||||
BoundByDuty1,
|
BoundByDuty1,
|
||||||
Mounting,
|
Mounting,
|
||||||
WatchingCutscene,
|
WatchingCutscene,
|
||||||
|
@ -657,9 +702,9 @@ namespace Core {
|
||||||
FreeTrail,
|
FreeTrail,
|
||||||
BeingMoved,
|
BeingMoved,
|
||||||
Mounting2,
|
Mounting2,
|
||||||
|
|
||||||
StatusAffliction3,
|
StatusAffliction3,
|
||||||
StatusAffliction4,
|
StatusAffliction4,
|
||||||
|
|
||||||
RegisteringRaceOrMatch,
|
RegisteringRaceOrMatch,
|
||||||
WaitingForRaceOrMatch,
|
WaitingForRaceOrMatch,
|
||||||
WaitingForTripleTriadMatch,
|
WaitingForTripleTriadMatch,
|
||||||
|
|
|
@ -323,70 +323,74 @@ bool Core::Data::ExdData::loadActionInfo()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string name = getField< std::string >( fields, 0 ); // 0
|
std::string name = getField< std::string >( fields, 0 ); // 0
|
||||||
uint8_t category = getField< uint8_t >( fields, 3 ); // 3
|
uint8_t category = getField< uint8_t >( fields, 3 ); // 3
|
||||||
|
|
||||||
int8_t class_job = getField< int8_t >( fields, 10 ); // 10
|
int8_t class_job = getField< int8_t >( fields, 10 ); // 10
|
||||||
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
|
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
|
||||||
int8_t range = getField< int8_t >( fields, 13 ); // 13
|
int8_t range = getField< int8_t >( fields, 13 ); // 13
|
||||||
bool can_target_self = getField< bool >( fields, 14 ); // 14
|
bool can_target_self = getField< bool >( fields, 14 ); // 14
|
||||||
bool can_target_party = getField< bool>( fields, 15 ); // 15
|
bool can_target_party = getField< bool>( fields, 15 ); // 15
|
||||||
bool can_target_friendly = getField< bool >( fields, 16 ); // 16
|
bool can_target_friendly = getField< bool >( fields, 16 ); // 16
|
||||||
bool can_target_enemy = getField< bool >( fields, 17 ); // 17
|
bool can_target_enemy = getField< bool >( fields, 17 ); // 17
|
||||||
|
|
||||||
bool is_aoe = getField< bool >( fields, 20 ); // 20
|
bool is_ground_aoe = getField< bool >( fields, 20 ); // 20
|
||||||
// Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate)
|
// Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate)
|
||||||
bool can_target_ko = getField< bool >( fields, 24 ); // 24
|
bool can_target_ko = getField< bool >( fields, 24 ); // 24
|
||||||
|
|
||||||
uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26
|
uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26
|
||||||
uint8_t radius = getField< uint8_t >( fields, 27 ); // 27
|
uint8_t aoe_range = getField< uint8_t >( fields, 27 ); // 27
|
||||||
|
uint8_t aoe_width = getField< uint8_t >( fields, 28 ); // 28
|
||||||
|
|
||||||
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
|
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
|
||||||
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
||||||
|
|
||||||
uint32_t instantval = getField< bool >( fields, 35 ); // 35
|
bool is_instant = getField< bool >( fields, 35 ); // 35
|
||||||
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
||||||
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
||||||
|
|
||||||
int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model
|
int8_t model = getField< int8_t >( fields, 39 ); // 39
|
||||||
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect
|
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40
|
||||||
|
|
||||||
uint8_t typeshift = 0x6;
|
uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42
|
||||||
uint8_t mask = 1 << typeshift;
|
bool affects_position = getField< bool >( fields, 47 ); // 47
|
||||||
instantval &= mask;
|
|
||||||
bool final = ( instantval & mask ) == mask;
|
|
||||||
bool is_instant = final;
|
|
||||||
|
|
||||||
|
info->id = id;
|
||||||
|
info->name = name;
|
||||||
|
info->category = category;
|
||||||
|
|
||||||
info->id = id;
|
info->class_job = class_job;
|
||||||
info->name = name;
|
info->unlock_level = unlock_level;
|
||||||
info->category = category;
|
info->range = range;
|
||||||
|
info->can_target_self = can_target_self;
|
||||||
info->class_job = class_job;
|
info->can_target_party = can_target_party;
|
||||||
info->unlock_level = unlock_level;
|
|
||||||
info->range = range;
|
|
||||||
info->can_target_self = can_target_self;
|
|
||||||
info->can_target_party = can_target_party;
|
|
||||||
info->can_target_friendly = can_target_friendly;
|
info->can_target_friendly = can_target_friendly;
|
||||||
info->can_target_enemy = can_target_enemy;
|
info->can_target_enemy = can_target_enemy;
|
||||||
|
|
||||||
info->can_target_ko = can_target_ko;
|
info->can_target_ko = can_target_ko;
|
||||||
|
|
||||||
info->is_aoe = is_aoe;
|
info->is_ground_aoe = is_ground_aoe;
|
||||||
|
|
||||||
info->aoe_type = aoe_type;
|
|
||||||
info->radius = radius;
|
|
||||||
|
|
||||||
info->points_type = points_type;
|
info->aoe_type = aoe_type;
|
||||||
info->points_cost = points_cost;
|
info->aoe_range = aoe_range;
|
||||||
|
info->aoe_width = aoe_width;
|
||||||
|
|
||||||
info->is_instant = is_instant;
|
info->points_type = points_type;
|
||||||
info->cast_time = cast_time * 100;
|
info->points_cost = points_cost;
|
||||||
info->recast_time = recast_time * 100;
|
|
||||||
|
|
||||||
info->model = model;
|
info->is_instant = is_instant;
|
||||||
info->aspect = aspect;
|
info->cast_time = cast_time * 100;
|
||||||
|
info->recast_time = recast_time * 100;
|
||||||
|
|
||||||
|
info->model = model;
|
||||||
|
info->aspect = aspect;
|
||||||
|
|
||||||
|
info->toggle_status_id = toggle_status_id;
|
||||||
|
info->affects_position = affects_position;
|
||||||
|
|
||||||
|
// If action type is SingleTarget with an AoE radius set, or if action type isn't SingleTarget
|
||||||
|
info->is_aoe = ( info->aoe_type == 1 && info->aoe_width != 0 ) || ( info->aoe_type != 1 );
|
||||||
|
|
||||||
m_actionInfoMap.emplace( std::make_pair( info->id, info ) );
|
m_actionInfoMap.emplace( std::make_pair( info->id, info ) );
|
||||||
|
|
||||||
|
|
|
@ -233,12 +233,13 @@ namespace Core {
|
||||||
bool can_target_friendly; // 16
|
bool can_target_friendly; // 16
|
||||||
bool can_target_enemy; // 17
|
bool can_target_enemy; // 17
|
||||||
|
|
||||||
bool is_aoe; // 20
|
bool is_ground_aoe; // 20
|
||||||
|
|
||||||
bool can_target_ko; // 24
|
bool can_target_ko; // 24
|
||||||
|
|
||||||
uint8_t aoe_type; // 26
|
uint8_t aoe_type; // 26
|
||||||
uint8_t radius; // 27
|
uint8_t aoe_range; // 27
|
||||||
|
uint8_t aoe_width; // 28
|
||||||
|
|
||||||
uint8_t points_type; // 30
|
uint8_t points_type; // 30
|
||||||
uint16_t points_cost; // 31
|
uint16_t points_cost; // 31
|
||||||
|
@ -249,6 +250,12 @@ namespace Core {
|
||||||
|
|
||||||
int8_t model; // 39
|
int8_t model; // 39
|
||||||
uint8_t aspect; // 40
|
uint8_t aspect; // 40
|
||||||
|
|
||||||
|
uint16_t toggle_status_id; // 42
|
||||||
|
|
||||||
|
bool affects_position; // 47
|
||||||
|
|
||||||
|
bool is_aoe; // Internal only
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EventItemInfo
|
struct EventItemInfo
|
||||||
|
|
|
@ -50,7 +50,7 @@ void Core::Action::ActionCast::onStart()
|
||||||
m_pSource->getAsPlayer()->sendDebug( "onStart()" );
|
m_pSource->getAsPlayer()->sendDebug( "onStart()" );
|
||||||
m_startTime = Util::getTimeMs();
|
m_startTime = Util::getTimeMs();
|
||||||
|
|
||||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() );
|
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() );
|
||||||
|
|
||||||
castPacket.data().action_id = m_id;
|
castPacket.data().action_id = m_id;
|
||||||
castPacket.data().unknown = 1;
|
castPacket.data().unknown = 1;
|
||||||
|
|
137
src/servers/Server_Zone/Action/ActionCollision.cpp
Normal file
137
src/servers/Server_Zone/Action/ActionCollision.cpp
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
#include <src/servers/Server_Common/Util/Util.h>
|
||||||
|
#include <src/servers/Server_Common/Exd/ExdData.h>
|
||||||
|
#include <src/servers/Server_Common/Util/UtilMath.h>
|
||||||
|
|
||||||
|
#include "ActionCollision.h"
|
||||||
|
#include <src/servers/Server_Zone/Actor/Actor.h>
|
||||||
|
#include <src/servers/Server_Zone/Actor/Player.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
|
using namespace Core::Entity;
|
||||||
|
using namespace Core::Common;
|
||||||
|
|
||||||
|
// todo: add AoE actor limits (16, 32)
|
||||||
|
|
||||||
|
bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter )
|
||||||
|
{
|
||||||
|
bool actorApplicable = false;
|
||||||
|
switch ( targetFilter )
|
||||||
|
{
|
||||||
|
case TargetFilter::All:
|
||||||
|
{
|
||||||
|
actorApplicable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TargetFilter::Players:
|
||||||
|
{
|
||||||
|
actorApplicable = actorPtr->isPlayer();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TargetFilter::Allies:
|
||||||
|
{
|
||||||
|
// todo: implement ally NPCs
|
||||||
|
actorApplicable = !actorPtr->isMob();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TargetFilter::Party:
|
||||||
|
{
|
||||||
|
// todo: implement party
|
||||||
|
actorApplicable = actorPtr->isPlayer();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TargetFilter::Enemies:
|
||||||
|
{
|
||||||
|
actorApplicable = actorPtr->isMob();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( actorApplicable && actorPtr->isAlive() );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, TargetFilter targetFilter )
|
||||||
|
{
|
||||||
|
std::set< ActorPtr > actorsCollided;
|
||||||
|
|
||||||
|
switch ( static_cast< ActionCollisionType >( actionInfo->aoe_type ) )
|
||||||
|
{
|
||||||
|
case ActionCollisionType::None:
|
||||||
|
case ActionCollisionType::SingleTarget:
|
||||||
|
{
|
||||||
|
// This is actually needed. There is "splash damage" in actions marked as single target.
|
||||||
|
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
|
||||||
|
for ( auto pActor : actorsInRange )
|
||||||
|
{
|
||||||
|
// Make sure actor exists. If it doesn't we done goofed.
|
||||||
|
assert( pActor );
|
||||||
|
|
||||||
|
// Don't bother wasting on collision if actor doesn't apply for it
|
||||||
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Test our collision from actor with the area generated by the action from the AoE data
|
||||||
|
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) )
|
||||||
|
{
|
||||||
|
// Add it to the actors collided with the area
|
||||||
|
actorsCollided.insert( pActor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ActionCollisionType::Circle:
|
||||||
|
{
|
||||||
|
for ( auto pActor : actorsInRange )
|
||||||
|
{
|
||||||
|
assert( pActor );
|
||||||
|
|
||||||
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) )
|
||||||
|
{
|
||||||
|
actorsCollided.insert( pActor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ActionCollisionType::Box:
|
||||||
|
{
|
||||||
|
for ( auto pActor : actorsInRange )
|
||||||
|
{
|
||||||
|
assert( pActor );
|
||||||
|
|
||||||
|
if ( !isActorApplicable( pActor, targetFilter ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) )
|
||||||
|
{
|
||||||
|
// todo: does this actually work?
|
||||||
|
|
||||||
|
actorsCollided.insert( pActor );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actorsCollided;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActionCollision::radiusCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t radius )
|
||||||
|
{
|
||||||
|
return Core::Math::Util::distance( actorPosition.x, actorPosition.y, actorPosition.z,
|
||||||
|
aoePosition.x, aoePosition.y, aoePosition.z ) <= radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ActionCollision::boxCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t width, uint16_t height )
|
||||||
|
{
|
||||||
|
return actorPosition.x < aoePosition.x + width &&
|
||||||
|
actorPosition.x > aoePosition.x &&
|
||||||
|
actorPosition.y < aoePosition.y + height &&
|
||||||
|
actorPosition.y > aoePosition.y;
|
||||||
|
}
|
37
src/servers/Server_Zone/Action/ActionCollision.h
Normal file
37
src/servers/Server_Zone/Action/ActionCollision.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef _ACTIONCOLLISION_H
|
||||||
|
#define _ACTIONCOLLISION_H
|
||||||
|
|
||||||
|
#include <src/servers/Server_Common/Common.h>
|
||||||
|
|
||||||
|
#include <src/servers/Server_Zone/Actor/Actor.h>
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
namespace Entity {
|
||||||
|
|
||||||
|
enum class TargetFilter
|
||||||
|
{
|
||||||
|
All, // All actors in the AoE are applicable for collision
|
||||||
|
Players, // Only players
|
||||||
|
Allies, // Only allies (players, ally NPCs)
|
||||||
|
Party, // Only party members
|
||||||
|
Enemies // Only enemies
|
||||||
|
};
|
||||||
|
|
||||||
|
class ActionCollision
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter );
|
||||||
|
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, TargetFilter targetFilter );
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t radius );
|
||||||
|
static bool boxCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t width, uint16_t height );
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -45,7 +45,7 @@ void Core::Action::ActionTeleport::onStart()
|
||||||
|
|
||||||
m_startTime = Util::getTimeMs();
|
m_startTime = Util::getTimeMs();
|
||||||
|
|
||||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() );
|
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() );
|
||||||
|
|
||||||
castPacket.data().action_id = 5;
|
castPacket.data().action_id = 5;
|
||||||
castPacket.data().unknown = 1;
|
castPacket.data().unknown = 1;
|
||||||
|
|
|
@ -53,8 +53,7 @@ void Core::Action::EventAction::onStart()
|
||||||
if( m_pSource->isPlayer() )
|
if( m_pSource->isPlayer() )
|
||||||
{
|
{
|
||||||
m_pSource->sendToInRangeSet( control, true );
|
m_pSource->sendToInRangeSet( control, true );
|
||||||
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::NoCombat );
|
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag );
|
||||||
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Occupied1 );
|
|
||||||
m_pSource->getAsPlayer()->sendStateFlags();
|
m_pSource->getAsPlayer()->sendStateFlags();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -85,8 +84,7 @@ void Core::Action::EventAction::onFinish()
|
||||||
|
|
||||||
if( m_pSource->isPlayer() )
|
if( m_pSource->isPlayer() )
|
||||||
{
|
{
|
||||||
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat );
|
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag );
|
||||||
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
|
|
||||||
m_pSource->getAsPlayer()->sendStateFlags();
|
m_pSource->getAsPlayer()->sendStateFlags();
|
||||||
m_pSource->sendToInRangeSet( control, true );
|
m_pSource->sendToInRangeSet( control, true );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <src/servers/Server_Common/Util/Util.h>
|
#include <src/servers/Server_Common/Util/Util.h>
|
||||||
#include <src/servers/Server_Common/Util/UtilMath.h>
|
#include <src/servers/Server_Common/Util/UtilMath.h>
|
||||||
#include <src/servers/Server_Common/Network/PacketContainer.h>
|
#include <src/servers/Server_Common/Network/PacketContainer.h>
|
||||||
|
#include <src/servers/Server_Common/Exd/ExdData.h>
|
||||||
|
|
||||||
#include "src/servers/Server_Zone/Forwards.h"
|
#include "src/servers/Server_Zone/Forwards.h"
|
||||||
#include "src/servers/Server_Zone/Action/Action.h"
|
#include "src/servers/Server_Zone/Action/Action.h"
|
||||||
|
@ -15,11 +16,14 @@
|
||||||
|
|
||||||
#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h"
|
#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h"
|
||||||
#include "src/servers/Server_Zone/StatusEffect/StatusEffect.h"
|
#include "src/servers/Server_Zone/StatusEffect/StatusEffect.h"
|
||||||
|
#include "src/servers/Server_Zone/Action/ActionCollision.h"
|
||||||
#include "src/servers/Server_Zone/ServerZone.h"
|
#include "src/servers/Server_Zone/ServerZone.h"
|
||||||
#include "src/servers/Server_Zone/Session.h"
|
#include "src/servers/Server_Zone/Session.h"
|
||||||
|
#include "CalcBattle.h"
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
extern Core::ServerZone g_serverZone;
|
extern Core::ServerZone g_serverZone;
|
||||||
|
extern Core::Data::ExdData g_exdData;
|
||||||
|
|
||||||
using namespace Core::Common;
|
using namespace Core::Common;
|
||||||
using namespace Core::Network::Packets;
|
using namespace Core::Network::Packets;
|
||||||
|
@ -53,13 +57,13 @@ std::string Core::Entity::Actor::getName() const
|
||||||
/*! \return true if the actor is of type player */
|
/*! \return true if the actor is of type player */
|
||||||
bool Core::Entity::Actor::isPlayer() const
|
bool Core::Entity::Actor::isPlayer() const
|
||||||
{
|
{
|
||||||
return ( m_type == ActorType::Player ? true : false );
|
return m_type == ActorType::Player;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \return true if the actor is of type mob */
|
/*! \return true if the actor is of type mob */
|
||||||
bool Core::Entity::Actor::isMob() const
|
bool Core::Entity::Actor::isMob() const
|
||||||
{
|
{
|
||||||
return ( m_type == ActorType::BattleNpc ? true : false );
|
return m_type == ActorType::BattleNpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \return list of actors currently in range */
|
/*! \return list of actors currently in range */
|
||||||
|
@ -109,6 +113,12 @@ uint16_t Core::Entity::Actor::getGp() const
|
||||||
return m_gp;
|
return m_gp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \return current invincibility type */
|
||||||
|
InvincibilityType Core::Entity::Actor::getInvincibilityType() const
|
||||||
|
{
|
||||||
|
return m_invincibilityType;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \return current class or job */
|
/*! \return current class or job */
|
||||||
Core::Common::ClassJob Core::Entity::Actor::getClass() const
|
Core::Common::ClassJob Core::Entity::Actor::getClass() const
|
||||||
{
|
{
|
||||||
|
@ -161,32 +171,44 @@ uint32_t Core::Entity::Actor::getMaxMp() const
|
||||||
void Core::Entity::Actor::resetHp()
|
void Core::Entity::Actor::resetHp()
|
||||||
{
|
{
|
||||||
m_hp = getMaxHp();
|
m_hp = getMaxHp();
|
||||||
|
sendStatusUpdate( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \return reset mp to current max mp */
|
/*! \return reset mp to current max mp */
|
||||||
void Core::Entity::Actor::resetMp()
|
void Core::Entity::Actor::resetMp()
|
||||||
{
|
{
|
||||||
m_mp = getMaxMp();
|
m_mp = getMaxMp();
|
||||||
|
sendStatusUpdate( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \param hp amount to set ( caps to maxHp ) */
|
/*! \param hp amount to set ( caps to maxHp ) */
|
||||||
void Core::Entity::Actor::setHp( uint32_t hp )
|
void Core::Entity::Actor::setHp( uint32_t hp )
|
||||||
{
|
{
|
||||||
m_hp = hp < getMaxHp() ? hp : getMaxHp();
|
m_hp = hp < getMaxHp() ? hp : getMaxHp();
|
||||||
|
sendStatusUpdate( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \param mp amount to set ( caps to maxMp ) */
|
/*! \param mp amount to set ( caps to maxMp ) */
|
||||||
void Core::Entity::Actor::setMp( uint32_t mp )
|
void Core::Entity::Actor::setMp( uint32_t mp )
|
||||||
{
|
{
|
||||||
m_mp = mp < getMaxMp() ? mp : getMaxMp();
|
m_mp = mp < getMaxMp() ? mp : getMaxMp();
|
||||||
|
sendStatusUpdate( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \param mp amount to set ( caps to maxMp ) */
|
/*! \param gp amount to set*/
|
||||||
void Core::Entity::Actor::setGp( uint32_t gp )
|
void Core::Entity::Actor::setGp( uint32_t gp )
|
||||||
{
|
{
|
||||||
m_gp = gp;
|
m_gp = gp;
|
||||||
|
sendStatusUpdate( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \param type invincibility type to set */
|
||||||
|
void Core::Entity::Actor::setInvincibilityType( Common::InvincibilityType type )
|
||||||
|
{
|
||||||
|
m_invincibilityType = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \return current status of the actor */
|
/*! \return current status of the actor */
|
||||||
Core::Entity::Actor::ActorStatus Core::Entity::Actor::getStatus() const
|
Core::Entity::Actor::ActorStatus Core::Entity::Actor::getStatus() const
|
||||||
{
|
{
|
||||||
|
@ -240,10 +262,7 @@ bool Core::Entity::Actor::face( const Common::FFXIVARR_POSITION3& p )
|
||||||
|
|
||||||
setRotation( newRot );
|
setRotation( newRot );
|
||||||
|
|
||||||
if( oldRot != newRot )
|
return oldRot != newRot ? true : false;
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -331,8 +350,18 @@ void Core::Entity::Actor::takeDamage( uint32_t damage )
|
||||||
{
|
{
|
||||||
if( damage >= m_hp )
|
if( damage >= m_hp )
|
||||||
{
|
{
|
||||||
m_hp = 0;
|
switch( m_invincibilityType ) {
|
||||||
die();
|
case InvincibilityNone:
|
||||||
|
setHp( 0 );
|
||||||
|
die();
|
||||||
|
break;
|
||||||
|
case InvincibilityRefill:
|
||||||
|
resetHp();
|
||||||
|
break;
|
||||||
|
case InvincibilityStayAlive:
|
||||||
|
setHp( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_hp -= damage;
|
m_hp -= damage;
|
||||||
|
@ -620,6 +649,135 @@ void Core::Entity::Actor::autoAttack( ActorPtr pTarget )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
ChaiScript Skill Handler.
|
||||||
|
|
||||||
|
\param GamePacketPtr to send
|
||||||
|
\param bool should be send to self?
|
||||||
|
*/
|
||||||
|
void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& pTarget )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( isPlayer() )
|
||||||
|
{
|
||||||
|
getAsPlayer()->sendDebug( std::to_string( pTarget.getId() ) );
|
||||||
|
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto actionInfoPtr = g_exdData.getActionInfo( actionId );
|
||||||
|
|
||||||
|
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable.
|
||||||
|
// Prepare packet. This is seemingly common for all packets in the action handler.
|
||||||
|
|
||||||
|
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
||||||
|
effectPacket.data().targetId = pTarget.getId();
|
||||||
|
effectPacket.data().actionAnimationId = actionId;
|
||||||
|
effectPacket.data().unknown_62 = 1; // Affects displaying action name next to number in floating text
|
||||||
|
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
|
||||||
|
effectPacket.data().actionTextId = actionId;
|
||||||
|
effectPacket.data().numEffects = 1;
|
||||||
|
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
||||||
|
effectPacket.data().effectTarget = pTarget.getId();
|
||||||
|
|
||||||
|
// Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
|
||||||
|
case ActionEffectType::Damage:
|
||||||
|
{
|
||||||
|
effectPacket.data().effects[0].value = param1;
|
||||||
|
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
||||||
|
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
|
||||||
|
effectPacket.data().effects[0].unknown_3 = 7;
|
||||||
|
|
||||||
|
if ( !actionInfoPtr->is_aoe )
|
||||||
|
{
|
||||||
|
// If action on this specific target is valid...
|
||||||
|
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
|
||||||
|
pTarget.onActionHostile( shared_from_this() );
|
||||||
|
sendToInRangeSet( effectPacket, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Enemies );
|
||||||
|
|
||||||
|
for ( auto pHitActor : actorsCollided )
|
||||||
|
{
|
||||||
|
effectPacket.data().targetId = pHitActor->getId();
|
||||||
|
effectPacket.data().effectTarget = pHitActor->getId();
|
||||||
|
|
||||||
|
sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking
|
||||||
|
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
|
||||||
|
pHitActor->onActionHostile( shared_from_this() );
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
if ( isPlayer() )
|
||||||
|
{
|
||||||
|
if ( pHitActor->isPlayer() ) {
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ActionEffectType::Heal:
|
||||||
|
{
|
||||||
|
uint32_t calculatedHeal = Data::CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) );
|
||||||
|
|
||||||
|
effectPacket.data().effects[0].value = calculatedHeal;
|
||||||
|
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
|
||||||
|
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
|
||||||
|
|
||||||
|
if ( !actionInfoPtr->is_aoe )
|
||||||
|
{
|
||||||
|
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) )
|
||||||
|
break;
|
||||||
|
|
||||||
|
sendToInRangeSet( effectPacket, true );
|
||||||
|
pTarget.heal( calculatedHeal );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// todo: get proper packets: the following was just kind of thrown together from what we know. atm buggy (packets look "delayed" from client)
|
||||||
|
|
||||||
|
std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Allies );
|
||||||
|
|
||||||
|
for ( auto pHitActor : actorsCollided )
|
||||||
|
{
|
||||||
|
effectPacket.data().targetId = pTarget.getId();
|
||||||
|
effectPacket.data().effectTarget = pHitActor->getId();
|
||||||
|
|
||||||
|
sendToInRangeSet( effectPacket, true );
|
||||||
|
pHitActor->heal( calculatedHeal );
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
if ( isPlayer() )
|
||||||
|
{
|
||||||
|
if ( pHitActor->isPlayer() ) {
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*! \param StatusEffectPtr to be applied to the actor */
|
/*! \param StatusEffectPtr to be applied to the actor */
|
||||||
void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
|
void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
|
||||||
{
|
{
|
||||||
|
@ -629,7 +787,8 @@ void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect
|
||||||
/*! \param StatusEffectPtr to be applied to the actor */
|
/*! \param StatusEffectPtr to be applied to the actor */
|
||||||
void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param )
|
void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param )
|
||||||
{
|
{
|
||||||
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), shared_from_this(), duration, 3000 ) );
|
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(),
|
||||||
|
shared_from_this(), duration, 3000 ) );
|
||||||
effect->setParam( param );
|
effect->setParam( param );
|
||||||
addStatusEffect( effect );
|
addStatusEffect( effect );
|
||||||
}
|
}
|
||||||
|
@ -639,7 +798,8 @@ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t du
|
||||||
{
|
{
|
||||||
if( !m_pStatusEffectContainer->hasStatusEffect( id ) )
|
if( !m_pStatusEffectContainer->hasStatusEffect( id ) )
|
||||||
{
|
{
|
||||||
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), shared_from_this(), duration, 3000 ) );
|
StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(),
|
||||||
|
shared_from_this(), duration, 3000 ) );
|
||||||
effect->setParam( param );
|
effect->setParam( param );
|
||||||
addStatusEffect( effect );
|
addStatusEffect( effect );
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,8 @@ protected:
|
||||||
Action::ActionPtr m_pCurrentAction;
|
Action::ActionPtr m_pCurrentAction;
|
||||||
/*! Container for status effects */
|
/*! Container for status effects */
|
||||||
StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer;
|
StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer;
|
||||||
|
/*! Invincibility type */
|
||||||
|
Common::InvincibilityType m_invincibilityType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Actor();
|
Actor();
|
||||||
|
@ -199,6 +201,8 @@ public:
|
||||||
|
|
||||||
uint16_t getGp() const;
|
uint16_t getGp() const;
|
||||||
|
|
||||||
|
Common::InvincibilityType getInvincibilityType() const;
|
||||||
|
|
||||||
Common::ClassJob getClass() const;
|
Common::ClassJob getClass() const;
|
||||||
|
|
||||||
uint8_t getClassAsInt() const;
|
uint8_t getClassAsInt() const;
|
||||||
|
@ -225,12 +229,16 @@ public:
|
||||||
|
|
||||||
void setGp( uint32_t gp );
|
void setGp( uint32_t gp );
|
||||||
|
|
||||||
|
void setInvincibilityType( Common::InvincibilityType type );
|
||||||
|
|
||||||
void die();
|
void die();
|
||||||
|
|
||||||
ActorStatus getStatus() const;
|
ActorStatus getStatus() const;
|
||||||
|
|
||||||
void setStatus( ActorStatus status );
|
void setStatus( ActorStatus status );
|
||||||
|
|
||||||
|
void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target );
|
||||||
|
|
||||||
virtual void autoAttack( ActorPtr pTarget );
|
virtual void autoAttack( ActorPtr pTarget );
|
||||||
|
|
||||||
virtual void spawn( PlayerPtr pTarget ) {}
|
virtual void spawn( PlayerPtr pTarget ) {}
|
||||||
|
|
|
@ -54,6 +54,7 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com
|
||||||
m_type = ActorType::BattleNpc;
|
m_type = ActorType::BattleNpc;
|
||||||
|
|
||||||
m_mode = MODE_IDLE;
|
m_mode = MODE_IDLE;
|
||||||
|
m_targetId = INVALID_GAME_OBJECT_ID;
|
||||||
|
|
||||||
m_maxHp = 150;
|
m_maxHp = 150;
|
||||||
m_maxMp = 100;
|
m_maxMp = 100;
|
||||||
|
@ -82,6 +83,8 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com
|
||||||
|
|
||||||
m_mobType = mobType;
|
m_mobType = mobType;
|
||||||
|
|
||||||
|
m_invincibilityType = InvincibilityType::InvincibilityNone;
|
||||||
|
|
||||||
//m_type = static_cast< Common::ActorType >( type );
|
//m_type = static_cast< Common::ActorType >( type );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -229,7 +232,7 @@ void Core::Entity::BattleNpc::setOwner( Core::Entity::PlayerPtr pPlayer )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GamePacketNew< FFXIVIpcActorOwner, ServerZoneIpcType > setOwnerPacket(getId(), INVALID_GAME_OBJECT_ID);
|
GamePacketNew< FFXIVIpcActorOwner, ServerZoneIpcType > setOwnerPacket(getId(), INVALID_GAME_OBJECT_ID );
|
||||||
setOwnerPacket.data().type = 0x01;
|
setOwnerPacket.data().type = 0x01;
|
||||||
setOwnerPacket.data().actorId = INVALID_GAME_OBJECT_ID;
|
setOwnerPacket.data().actorId = INVALID_GAME_OBJECT_ID;
|
||||||
sendToInRangeSet( setOwnerPacket );
|
sendToInRangeSet( setOwnerPacket );
|
||||||
|
@ -251,15 +254,15 @@ bool Core::Entity::BattleNpc::moveTo( Common::FFXIVARR_POSITION3& pos )
|
||||||
// reached destination
|
// reached destination
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
float rot = Math::Util::calcAngFrom(getPos().x, getPos().z, pos.x, pos.z);
|
float rot = Math::Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z );
|
||||||
float newRot = PI - rot + (PI / 2);
|
float newRot = PI - rot + (PI / 2);
|
||||||
|
|
||||||
face( pos );
|
face( pos );
|
||||||
float angle = Math::Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z ) + PI;
|
float angle = Math::Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z ) + PI;
|
||||||
|
|
||||||
float x = static_cast< float >( cosf(angle) * 1.1f );
|
float x = static_cast< float >( cosf( angle ) * 1.1f );
|
||||||
float y = ( getPos().y + pos.y ) * 0.5f; // fake value while there is no collision
|
float y = ( getPos().y + pos.y ) * 0.5f; // fake value while there is no collision
|
||||||
float z = static_cast< float >( sinf(angle) * 1.1f );
|
float z = static_cast< float >( sinf( angle ) * 1.1f );
|
||||||
|
|
||||||
Common::FFXIVARR_POSITION3 newPos;
|
Common::FFXIVARR_POSITION3 newPos;
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ private:
|
||||||
uint32_t m_unk2;
|
uint32_t m_unk2;
|
||||||
std::set< HateListEntry* > m_hateList;
|
std::set< HateListEntry* > m_hateList;
|
||||||
ActorPtr m_pOwner;
|
ActorPtr m_pOwner;
|
||||||
int32_t m_timeOfDeath;
|
uint32_t m_timeOfDeath;
|
||||||
uint32_t m_mobType;
|
uint32_t m_mobType;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
using namespace Core::Data;
|
||||||
using namespace Core::Entity;
|
using namespace Core::Entity;
|
||||||
|
|
||||||
extern Core::Data::ExdData g_exdData;
|
extern Core::Data::ExdData g_exdData;
|
||||||
|
@ -44,9 +45,6 @@ float CalcBattle::calculateBaseStat( PlayerPtr pPlayer )
|
||||||
base = 1.63f * level + 121.02f;
|
base = 1.63f * level + 121.02f;
|
||||||
// ARR Base Stat Formula (Off by one in several cases)
|
// ARR Base Stat Formula (Off by one in several cases)
|
||||||
else
|
else
|
||||||
// Old: base = 0.053f * ( level * level ) + ( 1.022f * level ) - 0.907f + 20;
|
|
||||||
// V1: base = 0.0523f * ( level * level ) + ( 1.04f * level ) + 19.405f;
|
|
||||||
// V2: base = 0.05223f * ( level * level ) + ( 1.0405f * level ) + 19.405f;
|
|
||||||
base = 0.052602f * ( level * level ) + ( 1.0179f * level ) + 19.6f;
|
base = 0.052602f * ( level * level ) + ( 1.0179f * level ) + 19.6f;
|
||||||
|
|
||||||
return base;
|
return base;
|
||||||
|
@ -83,7 +81,7 @@ uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer )
|
||||||
else if ( level >= 50 )
|
else if ( level >= 50 )
|
||||||
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
|
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
|
||||||
else
|
else
|
||||||
approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7596f;
|
approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7667f;
|
||||||
|
|
||||||
uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
|
uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
|
||||||
|
|
||||||
|
@ -113,7 +111,6 @@ uint32_t CalcBattle::calculateMaxMp( PlayerPtr pPlayer )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
|
uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
|
||||||
{
|
{
|
||||||
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
|
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
|
|
||||||
|
using namespace Core::Entity;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace Entity {
|
namespace Data {
|
||||||
|
|
||||||
class CalcBattle
|
class CalcBattle
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,6 +82,7 @@ Core::Entity::Player::Player() :
|
||||||
m_onlineStatus = 0;
|
m_onlineStatus = 0;
|
||||||
m_queuedZoneing = nullptr;
|
m_queuedZoneing = nullptr;
|
||||||
m_status = ActorStatus::Idle;
|
m_status = ActorStatus::Idle;
|
||||||
|
m_invincibilityType = InvincibilityType::InvincibilityNone;
|
||||||
|
|
||||||
memset( m_questTracking, 0, sizeof( m_questTracking ) );
|
memset( m_questTracking, 0, sizeof( m_questTracking ) );
|
||||||
memset( m_name, 0, sizeof( m_name ) );
|
memset( m_name, 0, sizeof( m_name ) );
|
||||||
|
@ -192,7 +193,7 @@ void Core::Entity::Player::prepareZoning( uint16_t targetZone, bool fadeOut, uin
|
||||||
preparePacket.data().targetZone = targetZone;
|
preparePacket.data().targetZone = targetZone;
|
||||||
preparePacket.data().fadeOutTime = fadeOutTime;
|
preparePacket.data().fadeOutTime = fadeOutTime;
|
||||||
preparePacket.data().animation = animation;
|
preparePacket.data().animation = animation;
|
||||||
preparePacket.data().fadeOut = fadeOut == true ? 1 : 0;
|
preparePacket.data().fadeOut = static_cast< uint8_t >( fadeOut ? 1 : 0 );
|
||||||
queuePacket( preparePacket );
|
queuePacket( preparePacket );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +217,7 @@ void Core::Entity::Player::calculateStats()
|
||||||
auto paramGrowthInfo = paramGrowthInfoIt->second;
|
auto paramGrowthInfo = paramGrowthInfoIt->second;
|
||||||
|
|
||||||
// TODO: put formula somewhere else...
|
// TODO: put formula somewhere else...
|
||||||
float base = CalcBattle::calculateBaseStat( getAsPlayer() );
|
float base = Data::CalcBattle::calculateBaseStat( getAsPlayer() );
|
||||||
|
|
||||||
m_baseStats.str = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_str ) / 100 ) + tribeInfo.mod_str );
|
m_baseStats.str = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_str ) / 100 ) + tribeInfo.mod_str );
|
||||||
m_baseStats.dex = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_dex ) / 100 ) + tribeInfo.mod_dex );
|
m_baseStats.dex = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_dex ) / 100 ) + tribeInfo.mod_dex );
|
||||||
|
@ -232,9 +233,9 @@ void Core::Entity::Player::calculateStats()
|
||||||
m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary;
|
m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary;
|
||||||
m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary;
|
m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary;
|
||||||
|
|
||||||
m_baseStats.max_mp = CalcBattle::calculateMaxMp( getAsPlayer() );
|
m_baseStats.max_mp = Data::CalcBattle::calculateMaxMp( getAsPlayer() );
|
||||||
|
|
||||||
m_baseStats.max_hp = CalcBattle::calculateMaxHp( getAsPlayer() );
|
m_baseStats.max_hp = Data::CalcBattle::calculateMaxHp( getAsPlayer() );
|
||||||
|
|
||||||
if( m_mp > m_baseStats.max_mp )
|
if( m_mp > m_baseStats.max_mp )
|
||||||
m_mp = m_baseStats.max_mp;
|
m_mp = m_baseStats.max_mp;
|
||||||
|
@ -398,7 +399,7 @@ void Core::Entity::Player::setZone( uint32_t zoneId )
|
||||||
if( isLogin() )
|
if( isLogin() )
|
||||||
{
|
{
|
||||||
GamePacketNew< FFXIVIpcCFAvailableContents, ServerZoneIpcType > contentFinderList( getId() );
|
GamePacketNew< FFXIVIpcCFAvailableContents, ServerZoneIpcType > contentFinderList( getId() );
|
||||||
for( auto i = 0; i < 72; i++ )
|
for( auto i = 0; i < sizeof( contentFinderList.data().contents ); i++ )
|
||||||
{
|
{
|
||||||
// unlock all contents for now
|
// unlock all contents for now
|
||||||
contentFinderList.data().contents[i] = 0xFF;
|
contentFinderList.data().contents[i] = 0xFF;
|
||||||
|
@ -632,7 +633,9 @@ void Core::Entity::Player::gainExp( uint32_t amount )
|
||||||
if( ( currentExp + amount ) >= neededExpToLevel )
|
if( ( currentExp + amount ) >= neededExpToLevel )
|
||||||
{
|
{
|
||||||
// levelup
|
// levelup
|
||||||
amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ? neededExpToLevelplus1 - 1 : ( currentExp + amount - neededExpToLevel );
|
amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ?
|
||||||
|
neededExpToLevelplus1 - 1 :
|
||||||
|
( currentExp + amount - neededExpToLevel );
|
||||||
setExp( amount );
|
setExp( amount );
|
||||||
gainLevel();
|
gainLevel();
|
||||||
queuePacket( ActorControlPacket143( getId(), UpdateUiExp, static_cast< uint8_t >( getClass() ), amount ) );
|
queuePacket( ActorControlPacket143( getId(), UpdateUiExp, static_cast< uint8_t >( getClass() ), amount ) );
|
||||||
|
@ -791,50 +794,6 @@ void Core::Entity::Player::setLevelForClass( uint8_t level, Core::Common::ClassJ
|
||||||
setSyncFlag( PlayerSyncFlags::ExpLevel );
|
setSyncFlag( PlayerSyncFlags::ExpLevel );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::eventActionStart( uint32_t eventId,
|
|
||||||
uint32_t action,
|
|
||||||
ActionCallback finishCallback,
|
|
||||||
ActionCallback interruptCallback,
|
|
||||||
uint64_t additional )
|
|
||||||
{
|
|
||||||
Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action,
|
|
||||||
finishCallback, interruptCallback, additional ) );
|
|
||||||
|
|
||||||
setCurrentAction( pEventAction );
|
|
||||||
auto pEvent = getEvent( eventId );
|
|
||||||
|
|
||||||
if( !pEvent && getEventCount() )
|
|
||||||
{
|
|
||||||
// We're trying to play a nested event, need to start it first.
|
|
||||||
eventStart( getId(), eventId, Event::Event::Nest, 0, 0 );
|
|
||||||
pEvent = getEvent( eventId );
|
|
||||||
}
|
|
||||||
else if( !pEvent )
|
|
||||||
{
|
|
||||||
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( pEvent )
|
|
||||||
pEvent->setPlayedScene( true );
|
|
||||||
pEventAction->onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
|
|
||||||
uint32_t action,
|
|
||||||
ActionCallback finishCallback,
|
|
||||||
ActionCallback interruptCallback,
|
|
||||||
uint64_t additional )
|
|
||||||
{
|
|
||||||
Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action,
|
|
||||||
finishCallback, interruptCallback, additional ) );
|
|
||||||
|
|
||||||
setCurrentAction( pEventItemAction );
|
|
||||||
|
|
||||||
pEventItemAction->onStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::Entity::Player::sendModel()
|
void Core::Entity::Player::sendModel()
|
||||||
{
|
{
|
||||||
ModelEquipPacket modelEquip( getAsPlayer() );
|
ModelEquipPacket modelEquip( getAsPlayer() );
|
||||||
|
@ -846,6 +805,12 @@ uint32_t Core::Entity::Player::getModelForSlot( Inventory::EquipSlot slot )
|
||||||
return m_modelEquip[slot];
|
return m_modelEquip[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Entity::Player::setModelForSlot( Inventory::EquipSlot slot, uint32_t val )
|
||||||
|
{
|
||||||
|
m_modelEquip[slot] = val;
|
||||||
|
setSyncFlag( PlayerSyncFlags::Status );
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t Core::Entity::Player::getModelMainWeapon() const
|
uint64_t Core::Entity::Player::getModelMainWeapon() const
|
||||||
{
|
{
|
||||||
return m_modelMainWeapon;
|
return m_modelMainWeapon;
|
||||||
|
@ -973,7 +938,7 @@ void Core::Entity::Player::setGcRankAt( uint8_t index, uint8_t rank )
|
||||||
setSyncFlag( PlayerSyncFlags::GC );
|
setSyncFlag( PlayerSyncFlags::GC );
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t * Core::Entity::Player::getStateFlags() const
|
const uint8_t* Core::Entity::Player::getStateFlags() const
|
||||||
{
|
{
|
||||||
return m_stateFlags;
|
return m_stateFlags;
|
||||||
}
|
}
|
||||||
|
@ -1086,21 +1051,16 @@ void Core::Entity::Player::update( int64_t currTime )
|
||||||
|
|
||||||
m_lastUpdate = currTime;
|
m_lastUpdate = currTime;
|
||||||
|
|
||||||
// @TODO needs to happen in a if check. Don't want autoattacking while an action is being performed.
|
|
||||||
if( !checkAction() )
|
if( !checkAction() )
|
||||||
{
|
{
|
||||||
if( m_targetId )
|
if( m_targetId && m_currentStance == Entity::Actor::Stance::Active && isAutoattackOn() )
|
||||||
{
|
{
|
||||||
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
|
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
|
||||||
|
|
||||||
|
// @TODO i dislike this, iterating over all in range actors when you already know the id of the actor you need...
|
||||||
for( auto actor : m_inRangeActors )
|
for( auto actor : m_inRangeActors )
|
||||||
{
|
{
|
||||||
if( isAutoattackOn() &&
|
if( actor->getId() == m_targetId && actor->isAlive() && mainWeap )
|
||||||
actor->getId() == m_targetId &&
|
|
||||||
actor->isAlive() &&
|
|
||||||
mainWeap &&
|
|
||||||
m_currentStance == Entity::Actor::Stance::Active
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// default autoattack range
|
// default autoattack range
|
||||||
// TODO make this dependant on bnpc size
|
// TODO make this dependant on bnpc size
|
||||||
|
@ -1514,114 +1474,6 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& pTarget )
|
|
||||||
{
|
|
||||||
sendDebug( std::to_string( pTarget.getId() ) );
|
|
||||||
sendDebug( "Handle script skill type: " + std::to_string( type ) );
|
|
||||||
|
|
||||||
auto actionInfoPtr = g_exdData.getActionInfo( actionId );
|
|
||||||
|
|
||||||
|
|
||||||
switch( type )
|
|
||||||
{
|
|
||||||
|
|
||||||
case Core::Common::HandleSkillType::StdDamage:
|
|
||||||
{
|
|
||||||
sendDebug( "STD_DAMAGE" );
|
|
||||||
|
|
||||||
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
|
||||||
effectPacket.data().targetId = pTarget.getId();
|
|
||||||
effectPacket.data().actionAnimationId = actionId;
|
|
||||||
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
|
|
||||||
// effectPacket.data().unknown_3 = 1;
|
|
||||||
effectPacket.data().actionTextId = actionId;
|
|
||||||
effectPacket.data().numEffects = 1;
|
|
||||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
|
||||||
effectPacket.data().effectTarget = pTarget.getId();
|
|
||||||
effectPacket.data().effects[0].value = static_cast< int16_t >( param1 );
|
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
|
|
||||||
effectPacket.data().effects[0].unknown_3 = 7;
|
|
||||||
|
|
||||||
sendToInRangeSet( effectPacket, true );
|
|
||||||
|
|
||||||
if ( !pTarget.isAlive() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
pTarget.takeDamage( static_cast< uint32_t >( param1 ) );
|
|
||||||
pTarget.onActionHostile( shared_from_this() );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Core::Common::HandleSkillType::StdHeal:
|
|
||||||
{
|
|
||||||
uint32_t calculatedHeal = CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) );
|
|
||||||
|
|
||||||
sendDebug( "STD_HEAL" );
|
|
||||||
|
|
||||||
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
|
||||||
effectPacket.data().targetId = pTarget.getId();
|
|
||||||
effectPacket.data().actionAnimationId = actionId;
|
|
||||||
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
|
|
||||||
// effectPacket.data().unknown_3 = 1;
|
|
||||||
effectPacket.data().actionTextId = actionId;
|
|
||||||
effectPacket.data().numEffects = 1;
|
|
||||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
|
||||||
effectPacket.data().effectTarget = pTarget.getId();
|
|
||||||
effectPacket.data().effects[0].value = calculatedHeal;
|
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
|
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
|
|
||||||
effectPacket.data().effects[0].unknown_3 = 7;
|
|
||||||
|
|
||||||
sendToInRangeSet( effectPacket, true );
|
|
||||||
|
|
||||||
if ( !pTarget.isAlive() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
// todo: get proper packets: the following was just kind of thrown together from what we know
|
|
||||||
// also toss AoE to another spot and make it generic
|
|
||||||
|
|
||||||
if ( actionInfoPtr->is_aoe )
|
|
||||||
{
|
|
||||||
for ( auto pCurAct : m_inRangePlayers )
|
|
||||||
{
|
|
||||||
assert( pCurAct );
|
|
||||||
if ( !pCurAct->isAlive() )
|
|
||||||
break;
|
|
||||||
|
|
||||||
if ( Math::Util::distance( pTarget.getPos().x, pTarget.getPos().y, pTarget.getPos().z, pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z ) <= actionInfoPtr->radius )
|
|
||||||
{
|
|
||||||
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( pCurAct->getId() );
|
|
||||||
effectPacket.data().targetId = pCurAct->getId();
|
|
||||||
effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work
|
|
||||||
effectPacket.data().unknown_2 = 1;
|
|
||||||
effectPacket.data().unknown_8 = 1;
|
|
||||||
effectPacket.data().unknown_5 = 1;
|
|
||||||
effectPacket.data().actionAnimationId = actionId;
|
|
||||||
effectPacket.data().actionTextId = 0;
|
|
||||||
effectPacket.data().numEffects = 1;
|
|
||||||
effectPacket.data().effectTarget = pCurAct->getId();
|
|
||||||
effectPacket.data().effects[0].value = calculatedHeal;
|
|
||||||
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
|
|
||||||
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
|
|
||||||
effectPacket.data().effects[0].unknown_3 = 7;
|
|
||||||
|
|
||||||
pCurAct->sendToInRangeSet( effectPacket, true );
|
|
||||||
pCurAct->heal( calculatedHeal );
|
|
||||||
sendDebug( "AoE hit actor " + pCurAct->getName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pTarget.heal( calculatedHeal );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
// Content Finder
|
// Content Finder
|
||||||
|
@ -1644,9 +1496,7 @@ uint32_t Core::Entity::Player::getCFPenaltyMinutes() const
|
||||||
|
|
||||||
// check if penalty timestamp already passed current time
|
// check if penalty timestamp already passed current time
|
||||||
if (currentTimestamp > endTimestamp)
|
if (currentTimestamp > endTimestamp)
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
auto deltaTime = endTimestamp - currentTimestamp;
|
auto deltaTime = endTimestamp - currentTimestamp;
|
||||||
return static_cast< uint32_t > ( ceil( static_cast< float > (deltaTime) / 60 ) );
|
return static_cast< uint32_t > ( ceil( static_cast< float > (deltaTime) / 60 ) );
|
||||||
|
|
|
@ -103,7 +103,7 @@ public:
|
||||||
/*! load data for currently active quests */
|
/*! load data for currently active quests */
|
||||||
bool loadActiveQuests();
|
bool loadActiveQuests();
|
||||||
/*! update quest ( register it as active quest if new ) */
|
/*! update quest ( register it as active quest if new ) */
|
||||||
void updateQuest( uint16_t questId, uint16_t sequence );
|
void updateQuest( uint16_t questId, uint8_t sequence );
|
||||||
/*! return true if quest is currently active */
|
/*! return true if quest is currently active */
|
||||||
bool hasQuest( uint16_t questId );
|
bool hasQuest( uint16_t questId );
|
||||||
/*! return the current quest sequence */
|
/*! return the current quest sequence */
|
||||||
|
@ -218,6 +218,8 @@ public:
|
||||||
const uint32_t * getModelArray() const;
|
const uint32_t * getModelArray() const;
|
||||||
/*! return the equipment model in a specified equipment slot */
|
/*! return the equipment model in a specified equipment slot */
|
||||||
uint32_t getModelForSlot( Inventory::EquipSlot slot );
|
uint32_t getModelForSlot( Inventory::EquipSlot slot );
|
||||||
|
/*! set the equipment model in a specified equipment slot */
|
||||||
|
void setModelForSlot( Inventory::EquipSlot slot, uint32_t val );
|
||||||
/*! return the current amount of currency of type */
|
/*! return the current amount of currency of type */
|
||||||
uint32_t getCurrency( uint8_t type ) const;
|
uint32_t getCurrency( uint8_t type ) const;
|
||||||
/*! add amount to the currency of type */
|
/*! add amount to the currency of type */
|
||||||
|
@ -487,8 +489,6 @@ public:
|
||||||
void setAutoattack( bool mode );
|
void setAutoattack( bool mode );
|
||||||
bool isAutoattackOn() const;
|
bool isAutoattackOn() const;
|
||||||
|
|
||||||
void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target );
|
|
||||||
|
|
||||||
// Content Finder handling
|
// Content Finder handling
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
/*! Get an unix time when the player can register into content finder again. */
|
/*! Get an unix time when the player can register into content finder again. */
|
||||||
|
|
|
@ -18,6 +18,10 @@
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/EventPlayPacket.h"
|
#include "src/servers/Server_Zone/Network/PacketWrappers/EventPlayPacket.h"
|
||||||
#include "src/servers/Server_Zone/Network/PacketWrappers/EventFinishPacket.h"
|
#include "src/servers/Server_Zone/Network/PacketWrappers/EventFinishPacket.h"
|
||||||
|
|
||||||
|
#include "src/servers/Server_Zone/Action/EventAction.h"
|
||||||
|
#include "src/servers/Server_Zone/Action/EventItemAction.h"
|
||||||
|
|
||||||
|
#include "src/servers/Server_Zone/Event/Event.h"
|
||||||
#include "src/servers/Server_Zone/Event/Event.h"
|
#include "src/servers/Server_Zone/Event/Event.h"
|
||||||
#include "Server_Zone/ServerZone.h"
|
#include "Server_Zone/ServerZone.h"
|
||||||
|
|
||||||
|
@ -230,6 +234,50 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Entity::Player::eventActionStart( uint32_t eventId,
|
||||||
|
uint32_t action,
|
||||||
|
ActionCallback finishCallback,
|
||||||
|
ActionCallback interruptCallback,
|
||||||
|
uint64_t additional )
|
||||||
|
{
|
||||||
|
Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action,
|
||||||
|
finishCallback, interruptCallback, additional ) );
|
||||||
|
|
||||||
|
setCurrentAction( pEventAction );
|
||||||
|
auto pEvent = getEvent( eventId );
|
||||||
|
|
||||||
|
if( !pEvent && getEventCount() )
|
||||||
|
{
|
||||||
|
// We're trying to play a nested event, need to start it first.
|
||||||
|
eventStart( getId(), eventId, Event::Event::Nest, 0, 0 );
|
||||||
|
pEvent = getEvent( eventId );
|
||||||
|
}
|
||||||
|
else if( !pEvent )
|
||||||
|
{
|
||||||
|
g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( pEvent )
|
||||||
|
pEvent->setPlayedScene( true );
|
||||||
|
pEventAction->onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
|
||||||
|
uint32_t action,
|
||||||
|
ActionCallback finishCallback,
|
||||||
|
ActionCallback interruptCallback,
|
||||||
|
uint64_t additional )
|
||||||
|
{
|
||||||
|
Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action,
|
||||||
|
finishCallback, interruptCallback, additional ) );
|
||||||
|
|
||||||
|
setCurrentAction( pEventItemAction );
|
||||||
|
|
||||||
|
pEventItemAction->onStart();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Core::Entity::Player::onLogin()
|
void Core::Entity::Player::onLogin()
|
||||||
|
|
|
@ -74,7 +74,7 @@ bool Core::Entity::Player::loadActiveQuests()
|
||||||
void Core::Entity::Player::finishQuest( uint16_t questId )
|
void Core::Entity::Player::finishQuest( uint16_t questId )
|
||||||
{
|
{
|
||||||
|
|
||||||
int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) );
|
int16_t idx = getQuestIndex( questId );
|
||||||
|
|
||||||
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ void Core::Entity::Player::finishQuest( uint16_t questId )
|
||||||
m_questTracking[ii] = -1;
|
m_questTracking[ii] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<QuestActive> pQuest = m_activeQuests[idx];
|
boost::shared_ptr< QuestActive > pQuest = m_activeQuests[idx];
|
||||||
m_activeQuests[idx].reset();
|
m_activeQuests[idx].reset();
|
||||||
|
|
||||||
m_freeQuestIdxQueue.push( idx );
|
m_freeQuestIdxQueue.push( idx );
|
||||||
|
@ -123,7 +123,7 @@ void Core::Entity::Player::unfinishQuest( uint16_t questId )
|
||||||
void Core::Entity::Player::removeQuest( uint16_t questId )
|
void Core::Entity::Player::removeQuest( uint16_t questId )
|
||||||
{
|
{
|
||||||
|
|
||||||
int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) );
|
int16_t idx = getQuestIndex( questId );
|
||||||
|
|
||||||
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) )
|
||||||
{
|
{
|
||||||
|
@ -973,7 +973,7 @@ uint8_t Core::Entity::Player::getQuestSeq( uint16_t questId )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::updateQuest( uint16_t questId, uint16_t sequence )
|
void Core::Entity::Player::updateQuest( uint16_t questId, uint8_t sequence )
|
||||||
{
|
{
|
||||||
if( hasQuest( questId ) )
|
if( hasQuest( questId ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -239,25 +239,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
else
|
else
|
||||||
pPlayer->setClassJob( static_cast<Core::Common::ClassJob> ( id ) );
|
pPlayer->setClassJob( static_cast<Core::Common::ClassJob> ( id ) );
|
||||||
}
|
}
|
||||||
else if( subCommand == "no" )
|
|
||||||
{
|
|
||||||
int32_t id;
|
|
||||||
|
|
||||||
sscanf( params.c_str(), "%d", &id );
|
|
||||||
|
|
||||||
uint8_t typeshift = 0x6;
|
|
||||||
uint8_t mask = 1 << typeshift;
|
|
||||||
id &= mask;
|
|
||||||
bool final = ( id & mask ) == mask;
|
|
||||||
pPlayer->sendDebug( std::to_string(final) );
|
|
||||||
}
|
|
||||||
else if( subCommand == "aaah" )
|
|
||||||
{
|
|
||||||
int32_t id;
|
|
||||||
sscanf( params.c_str(), "%d", &id );
|
|
||||||
|
|
||||||
pPlayer->sendDebug( std::to_string( pPlayer->actionHasCastTime( id ) ) );
|
|
||||||
}
|
|
||||||
else if ( subCommand == "cfpenalty" )
|
else if ( subCommand == "cfpenalty" )
|
||||||
{
|
{
|
||||||
int32_t minutes;
|
int32_t minutes;
|
||||||
|
@ -273,6 +254,20 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
pPlayer->setEorzeaTimeOffset( timestamp );
|
pPlayer->setEorzeaTimeOffset( timestamp );
|
||||||
pPlayer->sendNotice( "Eorzea time offset: " + std::to_string( timestamp ) );
|
pPlayer->sendNotice( "Eorzea time offset: " + std::to_string( timestamp ) );
|
||||||
}
|
}
|
||||||
|
else if ( subCommand == "model" )
|
||||||
|
{
|
||||||
|
uint32_t slot;
|
||||||
|
uint32_t val;
|
||||||
|
sscanf( params.c_str(), "%d %d", &slot, &val );
|
||||||
|
|
||||||
|
pPlayer->setModelForSlot( static_cast<Inventory::EquipSlot>( slot ), val );
|
||||||
|
pPlayer->sendModel();
|
||||||
|
pPlayer->sendDebug( "Model updated" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPlayer->sendUrgent( subCommand + " is not a valid SET command." );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +373,10 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
pPlayer->queuePacket(controlPacket);*/
|
pPlayer->queuePacket(controlPacket);*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPlayer->sendUrgent( subCommand + " is not a valid ADD command." );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -419,6 +418,10 @@ void Core::DebugCommandHandler::get( char * data, Core::Entity::PlayerPtr pPlaye
|
||||||
std::to_string( map_id ) + "\nZoneID: " +
|
std::to_string( map_id ) + "\nZoneID: " +
|
||||||
std::to_string( pPlayer->getCurrentZone()->getId() ) + "\n" );
|
std::to_string( pPlayer->getCurrentZone()->getId() ) + "\n" );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPlayer->sendUrgent( subCommand + " is not a valid GET command." );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,6 +489,7 @@ void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, b
|
||||||
|
|
||||||
void Core::DebugCommandHandler::serverInfo( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command )
|
void Core::DebugCommandHandler::serverInfo( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command )
|
||||||
{
|
{
|
||||||
pPlayer->sendDebug( "SapphireServer " + Version::VERSION + " - " + Version::GIT_HASH );
|
pPlayer->sendDebug( "SapphireServer " + Version::VERSION + "\nRev: " + Version::GIT_HASH );
|
||||||
|
pPlayer->sendDebug( "Compiled: " __DATE__ " " __TIME__ );
|
||||||
pPlayer->sendDebug( "Sessions: " + std::to_string( g_serverZone.getSessionCount() ) );
|
pPlayer->sendDebug( "Sessions: " + std::to_string( g_serverZone.getSessionCount() ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -440,14 +440,14 @@ bool Core::Inventory::removeCrystal( CrystalType type, uint32_t amount )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::Inventory::isObtainable( uint32_t catalogId, uint16_t quantity )
|
bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
|
||||||
{
|
{
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity )
|
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity )
|
||||||
{
|
{
|
||||||
|
|
||||||
auto itemInfo = g_exdData.getItemInfo( catalogId );
|
auto itemInfo = g_exdData.getItemInfo( catalogId );
|
||||||
|
@ -587,7 +587,7 @@ void Core::Inventory::swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, ui
|
||||||
{
|
{
|
||||||
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
||||||
fromInventoryId = getArmoryToEquipSlot( toSlot );
|
fromInventoryId = getArmoryToEquipSlot( toSlot );
|
||||||
fromSlotId = m_inventoryMap[fromInventoryId]->getFreeSlot();
|
fromSlotId = static_cast < uint8_t >( m_inventoryMap[fromInventoryId]->getFreeSlot() );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto containerTypeFrom = getContainerType( fromInventoryId );
|
auto containerTypeFrom = getContainerType( fromInventoryId );
|
||||||
|
|
|
@ -140,7 +140,7 @@ public:
|
||||||
|
|
||||||
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
||||||
InvSlotPair getFreeBagSlot();
|
InvSlotPair getFreeBagSlot();
|
||||||
int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity = 1 );
|
int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity = 1 );
|
||||||
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||||
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
bool addCrystal( CrystalType type, uint32_t amount );
|
bool addCrystal( CrystalType type, uint32_t amount );
|
||||||
/*! remove amount from the crystals of type */
|
/*! remove amount from the crystals of type */
|
||||||
bool removeCrystal( CrystalType type, uint32_t amount );
|
bool removeCrystal( CrystalType type, uint32_t amount );
|
||||||
bool isObtainable( uint32_t catalogId, uint16_t quantity );
|
bool isObtainable( uint32_t catalogId, uint8_t quantity );
|
||||||
|
|
||||||
void updateCrystalDb();
|
void updateCrystalDb();
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ enum GmCommand
|
||||||
Tp = 0x0066,
|
Tp = 0x0066,
|
||||||
Gp = 0x0067,
|
Gp = 0x0067,
|
||||||
Exp = 0x0068,
|
Exp = 0x0068,
|
||||||
|
Inv = 0x006A,
|
||||||
|
|
||||||
Item = 0x00C8,
|
Item = 0x00C8,
|
||||||
Gil = 0x00C9,
|
Gil = 0x00C9,
|
||||||
|
@ -352,6 +353,17 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
" was set to " + std::to_string( targetPlayer->getGcRankArray()[targetPlayer->getGc() - 1] ) );
|
" was set to " + std::to_string( targetPlayer->getGcRankArray()[targetPlayer->getGc() - 1] ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GmCommand::Inv:
|
||||||
|
{
|
||||||
|
if( targetActor->getInvincibilityType() == Common::InvincibilityType::InvincibilityRefill )
|
||||||
|
targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityNone );
|
||||||
|
else
|
||||||
|
targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill );
|
||||||
|
|
||||||
|
pPlayer->sendNotice( "Invincibility for " + targetPlayer->getName() +
|
||||||
|
" was switched." );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) );
|
pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) );
|
||||||
|
|
|
@ -54,7 +54,8 @@ Core::LinkshellMgr g_linkshellMgr;
|
||||||
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > CharacterDatabase;
|
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > CharacterDatabase;
|
||||||
|
|
||||||
Core::ServerZone::ServerZone( const std::string& configPath, uint16_t serverId )
|
Core::ServerZone::ServerZone( const std::string& configPath, uint16_t serverId )
|
||||||
: m_configPath( configPath )
|
: m_configPath( configPath ),
|
||||||
|
m_bRunning( true )
|
||||||
{
|
{
|
||||||
m_pConfig = XMLConfigPtr( new XMLConfig );
|
m_pConfig = XMLConfigPtr( new XMLConfig );
|
||||||
}
|
}
|
||||||
|
@ -332,12 +333,8 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
||||||
g_log.setLogPath( "log\\SapphireZone_" );
|
g_log.setLogPath( "log\\SapphireZone_" );
|
||||||
g_log.init();
|
g_log.init();
|
||||||
|
|
||||||
g_log.info( "===========================================================" );
|
|
||||||
g_log.info( "Sapphire Server Project " );
|
printBanner();
|
||||||
g_log.info( "Version: " + Core::Version::VERSION );
|
|
||||||
g_log.info( "GitHash: " + Core::Version::GIT_HASH );
|
|
||||||
g_log.info( "Compiled: " __DATE__ " " __TIME__ );
|
|
||||||
g_log.info( "===========================================================" );
|
|
||||||
|
|
||||||
if( !loadSettings( argc, argv ) )
|
if( !loadSettings( argc, argv ) )
|
||||||
{
|
{
|
||||||
|
@ -364,24 +361,47 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
||||||
Network::HivePtr hive( new Network::Hive() );
|
Network::HivePtr hive( new Network::Hive() );
|
||||||
Network::addServerToHive< Network::GameConnection >( m_ip, m_port, hive );
|
Network::addServerToHive< Network::GameConnection >( m_ip, m_port, hive );
|
||||||
|
|
||||||
g_scriptMgr.init();
|
|
||||||
|
|
||||||
g_log.info( "ZoneMgr: Setting up zones" );
|
g_log.info( "ZoneMgr: Setting up zones" );
|
||||||
g_zoneMgr.createZones();
|
g_zoneMgr.createZones();
|
||||||
|
|
||||||
|
g_scriptMgr.init();
|
||||||
|
|
||||||
std::vector< std::thread > thread_list;
|
std::vector< std::thread > thread_list;
|
||||||
thread_list.push_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) );
|
thread_list.emplace_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) );
|
||||||
|
|
||||||
g_log.info( "Server listening on port: " + std::to_string( m_port ) );
|
g_log.info( "Server listening on port: " + std::to_string( m_port ) );
|
||||||
g_log.info( "Ready for connections..." );
|
g_log.info( "Ready for connections..." );
|
||||||
|
|
||||||
while( true )
|
mainLoop();
|
||||||
|
|
||||||
|
for( auto& thread_entry : thread_list )
|
||||||
{
|
{
|
||||||
std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) );
|
thread_entry.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::ServerZone::printBanner() const
|
||||||
|
{
|
||||||
|
g_log.info("===========================================================" );
|
||||||
|
g_log.info( "Sapphire Server Project " );
|
||||||
|
g_log.info( "Version: x.y.z" );
|
||||||
|
g_log.info( "Compiled: " __DATE__ " " __TIME__ );
|
||||||
|
g_log.info( "===========================================================" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::ServerZone::mainLoop()
|
||||||
|
{
|
||||||
|
while( isRunning() )
|
||||||
|
{
|
||||||
|
this_thread::sleep_for( chrono::milliseconds( 50 ) );
|
||||||
|
|
||||||
g_zoneMgr.updateZones();
|
g_zoneMgr.updateZones();
|
||||||
std::lock_guard<std::mutex> lock( m_sessionMutex );
|
|
||||||
for( auto sessionIt : m_sessionMap )
|
auto currTime = static_cast< uint32_t >( time( nullptr ) );
|
||||||
|
|
||||||
|
lock_guard< std::mutex > lock( this->m_sessionMutex );
|
||||||
|
for( auto sessionIt : this->m_sessionMap )
|
||||||
{
|
{
|
||||||
auto session = sessionIt.second;
|
auto session = sessionIt.second;
|
||||||
if( session && session->getPlayer() )
|
if( session && session->getPlayer() )
|
||||||
|
@ -393,9 +413,9 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t currTime = static_cast< uint32_t >( time( nullptr ) );
|
|
||||||
auto it = m_sessionMap.begin();
|
auto it = this->m_sessionMap.begin();
|
||||||
for( ; it != m_sessionMap.end(); )
|
for( ; it != this->m_sessionMap.end(); )
|
||||||
{
|
{
|
||||||
uint32_t diff = currTime - it->second->getLastDataTime();
|
uint32_t diff = currTime - it->second->getLastDataTime();
|
||||||
|
|
||||||
|
@ -403,11 +423,11 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
||||||
|
|
||||||
if( diff > 20 )
|
if( diff > 20 )
|
||||||
{
|
{
|
||||||
g_log.info( "[" + std::to_string( it->second->getId() ) + "] Session time out" );
|
g_log.info("[" + std::to_string(it->second->getId() ) + "] Session time out" );
|
||||||
it->second->close();
|
it->second->close();
|
||||||
// if( it->second.unique() )
|
// if( it->second.unique() )
|
||||||
{
|
{
|
||||||
it = m_sessionMap.erase( it );
|
it = this->m_sessionMap.erase(it );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -418,13 +438,6 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// currently never reached, need a "stopServer" variable to break out of the above while loop
|
|
||||||
/*for( auto& thread_entry : thread_list )
|
|
||||||
{
|
|
||||||
thread_entry.join();
|
|
||||||
}*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Core::ServerZone::createSession( uint32_t sessionId )
|
bool Core::ServerZone::createSession( uint32_t sessionId )
|
||||||
|
@ -510,3 +523,8 @@ void Core::ServerZone::updateSession( std::string playerName )
|
||||||
it->second->loadPlayer();
|
it->second->loadPlayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Core::ServerZone::isRunning() const
|
||||||
|
{
|
||||||
|
return m_bRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,12 +40,20 @@ namespace Core {
|
||||||
|
|
||||||
Entity::BattleNpcTemplatePtr getBnpcTemplate( std::string templateName );
|
Entity::BattleNpcTemplatePtr getBnpcTemplate( std::string templateName );
|
||||||
|
|
||||||
|
void mainLoop();
|
||||||
|
|
||||||
|
bool isRunning() const;
|
||||||
|
|
||||||
|
void printBanner() const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
uint16_t m_port;
|
uint16_t m_port;
|
||||||
std::string m_ip;
|
std::string m_ip;
|
||||||
|
|
||||||
|
bool m_bRunning;
|
||||||
|
|
||||||
std::string m_configPath;
|
std::string m_configPath;
|
||||||
|
|
||||||
XMLConfigPtr m_pConfig;
|
XMLConfigPtr m_pConfig;
|
||||||
|
|
|
@ -194,13 +194,13 @@ void Core::StatusEffect::StatusEffectContainer::update()
|
||||||
if( thisTickDmg != 0 )
|
if( thisTickDmg != 0 )
|
||||||
{
|
{
|
||||||
m_pOwner->takeDamage( thisTickDmg );
|
m_pOwner->takeDamage( thisTickDmg );
|
||||||
m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, 3, thisTickDmg ) );
|
m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( thisTickHeal != 0 )
|
if( thisTickHeal != 0 )
|
||||||
{
|
{
|
||||||
m_pOwner->heal( thisTickDmg );
|
m_pOwner->heal( thisTickDmg );
|
||||||
m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, 4, thisTickHeal ) );
|
m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
33
src/tools/exd_common_gen/CMakeLists.txt
Normal file
33
src/tools/exd_common_gen/CMakeLists.txt
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
cmake_minimum_required(VERSION 2.6)
|
||||||
|
cmake_policy(SET CMP0015 NEW)
|
||||||
|
project(Tool_ExdCommonGen)
|
||||||
|
|
||||||
|
set(SAPPHIRE_BOOST_VER 1.63.0)
|
||||||
|
set(SAPPHIRE_BOOST_FOLDER_NAME boost_1_63_0)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/")
|
||||||
|
|
||||||
|
|
||||||
|
file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||||
|
file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
||||||
|
|
||||||
|
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/")
|
||||||
|
add_executable(exd_common_gen ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||||
|
|
||||||
|
set_target_properties(exd_common_gen PROPERTIES
|
||||||
|
CXX_STANDARD 14
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
CXX_EXTENSIONS ON
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
target_link_libraries (exd_common_gen Common xivdat pthread mysqlclient dl z)
|
||||||
|
else()
|
||||||
|
target_link_libraries (exd_common_gen Common xivdat libmysql zlib1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(exd_common_gen ${Boost_LIBRARIES} ${Boost_LIBRARIES})
|
||||||
|
|
560
src/tools/exd_common_gen/generated.h
Normal file
560
src/tools/exd_common_gen/generated.h
Normal file
|
@ -0,0 +1,560 @@
|
||||||
|
[14:21:11][info] Setting up EXD data
|
||||||
|
[14:21:12][info] /* This file has been automatically generated.
|
||||||
|
Changes will be lost upon regeneration.
|
||||||
|
To change the content edit tools/exd_common_gen */
|
||||||
|
namespace Core {
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ActionCategory.exd
|
||||||
|
enum ActionCategory : uint8_t
|
||||||
|
{
|
||||||
|
Autoattack = 1,
|
||||||
|
Spell = 2,
|
||||||
|
Weaponskill = 3,
|
||||||
|
Ability = 4,
|
||||||
|
Item = 5,
|
||||||
|
DoLAbility = 6,
|
||||||
|
DoHAbility = 7,
|
||||||
|
Event = 8,
|
||||||
|
LimitBreak = 9,
|
||||||
|
System = 10,
|
||||||
|
Artillery = 11,
|
||||||
|
Mount = 12,
|
||||||
|
Glamour = 13,
|
||||||
|
ItemManipulation = 14,
|
||||||
|
AdrenalineRush = 15,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//BeastReputationRank.exd
|
||||||
|
enum BeastReputationRank : uint8_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Neutral = 1,
|
||||||
|
Recognized = 2,
|
||||||
|
Friendly = 3,
|
||||||
|
Trusted = 4,
|
||||||
|
Respected = 5,
|
||||||
|
Honored = 6,
|
||||||
|
Sworn = 7,
|
||||||
|
Allied = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//BeastTribe.exd
|
||||||
|
enum BeastTribe : uint8_t
|
||||||
|
{
|
||||||
|
Amaljaa = 1,
|
||||||
|
Sylphs = 2,
|
||||||
|
Kobolds = 3,
|
||||||
|
Sahagin = 4,
|
||||||
|
Ixal = 5,
|
||||||
|
VanuVanu = 6,
|
||||||
|
Vath = 7,
|
||||||
|
Moogles = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ClassJob.exd
|
||||||
|
enum ClassJob : uint8_t
|
||||||
|
{
|
||||||
|
Adventurer = 0,
|
||||||
|
Gladiator = 1,
|
||||||
|
Pugilist = 2,
|
||||||
|
Marauder = 3,
|
||||||
|
Lancer = 4,
|
||||||
|
Archer = 5,
|
||||||
|
Conjurer = 6,
|
||||||
|
Thaumaturge = 7,
|
||||||
|
Carpenter = 8,
|
||||||
|
Blacksmith = 9,
|
||||||
|
Armorer = 10,
|
||||||
|
Goldsmith = 11,
|
||||||
|
Leatherworker = 12,
|
||||||
|
Weaver = 13,
|
||||||
|
Alchemist = 14,
|
||||||
|
Culinarian = 15,
|
||||||
|
Miner = 16,
|
||||||
|
Botanist = 17,
|
||||||
|
Fisher = 18,
|
||||||
|
Paladin = 19,
|
||||||
|
Monk = 20,
|
||||||
|
Warrior = 21,
|
||||||
|
Dragoon = 22,
|
||||||
|
Bard = 23,
|
||||||
|
Whitemage = 24,
|
||||||
|
Blackmage = 25,
|
||||||
|
Arcanist = 26,
|
||||||
|
Summoner = 27,
|
||||||
|
Scholar = 28,
|
||||||
|
Rogue = 29,
|
||||||
|
Ninja = 30,
|
||||||
|
Machinist = 31,
|
||||||
|
Darkknight = 32,
|
||||||
|
Astrologian = 33,
|
||||||
|
Samurai = 34,
|
||||||
|
Redmage = 35,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ContentType.exd
|
||||||
|
enum ContentType : uint8_t
|
||||||
|
{
|
||||||
|
DutyRoulette = 1,
|
||||||
|
Dungeons = 2,
|
||||||
|
Guildhests = 3,
|
||||||
|
Trials = 4,
|
||||||
|
Raids = 5,
|
||||||
|
PvP = 6,
|
||||||
|
QuestBattles = 7,
|
||||||
|
FATEs = 8,
|
||||||
|
TreasureHunt = 9,
|
||||||
|
Levequests = 10,
|
||||||
|
GrandCompany = 11,
|
||||||
|
Companions = 12,
|
||||||
|
BeastTribeQuests = 13,
|
||||||
|
OverallCompletion = 14,
|
||||||
|
PlayerCommendation = 15,
|
||||||
|
DisciplesoftheLand = 16,
|
||||||
|
DisciplesoftheHand = 17,
|
||||||
|
RetainerVentures = 18,
|
||||||
|
GoldSaucer = 19,
|
||||||
|
DeepDungeons = 21,
|
||||||
|
WondrousTails = 24,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//EmoteCategory.exd
|
||||||
|
enum EmoteCategory : uint8_t
|
||||||
|
{
|
||||||
|
General = 1,
|
||||||
|
Persistent = 2,
|
||||||
|
Expressions = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ExVersion.exd
|
||||||
|
enum ExVersion : uint8_t
|
||||||
|
{
|
||||||
|
ARealmReborn = 0,
|
||||||
|
Heavensward = 1,
|
||||||
|
Stormblood = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//GrandCompany.exd
|
||||||
|
enum GrandCompany : uint8_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Maelstrom = 1,
|
||||||
|
OrderoftheTwinAdder = 2,
|
||||||
|
ImmortalFlames = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//GuardianDeity.exd
|
||||||
|
enum GuardianDeity : uint8_t
|
||||||
|
{
|
||||||
|
HalonetheFury = 1,
|
||||||
|
MenphinatheLover = 2,
|
||||||
|
ThaliaktheScholar = 3,
|
||||||
|
NymeiatheSpinner = 4,
|
||||||
|
LlymlaentheNavigator = 5,
|
||||||
|
OschontheWanderer = 6,
|
||||||
|
ByregottheBuilder = 7,
|
||||||
|
RhalgrtheDestroyer = 8,
|
||||||
|
AzeymatheWarden = 9,
|
||||||
|
NaldthaltheTraders = 10,
|
||||||
|
NophicatheMatron = 11,
|
||||||
|
AlthyktheKeeper = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ItemUICategory.exd
|
||||||
|
enum ItemUICategory : uint8_t
|
||||||
|
{
|
||||||
|
PugilistsArm = 1,
|
||||||
|
GladiatorsArm = 2,
|
||||||
|
MaraudersArm = 3,
|
||||||
|
ArchersArm = 4,
|
||||||
|
LancersArm = 5,
|
||||||
|
OnehandedThaumaturgesArm = 6,
|
||||||
|
TwohandedThaumaturgesArm = 7,
|
||||||
|
OnehandedConjurersArm = 8,
|
||||||
|
TwohandedConjurersArm = 9,
|
||||||
|
ArcanistsGrimoire = 10,
|
||||||
|
Shield = 11,
|
||||||
|
CarpentersPrimaryTool = 12,
|
||||||
|
CarpentersSecondaryTool = 13,
|
||||||
|
BlacksmithsPrimaryTool = 14,
|
||||||
|
BlacksmithsSecondaryTool = 15,
|
||||||
|
ArmorersPrimaryTool = 16,
|
||||||
|
ArmorersSecondaryTool = 17,
|
||||||
|
GoldsmithsPrimaryTool = 18,
|
||||||
|
GoldsmithsSecondaryTool = 19,
|
||||||
|
LeatherworkersPrimaryTool = 20,
|
||||||
|
LeatherworkersSecondaryTool = 21,
|
||||||
|
WeaversPrimaryTool = 22,
|
||||||
|
WeaversSecondaryTool = 23,
|
||||||
|
AlchemistsPrimaryTool = 24,
|
||||||
|
AlchemistsSecondaryTool = 25,
|
||||||
|
CulinariansPrimaryTool = 26,
|
||||||
|
CulinariansSecondaryTool = 27,
|
||||||
|
MinersPrimaryTool = 28,
|
||||||
|
MinersSecondaryTool = 29,
|
||||||
|
BotanistsPrimaryTool = 30,
|
||||||
|
BotanistsSecondaryTool = 31,
|
||||||
|
FishersPrimaryTool = 32,
|
||||||
|
FishingTackle = 33,
|
||||||
|
Head = 34,
|
||||||
|
Body = 35,
|
||||||
|
Legs = 36,
|
||||||
|
Hands = 37,
|
||||||
|
Feet = 38,
|
||||||
|
Waist = 39,
|
||||||
|
Necklace = 40,
|
||||||
|
Earrings = 41,
|
||||||
|
Bracelets = 42,
|
||||||
|
Ring = 43,
|
||||||
|
Medicine = 44,
|
||||||
|
Ingredient = 45,
|
||||||
|
Meal = 46,
|
||||||
|
Seafood = 47,
|
||||||
|
Stone = 48,
|
||||||
|
Metal = 49,
|
||||||
|
Lumber = 50,
|
||||||
|
Cloth = 51,
|
||||||
|
Leather = 52,
|
||||||
|
Bone = 53,
|
||||||
|
Reagent = 54,
|
||||||
|
Dye = 55,
|
||||||
|
Part = 56,
|
||||||
|
Furnishing = 57,
|
||||||
|
Materia = 58,
|
||||||
|
Crystal = 59,
|
||||||
|
Catalyst = 60,
|
||||||
|
Miscellany = 61,
|
||||||
|
SoulCrystal = 62,
|
||||||
|
Other = 63,
|
||||||
|
ConstructionPermit = 64,
|
||||||
|
Roof = 65,
|
||||||
|
ExteriorWall = 66,
|
||||||
|
Window = 67,
|
||||||
|
Door = 68,
|
||||||
|
RoofDecoration = 69,
|
||||||
|
ExteriorWallDecoration = 70,
|
||||||
|
Placard = 71,
|
||||||
|
Fence = 72,
|
||||||
|
InteriorWall = 73,
|
||||||
|
Flooring = 74,
|
||||||
|
CeilingLight = 75,
|
||||||
|
OutdoorFurnishing = 76,
|
||||||
|
Table = 77,
|
||||||
|
Tabletop = 78,
|
||||||
|
Wallmounted = 79,
|
||||||
|
Rug = 80,
|
||||||
|
Minion = 81,
|
||||||
|
Gardening = 82,
|
||||||
|
Demimateria = 83,
|
||||||
|
RoguesArm = 84,
|
||||||
|
SeasonalMiscellany = 85,
|
||||||
|
TripleTriadCard = 86,
|
||||||
|
DarkKnightsArm = 87,
|
||||||
|
MachinistsArm = 88,
|
||||||
|
AstrologiansArm = 89,
|
||||||
|
AirshipHull = 90,
|
||||||
|
AirshipRigging = 91,
|
||||||
|
AirshipAftcastle = 92,
|
||||||
|
AirshipForecastle = 93,
|
||||||
|
OrchestrionRoll = 94,
|
||||||
|
Painting = 95,
|
||||||
|
SamuraisArm = 96,
|
||||||
|
RedMagesArm = 97,
|
||||||
|
ScholarsArm = 98,
|
||||||
|
FishersSecondaryTool = 99,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//ItemSearchCategory.exd
|
||||||
|
enum ItemSearchCategory : uint8_t
|
||||||
|
{
|
||||||
|
PrimaryArms = 1,
|
||||||
|
PrimaryTools = 2,
|
||||||
|
PrimaryTools1 = 3,
|
||||||
|
Armor = 4,
|
||||||
|
Accessories = 5,
|
||||||
|
Medicines = 6,
|
||||||
|
Materials = 7,
|
||||||
|
Other = 8,
|
||||||
|
PugilistsArms = 9,
|
||||||
|
GladiatorsArms = 10,
|
||||||
|
MaraudersArms = 11,
|
||||||
|
ArchersArms = 12,
|
||||||
|
LancersArms = 13,
|
||||||
|
ThaumaturgesArms = 14,
|
||||||
|
ConjurersArms = 15,
|
||||||
|
ArcanistsArms = 16,
|
||||||
|
Shields = 17,
|
||||||
|
ThrowingWeapons = 18,
|
||||||
|
CarpentersTools = 19,
|
||||||
|
BlacksmithsTools = 20,
|
||||||
|
ArmorersTools = 21,
|
||||||
|
GoldsmithsTools = 22,
|
||||||
|
LeatherworkersTools = 23,
|
||||||
|
WeaversTools = 24,
|
||||||
|
AlchemistsTools = 25,
|
||||||
|
CulinariansTools = 26,
|
||||||
|
MinersTools = 27,
|
||||||
|
BotanistsTools = 28,
|
||||||
|
FishersTools = 29,
|
||||||
|
FishingTackle = 30,
|
||||||
|
Head = 31,
|
||||||
|
Undershirts = 32,
|
||||||
|
Body = 33,
|
||||||
|
Undergarments = 34,
|
||||||
|
Legs = 35,
|
||||||
|
Hands = 36,
|
||||||
|
Feet = 37,
|
||||||
|
Waist = 38,
|
||||||
|
Necklaces = 39,
|
||||||
|
Earrings = 40,
|
||||||
|
Bracelets = 41,
|
||||||
|
Rings = 42,
|
||||||
|
Medicine = 43,
|
||||||
|
Ingredients = 44,
|
||||||
|
Meals = 45,
|
||||||
|
Seafood = 46,
|
||||||
|
Stone = 47,
|
||||||
|
Metal = 48,
|
||||||
|
Lumber = 49,
|
||||||
|
Cloth = 50,
|
||||||
|
Leather = 51,
|
||||||
|
Bone = 52,
|
||||||
|
Reagents = 53,
|
||||||
|
Dyes = 54,
|
||||||
|
WeaponParts = 55,
|
||||||
|
Furnishings = 56,
|
||||||
|
Materia = 57,
|
||||||
|
Crystals = 58,
|
||||||
|
Catalysts = 59,
|
||||||
|
Miscellany = 60,
|
||||||
|
SoulCrystals = 61,
|
||||||
|
Arrows = 62,
|
||||||
|
QuestItems = 63,
|
||||||
|
Other1 = 64,
|
||||||
|
ExteriorFixtures = 65,
|
||||||
|
InteriorFixtures = 66,
|
||||||
|
OutdoorFurnishings = 67,
|
||||||
|
ChairsandBeds = 68,
|
||||||
|
Tables = 69,
|
||||||
|
Tabletop = 70,
|
||||||
|
Wallmounted = 71,
|
||||||
|
Rugs = 72,
|
||||||
|
RoguesArms = 73,
|
||||||
|
SeasonalMiscellany = 74,
|
||||||
|
Minions = 75,
|
||||||
|
DarkKnightsArms = 76,
|
||||||
|
MachinistsArms = 77,
|
||||||
|
AstrologiansArms = 78,
|
||||||
|
AirshipComponents = 79,
|
||||||
|
OrchestrionComponents = 80,
|
||||||
|
GardeningItems = 81,
|
||||||
|
Paintings = 82,
|
||||||
|
SamuraisArms = 83,
|
||||||
|
RedMagesArms = 84,
|
||||||
|
ScholarsArms = 85,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//OnlineStatus.exd
|
||||||
|
enum OnlineStatus : uint8_t
|
||||||
|
{
|
||||||
|
Producer = 1,
|
||||||
|
GameMaster = 2,
|
||||||
|
GameMaster1 = 3,
|
||||||
|
GameMaster2 = 4,
|
||||||
|
Disconnected = 5,
|
||||||
|
WaitingforFriendListApproval = 6,
|
||||||
|
WaitingforLinkshellApproval = 7,
|
||||||
|
WaitingforFreeCompanyApproval = 8,
|
||||||
|
NotFound = 9,
|
||||||
|
Offline = 10,
|
||||||
|
Mentor = 11,
|
||||||
|
Busy = 12,
|
||||||
|
PvP = 13,
|
||||||
|
PlayingTripleTriad = 14,
|
||||||
|
ViewingCutscene = 15,
|
||||||
|
UsingaChocoboPorter = 16,
|
||||||
|
AwayfromKeyboard = 17,
|
||||||
|
CameraMode = 18,
|
||||||
|
LookingforRepairs = 19,
|
||||||
|
LookingtoRepair = 20,
|
||||||
|
LookingtoMeldMateria = 21,
|
||||||
|
Roleplaying = 22,
|
||||||
|
LookingforParty = 23,
|
||||||
|
SwordforHire = 24,
|
||||||
|
WaitingforDutyFinder = 25,
|
||||||
|
RecruitingPartyMembers = 26,
|
||||||
|
Mentor1 = 27,
|
||||||
|
PvEMentor = 28,
|
||||||
|
TradeMentor = 29,
|
||||||
|
PvPMentor = 30,
|
||||||
|
Returner = 31,
|
||||||
|
NewAdventurer = 32,
|
||||||
|
AllianceLeader = 33,
|
||||||
|
AlliancePartyLeader = 34,
|
||||||
|
AlliancePartyMember = 35,
|
||||||
|
PartyLeader = 36,
|
||||||
|
PartyMember = 37,
|
||||||
|
PartyLeaderCrossworld = 38,
|
||||||
|
PartyMemberCrossworld = 39,
|
||||||
|
AnotherWorld = 40,
|
||||||
|
SharingDuty = 41,
|
||||||
|
SimilarDuty = 42,
|
||||||
|
InDuty = 43,
|
||||||
|
TrialAdventurer = 44,
|
||||||
|
FreeCompany = 45,
|
||||||
|
GrandCompany = 46,
|
||||||
|
Online = 47,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//Race.exd
|
||||||
|
enum Race : uint8_t
|
||||||
|
{
|
||||||
|
Hyur = 1,
|
||||||
|
Elezen = 2,
|
||||||
|
Lalafell = 3,
|
||||||
|
Miqote = 4,
|
||||||
|
Roegadyn = 5,
|
||||||
|
AuRa = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//Tribe.exd
|
||||||
|
enum Tribe : uint8_t
|
||||||
|
{
|
||||||
|
Midlander = 1,
|
||||||
|
Highlander = 2,
|
||||||
|
Wildwood = 3,
|
||||||
|
Duskwight = 4,
|
||||||
|
Plainsfolk = 5,
|
||||||
|
Dunesfolk = 6,
|
||||||
|
SeekeroftheSun = 7,
|
||||||
|
KeeperoftheMoon = 8,
|
||||||
|
SeaWolf = 9,
|
||||||
|
Hellsguard = 10,
|
||||||
|
Raen = 11,
|
||||||
|
Xaela = 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//Town.exd
|
||||||
|
enum Town : uint8_t
|
||||||
|
{
|
||||||
|
Nowheresville = 0,
|
||||||
|
LimsaLominsa = 1,
|
||||||
|
Gridania = 2,
|
||||||
|
Uldah = 3,
|
||||||
|
Ishgard = 4,
|
||||||
|
Kugane = 7,
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////
|
||||||
|
//Weather.exd
|
||||||
|
enum Weather : uint8_t
|
||||||
|
{
|
||||||
|
ClearSkies = 1,
|
||||||
|
FairSkies = 2,
|
||||||
|
Clouds = 3,
|
||||||
|
Fog = 4,
|
||||||
|
Wind = 5,
|
||||||
|
Gales = 6,
|
||||||
|
Rain = 7,
|
||||||
|
Showers = 8,
|
||||||
|
Thunder = 9,
|
||||||
|
Thunderstorms = 10,
|
||||||
|
DustStorms = 11,
|
||||||
|
Sandstorms = 12,
|
||||||
|
HotSpells = 13,
|
||||||
|
HeatWaves = 14,
|
||||||
|
Snow = 15,
|
||||||
|
Blizzards = 16,
|
||||||
|
Gloom = 17,
|
||||||
|
Auroras = 18,
|
||||||
|
Darkness = 19,
|
||||||
|
Tension = 20,
|
||||||
|
Clouds1 = 21,
|
||||||
|
StormClouds = 22,
|
||||||
|
RoughSeas = 23,
|
||||||
|
RoughSeas1 = 24,
|
||||||
|
Louring = 25,
|
||||||
|
HeatWaves1 = 26,
|
||||||
|
Gloom1 = 27,
|
||||||
|
Gales1 = 28,
|
||||||
|
Eruptions = 29,
|
||||||
|
FairSkies1 = 30,
|
||||||
|
FairSkies2 = 31,
|
||||||
|
FairSkies3 = 32,
|
||||||
|
FairSkies4 = 33,
|
||||||
|
FairSkies5 = 34,
|
||||||
|
Irradiance = 35,
|
||||||
|
CoreRadiation = 36,
|
||||||
|
CoreRadiation1 = 37,
|
||||||
|
CoreRadiation2 = 38,
|
||||||
|
CoreRadiation3 = 39,
|
||||||
|
ShelfClouds = 40,
|
||||||
|
ShelfClouds1 = 41,
|
||||||
|
ShelfClouds2 = 42,
|
||||||
|
ShelfClouds3 = 43,
|
||||||
|
Oppression = 44,
|
||||||
|
Oppression1 = 45,
|
||||||
|
Oppression2 = 46,
|
||||||
|
Oppression3 = 47,
|
||||||
|
Oppression4 = 48,
|
||||||
|
UmbralWind = 49,
|
||||||
|
UmbralStatic = 50,
|
||||||
|
Smoke = 51,
|
||||||
|
FairSkies6 = 52,
|
||||||
|
RoyalLevin = 53,
|
||||||
|
Hyperelectricity = 54,
|
||||||
|
RoyalLevin1 = 55,
|
||||||
|
Oppression5 = 56,
|
||||||
|
Thunder1 = 57,
|
||||||
|
Thunder2 = 58,
|
||||||
|
CutScene = 59,
|
||||||
|
Multiplicity = 60,
|
||||||
|
Multiplicity1 = 61,
|
||||||
|
Rain1 = 62,
|
||||||
|
FairSkies7 = 63,
|
||||||
|
Rain2 = 64,
|
||||||
|
FairSkies8 = 65,
|
||||||
|
Dragonstorm = 66,
|
||||||
|
Dragonstorm1 = 67,
|
||||||
|
Subterrain = 68,
|
||||||
|
Concordance = 69,
|
||||||
|
Concordance1 = 70,
|
||||||
|
BeyondTime = 71,
|
||||||
|
BeyondTime1 = 72,
|
||||||
|
BeyondTime2 = 73,
|
||||||
|
DemonicInfinity = 74,
|
||||||
|
DemonicInfinity1 = 75,
|
||||||
|
DemonicInfinity2 = 76,
|
||||||
|
DimensionalDisruption = 77,
|
||||||
|
DimensionalDisruption1 = 78,
|
||||||
|
DimensionalDisruption2 = 79,
|
||||||
|
Revelstorm = 80,
|
||||||
|
Revelstorm1 = 81,
|
||||||
|
EternalBliss = 82,
|
||||||
|
EternalBliss1 = 83,
|
||||||
|
Wyrmstorm = 84,
|
||||||
|
Wyrmstorm1 = 85,
|
||||||
|
Revelstorm2 = 86,
|
||||||
|
Quicklevin = 87,
|
||||||
|
Thunder3 = 88,
|
||||||
|
DimensionalDisruption3 = 89,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
114
src/tools/exd_common_gen/main.cpp
Normal file
114
src/tools/exd_common_gen/main.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
|
||||||
|
#include <GameData.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <DatCat.h>
|
||||||
|
#include <ExdData.h>
|
||||||
|
#include <ExdCat.h>
|
||||||
|
#include <Exd.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cctype>
|
||||||
|
#include <set>
|
||||||
|
#include <src/servers/Server_Common/Exd/ExdData.h>
|
||||||
|
#include <src/servers/Server_Common/Logging/Logger.h>
|
||||||
|
#include <boost/range/algorithm/remove_if.hpp>
|
||||||
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
|
||||||
|
Core::Logger g_log;
|
||||||
|
Core::Data::ExdData g_exdData;
|
||||||
|
|
||||||
|
|
||||||
|
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
|
||||||
|
const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" );
|
||||||
|
|
||||||
|
std::string generateEnum( const std::string& exd, int8_t nameIndex, const std::string& type, bool useLang = true )
|
||||||
|
{
|
||||||
|
|
||||||
|
xiv::dat::GameData data( datLocation );
|
||||||
|
xiv::exd::ExdData eData( data );
|
||||||
|
|
||||||
|
std::map< std::string, uint32_t> nameMap;
|
||||||
|
|
||||||
|
std::string result = "\n ///////////////////////////////////////////////////////////\n";
|
||||||
|
result += " //" + exd + ".exd\n";
|
||||||
|
result += " enum " + exd + " : " + type + "\n";
|
||||||
|
result += " {\n";
|
||||||
|
auto lang = useLang ? xiv::exd::Language::en : xiv::exd::Language::none;
|
||||||
|
auto access = g_exdData.setupDatAccess( exd, lang );
|
||||||
|
auto rows = access.get_rows();
|
||||||
|
|
||||||
|
for( auto row : rows )
|
||||||
|
{
|
||||||
|
auto& fields = row.second;
|
||||||
|
uint32_t id = row.first;
|
||||||
|
auto test = boost::get< std::string >( &fields.at( nameIndex ) );
|
||||||
|
if( !test )
|
||||||
|
continue;
|
||||||
|
auto str = *test ;
|
||||||
|
str.erase( boost::remove_if( str, boost::is_any_of(",_-':!(){} \x02\x1f\x01\x03") ), str.end() );
|
||||||
|
if( str.empty() )
|
||||||
|
continue;
|
||||||
|
str[0] = std::toupper( str[0] );
|
||||||
|
|
||||||
|
auto it = nameMap.find( str );
|
||||||
|
if( it != nameMap.end() )
|
||||||
|
{
|
||||||
|
nameMap[str]++;
|
||||||
|
str = str + std::to_string( nameMap[str] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nameMap[str] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result += " " + str + " = " + std::to_string( id ) + ",\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
result += " };\n";
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
|
||||||
|
g_log.init();
|
||||||
|
|
||||||
|
|
||||||
|
g_log.info( "Setting up EXD data" );
|
||||||
|
if( !g_exdData.init( datLocation ) )
|
||||||
|
{
|
||||||
|
g_log.fatal( "Error setting up EXD data " );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string result =
|
||||||
|
"/* This file has been automatically generated.\n Changes will be lost upon regeneration.\n To change the content edit tools/exd_common_gen */\n";
|
||||||
|
|
||||||
|
|
||||||
|
result += "namespace Core {\n";
|
||||||
|
result += "namespace Common {\n";
|
||||||
|
result += generateEnum( "ActionCategory", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "BeastReputationRank", 1, "uint8_t" );
|
||||||
|
result += generateEnum( "BeastTribe", 10, "uint8_t" );
|
||||||
|
result += generateEnum( "ClassJob", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "ContentType", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "EmoteCategory", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "ExVersion", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "GrandCompany", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "GuardianDeity", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "ItemUICategory", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "ItemSearchCategory", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "OnlineStatus", 2, "uint8_t" );
|
||||||
|
result += generateEnum( "Race", 1, "uint8_t" );
|
||||||
|
result += generateEnum( "Tribe", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "Town", 0, "uint8_t" );
|
||||||
|
result += generateEnum( "Weather", 1, "uint8_t" );
|
||||||
|
result += "}\n";
|
||||||
|
result += "}\n";
|
||||||
|
g_log.info( result );
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -15,58 +15,6 @@ include_directories("../")
|
||||||
file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*")
|
||||||
file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
||||||
|
|
||||||
set(SERVER_COMMON_DIR ../../sapphire/Server_Common)
|
|
||||||
set(Boost_USE_STATIC_LIBS ON)
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
include_directories("/usr/include/mysql/")
|
|
||||||
message(STATUS "Setting GCC flags")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -m32")
|
|
||||||
|
|
||||||
find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system)
|
|
||||||
if(Boost_FOUND)
|
|
||||||
set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR})
|
|
||||||
else()
|
|
||||||
if (EXISTS /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME})
|
|
||||||
set(Boost_INCLUDE_DIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME})
|
|
||||||
set(BOOST_LIBRARYDIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME}/stage/lib)
|
|
||||||
find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system)
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unable to find boost ${SAPPHIRE_BOOST_VER} package!")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
add_definitions(-D_WIN32_WINNT=0x601)
|
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL/")
|
|
||||||
message(STATUS "Setting MSVC flags")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHc")
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
|
||||||
|
|
||||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME})
|
|
||||||
message(STATUS "Using boost in /src/lib")
|
|
||||||
set(Boost_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME})
|
|
||||||
set(BOOST_LIBRARYDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME}/lib32-msvc-14.0)
|
|
||||||
else()
|
|
||||||
find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system)
|
|
||||||
if(Boost_FOUND)
|
|
||||||
set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR})
|
|
||||||
elseif ((EXISTS $ENV{BOOST_ROOT_DIR}) AND (EXISTS $ENV{BOOST_LIB_DIR}))
|
|
||||||
set(Boost_INCLUDE_DIR $ENV{BOOST_ROOT_DIR})
|
|
||||||
set(BOOST_LIBRARYDIR $ENV{BOOST_LIB_DIR})
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "SapphireError: Unable to find boost ${SAPPHIRE_BOOST_VER} package and environment variables BOOST_ROOT_DIR and BOOST_LIB_DIR not set!")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include_directories(${Boost_INCLUDE_DIR})
|
|
||||||
|
|
||||||
link_directories(${BOOST_LIBRARYDIR})
|
|
||||||
link_directories(${SERVER_COMMON_DIR})
|
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../sapphire/datReader/)
|
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL)
|
|
||||||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/zlib)
|
|
||||||
|
|
||||||
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/")
|
#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/")
|
||||||
add_executable(quest_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
add_executable(quest_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
Core::Logger g_log;
|
Core::Logger g_log;
|
||||||
Core::Data::ExdData g_exdData;
|
Core::Data::ExdData g_exdData;
|
||||||
|
|
Loading…
Add table
Reference in a new issue