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)
|
||||
get_git_head_revision(GIT_REFSPEC GIT_SHA1)
|
||||
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
|
||||
|
@ -56,5 +57,10 @@ link_directories(${SERVER_COMMON_DIR})
|
|||
link_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader)
|
||||
|
||||
add_subdirectory("src/servers")
|
||||
|
||||
add_subdirectory("src/libraries/sapphire/datReader")
|
||||
add_subdirectory("src/libraries/sapphire/mysqlConnector")
|
||||
|
||||
add_subdirectory("src/tools/exd_common_gen")
|
||||
add_subdirectory("src/tools/quest_parser")
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body scroll="no">
|
||||
<div id="TopDiv"></div>
|
||||
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
||||
<div class="container" id="Conttwo">
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body scroll="no">
|
||||
<div id="TopDiv"></div>
|
||||
<div class="container"><img src="assets/img/sapphire_logo.png" width="40%" height="40%"></div>
|
||||
<div class="container" id="Conttwo">
|
||||
|
|
|
@ -228,6 +228,9 @@ global CURRENCY_TOMESTONELORE = 0X0E
|
|||
////////////////////////////////////////////////////////////
|
||||
// Skill handle types
|
||||
////////////////////////////////////////////////////////////
|
||||
global STD_DAMAGE = 0X00
|
||||
global STD_HEAL = 0X01
|
||||
global STD_DOT = 0X02
|
||||
global STD_DAMAGE = 0X03
|
||||
global STD_HEAL = 0X04
|
||||
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 )
|
||||
{
|
||||
player.eventPlay( this.id, 0, 0x2001, 0, 1,
|
||||
player.eventPlay( this.id, 0, 0x04AC05, 0, 1,
|
||||
fun( player, eventId, param1, param2, param3 )
|
||||
{
|
||||
player.setOpeningSequence( 1 );
|
||||
|
|
|
@ -72,7 +72,6 @@ class OpeningLimsaLominsaDef
|
|||
player.eventPlay( this.id, 40, 1, 2, 1,
|
||||
fun( player, eventId, param1, param2, param3 )
|
||||
{
|
||||
player.eventFinish( eventId, UNLOCK );
|
||||
if( player.getOpeningSequence() == 2 )
|
||||
{
|
||||
// update the instance boundaries
|
||||
|
|
|
@ -35,7 +35,7 @@ class OpeningUldahDef
|
|||
|
||||
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 )
|
||||
{
|
||||
player.setOpeningSequence( 1 );
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
// Start NPC: 1001140
|
||||
// End NPC: 1000100
|
||||
|
||||
class ManFst003Def
|
||||
class ManFst003Def
|
||||
{
|
||||
def ManFst003Def()
|
||||
{
|
||||
// Basic quest information
|
||||
// Basic quest information
|
||||
this.name = "Close to Home";
|
||||
this.id = 65659;
|
||||
|
||||
|
@ -24,13 +24,13 @@ class ManFst003Def
|
|||
// GetQuestUI8BL
|
||||
// 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
|
||||
this.SEQ_0 = 0;
|
||||
this.SEQ_1 = 1;
|
||||
this.SEQ_FINISH = 255;
|
||||
|
||||
// Quest rewards
|
||||
// Quest rewards
|
||||
this.RewardExpFactor = 100;
|
||||
this.RewardGil = 107;
|
||||
|
||||
|
@ -74,7 +74,6 @@ class ManFst003Def
|
|||
def checkQuestCompletion( player, varIdx )
|
||||
{
|
||||
|
||||
print( varIdx );
|
||||
if (varIdx == 3)
|
||||
{
|
||||
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*/,
|
||||
fun( player, eventId, param1, param2, param3 )
|
||||
{
|
||||
player.setQuestUI8AL( ManFst004.id, 1 );
|
||||
ManFst003.checkQuestCompletion( player, 1 );
|
||||
player.setQuestUI8AL( ManFst003.id, 1 );
|
||||
ManFst003.checkQuestCompletion( player, 0 );
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -128,7 +127,7 @@ class ManFst003Def
|
|||
player.eventPlay( this.id, 2, 0, 0, 0,
|
||||
fun( player, eventId, param1, param2, param3 )
|
||||
{
|
||||
player.setQuestUI8BH( ManFst004.id, 1 );
|
||||
player.setQuestUI8BH( ManFst003.id, 1 );
|
||||
ManFst003.checkQuestCompletion( player, 3 );
|
||||
});
|
||||
}
|
||||
|
@ -207,8 +206,8 @@ class ManFst003Def
|
|||
player.eventPlay( this.id, 100, 0x0EFB, 0, 0,
|
||||
fun( player, eventId, param1, param2, param3 )
|
||||
{
|
||||
player.setQuestUI8CH( ManFst004.id, 0 ); // remove key item, since we have just traded it
|
||||
player.setQuestUI8BL( ManFst004.id, 1 );
|
||||
player.setQuestUI8CH( ManFst003.id, 0 ); // remove key item, since we have just traded it
|
||||
player.setQuestUI8BL( ManFst003.id, 1 );
|
||||
ManFst003.checkQuestCompletion(player, 2 );
|
||||
});
|
||||
}
|
||||
|
@ -237,7 +236,6 @@ class ManFst003Def
|
|||
},
|
||||
fun( player, eventId, additional ) {},
|
||||
eventId );
|
||||
player.unlock();
|
||||
}
|
||||
else if( actor == this.ACTOR2 )
|
||||
{
|
||||
|
@ -257,4 +255,3 @@ class ManFst003Def
|
|||
};
|
||||
|
||||
GLOBAL ManFst003 = ManFst003Def();
|
||||
|
||||
|
|
|
@ -51,11 +51,12 @@ class ManSea001Def
|
|||
// Available Scenes in this quest, not necessarly all are used
|
||||
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 )
|
||||
{
|
||||
if( param2 == 1 )
|
||||
{
|
||||
player.setOpeningSequence( 2 );
|
||||
ManSea001.Scene00001( player );
|
||||
}
|
||||
});
|
||||
|
@ -63,7 +64,7 @@ class ManSea001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
ManSea001.Scene00002( player );
|
||||
|
@ -81,13 +82,13 @@ class ManSea001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
player.questUpdate( ManSea001.id, 0x01 ); // add quest to player.
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if( param2 == 1 )
|
||||
|
@ -141,7 +142,7 @@ class ManSea001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
ManSea001.Scene00012( player );
|
||||
|
@ -150,7 +151,7 @@ class ManSea001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
if( param2 == 1 )
|
||||
|
|
|
@ -9,25 +9,25 @@
|
|||
// Start NPC: 1003987
|
||||
// End NPC: 1003988
|
||||
|
||||
class ManWil001Def
|
||||
class ManWil001Def
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// default ctor
|
||||
def ManWil001Def()
|
||||
{
|
||||
// Basic quest information
|
||||
// Basic quest information
|
||||
this.name = "Coming to Ul'dah";
|
||||
this.id = 66130;
|
||||
|
||||
// Quest vars / flags used
|
||||
// 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
|
||||
this.SEQ_0 = 0;
|
||||
this.SEQ_FINISH = 255;
|
||||
|
||||
// Quest rewards
|
||||
// Quest rewards
|
||||
this.RewardExpFactor = 50;
|
||||
this.RewardGil = 103;
|
||||
|
||||
|
@ -49,11 +49,12 @@ class ManWil001Def
|
|||
// Available Scenes in this quest, not necessarly all are used
|
||||
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 )
|
||||
{
|
||||
if( param2 == 1 ) // accept quest
|
||||
{
|
||||
player.setOpeningSequence( 2 );
|
||||
ManWil001.Scene00001( player );
|
||||
}
|
||||
});
|
||||
|
@ -61,7 +62,7 @@ class ManWil001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
ManWil001.Scene00002( player );
|
||||
|
@ -70,11 +71,11 @@ class ManWil001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
player.questUpdate( ManWil001.id, ManWil001Obj.SEQ_FINISH );// add quest to player.
|
||||
player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 );
|
||||
player.questUpdate( ManWil001.id, ManWil001.SEQ_FINISH );// add quest to player.
|
||||
player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 );
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -85,7 +86,7 @@ class ManWil001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
ManWil001.Scene00005( player );
|
||||
|
@ -94,7 +95,7 @@ class ManWil001Def
|
|||
|
||||
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 )
|
||||
{
|
||||
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,
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
Race = 0x00,
|
||||
|
@ -548,7 +571,7 @@ namespace Core {
|
|||
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)?
|
||||
Unknown_0 = 0,
|
||||
|
@ -581,7 +604,7 @@ namespace Core {
|
|||
GpGain = 14
|
||||
};
|
||||
|
||||
enum ActionHitSeverityType : uint8_t
|
||||
enum class ActionHitSeverityType : uint8_t
|
||||
{
|
||||
NormalDamage = 0,
|
||||
CritHeal = 0,
|
||||
|
@ -591,6 +614,19 @@ namespace Core {
|
|||
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
|
||||
{
|
||||
Event,
|
||||
|
@ -605,8 +641,16 @@ namespace Core {
|
|||
StdDot,
|
||||
};
|
||||
|
||||
enum InvincibilityType : uint8_t
|
||||
{
|
||||
InvincibilityNone,
|
||||
InvincibilityRefill,
|
||||
InvincibilityStayAlive,
|
||||
};
|
||||
|
||||
enum struct PlayerStateFlag : uint8_t
|
||||
{
|
||||
SomeFlag,
|
||||
NoCombat,
|
||||
Combat,
|
||||
Casting,
|
||||
|
@ -614,9 +658,9 @@ namespace Core {
|
|||
StatusAffliction1,
|
||||
Occupied,
|
||||
Occupied1,
|
||||
|
||||
Occupied2,
|
||||
Occupied3,
|
||||
|
||||
BoundByDuty,
|
||||
Occupied4,
|
||||
DuelingArea,
|
||||
|
@ -627,6 +671,7 @@ namespace Core {
|
|||
PreparingToCraft,
|
||||
Gathering,
|
||||
Fishing,
|
||||
|
||||
BeingRaised,
|
||||
BetweenAreas,
|
||||
Stealthed,
|
||||
|
@ -637,9 +682,9 @@ namespace Core {
|
|||
BetweenAreas1,
|
||||
SystemError,
|
||||
LoggingOut,
|
||||
|
||||
InvalidLocation,
|
||||
WaitingForDuty,
|
||||
|
||||
BoundByDuty1,
|
||||
Mounting,
|
||||
WatchingCutscene,
|
||||
|
@ -657,9 +702,9 @@ namespace Core {
|
|||
FreeTrail,
|
||||
BeingMoved,
|
||||
Mounting2,
|
||||
|
||||
StatusAffliction3,
|
||||
StatusAffliction4,
|
||||
|
||||
RegisteringRaceOrMatch,
|
||||
WaitingForRaceOrMatch,
|
||||
WaitingForTripleTriadMatch,
|
||||
|
|
|
@ -323,70 +323,74 @@ bool Core::Data::ExdData::loadActionInfo()
|
|||
continue;
|
||||
}
|
||||
|
||||
std::string name = getField< std::string >( fields, 0 ); // 0
|
||||
uint8_t category = getField< uint8_t >( fields, 3 ); // 3
|
||||
std::string name = getField< std::string >( fields, 0 ); // 0
|
||||
uint8_t category = getField< uint8_t >( fields, 3 ); // 3
|
||||
|
||||
int8_t class_job = getField< int8_t >( fields, 10 ); // 10
|
||||
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
|
||||
int8_t range = getField< int8_t >( fields, 13 ); // 13
|
||||
bool can_target_self = getField< bool >( fields, 14 ); // 14
|
||||
bool can_target_party = getField< bool>( fields, 15 ); // 15
|
||||
bool can_target_friendly = getField< bool >( fields, 16 ); // 16
|
||||
bool can_target_enemy = getField< bool >( fields, 17 ); // 17
|
||||
int8_t class_job = getField< int8_t >( fields, 10 ); // 10
|
||||
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
|
||||
int8_t range = getField< int8_t >( fields, 13 ); // 13
|
||||
bool can_target_self = getField< bool >( fields, 14 ); // 14
|
||||
bool can_target_party = getField< bool>( fields, 15 ); // 15
|
||||
bool can_target_friendly = getField< bool >( fields, 16 ); // 16
|
||||
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)
|
||||
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 radius = getField< uint8_t >( fields, 27 ); // 27
|
||||
uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26
|
||||
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
|
||||
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
||||
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30
|
||||
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31
|
||||
|
||||
uint32_t instantval = getField< bool >( fields, 35 ); // 35
|
||||
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
||||
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
||||
bool is_instant = getField< bool >( fields, 35 ); // 35
|
||||
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36
|
||||
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37
|
||||
|
||||
int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model
|
||||
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect
|
||||
int8_t model = getField< int8_t >( fields, 39 ); // 39
|
||||
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40
|
||||
|
||||
uint8_t typeshift = 0x6;
|
||||
uint8_t mask = 1 << typeshift;
|
||||
instantval &= mask;
|
||||
bool final = ( instantval & mask ) == mask;
|
||||
bool is_instant = final;
|
||||
uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42
|
||||
bool affects_position = getField< bool >( fields, 47 ); // 47
|
||||
|
||||
|
||||
info->id = id;
|
||||
info->name = name;
|
||||
info->category = category;
|
||||
|
||||
info->id = id;
|
||||
info->name = name;
|
||||
info->category = category;
|
||||
|
||||
info->class_job = class_job;
|
||||
info->unlock_level = unlock_level;
|
||||
info->range = range;
|
||||
info->can_target_self = can_target_self;
|
||||
info->can_target_party = can_target_party;
|
||||
info->class_job = class_job;
|
||||
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_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->points_cost = points_cost;
|
||||
info->aoe_type = aoe_type;
|
||||
info->aoe_range = aoe_range;
|
||||
info->aoe_width = aoe_width;
|
||||
|
||||
info->is_instant = is_instant;
|
||||
info->cast_time = cast_time * 100;
|
||||
info->recast_time = recast_time * 100;
|
||||
info->points_type = points_type;
|
||||
info->points_cost = points_cost;
|
||||
|
||||
info->model = model;
|
||||
info->aspect = aspect;
|
||||
info->is_instant = is_instant;
|
||||
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 ) );
|
||||
|
||||
|
|
|
@ -233,12 +233,13 @@ namespace Core {
|
|||
bool can_target_friendly; // 16
|
||||
bool can_target_enemy; // 17
|
||||
|
||||
bool is_aoe; // 20
|
||||
bool is_ground_aoe; // 20
|
||||
|
||||
bool can_target_ko; // 24
|
||||
|
||||
uint8_t aoe_type; // 26
|
||||
uint8_t radius; // 27
|
||||
uint8_t aoe_range; // 27
|
||||
uint8_t aoe_width; // 28
|
||||
|
||||
uint8_t points_type; // 30
|
||||
uint16_t points_cost; // 31
|
||||
|
@ -249,6 +250,12 @@ namespace Core {
|
|||
|
||||
int8_t model; // 39
|
||||
uint8_t aspect; // 40
|
||||
|
||||
uint16_t toggle_status_id; // 42
|
||||
|
||||
bool affects_position; // 47
|
||||
|
||||
bool is_aoe; // Internal only
|
||||
};
|
||||
|
||||
struct EventItemInfo
|
||||
|
|
|
@ -50,7 +50,7 @@ void Core::Action::ActionCast::onStart()
|
|||
m_pSource->getAsPlayer()->sendDebug( "onStart()" );
|
||||
m_startTime = Util::getTimeMs();
|
||||
|
||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() );
|
||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() );
|
||||
|
||||
castPacket.data().action_id = m_id;
|
||||
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();
|
||||
|
||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() );
|
||||
GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() );
|
||||
|
||||
castPacket.data().action_id = 5;
|
||||
castPacket.data().unknown = 1;
|
||||
|
|
|
@ -53,8 +53,7 @@ void Core::Action::EventAction::onStart()
|
|||
if( m_pSource->isPlayer() )
|
||||
{
|
||||
m_pSource->sendToInRangeSet( control, true );
|
||||
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::NoCombat );
|
||||
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Occupied1 );
|
||||
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag );
|
||||
m_pSource->getAsPlayer()->sendStateFlags();
|
||||
}
|
||||
else
|
||||
|
@ -85,8 +84,7 @@ void Core::Action::EventAction::onFinish()
|
|||
|
||||
if( m_pSource->isPlayer() )
|
||||
{
|
||||
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat );
|
||||
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
|
||||
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag );
|
||||
m_pSource->getAsPlayer()->sendStateFlags();
|
||||
m_pSource->sendToInRangeSet( control, true );
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <src/servers/Server_Common/Util/Util.h>
|
||||
#include <src/servers/Server_Common/Util/UtilMath.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/Action/Action.h"
|
||||
|
@ -15,11 +16,14 @@
|
|||
|
||||
#include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.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/Session.h"
|
||||
#include "CalcBattle.h"
|
||||
#include "Player.h"
|
||||
|
||||
extern Core::ServerZone g_serverZone;
|
||||
extern Core::Data::ExdData g_exdData;
|
||||
|
||||
using namespace Core::Common;
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
|
@ -109,6 +113,12 @@ uint16_t Core::Entity::Actor::getGp() const
|
|||
return m_gp;
|
||||
}
|
||||
|
||||
/*! \return current invincibility type */
|
||||
InvincibilityType Core::Entity::Actor::getInvincibilityType() const
|
||||
{
|
||||
return m_invincibilityType;
|
||||
}
|
||||
|
||||
/*! \return current class or job */
|
||||
Core::Common::ClassJob Core::Entity::Actor::getClass() const
|
||||
{
|
||||
|
@ -161,32 +171,44 @@ uint32_t Core::Entity::Actor::getMaxMp() const
|
|||
void Core::Entity::Actor::resetHp()
|
||||
{
|
||||
m_hp = getMaxHp();
|
||||
sendStatusUpdate( true );
|
||||
}
|
||||
|
||||
/*! \return reset mp to current max mp */
|
||||
void Core::Entity::Actor::resetMp()
|
||||
{
|
||||
m_mp = getMaxMp();
|
||||
sendStatusUpdate( true );
|
||||
}
|
||||
|
||||
/*! \param hp amount to set ( caps to maxHp ) */
|
||||
void Core::Entity::Actor::setHp( uint32_t hp )
|
||||
{
|
||||
m_hp = hp < getMaxHp() ? hp : getMaxHp();
|
||||
sendStatusUpdate( true );
|
||||
}
|
||||
|
||||
/*! \param mp amount to set ( caps to maxMp ) */
|
||||
void Core::Entity::Actor::setMp( uint32_t mp )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 */
|
||||
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 );
|
||||
|
||||
if( oldRot != newRot )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return oldRot != newRot ? true : false;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -331,8 +350,18 @@ void Core::Entity::Actor::takeDamage( uint32_t damage )
|
|||
{
|
||||
if( damage >= m_hp )
|
||||
{
|
||||
m_hp = 0;
|
||||
die();
|
||||
switch( m_invincibilityType ) {
|
||||
case InvincibilityNone:
|
||||
setHp( 0 );
|
||||
die();
|
||||
break;
|
||||
case InvincibilityRefill:
|
||||
resetHp();
|
||||
break;
|
||||
case InvincibilityStayAlive:
|
||||
setHp( 0 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
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 */
|
||||
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 */
|
||||
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 );
|
||||
addStatusEffect( effect );
|
||||
}
|
||||
|
@ -639,7 +798,8 @@ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t du
|
|||
{
|
||||
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 );
|
||||
addStatusEffect( effect );
|
||||
}
|
||||
|
|
|
@ -150,6 +150,8 @@ protected:
|
|||
Action::ActionPtr m_pCurrentAction;
|
||||
/*! Container for status effects */
|
||||
StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer;
|
||||
/*! Invincibility type */
|
||||
Common::InvincibilityType m_invincibilityType;
|
||||
|
||||
public:
|
||||
Actor();
|
||||
|
@ -199,6 +201,8 @@ public:
|
|||
|
||||
uint16_t getGp() const;
|
||||
|
||||
Common::InvincibilityType getInvincibilityType() const;
|
||||
|
||||
Common::ClassJob getClass() const;
|
||||
|
||||
uint8_t getClassAsInt() const;
|
||||
|
@ -225,12 +229,16 @@ public:
|
|||
|
||||
void setGp( uint32_t gp );
|
||||
|
||||
void setInvincibilityType( Common::InvincibilityType type );
|
||||
|
||||
void die();
|
||||
|
||||
ActorStatus getStatus() const;
|
||||
|
||||
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 spawn( PlayerPtr pTarget ) {}
|
||||
|
|
|
@ -54,6 +54,7 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com
|
|||
m_type = ActorType::BattleNpc;
|
||||
|
||||
m_mode = MODE_IDLE;
|
||||
m_targetId = INVALID_GAME_OBJECT_ID;
|
||||
|
||||
m_maxHp = 150;
|
||||
m_maxMp = 100;
|
||||
|
@ -82,6 +83,8 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com
|
|||
|
||||
m_mobType = mobType;
|
||||
|
||||
m_invincibilityType = InvincibilityType::InvincibilityNone;
|
||||
|
||||
//m_type = static_cast< Common::ActorType >( type );
|
||||
|
||||
}
|
||||
|
@ -229,7 +232,7 @@ void Core::Entity::BattleNpc::setOwner( Core::Entity::PlayerPtr pPlayer )
|
|||
}
|
||||
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().actorId = INVALID_GAME_OBJECT_ID;
|
||||
sendToInRangeSet( setOwnerPacket );
|
||||
|
@ -251,15 +254,15 @@ bool Core::Entity::BattleNpc::moveTo( Common::FFXIVARR_POSITION3& pos )
|
|||
// reached destination
|
||||
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);
|
||||
|
||||
face( pos );
|
||||
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 z = static_cast< float >( sinf(angle) * 1.1f );
|
||||
float z = static_cast< float >( sinf( angle ) * 1.1f );
|
||||
|
||||
Common::FFXIVARR_POSITION3 newPos;
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ private:
|
|||
uint32_t m_unk2;
|
||||
std::set< HateListEntry* > m_hateList;
|
||||
ActorPtr m_pOwner;
|
||||
int32_t m_timeOfDeath;
|
||||
uint32_t m_timeOfDeath;
|
||||
uint32_t m_mobType;
|
||||
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Player.h"
|
||||
#include <cmath>
|
||||
|
||||
using namespace Core::Data;
|
||||
using namespace Core::Entity;
|
||||
|
||||
extern Core::Data::ExdData g_exdData;
|
||||
|
@ -44,9 +45,6 @@ float CalcBattle::calculateBaseStat( PlayerPtr pPlayer )
|
|||
base = 1.63f * level + 121.02f;
|
||||
// ARR Base Stat Formula (Off by one in several cases)
|
||||
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;
|
||||
|
||||
return base;
|
||||
|
@ -83,7 +81,7 @@ uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer )
|
|||
else if ( level >= 50 )
|
||||
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
|
||||
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 ) ) );
|
||||
|
||||
|
@ -113,7 +111,6 @@ uint32_t CalcBattle::calculateMaxMp( PlayerPtr pPlayer )
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
|
||||
{
|
||||
auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() );
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
#include "Actor.h"
|
||||
|
||||
using namespace Core::Entity;
|
||||
|
||||
namespace Core {
|
||||
namespace Entity {
|
||||
namespace Data {
|
||||
|
||||
class CalcBattle
|
||||
{
|
||||
|
|
|
@ -82,6 +82,7 @@ Core::Entity::Player::Player() :
|
|||
m_onlineStatus = 0;
|
||||
m_queuedZoneing = nullptr;
|
||||
m_status = ActorStatus::Idle;
|
||||
m_invincibilityType = InvincibilityType::InvincibilityNone;
|
||||
|
||||
memset( m_questTracking, 0, sizeof( m_questTracking ) );
|
||||
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().fadeOutTime = fadeOutTime;
|
||||
preparePacket.data().animation = animation;
|
||||
preparePacket.data().fadeOut = fadeOut == true ? 1 : 0;
|
||||
preparePacket.data().fadeOut = static_cast< uint8_t >( fadeOut ? 1 : 0 );
|
||||
queuePacket( preparePacket );
|
||||
}
|
||||
|
||||
|
@ -216,7 +217,7 @@ void Core::Entity::Player::calculateStats()
|
|||
auto paramGrowthInfo = paramGrowthInfoIt->second;
|
||||
|
||||
// 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.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.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 )
|
||||
m_mp = m_baseStats.max_mp;
|
||||
|
@ -398,7 +399,7 @@ void Core::Entity::Player::setZone( uint32_t zoneId )
|
|||
if( isLogin() )
|
||||
{
|
||||
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
|
||||
contentFinderList.data().contents[i] = 0xFF;
|
||||
|
@ -632,7 +633,9 @@ void Core::Entity::Player::gainExp( uint32_t amount )
|
|||
if( ( currentExp + amount ) >= neededExpToLevel )
|
||||
{
|
||||
// levelup
|
||||
amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ? neededExpToLevelplus1 - 1 : ( currentExp + amount - neededExpToLevel );
|
||||
amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ?
|
||||
neededExpToLevelplus1 - 1 :
|
||||
( currentExp + amount - neededExpToLevel );
|
||||
setExp( amount );
|
||||
gainLevel();
|
||||
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 );
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
ModelEquipPacket modelEquip( getAsPlayer() );
|
||||
|
@ -846,6 +805,12 @@ uint32_t Core::Entity::Player::getModelForSlot( Inventory::EquipSlot 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
|
||||
{
|
||||
return m_modelMainWeapon;
|
||||
|
@ -973,7 +938,7 @@ void Core::Entity::Player::setGcRankAt( uint8_t index, uint8_t rank )
|
|||
setSyncFlag( PlayerSyncFlags::GC );
|
||||
}
|
||||
|
||||
const uint8_t * Core::Entity::Player::getStateFlags() const
|
||||
const uint8_t* Core::Entity::Player::getStateFlags() const
|
||||
{
|
||||
return m_stateFlags;
|
||||
}
|
||||
|
@ -1086,21 +1051,16 @@ void Core::Entity::Player::update( int64_t 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( m_targetId )
|
||||
if( m_targetId && m_currentStance == Entity::Actor::Stance::Active && isAutoattackOn() )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if( isAutoattackOn() &&
|
||||
actor->getId() == m_targetId &&
|
||||
actor->isAlive() &&
|
||||
mainWeap &&
|
||||
m_currentStance == Entity::Actor::Stance::Active
|
||||
)
|
||||
if( actor->getId() == m_targetId && actor->isAlive() && mainWeap )
|
||||
{
|
||||
// default autoattack range
|
||||
// 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
|
||||
|
@ -1644,9 +1496,7 @@ uint32_t Core::Entity::Player::getCFPenaltyMinutes() const
|
|||
|
||||
// check if penalty timestamp already passed current time
|
||||
if (currentTimestamp > endTimestamp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto deltaTime = endTimestamp - currentTimestamp;
|
||||
return static_cast< uint32_t > ( ceil( static_cast< float > (deltaTime) / 60 ) );
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
/*! load data for currently active quests */
|
||||
bool loadActiveQuests();
|
||||
/*! 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 */
|
||||
bool hasQuest( uint16_t questId );
|
||||
/*! return the current quest sequence */
|
||||
|
@ -218,6 +218,8 @@ public:
|
|||
const uint32_t * getModelArray() const;
|
||||
/*! return the equipment model in a specified equipment 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 */
|
||||
uint32_t getCurrency( uint8_t type ) const;
|
||||
/*! add amount to the currency of type */
|
||||
|
@ -487,8 +489,6 @@ public:
|
|||
void setAutoattack( bool mode );
|
||||
bool isAutoattackOn() const;
|
||||
|
||||
void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target );
|
||||
|
||||
// Content Finder handling
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/*! 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/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 "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()
|
||||
|
|
|
@ -74,7 +74,7 @@ bool Core::Entity::Player::loadActiveQuests()
|
|||
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 ) )
|
||||
{
|
||||
|
@ -100,7 +100,7 @@ void Core::Entity::Player::finishQuest( uint16_t questId )
|
|||
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_freeQuestIdxQueue.push( idx );
|
||||
|
@ -123,7 +123,7 @@ void Core::Entity::Player::unfinishQuest( 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 ) )
|
||||
{
|
||||
|
@ -973,7 +973,7 @@ uint8_t Core::Entity::Player::getQuestSeq( uint16_t questId )
|
|||
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 ) )
|
||||
{
|
||||
|
|
|
@ -239,25 +239,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
|
|||
else
|
||||
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" )
|
||||
{
|
||||
int32_t minutes;
|
||||
|
@ -273,6 +254,20 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye
|
|||
pPlayer->setEorzeaTimeOffset( 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);*/
|
||||
|
||||
}
|
||||
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( 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 )
|
||||
{
|
||||
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() ) );
|
||||
}
|
||||
|
|
|
@ -440,14 +440,14 @@ bool Core::Inventory::removeCrystal( CrystalType type, uint32_t amount )
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Core::Inventory::isObtainable( uint32_t catalogId, uint16_t quantity )
|
||||
bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
|
||||
{
|
||||
|
||||
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 );
|
||||
|
@ -587,7 +587,7 @@ void Core::Inventory::swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, ui
|
|||
{
|
||||
updateContainer( fromInventoryId, fromSlotId, nullptr );
|
||||
fromInventoryId = getArmoryToEquipSlot( toSlot );
|
||||
fromSlotId = m_inventoryMap[fromInventoryId]->getFreeSlot();
|
||||
fromSlotId = static_cast < uint8_t >( m_inventoryMap[fromInventoryId]->getFreeSlot() );
|
||||
}
|
||||
|
||||
auto containerTypeFrom = getContainerType( fromInventoryId );
|
||||
|
|
|
@ -140,7 +140,7 @@ public:
|
|||
|
||||
InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId );
|
||||
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 swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot );
|
||||
void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId );
|
||||
|
@ -175,7 +175,7 @@ public:
|
|||
bool addCrystal( CrystalType type, uint32_t amount );
|
||||
/*! remove amount from the crystals of type */
|
||||
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();
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@ enum GmCommand
|
|||
Tp = 0x0066,
|
||||
Gp = 0x0067,
|
||||
Exp = 0x0068,
|
||||
Inv = 0x006A,
|
||||
|
||||
Item = 0x00C8,
|
||||
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] ) );
|
||||
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:
|
||||
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::ServerZone::ServerZone( const std::string& configPath, uint16_t serverId )
|
||||
: m_configPath( configPath )
|
||||
: m_configPath( configPath ),
|
||||
m_bRunning( true )
|
||||
{
|
||||
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.init();
|
||||
|
||||
g_log.info( "===========================================================" );
|
||||
g_log.info( "Sapphire Server Project " );
|
||||
g_log.info( "Version: " + Core::Version::VERSION );
|
||||
g_log.info( "GitHash: " + Core::Version::GIT_HASH );
|
||||
g_log.info( "Compiled: " __DATE__ " " __TIME__ );
|
||||
g_log.info( "===========================================================" );
|
||||
|
||||
printBanner();
|
||||
|
||||
if( !loadSettings( argc, argv ) )
|
||||
{
|
||||
|
@ -364,24 +361,47 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
|||
Network::HivePtr hive( new Network::Hive() );
|
||||
Network::addServerToHive< Network::GameConnection >( m_ip, m_port, hive );
|
||||
|
||||
g_scriptMgr.init();
|
||||
|
||||
g_log.info( "ZoneMgr: Setting up zones" );
|
||||
g_zoneMgr.createZones();
|
||||
|
||||
g_scriptMgr.init();
|
||||
|
||||
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( "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();
|
||||
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;
|
||||
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();
|
||||
for( ; it != m_sessionMap.end(); )
|
||||
|
||||
auto it = this->m_sessionMap.begin();
|
||||
for( ; it != this->m_sessionMap.end(); )
|
||||
{
|
||||
uint32_t diff = currTime - it->second->getLastDataTime();
|
||||
|
||||
|
@ -403,11 +423,11 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
|
|||
|
||||
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();
|
||||
// if( it->second.unique() )
|
||||
{
|
||||
it = m_sessionMap.erase( it );
|
||||
it = this->m_sessionMap.erase(it );
|
||||
}
|
||||
}
|
||||
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 )
|
||||
|
@ -510,3 +523,8 @@ void Core::ServerZone::updateSession( std::string playerName )
|
|||
it->second->loadPlayer();
|
||||
}
|
||||
|
||||
bool Core::ServerZone::isRunning() const
|
||||
{
|
||||
return m_bRunning;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,12 +40,20 @@ namespace Core {
|
|||
|
||||
Entity::BattleNpcTemplatePtr getBnpcTemplate( std::string templateName );
|
||||
|
||||
void mainLoop();
|
||||
|
||||
bool isRunning() const;
|
||||
|
||||
void printBanner() const;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
uint16_t m_port;
|
||||
std::string m_ip;
|
||||
|
||||
bool m_bRunning;
|
||||
|
||||
std::string m_configPath;
|
||||
|
||||
XMLConfigPtr m_pConfig;
|
||||
|
|
|
@ -194,13 +194,13 @@ void Core::StatusEffect::StatusEffectContainer::update()
|
|||
if( thisTickDmg != 0 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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_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/")
|
||||
add_executable(quest_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include <fstream>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
Core::Logger g_log;
|
||||
Core::Data::ExdData g_exdData;
|
||||
|
|
Loading…
Add table
Reference in a new issue