1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-07-12 07:07:45 +00:00
This commit is contained in:
Maru 2018-02-04 15:42:43 -02:00
commit 5e50ef48be
107 changed files with 3839 additions and 2331 deletions

2
.gitignore vendored
View file

@ -113,4 +113,4 @@ src/common/Version\.cpp
.mtime_cache .mtime_cache
# generated script loader files # generated script loader files
scripts/native/*/ScriptLoader.cpp src/servers/sapphire_zone/Script/Scripts/*/ScriptLoader.cpp

View file

@ -67,6 +67,4 @@ add_subdirectory("src/tools/exd_common_gen")
add_subdirectory("src/tools/exd_struct_gen") add_subdirectory("src/tools/exd_struct_gen")
add_subdirectory("src/tools/exd_struct_test") add_subdirectory("src/tools/exd_struct_test")
add_subdirectory("src/tools/quest_parser") add_subdirectory("src/tools/quest_parser")
add_subdirectory("src/tools/pcb_reader") #add_subdirectory("src/tools/pcb_reader")
add_subdirectory("scripts/native")

View file

@ -13,7 +13,7 @@
<CachePath>./cache/</CachePath> <CachePath>./cache/</CachePath>
<HotSwap> <HotSwap>
<Enabled>1</Enabled> <Enabled>true</Enabled>
<ScriptsDir>../scripts/native/</ScriptsDir> <ScriptsDir>../scripts/native/</ScriptsDir>
<BuildDir>../cmake-build-debug/</BuildDir> <BuildDir>../cmake-build-debug/</BuildDir>
<BuildCmd>cmake --build %1% --target %2%</BuildCmd> <BuildCmd>cmake --build %1% --target %2%</BuildCmd>

View file

@ -43,6 +43,7 @@ MODIFY COLUMN UPDATE_DATE DATETIME NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURR
ALTER TABLE charainfo ALTER TABLE charainfo
ADD `Orchestrion` binary(38) DEFAULT NULL AFTER `Mounts`; ADD `Orchestrion` binary(38) DEFAULT NULL AFTER `Mounts`;
ALTER TABLE `charainfo` CHANGE `Mounts` `Mounts` BINARY(14) NULL DEFAULT NULL; ALTER TABLE `charainfo` CHANGE `Mounts` `Mounts` BINARY(15) NULL DEFAULT NULL;
ALTER TABLE `charainfo` CHANGE `Orchestrion` `Orchestrion` BINARY(40) NULL DEFAULT NULL; ALTER TABLE `charainfo` CHANGE `Orchestrion` `Orchestrion` BINARY(40) NULL DEFAULT NULL;
ALTER TABLE `charainfo` CHANGE `Minions` `Minions` BINARY(35) NULL DEFAULT NULL; ALTER TABLE `charainfo` CHANGE `Minions` `Minions` BINARY(37) NULL DEFAULT NULL;
ALTER TABLE `charainfo` CHANGE `QuestCompleteFlags` `QuestCompleteFlags` VARBINARY(396) NULL DEFAULT NULL;

View file

@ -5,7 +5,8 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
file(GLOB UTILS_PUBLIC_INCLUDE_FILES file(GLOB UTILS_PUBLIC_INCLUDE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/*.h") "${CMAKE_CURRENT_SOURCE_DIR}/*.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Exd/*.h" )
file(GLOB UTILS_SOURCE_FILES file(GLOB UTILS_SOURCE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Config/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Config/*.cpp"

View file

@ -79,9 +79,9 @@ uint32_t Core::Db::DbConnection::getLastError()
return m_pConnection->getErrorNo(); return m_pConnection->getErrorNo();
} }
void Core::Db::DbConnection::ping() bool Core::Db::DbConnection::ping()
{ {
m_pConnection->ping(); return m_pConnection->ping();
} }
bool Core::Db::DbConnection::lockIfReady() bool Core::Db::DbConnection::lockIfReady()
@ -146,6 +146,17 @@ boost::shared_ptr< Mysql::ResultSet > Core::Db::DbConnection::query( boost::shar
if( !stmt ) if( !stmt )
return nullptr; return nullptr;
if( !ping() )
{
g_log.error( "MysqlConnection went down" );
// naivly reconnect and hope for the best
open();
lockIfReady();
if( !prepareStatements() )
g_log.error( "Mysql Statements failed to prepare..." );
g_log.info( "MysqlConnection reestablished" );
}
uint32_t index = stmt->getIndex(); uint32_t index = stmt->getIndex();
auto pStmt = getPreparedStatement( index ); auto pStmt = getPreparedStatement( index );

View file

@ -72,7 +72,7 @@ namespace Db
void rollbackTransaction(); void rollbackTransaction();
void commitTransaction(); void commitTransaction();
void ping(); bool ping();
uint32_t getLastError(); uint32_t getLastError();
bool lockIfReady(); bool lockIfReady();

View file

@ -85,10 +85,11 @@ bool Core::Data::ExdData::loadZoneInfo()
int16_t map_index = getField< int16_t >( mapDataFields, 12 ); int16_t map_index = getField< int16_t >( mapDataFields, 12 );
bool is_two_bytes = getField< bool >( mapDataFields, 15 ); bool is_two_bytes = getField< bool >( mapDataFields, 15 );
uint16_t weather_rate = getField< uint16_t >( fields, 10 ) > 75 ? 0 : getField< uint16_t >( fields, 10 ); uint8_t weather_rate = getField< uint8_t >( fields, 12 ) > 75 ? 0 : getField< uint8_t >( fields, 12 );
auto weatherRateFields = weatherRate.get_row( weather_rate ); auto weatherRateFields = weatherRate.get_row( weather_rate );
int32_t aetheryte_index = getField< int32_t >( fields, 23 ); int32_t aetheryte_index = getField< int32_t >( fields, 23 );
uint8_t zoneType = getField< uint8_t >( fields, 9 );
ZoneInfo info{ 0 }; ZoneInfo info{ 0 };
@ -101,6 +102,8 @@ bool Core::Data::ExdData::loadZoneInfo()
info.map_id = map_id; info.map_id = map_id;
info.weather_rate = weather_rate; // TODO: deal with weather groups info.weather_rate = weather_rate; // TODO: deal with weather groups
info.aetheryte_index = aetheryte_index; info.aetheryte_index = aetheryte_index;
info.zone_type = zoneType;
uint8_t sumPc = 0; uint8_t sumPc = 0;
for( size_t i = 0; i < 16; ) for( size_t i = 0; i < 16; )
@ -338,34 +341,34 @@ bool Core::Data::ExdData::loadActionInfo()
int8_t class_job = getField< int8_t >( fields, 10 ); // 10 int8_t class_job = getField< int8_t >( fields, 10 ); // 10
uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11 uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11
int8_t range = getField< int8_t >( fields, 13 ); // 13 int8_t range = getField< int8_t >( fields, 14 ); // 13
bool can_target_self = getField< bool >( fields, 14 ); // 14 bool can_target_self = getField< bool >( fields, 15 ); // 14
bool can_target_party = getField< bool>( fields, 15 ); // 15 bool can_target_party = getField< bool>( fields, 16 ); // 15
bool can_target_friendly = getField< bool >( fields, 16 ); // 16 bool can_target_friendly = getField< bool >( fields, 17 ); // 16
bool can_target_enemy = getField< bool >( fields, 17 ); // 17 bool can_target_enemy = getField< bool >( fields, 18 ); // 17
bool is_ground_aoe = getField< bool >( fields, 20 ); // 20 bool is_ground_aoe = getField< bool >( fields, 21 ); // 20
// Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate) // Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate)
bool can_target_ko = getField< bool >( fields, 24 ); // 24 bool can_target_ko = getField< bool >( fields, 25 ); // 24
uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26 uint8_t aoe_type = getField< uint8_t >( fields, 27 ); // 26
uint8_t aoe_range = getField< uint8_t >( fields, 27 ); // 27 uint8_t aoe_range = getField< uint8_t >( fields, 28 ); // 27
uint8_t aoe_width = getField< uint8_t >( fields, 28 ); // 28 uint8_t aoe_width = getField< uint8_t >( fields, 29 ); // 28
uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 uint8_t points_type = getField< uint8_t >( fields, 31 ); // 30
uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 uint16_t points_cost = getField< uint16_t >( fields, 32 ); // 31
bool is_instant = getField< bool >( fields, 35 ); // 35 bool is_instant = getField< bool >( fields, 36 ); // 35
uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 uint16_t cast_time = getField< uint16_t >( fields, 37 ); // 36
uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 uint16_t recast_time = getField< uint16_t >( fields, 38 ); // 37
int8_t model = getField< int8_t >( fields, 39 ); // 39 int8_t model = getField< int8_t >( fields, 40 ); // 39
uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40 uint8_t aspect = getField< uint8_t >( fields, 41 ); // 40
uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42 uint16_t toggle_status_id = getField< uint16_t >( fields, 43 ); // 42
bool affects_position = getField< bool >( fields, 47 ); // 47 bool affects_position = getField< bool >( fields, 48 ); // 47
bool no_effect_in_battle = getField< bool >( fields, 60 ); // 60 bool no_effect_in_battle = getField< bool >( fields, 61 ); // 60
info->id = id; info->id = id;

View file

@ -37,6 +37,7 @@ namespace Core {
std::map< uint8_t, int32_t> weather_rate_map; std::map< uint8_t, int32_t> weather_rate_map;
int32_t aetheryte_index; int32_t aetheryte_index;
uint8_t zone_type;
}; };
struct ClassJobInfo struct ClassJobInfo

View file

@ -44,9 +44,23 @@ namespace Packets {
*/ */
enum ServerZoneIpcType : uint16_t enum ServerZoneIpcType : uint16_t
{ {
// static opcode ( the ones that rarely if ever change )
Ping = 0x0065, Ping = 0x0065,
Init = 0x0066, Init = 0x0066,
Chat = 0x00B9,
ActorSpawn = 0x0190, // DEPRECATED
ActorFreeSpawn = 0x0191,
InitZone = 0x019A,
AddStatusEffect = 0x0141,
ActorControl142 = 0x0142,
ActorControl143 = 0x0143,
ActorControl144 = 0x0144,
UpdateHpMpTp = 0x0145,
///////////////////////////////////////////////////
ChatBanned = 0x006B, ChatBanned = 0x006B,
Logout = 0x0077, Logout = 0x0077,
CFNotify = 0x0078, CFNotify = 0x0078,
@ -54,92 +68,100 @@ namespace Packets {
CFDutyInfo = 0x007A, CFDutyInfo = 0x007A,
CFPlayerInNeed = 0x007F, CFPlayerInNeed = 0x007F,
SocialRequestError = 0x00AD, SocialRequestError = 0x00AD,
Playtime = 0x00B7, // updated 4.1
Playtime = 0x00DF, // updated 4.2
CFRegistered = 0x00B8, // updated 4.1 CFRegistered = 0x00B8, // updated 4.1
SocialRequestResponse = 0x00BC, // updated 4.1 SocialRequestResponse = 0x00BB, // updated 4.1
SocialRequestReceive = 0x00BD, Chat = 0x00E1, // updated 4.2
SocialList = 0x00BE, // updated 4.1 SocialList = 0x00E7, // updated 4.2
UpdateSearchInfo = 0x10BB,
InitSearchInfo = 0x00C1, // updated 4.1 UpdateSearchInfo = 0x00EA, // updated 4.2
ServerNotice = 0x00C6, // updated 4.1 InitSearchInfo = 0x00EB, // updated 4.2
SetOnlineStatus = 0x00C7, // updated 4.1
ServerNotice = 0x00F0, // updated 4.2
SetOnlineStatus = 0x00F1, // updated 4.2
CountdownInitiate = 0x00FB, // updated 4.2
CountdownCancel = 0x00FC, // updated 4.2
BlackList = 0x00FF, // updated 4.2
LogMessage = 0x00D0, LogMessage = 0x00D0,
BlackList = 0x00D4, // updated 4.1
LinkshellList = 0x00DC, // updated 4.1 LinkshellList = 0x0106, // updated 4.2
StatusEffectList = 0x00FA, // updated 4.1 SetCharacterFCInfo = 0x0114, // updated 4.2
Effect = 0x00FB, // updated 4.1 StatusEffectList = 0x0125, // updated 4.2
GCAffiliation = 0x00FC, Effect = 0x0128, // updated 4.2
PlayerSpawn = 0x011C, // updated 4.1 GCAffiliation = 0xCCFC, // OUTDATED
NpcSpawn = 0x011D, // updated 4.1
ActorMove = 0x011E, // updated 4.1
ActorSetPos = 0x0120, // updated 4.1
ActorCast = 0x0123, // updated 4.1
HateList = 0x0126, // updated 4.1
UpdateClassInfo = 0x012A, // updated 4.1
InitUI = 0x012B, // updated 4.1
ActorOwner = 0x012D, // updated 4.1
PlayerStats = 0x0138, // updated 4.1
PlayerStateFlags = 0x013A, // updated 4.1
PlayerClassInfo = 0x013B, // updated 4.1
ModelEquip = 0x013C, // updated 4.1
AddStatusEffect = 0x0141, PlayerSpawn = 0x015C, // updated 4.2
ActorControl142 = 0x0142, // updated 4.1 NpcSpawn = 0x015D, // updated 4.2
ActorControl143 = 0x0143, // updated 4.1 ActorMove = 0x015E, // updated 4.2
ActorControl144 = 0x0144, // updated 4.1 ActorSetPos = 0x0160, // updated 4.2
UpdateHpMpTp = 0x0145, // updated 4.1 ActorCast = 0x0162, // updated 4.2
HateList = 0x0165, // updated 4.2
UpdateClassInfo = 0x0169, // updated 4.2
InitUI = 0x016B, // updated 4.2
ItemInfo = 0x014C, // updated 4.1 ActorOwner = 0x016D, // updated 4.2 ?
ContainerInfo = 0x014D, // updated 4.1
InventoryTransactionFinish = 0x014E, // updated 4.1
InventoryTransaction = 0x014F, // updated 4.1
CurrencyCrystalInfo = 0x0150, // updated 4.1
InventoryActionAck = 0x1139,
UpdateInventorySlot = 0x0153, // updated 4.1
EventPlay = 0x0160, // updated 4.1 PlayerStats = 0x016C, // updated 4.2
EventStart = 0x0169, // updated 4.1 PlayerStateFlags = 0x016E, // updated 4.2
EventFinish = 0x016A, // updated 4.1 PlayerClassInfo = 0x016F, // updated 4.2
ModelEquip = 0x0170, // updated 4.2
ItemInfo = 0x017A, // updated 4.2
ContainerInfo = 0x017B, // updated 4.2
InventoryTransactionFinish = 0x017C, // updated 4.2
InventoryTransaction = 0x017D, // updated 4.2
CurrencyCrystalInfo = 0x017E, // updated 4.2
InventoryActionAck = 0x0180, // updated 4.2 ?
UpdateInventorySlot = 0x0181, // updated 4.2
EventPlay = 0x018E, // updated 4.2
EventStart = 0x0198, // updated 4.2
EventFinish = 0x0199, // updated 4.2
EventLinkshell = 0x1169, EventLinkshell = 0x1169,
QuestMessage = 0x0188, // updated 4.1 QuestMessage = 0x01B8, // updated 4.2
QuestActiveList = 0x017D, // updated 4.1 QuestTracker = 0x01BD, // updated 4.2
QuestUpdate = 0x017E, // updated 4.1
QuestCompleteList = 0x017F, // updated 4.1
QuestFinish = 0x0180, // updated 4.1 QuestFinish = 0x01B0, // updated 4.2
MSQTrackerComplete = 0x01B1, // updated 4.2
MSQTrackerProgress = 0x01B2, // updated 4.2
QuestTracker = 0x018D, // updated 4.1 QuestActiveList = 0x01AD, // updated 4.2
ActorSpawn = 0x0190, // todo: split into playerspawn/actorspawn and use opcode 0x110/0x111
ActorFreeSpawn = 0x0191, // unchanged for sb
InitZone = 0x019A, // unchanged for sb
Mount = 0x019F,
WeatherChange = 0x01AF, // updated for sb
PlayerTitleList = 0x01BD, // updated for 4.1
Discovery = 0x01BE, // updated for 4.1
EorzeaTimeOffset = 0x01C0, // updated 4.1 QuestUpdate = 0x01AE, // updated 4.2
QuestCompleteList = 0x01AF, // updated 4.2
EquipDisplayFlags = 0x01CC, // updated 4.1 Mount = 0x01CD, // updated 4.2
WeatherChange = 0x01EA, // updated 4.2
PlayerTitleList = 0x01EB, // updated 4.2
Discovery = 0x01EC, // updated 4.2
EorzeaTimeOffset = 0x01EE, // updated 4.2
EquipDisplayFlags = 0x01FA, // updated 4.2
CFAvailableContents = 0x01CF, CFAvailableContents = 0x01CF,
PrepareZoning = 0x0248, // updated 4.1 PrepareZoning = 0x027C, // updated 4.2
ActorGauge = 0x027D, // updated 4.2
PerformNote = 0x0286, // updated 4.2
// Unknown IPC types that still need to be sent // Unknown IPC types that still need to be sent
// TODO: figure all these out properly // TODO: figure all these out properly
IPCTYPE_UNK_320 = 0x0207, // updated 4.1 IPCTYPE_UNK_320 = 0x0235, // updated 4.2
IPCTYPE_UNK_322 = 0x0209, // updated 4.1 IPCTYPE_UNK_322 = 0x0237, // updated 4.2
ActorGauge = 0x0249,
PerformNote = 0x0252,
}; };
// TODO: Include structures for the individual packet segment types // TODO: Include structures for the individual packet segment types
@ -150,59 +172,69 @@ namespace Packets {
enum ClientZoneIpcType : uint16_t enum ClientZoneIpcType : uint16_t
{ {
PingHandler = 0x0065, // updated for sb PingHandler = 0x0065, // unchanged 4.2
InitHandler = 0x0066, // updated 4.1 InitHandler = 0x0066, // unchanged 4.2
ChatHandler = 0x00AD, // updated 4.1
FinishLoadingHandler = 0x0069, // updated 4.1 FinishLoadingHandler = 0x0069, // unchanged 4.2
CFCommenceHandler = 0x006F, CFCommenceHandler = 0x006F,
CFRegisterDuty = 0x0071, CFRegisterDuty = 0x0071,
CFRegisterRoulette = 0x0072, CFRegisterRoulette = 0x0072,
PlayTimeHandler = 0x0073, // updated 4.1 PlayTimeHandler = 0x0073, // unchanged 4.2
LogoutHandler = 0x0074, // updated 4.1 LogoutHandler = 0x0074, // unchanged 4.2
CFDutyInfoHandler = 0x0078, // updated 4.1 ?? CFDutyInfoHandler = 0x0078, // updated 4.2
SocialReqSendHandler = 0x00AF, // updated 4.1 SocialReqSendHandler = 0x00AE, // updated 4.1
SocialListHandler = 0x00B3, // updated 4.1
SetSearchInfoHandler = 0x00B5, // updated 4.1
ReqSearchInfoHandler = 0x00B6, // updated 4.1 ChatHandler = 0x00C7, // updated 4.2
BlackListHandler = 0x00C0, // updated 4.1 SocialListHandler = 0x00CF, // updated 4.2
ReqSearchInfoHandler = 0x00D4, // updated 4.2
SetSearchInfoHandler = 0x00D2, // updated 4.2
LinkshellListHandler = 0x00C8, // updated 4.1 BlackListHandler = 0x00E0, // updated 4.2
FcInfoReqHandler = 0x0109, // updated 4.1 LinkshellListHandler = 0x00E8, // updated 4.2
ZoneLineHandler = 0x0110, // updated 4.1 FcInfoReqHandler = 0x011A, // updated 4.2
ActionHandler = 0x0111, // updated 4.1
DiscoveryHandler = 0x0112, // updated 4.1
SkillHandler = 0x0114, // updated 4.1 ReqCountdownInitiate = 0x012C, // updated 4.2
GMCommand1 = 0x0115, // updated 4.1 ?? ReqCountdownCancel = 0x012D, // updated 4.2
GMCommand2 = 0x0116, // updated 4.1 ??
UpdatePositionHandler = 0x0118, // updated 4.1
InventoryModifyHandler = 0x011F, // updated 4.1 ZoneLineHandler = 0x0130, // updated 4.2
ActionHandler = 0x0131, // updated 4.2
DiscoveryHandler = 0x0132, // updated 4.2
TalkEventHandler = 0x0128, // updated 4.1 SkillHandler = 0x0134, // updated 4.2
EmoteEventHandler = 0x0129, // updated 4.1 GMCommand1 = 0x0135, // updated 4.2
WithinRangeEventHandler = 0x012A, // updated 4.1 GMCommand2 = 0x0136, // updated 4.2
OutOfRangeEventHandler = 0x012B, // updated 4.1 UpdatePositionHandler = 0x0138, // updated 4.2
EnterTeriEventHandler = 0x012C, // updated 4.1 UpdatePositionInstance = 0x0177, // updated 4.2
ReturnEventHandler = 0x0131, // updated 4.1 InventoryModifyHandler = 0x013F, // updated 4.2
TradeReturnEventHandler = 0x0132, // updated 4.1
TalkEventHandler = 0x0148, // updated 4.2
EmoteEventHandler = 0x0149, // updated 4.2
WithinRangeEventHandler = 0x014A, // updated 4.2
OutOfRangeEventHandler = 0x014B, // updated 4.2
EnterTeriEventHandler = 0x014C, // updated 4.2
ReturnEventHandler = 0x0151, // updated 4.2 ?
TradeReturnEventHandler = 0x0152, // updated 4.2 ?
LinkshellEventHandler = 0x0144, // updated 4.1 ?? LinkshellEventHandler = 0x0144, // updated 4.1 ??
LinkshellEventHandler1 = 0x0145, // updated 4.1 ?? LinkshellEventHandler1 = 0x0145, // updated 4.1 ??
ReqEquipDisplayFlagsChange = 0x014C, // updated 4.1 ??
PerformNoteHandler = 0x0160, PerformNoteHandler = 0x0160,
ReqEquipDisplayFlagsChange = 0x016C, // updated 4.2
}; };
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -388,10 +388,10 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
uint8_t u2b; uint8_t u2b;
uint8_t u2ab; uint8_t u2ab;
uint8_t gmRank; uint8_t gmRank;
uint8_t onlineStatus; uint8_t u3b;
uint8_t u3a; uint8_t u3a;
uint8_t u3b; uint8_t onlineStatus;
uint8_t u3c; uint8_t u3c;
uint8_t pose; uint8_t pose;
@ -410,7 +410,7 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
uint32_t bNPCName; uint32_t bNPCName;
uint32_t u18; uint32_t u18;
uint32_t u19; uint32_t u19;
uint32_t u20; uint32_t directorId;
uint32_t ownerId; uint32_t ownerId;
uint32_t u22; uint32_t u22;
uint32_t hPMax; uint32_t hPMax;
@ -443,6 +443,7 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket<PlayerSpawn>
uint8_t mountColor; uint8_t mountColor;
uint8_t scale; uint8_t scale;
uint32_t u29b; uint32_t u29b;
uint32_t u30b;
Common::StatusEffect effect[30]; Common::StatusEffect effect[30];
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos;
uint32_t models[10]; uint32_t models[10];
@ -644,7 +645,7 @@ struct FFXIVIpcInitZone : FFXIVIpcBasePacket<InitZone>
uint8_t weatherId; uint8_t weatherId;
uint8_t bitmask; uint8_t bitmask;
uint16_t unknown5; uint16_t unknown5;
uint16_t unknown6; uint16_t festivalId;
uint16_t unknown7; uint16_t unknown7;
uint32_t unknown8; uint32_t unknown8;
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos;
@ -665,6 +666,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint16_t unknown18; uint16_t unknown18;
uint8_t maxLevel; uint8_t maxLevel;
uint8_t expansion; uint8_t expansion;
uint8_t unknown1A;
uint8_t race; uint8_t race;
uint8_t tribe; uint8_t tribe;
uint8_t gender; uint8_t gender;
@ -680,24 +682,23 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint8_t companionRank; uint8_t companionRank;
uint8_t companionStars; uint8_t companionStars;
uint8_t companionSp; uint8_t companionSp;
uint8_t companionUnk1; uint8_t companionUnk2B;
uint8_t companionColor; uint8_t companionColor;
uint8_t companionFavoFeed; uint8_t companionFavoFeed;
uint16_t companionUnk2; uint8_t companionUnk2E;
float companionTimePassed; float companionTimePassed;
uint32_t companionCurrentExp; uint32_t companionCurrentExp;
uint32_t unknown38; uint32_t unknown38;
uint32_t unknown3C; uint32_t unknown3C;
uint32_t fishCaught; uint32_t fishCaught;
uint32_t useBaitCatalogId; uint32_t useBaitCatalogId;
uint16_t pvpWolfFoldMatches; uint32_t pvpWolfFoldMatches;
uint16_t pvpWolfFoldVictories;
uint16_t pvpWolfFoldWeeklyMatches; uint16_t pvpWolfFoldWeeklyMatches;
uint16_t pvpWolfFoldWeeklyVictories; uint16_t pvpWolfFoldWeeklyVictories;
uint16_t pvpStats[6]; uint16_t pvpStats[6];
uint16_t playerCommendations; uint16_t playerCommendations;
uint16_t pvpStats1; uint16_t pvpStats1;
uint32_t frontlineCampaigns; uint8_t frontlineCampaigns[4];
uint16_t frontlineCampaignsWeekly; uint16_t frontlineCampaignsWeekly;
uint8_t currentRelic; uint8_t currentRelic;
uint8_t currentBook; uint8_t currentBook;
@ -705,7 +706,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint8_t unknown69; uint8_t unknown69;
uint8_t unknown6A; uint8_t unknown6A;
uint8_t unknown6B; uint8_t unknown6B;
uint32_t unknown6C; uint8_t unknown6C[4];
uint8_t unknown70[61]; uint8_t unknown70[61];
uint8_t preNamePadding; uint8_t preNamePadding;
char name[32]; char name[32];
@ -716,30 +717,31 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint32_t exp[25]; uint32_t exp[25];
uint8_t unlockBitmask[64]; uint8_t unlockBitmask[64];
uint8_t aetheryte[16]; uint8_t aetheryte[16];
uint8_t discovery[420]; uint8_t discovery[421];
uint8_t howto[33]; uint8_t howto[33];
uint8_t minions[35]; uint8_t minions[37];
uint8_t chocoboTaxiMask[8]; uint8_t chocoboTaxiMask[8];
uint8_t contentClearMask[105]; uint8_t contentClearMask[108];
uint8_t contentClearPadding; uint8_t contentClearPadding;
uint16_t unknown422[8]; uint16_t unknown428[8];
uint8_t companionBardingMask[8]; uint8_t companionBardingMask[8];
uint8_t companionEquippedHead; uint8_t companionEquippedHead;
uint8_t companionEquippedBody; uint8_t companionEquippedBody;
uint8_t companionEquippedFeet; uint8_t companionEquippedFeet;
uint8_t companion_fields[15]; uint8_t companionUnk4[4];
uint8_t companion_fields[11];
uint8_t companion_name[21]; uint8_t companion_name[21];
uint8_t companionDefRank; uint8_t companionDefRank;
uint8_t companionAttRank; uint8_t companionAttRank;
uint8_t companionHealRank; uint8_t companionHealRank;
uint8_t mountGuideMask[14]; uint8_t mountGuideMask[15];
uint8_t fishingGuideMask[89]; uint8_t fishingGuideMask[89];
uint8_t fishingSpotVisited[25]; uint8_t fishingSpotVisited[25];
uint16_t fishingRecordsFish[26]; uint16_t fishingRecordsFish[26];
uint16_t fishingRecordsFishWeight[26]; uint16_t fishingRecordsFishWeight[26];
uint8_t unknownMask4[15]; uint8_t unknownMask554[15];
uint8_t unknownMask4Padding; uint8_t unknownMask4Padding;
uint8_t unknown55C[19]; uint8_t unknown564[19];
uint8_t rankAmalJaa; uint8_t rankAmalJaa;
uint8_t rankSylph; uint8_t rankSylph;
uint8_t rankKobold; uint8_t rankKobold;
@ -749,6 +751,7 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint8_t rankVath; uint8_t rankVath;
uint8_t rankMoogle; uint8_t rankMoogle;
uint8_t rankKojin; uint8_t rankKojin;
uint8_t rankAnata;
uint16_t expAmalJaa; uint16_t expAmalJaa;
uint16_t expSylph; uint16_t expSylph;
uint16_t expKobold; uint16_t expKobold;
@ -758,13 +761,14 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint16_t expVath; uint16_t expVath;
uint16_t expMoogle; uint16_t expMoogle;
uint16_t expKojin; uint16_t expKojin;
uint8_t unknown58A[10]; uint16_t expAnata;
uint16_t unknown594[5]; uint8_t unknown596[10];
uint16_t unknown5A0[5];
uint8_t unknownMask59E[5]; uint8_t unknownMask59E[5];
uint8_t unknown5A3[16]; uint8_t unknown5A3[18];
uint8_t unknownMask5B3[28]; uint8_t unknownMask5C1[28];
uint8_t unknown_03411; uint8_t unknown_03411;
uint32_t unknownDword5D0; uint32_t unknownDword5E0;
uint8_t relicBookCompletion[12]; uint8_t relicBookCompletion[12];
uint8_t sightseeingMask[26]; uint8_t sightseeingMask[26];
uint16_t unknown_XXX; uint16_t unknown_XXX;
@ -774,25 +778,25 @@ struct FFXIVIpcInitUI : FFXIVIpcBasePacket<InitUI>
uint16_t pvpFrontlineWeekly1st; uint16_t pvpFrontlineWeekly1st;
uint16_t pvpFrontlineWeekly2nd; uint16_t pvpFrontlineWeekly2nd;
uint16_t pvpFrontlineWeekly3rd; uint16_t pvpFrontlineWeekly3rd;
uint8_t unknown60E; uint8_t unknown61E;
uint8_t unknown60F[32]; uint8_t unknown61F[32];
uint8_t unknown62F[22]; uint8_t unknown63F[22];
uint8_t tripleTriadCards[27]; uint8_t tripleTriadCards[28];
uint8_t unknown660[11]; uint8_t unknown671[11];
uint8_t unknownMask66B[22]; uint8_t unknownMask67C[22];
uint8_t unknown681[3]; uint8_t unknown692[3];
uint8_t orchestrionMask[40]; uint8_t orchestrionMask[40];
uint8_t hallOfNoviceCompleteMask[3]; uint8_t hallOfNoviceCompleteMask[3];
uint8_t unknownMask6AF[11]; uint8_t unknownMask6C0[11];
uint8_t unknownMask6BA[16]; uint8_t unknownMask6CB[16];
uint8_t unknown6CA[13]; uint8_t unknown6DB[14];
uint8_t unlockedRaids[28]; uint8_t unlockedRaids[28];
uint8_t unlockedDungeons[18]; uint8_t unlockedDungeons[18];
uint8_t unlockedGuildhests[10]; uint8_t unlockedGuildhests[10];
uint8_t unlockedTrails[7]; uint8_t unlockedTrails[7];
uint8_t unlockedPvp[5]; uint8_t unlockedPvp[5];
uint8_t unknownMask71B[28]; uint8_t unknownMask72D[28];
uint8_t unknownMask737[18]; uint8_t unknownMask749[18];
uint8_t unknown749[23]; uint8_t unknown749[23];
}; };
@ -870,11 +874,10 @@ struct FFXIVIpcActorOwner : FFXIVIpcBasePacket<ActorOwner>
*/ */
struct FFXIVIpcPlayerStateFlags : FFXIVIpcBasePacket<PlayerStateFlags> struct FFXIVIpcPlayerStateFlags : FFXIVIpcBasePacket<PlayerStateFlags>
{ {
/* 0000 */ uint16_t padding; uint8_t flags[7];
/* 0002 */ uint8_t flags[7]; uint8_t padding1[3];
/* 0009 */ uint8_t padding1[3]; uint32_t padding2;
/* 000C */ uint32_t padding2; uint16_t padding;
}; };
/** /**
@ -1127,7 +1130,8 @@ struct FFXIVIpcQuestUpdate : FFXIVIpcBasePacket<QuestUpdate>
*/ */
struct FFXIVIpcQuestCompleteList : FFXIVIpcBasePacket<QuestCompleteList> struct FFXIVIpcQuestCompleteList : FFXIVIpcBasePacket<QuestCompleteList>
{ {
/* 0000 */ uint8_t questCompleteMask[200]; uint8_t questCompleteMask[396];
uint8_t unknownCompleteMask[32];
}; };
/** /**
@ -1200,7 +1204,7 @@ struct FFXIVARR_IPC_UNK322 : FFXIVIpcBasePacket<IPCTYPE_UNK_322>
*/ */
struct FFXIVARR_IPC_UNK320 : FFXIVIpcBasePacket<IPCTYPE_UNK_320> struct FFXIVARR_IPC_UNK320 : FFXIVIpcBasePacket<IPCTYPE_UNK_320>
{ {
/* 0000 */ uint8_t unk[32]; /* 0000 */ uint8_t unk[0x38];
}; };
/** /**
@ -1317,7 +1321,6 @@ struct FFXIVIpcMount : FFXIVIpcBasePacket<Mount>
uint32_t id; uint32_t id;
}; };
struct FFXIVIpcActorGauge : FFXIVIpcBasePacket<ActorGauge> struct FFXIVIpcActorGauge : FFXIVIpcBasePacket<ActorGauge>
{ {
uint8_t classJobId; uint8_t classJobId;
@ -1329,6 +1332,21 @@ struct FFXIVIpcPerformNote : FFXIVIpcBasePacket<PerformNote>
uint8_t data[32]; uint8_t data[32];
}; };
struct FFXIVIpcMSQTrackerProgress : FFXIVIpcBasePacket<MSQTrackerProgress>
{
uint32_t id;
uint32_t padding;
};
struct FFXIVIpcMSQTrackerComplete : FFXIVIpcBasePacket<MSQTrackerComplete>
{
uint32_t id;
uint32_t padding1;
uint64_t padding2;
uint64_t padding3;
uint64_t padding4; // last 4 bytes is uint32_t but who cares
};
} /* Server */ } /* Server */
} /* Packets */ } /* Packets */

View file

@ -62,7 +62,7 @@ std::string Core::Util::binaryToHexDump( uint8_t* pBinData, uint16_t size )
uint8_t by = pBinData[i + j]; uint8_t by = pBinData[i + j];
line[hexColumn] = hexChars[( by >> 4 ) & 0xF]; line[hexColumn] = hexChars[( by >> 4 ) & 0xF];
line[hexColumn + 1] = hexChars[by & 0xF]; line[hexColumn + 1] = hexChars[by & 0xF];
line[charColumn] = by < 32 ? '.' : static_cast<char>( by ); line[charColumn] = by < 32 ? '.' : static_cast< char >( by );
} }
hexColumn += 3; hexColumn += 3;
@ -78,13 +78,14 @@ std::string Core::Util::binaryToHexDump( uint8_t* pBinData, uint16_t size )
uint64_t Core::Util::getTimeMs() uint64_t Core::Util::getTimeMs()
{ {
std::chrono::milliseconds epoch = std::chrono::duration_cast< std::chrono::milliseconds >(std::chrono::system_clock::now().time_since_epoch()); std::chrono::milliseconds epoch = std::chrono::duration_cast< std::chrono::milliseconds >
( std::chrono::system_clock::now().time_since_epoch() );
return epoch.count(); return epoch.count();
} }
uint64_t Core::Util::getTimeSeconds() int64_t Core::Util::getTimeSeconds()
{ {
std::chrono::seconds epoch = std::chrono::duration_cast< std::chrono::seconds >(std::chrono::system_clock::now().time_since_epoch()); std::chrono::seconds epoch = std::chrono::seconds( std::time( nullptr ) );
return epoch.count(); return epoch.count();
} }

View file

@ -13,7 +13,7 @@ std::string binaryToHexDump( uint8_t* pBinData, uint16_t size );
uint64_t getTimeMs(); uint64_t getTimeMs();
uint64_t getTimeSeconds(); int64_t getTimeSeconds();
uint64_t getEorzeanTimeStamp(); uint64_t getEorzeanTimeStamp();

@ -1 +0,0 @@
Subproject commit 8a26ae78e37701a9b66e7200f1e0ad3387da17c3

View file

@ -45,9 +45,9 @@ namespace Core
namespace Event namespace Event
{ {
class Event; class EventHandler;
typedef boost::shared_ptr<Event> EventPtr; typedef boost::shared_ptr<EventHandler> EventPtr;
} }
namespace Action namespace Action

View file

@ -2,11 +2,11 @@
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Database/DatabaseDef.h> #include <common/Database/DatabaseDef.h>
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
namespace Core { namespace Core {
@ -151,7 +151,7 @@ namespace Core {
std::vector< uint8_t > howTo( 32 ); std::vector< uint8_t > howTo( 32 );
std::vector< uint8_t > aetherytes( 12 ); std::vector< uint8_t > aetherytes( 12 );
std::vector< uint8_t > discovery( 411 ); std::vector< uint8_t > discovery( 411 );
std::vector< uint8_t > questComplete( 200 ); std::vector< uint8_t > questComplete( 396 );
std::vector< uint8_t > unlocks( 64 ); std::vector< uint8_t > unlocks( 64 );
std::vector< uint8_t > mountGuide( 13 ); std::vector< uint8_t > mountGuide( 13 );
std::vector< uint8_t > orchestrion( 38 ); std::vector< uint8_t > orchestrion( 38 );
@ -220,7 +220,7 @@ namespace Core {
// CharacterId, ClassIdx, Exp, Lvl // CharacterId, ClassIdx, Exp, Lvl
auto stmtClass = g_charaDb.getPreparedStatement( Db::CharaDbStatements::CHARA_CLASS_INS ); auto stmtClass = g_charaDb.getPreparedStatement( Db::CharaDbStatements::CHARA_CLASS_INS );
stmtClass->setInt( 1, m_id ); stmtClass->setInt( 1, m_id );
stmtClass->setInt( 2, g_exdData.m_classJobInfoMap[m_class].exp_idx ); stmtClass->setInt( 2, g_exdDataGen.getClassJob( m_class )->expArrayIndex );
stmtClass->setInt( 3, 0 ); stmtClass->setInt( 3, 0 );
stmtClass->setInt( 4, 1 ); stmtClass->setInt( 4, 1 );
g_charaDb.directExecute( stmtClass ); g_charaDb.directExecute( stmtClass );
@ -292,14 +292,14 @@ namespace Core {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// SETUP EQUIPMENT / STARTING GEAR /// SETUP EQUIPMENT / STARTING GEAR
auto classJobInfo = g_exdData.m_classJobInfoMap[m_class]; auto classJobInfo = g_exdDataGen.getClassJob( m_class );
uint32_t weaponId = classJobInfo.start_weapon_id; uint32_t weaponId = classJobInfo->itemStartingWeapon;
uint64_t uniqueId = getNextUId64(); uint64_t uniqueId = getNextUId64();
uint8_t race = customize[CharaLook::Race]; uint8_t race = customize[CharaLook::Race];
uint8_t gender = customize[CharaLook::Gender]; uint8_t gender = customize[CharaLook::Gender];
auto raceInfo = g_exdData.getRaceInfo( race ); auto raceInfo = g_exdDataGen.getRace( race );
uint32_t body; uint32_t body;
uint32_t hands; uint32_t hands;
@ -312,17 +312,17 @@ namespace Core {
if( gender == 0 ) if( gender == 0 )
{ {
body = raceInfo->male_body; body = raceInfo->rSEMBody;
hands = raceInfo->male_hands; hands = raceInfo->rSEMHands;
legs = raceInfo->male_legs; legs = raceInfo->rSEMLegs;
feet = raceInfo->male_feet; feet = raceInfo->rSEMFeet;
} }
else else
{ {
body = raceInfo->female_body; body = raceInfo->rSEFBody;
hands = raceInfo->female_hands; hands = raceInfo->rSEFHands;
legs = raceInfo->female_legs; legs = raceInfo->rSEFLegs;
feet = raceInfo->female_feet; feet = raceInfo->rSEFFeet;
} }
insertDbGlobalItem( weaponId, uniqueId ); insertDbGlobalItem( weaponId, uniqueId );

View file

@ -13,7 +13,7 @@
#include <common/Network/Hive.h> #include <common/Network/Hive.h>
#include <common/Network/Acceptor.h> #include <common/Network/Acceptor.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Crypt/base64.h> #include <common/Crypt/base64.h>
#include <common/Database/DbLoader.h> #include <common/Database/DbLoader.h>
@ -35,7 +35,7 @@
Core::Logger g_log; Core::Logger g_log;
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb; Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
Core::Data::ExdData g_exdData; Core::Data::ExdDataGenerated g_exdDataGen;
Core::Network::SapphireAPI g_sapphireAPI; Core::Network::SapphireAPI g_sapphireAPI;
using namespace std; using namespace std;
@ -139,10 +139,10 @@ bool loadSettings( int32_t argc, char* argv[] )
} }
} }
g_log.info( "Setting up EXD data" ); g_log.info( "Setting up generated EXD data" );
if( !g_exdData.init( m_pConfig->getValue< std::string >( "Settings.General.DataPath", "" ) ) ) if( !g_exdDataGen.init( m_pConfig->getValue< std::string >( "Settings.General.DataPath", "" ) ) )
{ {
g_log.fatal( "Error setting up EXD data " ); g_log.fatal( "Error setting up generated EXD data " );
return false; return false;
} }
@ -241,10 +241,10 @@ std::string buildHttpResponse( uint16_t rCode, const std::string& content = "",
void getZoneName( shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request ) void getZoneName( shared_ptr<HttpServer::Response> response, shared_ptr<HttpServer::Request> request )
{ {
string number = request->path_match[1]; string number = request->path_match[1];
auto it = g_exdData.m_zoneInfoMap.find( atoi( number.c_str() ) ); auto info = g_exdDataGen.getTerritoryType( atoi( number.c_str() ) );
std::string responseStr = "Not found!"; std::string responseStr = "Not found!";
if( it != g_exdData.m_zoneInfoMap.end() ) if( info )
responseStr = it->second.zone_name + ", " + it->second.zone_str; responseStr = info->name + ", " + info->bg;
*response << buildHttpResponse( 200, responseStr ); *response << buildHttpResponse( 200, responseStr );
} }
@ -751,9 +751,6 @@ int main( int argc, char* argv[] )
if( !loadSettings( argc, argv ) ) if( !loadSettings( argc, argv ) )
throw std::exception(); throw std::exception();
g_exdData.loadZoneInfo();
g_exdData.loadClassJobInfo();
server.config.port = stoi( m_pConfig->getValue< std::string >( "Settings.General.HttpPort", "80" ) ); server.config.port = stoi( m_pConfig->getValue< std::string >( "Settings.General.HttpPort", "80" ) );
g_log.info( "Starting API server at port " + m_pConfig->getValue< std::string >( "Settings.General.HttpPort", "80" ) + "..." ); g_log.info( "Starting API server at port " + m_pConfig->getValue< std::string >( "Settings.General.HttpPort", "80" ) + "..." );

View file

@ -3,8 +3,8 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include <common/Exd/ExdData.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdDataGenerated.h>
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h" #include "Network/PacketWrappers/ActorControlPacket143.h"
@ -17,7 +17,7 @@ using namespace Core::Network;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
@ -31,7 +31,7 @@ Core::Action::ActionCast::ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr
m_startTime = 0; m_startTime = 0;
m_id = actionId; m_id = actionId;
m_handleActionType = HandleActionType::Spell; m_handleActionType = HandleActionType::Spell;
m_castTime = g_exdData.getActionInfo( actionId )->cast_time; // TODO: Add security checks. m_castTime = g_exdDataGen.getAction( actionId )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor; m_pSource = pActor;
m_pTarget = pTarget; m_pTarget = pTarget;
m_bInterrupt = false; m_bInterrupt = false;
@ -58,7 +58,6 @@ void Core::Action::ActionCast::onStart()
m_pSource->sendToInRangeSet( castPacket, true ); m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
} }
@ -71,7 +70,6 @@ void Core::Action::ActionCast::onFinish()
pPlayer->sendDebug( "onFinish()" ); pPlayer->sendDebug( "onFinish()" );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
pPlayer->sendStateFlags();
/*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7, /*auto control = ActorControlPacket143( m_pTarget->getId(), ActorControlType::Unk7,
0x219, m_id, m_id, m_id, m_id ); 0x219, m_id, m_id, m_id, m_id );
@ -87,7 +85,6 @@ void Core::Action::ActionCast::onInterrupt()
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 1, m_id, 0 ); 0x219, 1, m_id, 0 );

View file

@ -53,12 +53,12 @@ bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetF
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange, std::set< ActorPtr > actorsInRange,
boost::shared_ptr< Core::Data::ActionInfo > actionInfo, boost::shared_ptr< Core::Data::Action > actionInfo,
TargetFilter targetFilter ) TargetFilter targetFilter )
{ {
std::set< ActorPtr > actorsCollided; std::set< ActorPtr > actorsCollided;
switch( static_cast< ActionCollisionType >( actionInfo->aoe_type ) ) switch( static_cast< ActionCollisionType >( actionInfo->castType ) )
{ {
case ActionCollisionType::None: case ActionCollisionType::None:
case ActionCollisionType::SingleTarget: case ActionCollisionType::SingleTarget:
@ -75,7 +75,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
continue; continue;
// Test our collision from actor with the area generated by the action from the AoE data // Test our collision from actor with the area generated by the action from the AoE data
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) ) if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
{ {
// Add it to the actors collided with the area // Add it to the actors collided with the area
actorsCollided.insert( pActor ); actorsCollided.insert( pActor );
@ -92,7 +92,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
if ( !isActorApplicable( pActor, targetFilter ) ) if ( !isActorApplicable( pActor, targetFilter ) )
continue; continue;
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) ) if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
actorsCollided.insert( pActor ); actorsCollided.insert( pActor );
} }
break; break;
@ -106,7 +106,7 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
if ( !isActorApplicable( pActor, targetFilter ) ) if ( !isActorApplicable( pActor, targetFilter ) )
continue; continue;
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) ) if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )
{ {
// todo: does this actually work? // todo: does this actually work?

View file

@ -2,6 +2,7 @@
#define _ACTIONCOLLISION_H #define _ACTIONCOLLISION_H
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdDataGenerated.h>
#include "Actor/Actor.h" #include "Actor/Actor.h"
#include "Action.h" #include "Action.h"
@ -25,7 +26,7 @@ namespace Entity {
static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter ); static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter );
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange, std::set< ActorPtr > actorsInRange,
boost::shared_ptr< Data::ActionInfo > actionInfo, boost::shared_ptr< Data::Action > actionInfo,
TargetFilter targetFilter ); TargetFilter targetFilter );
private: private:

View file

@ -60,7 +60,6 @@ void Core::Action::ActionMount::onStart()
m_pSource->sendToInRangeSet( castPacket, true ); m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
} }
@ -73,7 +72,6 @@ void Core::Action::ActionMount::onFinish()
pPlayer->sendDebug( "ActionMount::onFinish()" ); pPlayer->sendDebug( "ActionMount::onFinish()" );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
pPlayer->sendStateFlags();
ZoneChannelPacket< FFXIVIpcEffect > effectPacket( pPlayer->getId() ); ZoneChannelPacket< FFXIVIpcEffect > effectPacket( pPlayer->getId() );
effectPacket.data().targetId = pPlayer->getId(); effectPacket.data().targetId = pPlayer->getId();
@ -100,7 +98,6 @@ void Core::Action::ActionMount::onInterrupt()
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 1, m_id, 0 ); 0x219, 1, m_id, 0 );

View file

@ -1,7 +1,7 @@
#include "ActionTeleport.h" #include "ActionTeleport.h"
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"
@ -13,7 +13,7 @@ using namespace Core::Network;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Logger g_log; extern Core::Logger g_log;
Core::Action::ActionTeleport::ActionTeleport() Core::Action::ActionTeleport::ActionTeleport()
@ -26,7 +26,7 @@ Core::Action::ActionTeleport::ActionTeleport( Entity::ActorPtr pActor, uint16_t
m_startTime = 0; m_startTime = 0;
m_id = 5; m_id = 5;
m_handleActionType = HandleActionType::Teleport; m_handleActionType = HandleActionType::Teleport;
m_castTime = g_exdData.getActionInfo(5)->cast_time; // TODO: Add security checks. m_castTime = g_exdDataGen.getAction( 5 )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor; m_pSource = pActor;
m_bInterrupt = false; m_bInterrupt = false;
m_targetAetheryte = targetZone; m_targetAetheryte = targetZone;
@ -54,7 +54,6 @@ void Core::Action::ActionTeleport::onStart()
m_pSource->sendToInRangeSet( castPacket, true ); m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
} }
@ -75,7 +74,6 @@ void Core::Action::ActionTeleport::onFinish()
pPlayer->removeCurrency( Inventory::CurrencyType::Gil, m_cost ); pPlayer->removeCurrency( Inventory::CurrencyType::Gil, m_cost );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting ); pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
pPlayer->sendStateFlags();
// TODO: not sure if this ever gets sent // TODO: not sure if this ever gets sent
//auto control = Network::Packets::Server::ActorControlPacket142( m_pSource->getId(), Common::ActorControlType::TeleportDone ); //auto control = Network::Packets::Server::ActorControlPacket142( m_pSource->getId(), Common::ActorControlType::TeleportDone );
@ -105,7 +103,6 @@ void Core::Action::ActionTeleport::onInterrupt()
return; return;
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt,
0x219, 0x04, m_id, 0 ); 0x219, 0x04, m_id, 0 );

View file

@ -1,15 +1,15 @@
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include "EventAction.h" #include "EventAction.h"
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h" #include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Actor/Player.h" #include "Actor/Player.h"
#include "Event/Event.h" #include "Event/EventHandler.h"
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network; using namespace Core::Network;
@ -28,7 +28,7 @@ Core::Action::EventAction::EventAction( Entity::ActorPtr pActor, uint32_t eventI
m_handleActionType = HandleActionType::Event; m_handleActionType = HandleActionType::Event;
m_eventId = eventId; m_eventId = eventId;
m_id = action; m_id = action;
m_castTime = g_exdData.m_EventActionInfoMap[action].castTime; // TODO: Add security checks. m_castTime = g_exdDataGen.getEventAction( action )->castTime * 1000; // TODO: Add security checks.
m_onActionFinishClb = finishRef; m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef; m_onActionInterruptClb = interruptRef;
m_pSource = pActor; m_pSource = pActor;
@ -53,8 +53,7 @@ void Core::Action::EventAction::onStart()
if( m_pSource->isPlayer() ) if( m_pSource->isPlayer() )
{ {
m_pSource->sendToInRangeSet( control, true ); m_pSource->sendToInRangeSet( control, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Occupied2 );
m_pSource->getAsPlayer()->sendStateFlags();
} }
else else
m_pSource->sendToInRangeSet( control ); m_pSource->sendToInRangeSet( control );
@ -83,8 +82,7 @@ void Core::Action::EventAction::onFinish()
if( m_pSource->isPlayer() ) if( m_pSource->isPlayer() )
{ {
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied2 );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( control, true ); m_pSource->sendToInRangeSet( control, true );
} }
else else
@ -114,7 +112,6 @@ void Core::Action::EventAction::onInterrupt()
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( control ); m_pSource->sendToInRangeSet( control );
m_pSource->sendToInRangeSet( control1 ); m_pSource->sendToInRangeSet( control1 );

View file

@ -56,7 +56,6 @@ void Core::Action::EventItemAction::onStart()
m_pSource->sendToInRangeSet( castPacket, true ); m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
} }
@ -78,7 +77,6 @@ void Core::Action::EventItemAction::onFinish()
effectPacket.data().effectTarget = static_cast< uint32_t >( m_additional ); effectPacket.data().effectTarget = static_cast< uint32_t >( m_additional );
m_pSource->getAsPlayer()->unsetStateFlag( Common::PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->unsetStateFlag( Common::PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( effectPacket, true ); m_pSource->sendToInRangeSet( effectPacket, true );
if( m_onActionFinishClb ) if( m_onActionFinishClb )
@ -104,7 +102,6 @@ void Core::Action::EventItemAction::onInterrupt()
if( m_pSource->isPlayer() ) if( m_pSource->isPlayer() )
{ {
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->getAsPlayer()->sendStateFlags();
m_pSource->sendToInRangeSet( control, true ); m_pSource->sendToInRangeSet( control, true );
} }
else else

View file

@ -2,6 +2,7 @@
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdData.h>
#include <common/Exd/ExdDataGenerated.h>
#include <common/Network/GamePacket.h> #include <common/Network/GamePacket.h>
#include "Forwards.h" #include "Forwards.h"
@ -24,7 +25,7 @@
#include "Player.h" #include "Player.h"
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
@ -682,7 +683,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) ); getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
} }
auto actionInfoPtr = g_exdData.getActionInfo( actionId ); auto actionInfoPtr = g_exdDataGen.getAction( actionId );
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable. // 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. // Prepare packet. This is seemingly common for all packets in the action handler.
@ -708,7 +709,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
effectPacket.data().effects[0].unknown_3 = 7; effectPacket.data().effects[0].unknown_3 = 7;
if( !actionInfoPtr->is_aoe ) if( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 || actionInfoPtr->castType != 1 )
{ {
// If action on this specific target is valid... // If action on this specific target is valid...
if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) ) if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) )
@ -764,7 +765,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
effectPacket.data().effects[0].effectType = ActionEffectType::Heal; effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
if( !actionInfoPtr->is_aoe ) if( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 || actionInfoPtr->castType != 1 )
{ {
if( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) ) if( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) )
break; break;

View file

@ -16,7 +16,6 @@ namespace Entity {
\class Actor \class Actor
\brief Base class for all actors \brief Base class for all actors
\author Mordred
*/ */
class Actor : public boost::enable_shared_from_this< Actor > class Actor : public boost::enable_shared_from_this< Actor >
{ {

View file

@ -5,7 +5,7 @@
#include <cmath> #include <cmath>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
@ -21,7 +21,7 @@ using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694; uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694;
@ -422,7 +422,7 @@ void Core::Entity::BattleNpc::onDeath()
auto levelDiff = static_cast< int32_t >( this->m_level ) - level; auto levelDiff = static_cast< int32_t >( this->m_level ) - level;
auto cappedLevelDiff = Math::Util::clamp( levelDiff, 1, 6 ); auto cappedLevelDiff = Math::Util::clamp( levelDiff, 1, 6 );
auto expNeeded = g_exdData.m_paramGrowthInfoMap[m_level + cappedLevelDiff - 1].needed_exp; auto expNeeded = g_exdDataGen.getParamGrow( m_level + cappedLevelDiff - 1 )->expToNext;
int32_t exp = 0; int32_t exp = 0;
// todo: arbitrary numbers pulled out of my ass // todo: arbitrary numbers pulled out of my ass

View file

@ -4,14 +4,14 @@
#include <common/Config/XMLConfig.h> #include <common/Config/XMLConfig.h>
#include <common/Network/GamePacket.h> #include <common/Network/GamePacket.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include "Session.h" #include "Session.h"
#include "Player.h" #include "Player.h"
#include "BattleNpc.h" #include "BattleNpc.h"
#include "Zone/ZoneMgr.h" #include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "ServerZone.h" #include "ServerZone.h"
@ -35,7 +35,7 @@
#include "Inventory/Item.h" #include "Inventory/Item.h"
#include "Inventory/Inventory.h" #include "Inventory/Inventory.h"
#include "Event/Event.h" #include "Event/EventHandler.h"
#include "Action/Action.h" #include "Action/Action.h"
#include "Action/EventAction.h" #include "Action/EventAction.h"
#include "Action/EventItemAction.h" #include "Action/EventItemAction.h"
@ -46,8 +46,8 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr; extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
extern Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr; extern Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr;
@ -215,36 +215,27 @@ void Core::Entity::Player::calculateStats()
uint8_t level = getLevel(); uint8_t level = getLevel();
uint8_t job = static_cast< uint8_t >( getClass() ); uint8_t job = static_cast< uint8_t >( getClass() );
auto classInfoIt = g_exdData.m_classJobInfoMap.find( job ); auto classInfo = g_exdDataGen.getClassJob( job );
auto tribeInfoIt = g_exdData.m_tribeInfoMap.find( tribe ); auto tribeInfo = g_exdDataGen.getTribe( tribe );
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( level ); auto paramGrowthInfo = g_exdDataGen.getParamGrow( level );
if( tribeInfoIt == g_exdData.m_tribeInfoMap.end() ||
classInfoIt == g_exdData.m_classJobInfoMap.end() ||
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end() )
return;
auto tribeInfo = tribeInfoIt->second;
auto classInfo = classInfoIt->second;
auto paramGrowthInfo = paramGrowthInfoIt->second;
// TODO: put formula somewhere else... // TODO: put formula somewhere else...
float base = Math::CalcStats::calculateBaseStat( getAsPlayer() ); float base = Math::CalcStats::calculateBaseStat( getAsPlayer() );
m_baseStats.str = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_str ) / 100 ) + tribeInfo.mod_str ); m_baseStats.str = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierStrength ) / 100 ) + tribeInfo->sTR );
m_baseStats.dex = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_dex ) / 100 ) + tribeInfo.mod_dex ); m_baseStats.dex = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierDexterity ) / 100 ) + tribeInfo->dEX );
m_baseStats.vit = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_vit ) / 100 ) + tribeInfo.mod_vit ); m_baseStats.vit = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierVitality ) / 100 ) + tribeInfo->vIT );
m_baseStats.inte = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_int ) / 100 ) + tribeInfo.mod_int ); m_baseStats.inte = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierIntelligence ) / 100 ) + tribeInfo->iNT );
m_baseStats.mnd = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_mnd ) / 100 ) + tribeInfo.mod_mnd ); m_baseStats.mnd = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierMind ) / 100 ) + tribeInfo->mND );
m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_pie ) / 100 ) + tribeInfo.mod_pie ); m_baseStats.pie = static_cast< uint32_t >( base * ( static_cast< float >( classInfo->modifierPiety ) / 100 ) + tribeInfo->pIE );
m_baseStats.skillSpeed = paramGrowthInfo.base_secondary; m_baseStats.skillSpeed = paramGrowthInfo->baseSpeed;
m_baseStats.spellSpeed = paramGrowthInfo.base_secondary; m_baseStats.spellSpeed = paramGrowthInfo->baseSpeed;
m_baseStats.accuracy = paramGrowthInfo.base_secondary; m_baseStats.accuracy = paramGrowthInfo->baseSpeed;
m_baseStats.critHitRate = paramGrowthInfo.base_secondary; m_baseStats.critHitRate = paramGrowthInfo->baseSpeed;
m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; m_baseStats.attackPotMagic = paramGrowthInfo->baseSpeed;
m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary; m_baseStats.healingPotMagic = paramGrowthInfo->baseSpeed;
m_baseStats.tenacity = paramGrowthInfo.base_secondary; m_baseStats.tenacity = paramGrowthInfo->baseSpeed;
m_baseStats.max_mp = Math::CalcStats::calculateMaxMp( getAsPlayer() ); m_baseStats.max_mp = Math::CalcStats::calculateMaxMp( getAsPlayer() );
@ -309,7 +300,7 @@ uint64_t Core::Entity::Player::getFriendsListId() const
void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type ) void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
{ {
auto data = g_exdData.getAetheryteInfo( aetheryteId ); auto data = g_exdDataGen.getAetheryte( aetheryteId );
if( data == nullptr ) if( data == nullptr )
{ {
@ -317,9 +308,8 @@ void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
} }
setStateFlag( PlayerStateFlag::BetweenAreas ); setStateFlag( PlayerStateFlag::BetweenAreas );
sendStateFlags();
auto z_pos = g_zoneMgr.getZonePosition( data->levelId ); auto z_pos = g_territoryMgr.getTerritoryPosition( data->destination );
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos;
pos.x = 0; pos.x = 0;
@ -333,30 +323,30 @@ void Core::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
rot = z_pos->getTargetRotation(); rot = z_pos->getTargetRotation();
} }
sendDebug( "Teleport: " + data->placename + " " + data->placename_aethernet + sendDebug( "Teleport: " + g_exdDataGen.getPlaceName( data->placeName )->name + " " + g_exdDataGen.getPlaceName( data->aethernetName )->name +
"(" + std::to_string( data->levelId ) + ")" ); "(" + std::to_string( data->territory ) + ")" );
// TODO: this should be simplified and a type created in server_common/common.h. // TODO: this should be simplified and a type created in server_common/common.h.
if( type == 1 ) // teleport if( type == 1 ) // teleport
{ {
prepareZoning( data->target_zone, true, 1, 112 ); prepareZoning( data->territory, true, 1, 112 ); // TODO: Really?
sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x04 ) ); sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x04 ) );
setZoningType( Common::ZoneingType::Teleport ); setZoningType( Common::ZoneingType::Teleport );
} }
else if( type == 2 ) // aethernet else if( type == 2 ) // aethernet
{ {
prepareZoning( data->target_zone, true, 1, 112 ); prepareZoning( data->territory, true, 1, 112 );
sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x04 ) ); sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x04 ) );
setZoningType( Common::ZoneingType::Teleport ); setZoningType( Common::ZoneingType::Teleport );
} }
else if( type == 3 ) // return else if( type == 3 ) // return
{ {
prepareZoning( data->target_zone, true, 1, 111 ); prepareZoning( data->territory, true, 1, 111 );
sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x03 ) ); sendToInRangeSet( ActorControlPacket142( getId(), ActorDespawnEffect, 0x03 ) );
setZoningType( Common::ZoneingType::Return ); setZoningType( Common::ZoneingType::Return );
} }
m_queuedZoneing = boost::make_shared< QueuedZoning >( data->target_zone, pos, Util::getTimeMs(), rot ); m_queuedZoneing = boost::make_shared< QueuedZoning >( data->territory, pos, Util::getTimeMs(), rot );
} }
@ -375,105 +365,62 @@ void Core::Entity::Player::returnToHomepoint()
void Core::Entity::Player::setZone( uint32_t zoneId ) void Core::Entity::Player::setZone( uint32_t zoneId )
{ {
auto pPlayer = getAsPlayer(); if( !g_territoryMgr.movePlayer( zoneId, getAsPlayer() ) )
auto pZone = g_zoneMgr.getZone( zoneId );
if( !pZone /*|| ( ( pZone == m_pCurrentZone ) && m_lastPing )*/ )
{ {
g_log.error( "Zone " + std::to_string( zoneId ) + " not found on this server." ); // todo: this will require proper handling, for now just return the player to their previous area
m_pos = m_prevPos;
m_rot = m_prevRot;
m_zoneId = m_prevZoneId;
if( !g_territoryMgr.movePlayer( m_zoneId, getAsPlayer() ) )
return; return;
} }
m_zoneId = zoneId; sendZonePackets();
}
// mark character as zoning in progress bool Core::Entity::Player::setInstance( uint32_t instanceContentId )
setLoadingComplete( false ); {
auto instance = g_territoryMgr.getInstanceZonePtr( instanceContentId );
if( !instance )
return false;
if( m_lastPing != 0 ) return setInstance( instance );
m_pCurrentZone->removeActor( shared_from_this() ); }
m_pCurrentZone = pZone; bool Core::Entity::Player::setInstance( ZonePtr instance )
m_pCurrentZone->pushActor( shared_from_this() ); {
if( !instance )
return false;
ZoneChannelPacket< FFXIVIpcInit > initPacket( getId() ); // zoning within the same zone won't cause the prev data to be overwritten
initPacket.data().charId = getId(); if( instance->getTerritoryId() != m_zoneId )
queuePacket( initPacket );
sendInventory();
if( isLogin() )
{ {
queuePacket(ActorControlPacket143( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) ); m_prevPos = m_pos;
m_prevRot = m_rot;
m_prevZoneId = m_zoneId;
} }
// set flags, will be reset automatically by zoning ( only on client side though ) if( !g_territoryMgr.movePlayer( instance, getAsPlayer() ) )
pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas ); return false;
pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas1 );
pPlayer->sendStateFlags();
pPlayer->sendStats(); sendZonePackets();
// only initialize the UI if the player in fact just logged in. return true;
if( isLogin() ) }
{
ZoneChannelPacket< FFXIVIpcCFAvailableContents > contentFinderList( getId() );
for( auto i = 0; i < sizeof( contentFinderList.data().contents ); i++ )
{
// unlock all contents for now
contentFinderList.data().contents[i] = 0xFF;
}
queuePacket( contentFinderList );
Server::InitUIPacket initUIPacket( *pPlayer ); bool Core::Entity::Player::exitInstance()
queuePacket( initUIPacket ); {
if( !g_territoryMgr.movePlayer( m_prevZoneId, getAsPlayer() ) )
return false;
ZoneChannelPacket< FFXIVIpcPlayerClassInfo > classInfoPacket( getId() ); m_pos = m_prevPos;
classInfoPacket.data().classId = static_cast< uint8_t >( getClass() ); m_rot = m_prevRot;
classInfoPacket.data().unknown = 1; m_zoneId = m_prevZoneId;
classInfoPacket.data().level = getLevel();
classInfoPacket.data().level1 = getLevel();
queuePacket( classInfoPacket );
ZoneChannelPacket< FFXIVGCAffiliation > gcAffPacket( getId() ); sendZonePackets();
gcAffPacket.data().gcId = m_gc;
gcAffPacket.data().gcRank[0] = m_gcRank[0];
gcAffPacket.data().gcRank[1] = m_gcRank[1];
gcAffPacket.data().gcRank[2] = m_gcRank[2];
queuePacket( gcAffPacket );
//todo: change this to extern, global obj return true;
m_friendsListId = g_friendListMgr.fetchPlayerFriendsList( getId() );
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
}
ZoneChannelPacket< FFXIVIpcInitZone > initZonePacket( getId() );
initZonePacket.data().zoneId = getCurrentZone()->getLayoutId();
initZonePacket.data().weatherId = static_cast< uint8_t >( getCurrentZone()->getCurrentWeather() );
initZonePacket.data().bitmask = 0x1;
initZonePacket.data().unknown5 = 0x2A;
initZonePacket.data().pos.x = getPos().x;
initZonePacket.data().pos.y = getPos().y;
initZonePacket.data().pos.z = getPos().z;
queuePacket( initZonePacket );
if( isLogin() )
{
ZoneChannelPacket< FFXIVARR_IPC_UNK322 > unk322( getId() );
queuePacket( unk322 );
ZoneChannelPacket< FFXIVARR_IPC_UNK320 > unk320( getId() );
queuePacket( unk320 );
}
if( getLastPing() == 0 )
sendQuestInfo();
m_bMarkedForZoning = false;
} }
uint32_t Core::Entity::Player::getPlayTime() const uint32_t Core::Entity::Player::getPlayTime() const
@ -555,11 +502,11 @@ void Core::Entity::Player::discover( int16_t map_id, int16_t sub_id )
int32_t offset = 4; int32_t offset = 4;
auto info = g_exdData.m_zoneInfoMap[getCurrentZone()->getId()]; auto info = g_exdDataGen.getMap( g_exdDataGen.getTerritoryType( getCurrentZone()->getTerritoryId() )->map );
if( info.is_two_byte ) if( info->discoveryArrayByte )
offset = 4 + 2 * info.discovery_index; offset = 4 + 2 * info->discoveryIndex;
else else
offset = 324 + 4 * info.discovery_index; offset = 324 + 4 * info->discoveryIndex;
int32_t index = offset + sub_id / 8; int32_t index = offset + sub_id / 8;
uint8_t bitIndex = sub_id % 8; uint8_t bitIndex = sub_id % 8;
@ -570,7 +517,7 @@ void Core::Entity::Player::discover( int16_t map_id, int16_t sub_id )
uint16_t level = getLevel(); uint16_t level = getLevel();
uint32_t exp = ( g_exdData.m_paramGrowthInfoMap[level].needed_exp * 5 / 100 ); uint32_t exp = ( g_exdDataGen.getParamGrow( level )->expToNext * 5 / 100 );
gainExp( exp ); gainExp( exp );
@ -593,7 +540,6 @@ void Core::Entity::Player::setNewAdventurer( bool state )
//{ //{
// setStateFlag( PlayerStateFlag::NewAdventurer ); // setStateFlag( PlayerStateFlag::NewAdventurer );
//} //}
sendStateFlags();
m_bNewAdventurer = state; m_bNewAdventurer = state;
} }
@ -648,9 +594,9 @@ void Core::Entity::Player::gainExp( uint32_t amount )
uint16_t level = getLevel(); uint16_t level = getLevel();
uint32_t neededExpToLevel = g_exdData.m_paramGrowthInfoMap[level].needed_exp; uint32_t neededExpToLevel = g_exdDataGen.getParamGrow( level )->expToNext;
uint32_t neededExpToLevelplus1 = g_exdData.m_paramGrowthInfoMap[level + 1].needed_exp; uint32_t neededExpToLevelplus1 = g_exdDataGen.getParamGrow( level + 1 )->expToNext;
queuePacket( ActorControlPacket143( getId(), GainExpMsg, static_cast< uint8_t >( getClass() ), amount ) ); queuePacket( ActorControlPacket143( getId(), GainExpMsg, static_cast< uint8_t >( getClass() ), amount ) );
@ -750,25 +696,25 @@ void Core::Entity::Player::sendStatusUpdate( bool toSelf )
uint8_t Core::Entity::Player::getLevel() const uint8_t Core::Entity::Player::getLevel() const
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( getClass() )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
return static_cast< uint8_t >( m_classArray[classJobIndex] ); return static_cast< uint8_t >( m_classArray[classJobIndex] );
} }
uint8_t Core::Entity::Player::getLevelForClass( Common::ClassJob pClass ) const uint8_t Core::Entity::Player::getLevelForClass( Common::ClassJob pClass ) const
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( pClass )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( pClass ) )->expArrayIndex;
return static_cast< uint8_t >( m_classArray[classJobIndex] ); return static_cast< uint8_t >( m_classArray[classJobIndex] );
} }
uint32_t Core::Entity::Player::getExp() const uint32_t Core::Entity::Player::getExp() const
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( getClass() )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
return m_expArray[classJobIndex]; return m_expArray[classJobIndex];
} }
void Core::Entity::Player::setExp( uint32_t amount ) void Core::Entity::Player::setExp( uint32_t amount )
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( getClass() )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
m_expArray[classJobIndex] = amount; m_expArray[classJobIndex] = amount;
} }
@ -808,13 +754,13 @@ void Core::Entity::Player::setClassJob( Common::ClassJob classJob )
void Core::Entity::Player::setLevel( uint8_t level ) void Core::Entity::Player::setLevel( uint8_t level )
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( static_cast< uint8_t >( getClass() ) )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( getClass() ) )->expArrayIndex;
m_classArray[classJobIndex] = level; m_classArray[classJobIndex] = level;
} }
void Core::Entity::Player::setLevelForClass( uint8_t level, Common::ClassJob classjob ) void Core::Entity::Player::setLevelForClass( uint8_t level, Common::ClassJob classjob )
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( classjob )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast< uint8_t >( classjob ) )->expArrayIndex;
if( m_classArray[classJobIndex] == 0 ) if( m_classArray[classJobIndex] == 0 )
insertDbClass( classJobIndex ); insertDbClass( classJobIndex );
@ -964,11 +910,11 @@ const uint8_t* Core::Entity::Player::getStateFlags() const
bool Core::Entity::Player::actionHasCastTime( uint32_t actionId ) //TODO: Add logic for special cases bool Core::Entity::Player::actionHasCastTime( uint32_t actionId ) //TODO: Add logic for special cases
{ {
auto actionInfoPtr = g_exdData.getActionInfo( actionId ); auto actionInfoPtr = g_exdDataGen.getAction( actionId );
if( actionInfoPtr->is_instant ) if( actionInfoPtr->preservesCombo )
return false; return false;
return actionInfoPtr->cast_time != 0; return actionInfoPtr->cast100ms != 0;
} }
@ -985,6 +931,7 @@ bool Core::Entity::Player::hasStateFlag( Common::PlayerStateFlag flag ) const
void Core::Entity::Player::setStateFlag( Common::PlayerStateFlag flag ) void Core::Entity::Player::setStateFlag( Common::PlayerStateFlag flag )
{ {
auto prevOnlineStatus = getOnlineStatus();
int32_t iFlag = static_cast< uint32_t >( flag ); int32_t iFlag = static_cast< uint32_t >( flag );
uint16_t index; uint16_t index;
@ -992,6 +939,13 @@ void Core::Entity::Player::setStateFlag( Common::PlayerStateFlag flag )
Util::valueToFlagByteIndexValue( iFlag, value, index ); Util::valueToFlagByteIndexValue( iFlag, value, index );
m_stateFlags[index] |= value; m_stateFlags[index] |= value;
sendStateFlags();
auto newOnlineStatus = getOnlineStatus();
if( prevOnlineStatus != newOnlineStatus )
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
} }
@ -999,13 +953,7 @@ void Core::Entity::Player::setStateFlags( std::vector< Common::PlayerStateFlag >
{ {
for( const auto& flag : flags ) for( const auto& flag : flags )
{ {
int iFlag = static_cast< uint32_t >( flag ); setStateFlag( flag );
uint16_t index;
uint8_t value;
Util::valueToFlagByteIndexValue( iFlag, value, index );
m_stateFlags[index] |= value;
} }
} }
@ -1019,6 +967,8 @@ void Core::Entity::Player::unsetStateFlag( Common::PlayerStateFlag flag )
if( !hasStateFlag( flag ) ) if( !hasStateFlag( flag ) )
return; return;
auto prevOnlineStatus = getOnlineStatus();
int32_t iFlag = static_cast< uint32_t >( flag ); int32_t iFlag = static_cast< uint32_t >( flag );
uint16_t index; uint16_t index;
@ -1026,7 +976,13 @@ void Core::Entity::Player::unsetStateFlag( Common::PlayerStateFlag flag )
Util::valueToFlagByteIndexValue( iFlag, value, index ); Util::valueToFlagByteIndexValue( iFlag, value, index );
m_stateFlags[index] ^= value; m_stateFlags[index] ^= value;
sendStateFlags();
auto newOnlineStatus = getOnlineStatus();
if( prevOnlineStatus != newOnlineStatus )
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
} }
void Core::Entity::Player::update( int64_t currTime ) void Core::Entity::Player::update( int64_t currTime )
@ -1036,7 +992,7 @@ void Core::Entity::Player::update( int64_t currTime )
if( m_queuedZoneing && ( currTime - m_queuedZoneing->m_queueTime ) > 800 ) if( m_queuedZoneing && ( currTime - m_queuedZoneing->m_queueTime ) > 800 )
{ {
Common::FFXIVARR_POSITION3 targetPos = m_queuedZoneing->m_targetPosition; Common::FFXIVARR_POSITION3 targetPos = m_queuedZoneing->m_targetPosition;
if( getCurrentZone()->getId() != m_queuedZoneing->m_targetZone ) if( getCurrentZone()->getTerritoryId() != m_queuedZoneing->m_targetZone )
{ {
performZoning( m_queuedZoneing->m_targetZone, targetPos, m_queuedZoneing->m_targetRotation); performZoning( m_queuedZoneing->m_targetZone, targetPos, m_queuedZoneing->m_targetRotation);
} }
@ -1609,3 +1565,83 @@ void Core::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp )
// Send to single player // Send to single player
queuePacket( packet ); queuePacket( packet );
} }
void Player::setTerritoryId( uint32_t territoryId )
{
m_zoneId = territoryId;
}
uint32_t Player::getTerritoryId() const
{
return m_zoneId;
}
void Player::sendZonePackets()
{
ZoneChannelPacket< FFXIVIpcInit > initPacket( getId() );
initPacket.data().charId = getId();
queuePacket( initPacket );
sendInventory();
if( isLogin() )
{
queuePacket(ActorControlPacket143( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) );
}
// set flags, will be reset automatically by zoning ( only on client side though )
setStateFlag( PlayerStateFlag::BetweenAreas );
setStateFlag( PlayerStateFlag::BetweenAreas1 );
sendStats();
// only initialize the UI if the player in fact just logged in.
if( isLogin() )
{
ZoneChannelPacket< FFXIVIpcCFAvailableContents > contentFinderList( getId() );
for( auto i = 0; i < sizeof( contentFinderList.data().contents ); i++ )
{
// unlock all contents for now
contentFinderList.data().contents[i] = 0xFF;
}
queuePacket( contentFinderList );
Server::InitUIPacket initUIPacket( *this );
queuePacket( initUIPacket );
ZoneChannelPacket< FFXIVIpcPlayerClassInfo > classInfoPacket( getId() );
classInfoPacket.data().classId = static_cast< uint8_t >( getClass() );
classInfoPacket.data().unknown = 1;
classInfoPacket.data().level = getLevel();
classInfoPacket.data().level1 = getLevel();
queuePacket( classInfoPacket );
m_itemLevel = getInventory()->calculateEquippedGearItemLevel();
sendItemLevel();
}
ZoneChannelPacket< FFXIVIpcInitZone > initZonePacket( getId() );
initZonePacket.data().zoneId = getCurrentZone()->getTerritoryId();
initZonePacket.data().weatherId = static_cast< uint8_t >( getCurrentZone()->getCurrentWeather() );
initZonePacket.data().bitmask = 0x1;
initZonePacket.data().unknown5 = 0x2A;
initZonePacket.data().festivalId = getCurrentZone()->getCurrentFestival();
initZonePacket.data().pos.x = getPos().x;
initZonePacket.data().pos.y = getPos().y;
initZonePacket.data().pos.z = getPos().z;
queuePacket( initZonePacket );
if( isLogin() )
{
ZoneChannelPacket< FFXIVARR_IPC_UNK322 > unk322( getId() );
queuePacket( unk322 );
ZoneChannelPacket< FFXIVARR_IPC_UNK320 > unk320( getId() );
queuePacket( unk320 );
}
if( getLastPing() == 0 )
sendQuestInfo();
m_bMarkedForZoning = false;
}

View file

@ -11,7 +11,7 @@
#include "Actor.h" #include "Actor.h"
#include "Inventory/Inventory.h" #include "Inventory/Inventory.h"
#include "Event/EventHandler.h"
#include <map> #include <map>
#include <queue> #include <queue>
@ -55,31 +55,33 @@ public:
/*! start an event item action */ /*! start an event item action */
void eventItemActionStart( uint32_t eventId, uint32_t action, ActionCallback finishCallback, ActionCallback interruptCallback, uint64_t additional ); void eventItemActionStart( uint32_t eventId, uint32_t action, ActionCallback finishCallback, ActionCallback interruptCallback, uint64_t additional );
/*! start/register a normal event */ /*! start/register a normal event */
void eventStart( uint64_t actorId, uint32_t eventId, uint8_t eventParam, uint8_t eventParam1, uint32_t eventParam2 ); void eventStart( uint64_t actorId, uint32_t eventId, Event::EventHandler::EventType eventParam, uint8_t eventParam1, uint32_t eventParam2 );
/*! play a subevent */ /*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3 ); void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, uint32_t eventParam2, uint32_t eventParam3 );
/*! play a subevent */ /*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
uint32_t eventParam2, uint32_t eventParam3, Scripting::EventReturnCallback eventReturnCallback ); uint32_t eventParam2, uint32_t eventParam3, Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */ /*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
uint32_t eventParam2, uint32_t eventParam3, uint32_t eventParam4, Scripting::EventReturnCallback eventReturnCallback ); uint32_t eventParam2, uint32_t eventParam3, uint32_t eventParam4,
Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */ /*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags, Scripting::EventReturnCallback eventReturnCallback ); void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags,
Event::EventHandler::SceneReturnCallback eventReturnCallback );
/*! play a subevent */ /*! play a subevent */
void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags ); void eventPlay( uint32_t eventId, uint32_t scene, uint32_t flags );
/*! finish / unregister an event */ /*! finish / unregister an event */
void eventFinish( uint32_t eventId, uint32_t freePlayer ); void eventFinish( uint32_t eventId, uint32_t freePlayer );
/*! add an event to the event array */ /*! add an event to the event array */
void addEvent( Event::EventPtr pEvent ); void addEvent( Event::EventHandlerPtr pEvent );
/*! retrieve an event from the event array */ /*! retrieve an event from the event array */
Event::EventPtr getEvent( uint32_t eventId ); Event::EventHandlerPtr getEvent( uint32_t eventId );
/*! get number of active events */ /*! get number of active events */
size_t getEventCount(); size_t getEventCount();
/*! remove an event from the event array */ /*! remove an event from the event array */
void removeEvent( uint32_t eventId ); void removeEvent( uint32_t eventId );
/*! return the eventlist */ /*! return the eventlist */
std::map< uint32_t, Event::EventPtr >& eventList(); std::map< uint32_t, Event::EventHandlerPtr >& eventList();
void checkEvent( uint32_t eventId ); void checkEvent( uint32_t eventId );
@ -311,6 +313,16 @@ public:
Common::OnlineStatus getOnlineStatus(); Common::OnlineStatus getOnlineStatus();
/*! sets the players zone, initiating a zoning process */ /*! sets the players zone, initiating a zoning process */
void setZone( uint32_t zoneId ); void setZone( uint32_t zoneId );
/*! sets the players instance & initiates zoning process */
bool setInstance( uint32_t instanceContentId );
/*! sets the players instance & initiates zoning process */
bool setInstance( ZonePtr instance );
/*! returns the player to their position before zoning into an instance */
bool exitInstance();
/*! sets the players territoryId */
void setTerritoryId( uint32_t territoryId );
/*! gets the players territoryId */
uint32_t getTerritoryId() const;
void forceZoneing( uint32_t zoneId ); void forceZoneing( uint32_t zoneId );
/*! return player to preset homepoint */ /*! return player to preset homepoint */
@ -478,10 +490,12 @@ public:
/*! set the loading complete bool */ /*! set the loading complete bool */
void setLoadingComplete( bool bComplete ); void setLoadingComplete( bool bComplete );
/*! mark this player for zoning, notify worldserver */ /*! mark this player for zoning, notify worldserver */
void performZoning(uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation); void performZoning( uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation );
/*! return true if the player is marked for zoning */ /*! return true if the player is marked for zoning */
bool isMarkedForZoning() const; bool isMarkedForZoning() const;
void sendZonePackets();
Common::ZoneingType getZoningType() const; Common::ZoneingType getZoningType() const;
void setZoningType( Common::ZoneingType zoneingType ); void setZoningType( Common::ZoneingType zoneingType );
@ -563,6 +577,11 @@ private:
private: private:
Common::FFXIVARR_POSITION3 m_prevPos;
uint32_t m_prevZoneType;
uint32_t m_prevZoneId;
float m_prevRot;
uint8_t m_voice; uint8_t m_voice;
uint64_t m_modelMainWeapon; uint64_t m_modelMainWeapon;
@ -590,13 +609,13 @@ private:
uint16_t m_activeTitle; uint16_t m_activeTitle;
uint8_t m_titleList[48]; uint8_t m_titleList[48];
uint8_t m_howTo[33]; uint8_t m_howTo[33];
uint8_t m_minions[35]; uint8_t m_minions[37];
uint8_t m_mountGuide[14]; uint8_t m_mountGuide[15];
uint8_t m_homePoint; uint8_t m_homePoint;
uint8_t m_startTown; uint8_t m_startTown;
uint16_t m_townWarpFstFlags; uint16_t m_townWarpFstFlags;
uint8_t m_questCompleteFlags[200]; uint8_t m_questCompleteFlags[396];
uint8_t m_discovery[420]; uint8_t m_discovery[421];
uint32_t m_playTime; uint32_t m_playTime;
uint16_t m_classArray[25]; uint16_t m_classArray[25];
@ -610,7 +629,8 @@ private:
uint16_t m_itemLevel; uint16_t m_itemLevel;
InventoryPtr m_pInventory; InventoryPtr m_pInventory;
std::map< uint32_t, Event::EventPtr > m_eventMap; std::map< uint32_t, Event::EventHandlerPtr > m_eventHandlerMap;
std::map< uint32_t, uint8_t > m_playerIdToSpawnIdMap; // maps player to spawn id std::map< uint32_t, uint8_t > m_playerIdToSpawnIdMap; // maps player to spawn id
std::queue< uint8_t > m_freeSpawnIdQueue; // queue with spawn ids free to be assigned std::queue< uint8_t > m_freeSpawnIdQueue; // queue with spawn ids free to be assigned
std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" free to be assigned std::queue< uint8_t > m_freeHateSlotQueue; // queue with "hate slots" free to be assigned

View file

@ -21,8 +21,8 @@
#include "Action/EventAction.h" #include "Action/EventAction.h"
#include "Action/EventItemAction.h" #include "Action/EventItemAction.h"
#include "Event/Event.h" #include "Event/EventHandler.h"
#include "Event/Event.h" #include "Event/EventHandler.h"
#include "ServerZone.h" #include "ServerZone.h"
extern Core::Logger g_log; extern Core::Logger g_log;
@ -32,37 +32,37 @@ using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
void Core::Entity::Player::addEvent( Event::EventPtr pEvent ) void Core::Entity::Player::addEvent( Event::EventHandlerPtr pEvent )
{ {
m_eventMap[pEvent->getId()] = pEvent; m_eventHandlerMap[pEvent->getId()] = pEvent;
} }
std::map< uint32_t, Core::Event::EventPtr >& Core::Entity::Player::eventList() std::map< uint32_t, Core::Event::EventHandlerPtr >& Core::Entity::Player::eventList()
{ {
return m_eventMap; return m_eventHandlerMap;
} }
Core::Event::EventPtr Core::Entity::Player::getEvent( uint32_t eventId ) Core::Event::EventHandlerPtr Core::Entity::Player::getEvent( uint32_t eventId )
{ {
auto it = m_eventMap.find( eventId ); auto it = m_eventHandlerMap.find( eventId );
if( it != m_eventMap.end() ) if( it != m_eventHandlerMap.end() )
return it->second; return it->second;
return Event::EventPtr( nullptr ); return Event::EventHandlerPtr( nullptr );
} }
size_t Core::Entity::Player::getEventCount() size_t Core::Entity::Player::getEventCount()
{ {
return m_eventMap.size(); return m_eventHandlerMap.size();
} }
void Core::Entity::Player::removeEvent( uint32_t eventId ) void Core::Entity::Player::removeEvent( uint32_t eventId )
{ {
auto it = m_eventMap.find( eventId ); auto it = m_eventHandlerMap.find( eventId );
if( it != m_eventMap.end() ) if( it != m_eventHandlerMap.end() )
{ {
auto tmpEvent = it->second; auto tmpEvent = it->second;
m_eventMap.erase( it ); m_eventHandlerMap.erase( it );
} }
} }
@ -76,14 +76,15 @@ void Core::Entity::Player::checkEvent( uint32_t eventId )
void Core::Entity::Player::eventStart( uint64_t actorId, uint32_t eventId, void Core::Entity::Player::eventStart( uint64_t actorId, uint32_t eventId,
uint8_t eventType, uint8_t eventParam1, Event::EventHandler::EventType eventType, uint8_t eventParam1,
uint32_t eventParam2 ) uint32_t eventParam2 )
{ {
Event::EventPtr newEvent( new Event::Event( actorId, eventId, eventType, eventParam1, eventParam2 ) );
Event::EventHandlerPtr newEvent( new Event::EventHandler( this, actorId, eventId, eventType, eventParam2 ) );
addEvent( newEvent ); addEvent( newEvent );
setStateFlag( PlayerStateFlag::Occupied2 ); setStateFlag( PlayerStateFlag::Occupied2 );
sendStateFlags();
EventStartPacket eventStart( getId(), actorId, eventId, eventType, eventParam1, eventParam2 ); EventStartPacket eventStart( getId(), actorId, eventId, eventType, eventParam1, eventParam2 );
@ -99,7 +100,7 @@ void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
} }
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene, void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, Scripting::EventReturnCallback eventCallback ) uint32_t flags, Event::EventHandler::SceneReturnCallback eventCallback )
{ {
eventPlay( eventId, scene, flags, 0, 0, eventCallback ); eventPlay( eventId, scene, flags, 0, 0, eventCallback );
} }
@ -111,20 +112,16 @@ void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene, uint32_t
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene, void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, uint32_t eventParam2, uint32_t flags, uint32_t eventParam2,
uint32_t eventParam3, Scripting::EventReturnCallback eventCallback ) uint32_t eventParam3, Event::EventHandler::SceneReturnCallback eventCallback )
{ {
if( flags & 0x02 ) if( flags & 0x02 )
{
setStateFlag( PlayerStateFlag::WatchingCutscene ); setStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
auto pEvent = getEvent( eventId ); auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() ) if( !pEvent && getEventCount() )
{ {
// We're trying to play a nested event, need to start it first. // We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::Event::Nest, 0, 0 ); eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId ); pEvent = getEvent( eventId );
} }
else if( !pEvent ) else if( !pEvent )
@ -143,20 +140,16 @@ void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene, void Core::Entity::Player::eventPlay( uint32_t eventId, uint32_t scene,
uint32_t flags, uint32_t eventParam2, uint32_t flags, uint32_t eventParam2,
uint32_t eventParam3, uint32_t eventParam4, Scripting::EventReturnCallback eventCallback ) uint32_t eventParam3, uint32_t eventParam4, Event::EventHandler::SceneReturnCallback eventCallback )
{ {
if( flags & 0x02 ) if( flags & 0x02 )
{
setStateFlag( PlayerStateFlag::WatchingCutscene ); setStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
auto pEvent = getEvent( eventId ); auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() ) if( !pEvent && getEventCount() )
{ {
// We're trying to play a nested event, need to start it first. // We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::Event::Nest, 0, 0 ); eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId ); pEvent = getEvent( eventId );
} }
else if( !pEvent ) else if( !pEvent )
@ -183,7 +176,7 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
return; return;
} }
if( getEventCount() > 1 && pEvent->getEventType() != Event::Event::Nest ) if( getEventCount() > 1 && pEvent->getEventType() != Event::EventHandler::Nest )
{ {
// this is the parent of a nested event, we can't finish it until the parent finishes // this is the parent of a nested event, we can't finish it until the parent finishes
return; return;
@ -191,9 +184,9 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
switch( pEvent->getEventType() ) switch( pEvent->getEventType() )
{ {
case Event::Event::Nest: case Event::EventHandler::Nest:
{ {
queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam3() ) ); queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam() ) );
removeEvent( pEvent->getId() ); removeEvent( pEvent->getId() );
auto events = eventList(); auto events = eventList();
@ -204,7 +197,8 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
if( it.second->hasPlayedScene() == false ) if( it.second->hasPlayedScene() == false )
{ {
// TODO: not happy with this, this is also prone to break wit more than one remaining event in there // TODO: not happy with this, this is also prone to break wit more than one remaining event in there
queuePacket( EventFinishPacket( getId(), it.second->getId(), it.second->getEventType(), it.second->getEventParam3() ) ); queuePacket( EventFinishPacket( getId(), it.second->getId(), it.second->getEventType(),
it.second->getEventParam() ) );
removeEvent( it.second->getId() ); removeEvent( it.second->getId() );
} }
} }
@ -213,25 +207,18 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer )
} }
default: default:
{ {
queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam3() ) ); queuePacket( EventFinishPacket( getId(), pEvent->getId(), pEvent->getEventType(), pEvent->getEventParam() ) );
break; break;
} }
} }
if( hasStateFlag( PlayerStateFlag::WatchingCutscene ) ) if( hasStateFlag( PlayerStateFlag::WatchingCutscene ) )
{
unsetStateFlag( PlayerStateFlag::WatchingCutscene ); unsetStateFlag( PlayerStateFlag::WatchingCutscene );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatusIcon,
static_cast< uint8_t >( getOnlineStatus() ) ), true );
}
removeEvent( pEvent->getId() ); removeEvent( pEvent->getId() );
if( freePlayer == 1 ) if( freePlayer == 1 )
{
unsetStateFlag( PlayerStateFlag::Occupied2 ); unsetStateFlag( PlayerStateFlag::Occupied2 );
sendStateFlags();
}
} }
void Core::Entity::Player::eventActionStart( uint32_t eventId, void Core::Entity::Player::eventActionStart( uint32_t eventId,
@ -249,7 +236,7 @@ void Core::Entity::Player::eventActionStart( uint32_t eventId,
if( !pEvent && getEventCount() ) if( !pEvent && getEventCount() )
{ {
// We're trying to play a nested event, need to start it first. // We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::Event::Nest, 0, 0 ); eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId ); pEvent = getEvent( eventId );
} }
else if( !pEvent ) else if( !pEvent )

View file

@ -5,7 +5,6 @@
#include "Player.h" #include "Player.h"
#include "Zone/ZoneMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"

View file

@ -1,7 +1,7 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h> #include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Network/GamePacket.h> #include <common/Network/GamePacket.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
@ -12,7 +12,7 @@
#include "Inventory/Inventory.h" #include "Inventory/Inventory.h"
#include "Player.h" #include "Player.h"
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
@ -979,7 +979,7 @@ void Core::Entity::Player::sendQuestInfo()
queuePacket( pe_qa ); queuePacket( pe_qa );
ZoneChannelPacket< FFXIVIpcQuestCompleteList > pe_qc( getId() ); ZoneChannelPacket< FFXIVIpcQuestCompleteList > pe_qc( getId() );
memcpy( pe_qc.data().questCompleteMask, m_questCompleteFlags, 200 ); memcpy( pe_qc.data().questCompleteMask, m_questCompleteFlags, sizeof( m_questCompleteFlags ) );
queuePacket( pe_qc ); queuePacket( pe_qc );
sendQuestTracker(); sendQuestTracker();
@ -1015,24 +1015,24 @@ void Core::Entity::Player::removeQuestsCompleted( uint32_t questId )
bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optionalChoice ) bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optionalChoice )
{ {
uint32_t playerLevel = getLevel(); uint32_t playerLevel = getLevel();
auto questInfo = g_exdData.getQuestInfo( questId ); auto questInfo = g_exdDataGen.getQuest( questId );
if( !questInfo ) if( !questInfo )
return false; return false;
auto paramGrowth = g_exdData.m_paramGrowthInfoMap[questInfo->quest_level]; auto paramGrowth = g_exdDataGen.getParamGrow( questInfo->classJobLevel0 );
// TODO: use the correct formula, this one is wrong // TODO: use the correct formula, this one is wrong
uint32_t exp = ( questInfo->reward_exp_factor * paramGrowth.quest_exp_mod * ( 45 + 5 * questInfo->quest_level) ) / 100; uint32_t exp = ( questInfo->expFactor * paramGrowth->questExpModifier * ( 45 + 5 * questInfo->classJobLevel0 ) ) / 100;
exp = exp + ( questInfo->reward_exp_factor / 100 ) * 10000; exp = exp + ( questInfo->expFactor / 100 ) * 10000;
exp = questInfo->reward_exp_factor; exp = questInfo->expFactor;
auto rewardItemCount = questInfo->reward_item.size(); auto rewardItemCount = questInfo->itemReward0.size();
uint16_t optionalItemCount = questInfo->reward_item_optional.size() > 0 ? 1 : 0; uint16_t optionalItemCount = questInfo->itemReward1.size();
uint32_t gilReward = questInfo->reward_gil; uint32_t gilReward = questInfo->gilReward;
// TODO: check if there is room in inventory, else return false; // TODO: check if there is room in inventory, else return false;
if( exp > 0 ) if( exp > 0 )
@ -1040,18 +1040,16 @@ bool Core::Entity::Player::giveQuestRewards( uint32_t questId, uint32_t optional
if( rewardItemCount > 0 ) if( rewardItemCount > 0 )
{ {
for( uint32_t i = 0; i < questInfo->reward_item.size(); i++ ) for( uint32_t i = 0; i < questInfo->itemReward0.size(); i++ )
{ {
// TODO: add the correct amount of items instead of 1 addItem( -1, questInfo->itemReward0.at( i ), questInfo->itemCountReward0.at( i ) );
addItem( -1, questInfo->reward_item.at( i ), questInfo->reward_item_count.at( i ) );
} }
} }
if( optionalItemCount > 0 ) if( optionalItemCount > 0 )
{ {
auto itemId = questInfo->reward_item_optional.at( optionalChoice ); auto itemId = questInfo->itemReward1.at( optionalChoice );
// TODO: add the correct amount of items instead of 1 addItem( -1, itemId, questInfo->itemCountReward1.at( optionalChoice ) );
addItem( -1, itemId, questInfo->reward_item_optional_count.at( optionalChoice ) );
} }
if( gilReward > 0 ) if( gilReward > 0 )

View file

@ -4,7 +4,7 @@
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include <common/Config/XMLConfig.h> #include <common/Config/XMLConfig.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Common.h> #include <common/Common.h>
#include <common/Database/DatabaseDef.h> #include <common/Database/DatabaseDef.h>
@ -16,7 +16,7 @@
#include "Player.h" #include "Player.h"
#include "Zone/ZoneMgr.h" #include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "ServerZone.h" #include "ServerZone.h"
@ -30,8 +30,8 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr; extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
@ -57,8 +57,10 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
strcpy( m_name, name.c_str() ); strcpy( m_name, name.c_str() );
auto zoneId = res->getUInt( "TerritoryId" ); auto zoneId = res->getUInt( "TerritoryId" );
m_prevZoneId = res->getUInt( "OTerritoryId" );
m_prevZoneType = res->getUInt( "OTerritoryType" );
ZonePtr pCurrZone = g_zoneMgr.getZone( zoneId ); ZonePtr pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
m_zoneId = zoneId; m_zoneId = zoneId;
// TODO: logic for instances needs to be added here // TODO: logic for instances needs to be added here
@ -70,7 +72,7 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
// default to new gridania // default to new gridania
// TODO: should probably just abort and mark character as corrupt // TODO: should probably just abort and mark character as corrupt
pCurrZone = g_zoneMgr.getZone( 132 ); pCurrZone = g_territoryMgr.getZoneByTerriId( 132 );
m_pos.x = 0.0f; m_pos.x = 0.0f;
m_pos.y = 0.0f; m_pos.y = 0.0f;
@ -91,6 +93,11 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_pos.z = res->getFloat( "PosZ" ); m_pos.z = res->getFloat( "PosZ" );
setRotation( res->getFloat( "PosR" ) ); setRotation( res->getFloat( "PosR" ) );
m_prevPos.x = res->getFloat( "OPosX" );
m_prevPos.y = res->getFloat( "OPosY" );
m_prevPos.z = res->getFloat( "OPosZ" );
m_prevRot = res->getFloat( "OPosR" );
// Model // Model
auto custom = res->getBlobVector( "Customize" ); auto custom = res->getBlobVector( "Customize" );
@ -338,12 +345,12 @@ void Core::Entity::Player::updateSql()
stmt->setDouble( 22, m_pos.z ); stmt->setDouble( 22, m_pos.z );
stmt->setDouble( 23, getRotation() ); stmt->setDouble( 23, getRotation() );
stmt->setInt( 24, 0 ); // OTerritoryType stmt->setInt( 24, m_prevZoneType ); // OTerritoryType
stmt->setInt( 25, 0 ); // OTerritoryId stmt->setInt( 25, m_prevZoneId ); // OTerritoryId
stmt->setDouble( 26, 0.0f ); stmt->setDouble( 26, m_prevPos.x );
stmt->setDouble( 27, 0.0f ); stmt->setDouble( 27, m_prevPos.y );
stmt->setDouble( 28, 0.0f ); stmt->setDouble( 28, m_prevPos.z );
stmt->setDouble( 29, 0.0f ); stmt->setDouble( 29, m_prevRot );
stmt->setInt( 30, static_cast< uint8_t >( getClass() ) ); stmt->setInt( 30, static_cast< uint8_t >( getClass() ) );
stmt->setInt( 31, static_cast< uint8_t >( getStatus() ) ); stmt->setInt( 31, static_cast< uint8_t >( getStatus() ) );
@ -426,7 +433,7 @@ void Core::Entity::Player::updateSql()
void Core::Entity::Player::updateDbClass() const void Core::Entity::Player::updateDbClass() const
{ {
uint8_t classJobIndex = g_exdData.m_classJobInfoMap[static_cast< uint8_t >( getClass() )].exp_idx; uint8_t classJobIndex = g_exdDataGen.getClassJob( static_cast<uint8_t>( getClass() ) )->expArrayIndex;
//Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ? //Exp = ?, Lvl = ? WHERE CharacterId = ? AND ClassIdx = ?
auto stmtS = g_charaDb.getPreparedStatement( Db::CHARA_CLASS_UP ); auto stmtS = g_charaDb.getPreparedStatement( Db::CHARA_CLASS_UP );

View file

@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 2.6)
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
cmake_policy(SET CMP0014 OLD) cmake_policy(SET CMP0014 OLD)
add_subdirectory("Script/Scripts")
project(sapphire_zone) project(sapphire_zone)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )

View file

@ -8,7 +8,7 @@
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Database/DatabaseDef.h> #include <common/Database/DatabaseDef.h>
#include "DebugCommand.h" #include "DebugCommand.h"
@ -38,11 +38,13 @@
#include <cinttypes> #include <cinttypes>
#include "Network/PacketWrappers/PlayerSpawnPacket.h" #include "Network/PacketWrappers/PlayerSpawnPacket.h"
#include "Zone/TerritoryMgr.h"
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::TerritoryMgr g_territoryMgr;
// instanciate and initialize commands // instanciate and initialize commands
Core::DebugCommandHandler::DebugCommandHandler() Core::DebugCommandHandler::DebugCommandHandler()
@ -59,6 +61,7 @@ Core::DebugCommandHandler::DebugCommandHandler()
registerCommand( "unlock", &DebugCommandHandler::unlockCharacter, "Unlock character.", 1 ); registerCommand( "unlock", &DebugCommandHandler::unlockCharacter, "Unlock character.", 1 );
registerCommand( "help", &DebugCommandHandler::help, "Shows registered commands.", 0 ); registerCommand( "help", &DebugCommandHandler::help, "Shows registered commands.", 0 );
registerCommand( "script", &DebugCommandHandler::script, "Server script utilities.", 1 ); registerCommand( "script", &DebugCommandHandler::script, "Server script utilities.", 1 );
registerCommand( "instance", &DebugCommandHandler::instance, "Instance utilities", 1 );
} }
// clear all loaded commands // clear all loaded commands
@ -280,6 +283,29 @@ void Core::DebugCommandHandler::set( char * data, Entity::Player& player, boost:
player.dismount(); player.dismount();
player.mount( id ); player.mount( id );
} }
else if ( subCommand == "msqguide" )
{
int32_t id;
sscanf( params.c_str(), "%d", &id );
Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcMSQTrackerProgress > msqPacket(
player.getId());
msqPacket.data().id = id;
player.queuePacket( msqPacket );
player.sendDebug( "MSQ Guide updated " );
}
else if ( subCommand == "msqdone")
{
int32_t id;
sscanf( params.c_str(), "%d", &id );
Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcMSQTrackerComplete > msqPacket ( player.getId() );
msqPacket.data().id = id;
player.queuePacket( msqPacket );
player.sendDebug( "MSQ Guide updated " );
}
else else
{ {
player.sendUrgent( subCommand + " is not a valid SET command." ); player.sendUrgent( subCommand + " is not a valid SET command." );
@ -479,7 +505,7 @@ void Core::DebugCommandHandler::get( char * data, Entity::Player& player, boost:
if( ( subCommand == "pos" ) ) if( ( subCommand == "pos" ) )
{ {
int16_t map_id = g_exdData.m_zoneInfoMap[player.getCurrentZone()->getId()].map_id; int16_t map_id = g_exdDataGen.getTerritoryType( player.getCurrentZone()->getTerritoryId() )->map;
player.sendNotice( "Pos:\n" + player.sendNotice( "Pos:\n" +
std::to_string( player.getPos().x ) + "\n" + std::to_string( player.getPos().x ) + "\n" +
@ -487,7 +513,7 @@ void Core::DebugCommandHandler::get( char * data, Entity::Player& player, boost:
std::to_string( player.getPos().z ) + "\n" + std::to_string( player.getPos().z ) + "\n" +
std::to_string( player.getRotation() ) + "\nMapId: " + std::to_string( player.getRotation() ) + "\nMapId: " +
std::to_string( map_id ) + "\nZoneID: " + std::to_string( map_id ) + "\nZoneID: " +
std::to_string( player.getCurrentZone()->getId() ) + "\n" ); std::to_string(player.getCurrentZone()->getTerritoryId() ) + "\n" );
} }
else else
{ {
@ -701,17 +727,70 @@ void Core::DebugCommandHandler::script( char* data, Entity::Player &player, boos
player.sendDebug( "Queued script reload for script: " + params ); player.sendDebug( "Queued script reload for script: " + params );
} }
} }
else if( subCommand == "build" || subCommand == "b" )
{
if( subCommand == params )
player.sendDebug( "Command failed: requires name of cmake target" );
else
{
}
}
else else
{ {
player.sendDebug( "Unknown script subcommand: " + subCommand ); player.sendDebug( "Unknown script subcommand: " + subCommand );
} }
} }
void Core::DebugCommandHandler::instance( char* data, Entity::Player &player, boost::shared_ptr< DebugCommand > command )
{
std::string cmd( data ), params, subCommand;
auto cmdPos = cmd.find_first_of( ' ' );
if( cmdPos != std::string::npos )
{
params = cmd.substr( cmdPos + 1 );
auto p = params.find_first_of( ' ' );
if( p != std::string::npos )
{
subCommand = params.substr( 0, p );
params = params.substr( subCommand.length() + 1 );
}
else
subCommand = params;
}
if( subCommand == "create" || subCommand == "cr" )
{
uint32_t instanceContentId;
sscanf( params.c_str(), "%d", &instanceContentId );
auto instance = g_territoryMgr.createInstanceContent( instanceContentId );
if( instance )
player.sendDebug( "Created instance with id: " + std::to_string( instance->getGuId() ) + " -> " + instance->getName() );
else
player.sendDebug( "Failed to create instance with id: " + std::to_string( instanceContentId ) );
}
else if( subCommand == "remove" || subCommand == "rm" )
{
uint32_t terriId;
sscanf( params.c_str(), "%d", &terriId );
if( g_territoryMgr.removeTerritoryInstance( terriId ) )
player.sendDebug( "Removed instance with id: " + std::to_string( terriId ) );
else
player.sendDebug( "Failed to remove instance with id: " + std::to_string( terriId ) );
}
else if( subCommand == "return" || subCommand == "ret" )
{
player.exitInstance();
}
else if( subCommand == "festival" )
{
uint32_t festivalId;
sscanf( params.c_str(), "%d", &festivalId );
player.getCurrentZone()->setCurrentFestival( static_cast< uint16_t >( festivalId ) );
}
else if( subCommand == "disablefestival" )
{
Network::Packets::ZoneChannelPacket< Network::Packets::Server::FFXIVIpcActorControl143 > actorControl( player.getId() );
actorControl.data().category = Core::Common::ActorControlType::DisableCurrentFestival;
player.queuePacket( actorControl );
player.getCurrentZone()->setCurrentFestival( 0 );
}
}

View file

@ -44,6 +44,8 @@ public:
void unlockCharacter( char* data, Entity::Player& player, boost::shared_ptr< DebugCommand > command ); void unlockCharacter( char* data, Entity::Player& player, boost::shared_ptr< DebugCommand > command );
void instance( char* data, Entity::Player& player, boost::shared_ptr< DebugCommand > command );
void script( char* data, Entity::Player& player, boost::shared_ptr< DebugCommand > command ); void script( char* data, Entity::Player& player, boost::shared_ptr< DebugCommand > command );
}; };

View file

@ -0,0 +1 @@
#include "Director.h"

View file

@ -0,0 +1,66 @@
#ifndef SAPPHIRE_DIRECTOR_H
#define SAPPHIRE_DIRECTOR_H
#include <common/Common.h>
#include "Forwards.h"
namespace Core {
namespace Event {
/*!
\class Director
\brief Base class for all Directors implements sequence and variables
*/
class Director
{
public:
enum DirectorType
{
InstanceContent = 0x8003, // used for dungeons/raids
CompanyLeve = 0x8007,
QuestBattle = 0x8006,
GatheringLeve = 0x8002,
BattleLeve = 0x8001,
GoldSaucer = 0x800A,
Fate = 0x801A,
DpsChallange = 0x800D
};
private:
/*! Id of the content of the director */
uint16_t m_id;
/*! DirectorType | ContentId */
uint32_t m_directorId;
/*! currect sequence */
uint8_t m_sequence;
/*! current branch */
uint8_t m_branch;
/*! raw storage for flags/vars */
uint8_t m_unionData[10];
/*! type of the director */
DirectorType m_type;
uint32_t getDirectorId() const;
uint16_t getContentId() const;
DirectorType getType() const;
uint8_t getSequence() const;
uint8_t getBranch() const;
};
}
}
#endif //SAPPHIRE_DIRECTOR_H

View file

@ -1,73 +0,0 @@
#include "Event.h"
Core::Event::Event::Event( uint64_t actorId, uint32_t eventId, uint8_t eventType, uint8_t eventParam2, uint32_t eventParam3 )
: m_actorId( actorId ),
m_eventId( eventId ),
m_playedScene( false )
{
m_param1 = static_cast< uint16_t >( eventId );
m_param2 = static_cast< uint16_t >( eventId >> 16 );
m_eventType = eventType;
m_eventParam2 = eventParam2;
m_eventParam3 = eventParam3;
m_callback = nullptr;
}
uint64_t Core::Event::Event::getActorId() const
{
return m_actorId;
}
uint32_t Core::Event::Event::getId() const
{
return m_eventId;
}
uint32_t Core::Event::Event::getParam1() const
{
return m_param1;
}
uint16_t Core::Event::Event::getParam2() const
{
return m_param2;
}
uint8_t Core::Event::Event::getEventType() const
{
return m_eventType;
}
uint32_t Core::Event::Event::getEventParam2() const
{
return m_eventParam2;
}
uint32_t Core::Event::Event::getEventParam3() const
{
return m_eventParam3;
}
Core::Scripting::EventReturnCallback Core::Event::Event::getEventReturnCallback() const
{
return m_callback;
}
void Core::Event::Event::setEventReturnCallback( Scripting::EventReturnCallback callback )
{
m_callback = callback;
}
bool Core::Event::Event::hasPlayedScene() const
{
return m_playedScene;
}
void Core::Event::Event::setPlayedScene( bool playedScene )
{
m_playedScene = playedScene;
}

View file

@ -1,78 +0,0 @@
#ifndef _EVENT_H
#define _EVENT_H
#include "../Forwards.h"
namespace Core {
namespace Event {
class Event
{
public:
Event( uint64_t actorId, uint32_t eventId, uint8_t eventType, uint8_t eventParam2, uint32_t eventParam3 );
~Event() {}
uint64_t getActorId() const;
uint32_t getId() const;
uint32_t getParam1() const;
uint16_t getParam2() const;
uint8_t getEventType() const;
uint32_t getEventParam2() const;
uint32_t getEventParam3() const;
bool hasPlayedScene() const;
void setPlayedScene( bool playedScene );
Scripting::EventReturnCallback getEventReturnCallback() const;
void setEventReturnCallback( Scripting::EventReturnCallback callback );
enum EventType : uint8_t
{
Talk = 1,
Emote = 2,
DistanceBelow = 3,
DistanceOver = 4,
BattleReward = 5,
Craft = 6,
Nest = 7,
Item = 8,
Drop = 9,
WithinRange = 10,
OutsideRange = 11,
GameStart = 12,
GameProgress = 13,
EnterTerritory = 15,
GameComeBack = 17,
ActionResult = 18,
MateriaCraft = 19,
Fishing = 20,
UI = 21,
Housing = 22,
Say = 23,
TableGame = 24,
};
protected:
uint64_t m_actorId;
uint32_t m_eventId;
uint32_t m_param1;
uint16_t m_param2;
uint8_t m_eventType;
uint8_t m_eventParam2;
uint32_t m_eventParam3;
bool m_playedScene;
Scripting::EventReturnCallback m_callback;
};
}
}
#endif

View file

@ -0,0 +1,75 @@
#include "EventHandler.h"
Core::Event::EventHandler::EventHandler( Entity::Player* pOwner, uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam ) :
m_pOwner( pOwner ),
m_actorId( actorId ),
m_eventId( eventId ),
m_eventType( eventType ),
m_playedScene( false )
{
m_entryId = static_cast< uint16_t >( eventId );
m_type = static_cast< uint16_t >( eventId >> 16 );
m_eventParam = eventParam;
m_callback = nullptr;
}
uint64_t Core::Event::EventHandler::getActorId() const
{
return m_actorId;
}
uint32_t Core::Event::EventHandler::getId() const
{
return m_eventId;
}
uint8_t Core::Event::EventHandler::getEventType() const
{
return m_eventType;
}
uint16_t Core::Event::EventHandler::getType() const
{
return m_type;
}
uint16_t Core::Event::EventHandler::getEntryId() const
{
return m_entryId;
}
uint32_t Core::Event::EventHandler::getEventParam() const
{
return m_eventParam;
}
Core::Event::EventHandler::SceneReturnCallback Core::Event::EventHandler::getEventReturnCallback() const
{
return m_callback;
}
void Core::Event::EventHandler::setEventReturnCallback( SceneReturnCallback callback )
{
m_callback = callback;
}
bool Core::Event::EventHandler::hasPlayedScene() const
{
return m_playedScene;
}
void Core::Event::EventHandler::setPlayedScene( bool playedScene )
{
m_playedScene = playedScene;
}
bool Core::Event::EventHandler::hasNestedEvent() const
{
return m_pNestedEvent != nullptr;
}
void Core::Event::EventHandler::removeNestedEvent()
{
m_pNestedEvent.reset();
}

View file

@ -0,0 +1,113 @@
#ifndef _EVENT_H
#define _EVENT_H
#include "../Forwards.h"
namespace Core {
namespace Event {
class EventHandler
{
public:
enum EventType : uint8_t
{
Talk = 1,
Emote = 2,
DistanceBelow = 3,
DistanceOver = 4,
BattleReward = 5,
Craft = 6,
Nest = 7,
Item = 8,
Drop = 9,
WithinRange = 10,
OutsideRange = 11,
GameStart = 12,
GameProgress = 13,
EnterTerritory = 15,
GameComeBack = 17,
ActionResult = 18,
MateriaCraft = 19,
Fishing = 20,
UI = 21,
Housing = 22,
Say = 23,
TableGame = 24,
};
enum EventHandlerType : uint16_t
{
Quest = 0x0001,
Warp = 0x0002,
Unknown = 0x0003, // Came up in the client with "Begin" unsure that means
Shop = 0x0004,
Aetheryte = 0x0005,
GuildLeveAssignment = 0x0006,
DefaultTalk = 0x0009,
CustomTalk = 0x000B,
CompanyLeveOfficer = 0x000C,
CraftLeve = 0x000E,
GimmickAccessor = 0x000F,
GimmickBill = 0x0010,
GimmickRect = 0x0011,
ChocoboTaxiStand = 0x0012,
Opening = 0x0013,
ExitRange = 0x0014,
GCShop = 0x0016,
GuildOrderGuide = 0x0017,
GuildOrderOfficer = 0x0018,
ContentNpc = 0x0019,
Story = 0x001A,
SpecialShop = 0x001B,
BahamutGuide = 0x001C,
FcTalk = 0x001F,
};
using SceneReturnCallback = std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t ) > ;
EventHandler( Entity::Player* pOwner, uint64_t actorId, uint32_t eventId, EventType eventType, uint32_t eventParam );
~EventHandler() {}
uint64_t getActorId() const;
uint32_t getId() const;
uint16_t getType() const;
uint16_t getEntryId() const;
uint8_t getEventType() const;
uint32_t getEventParam() const;
bool hasPlayedScene() const;
void setPlayedScene( bool playedScene );
SceneReturnCallback getEventReturnCallback() const;
void setEventReturnCallback( SceneReturnCallback callback );
bool hasNestedEvent() const;
void removeNestedEvent();
protected:
Entity::Player* m_pOwner;
uint64_t m_actorId;
uint32_t m_eventId;
uint16_t m_entryId;
uint16_t m_type;
uint8_t m_eventType;
uint32_t m_eventParam;
EventHandlerPtr m_pNestedEvent;
bool m_playedScene;
SceneReturnCallback m_callback;
};
}
}
#endif

View file

@ -1,9 +1,9 @@
#include "EventHelper.h" #include "EventHelper.h"
#include "Event.h" #include "EventHandler.h"
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
@ -15,43 +15,44 @@ std::string Core::Event::getEventName( uint32_t eventId )
switch( eventType ) switch( eventType )
{ {
case EventType::Quest: case Event::EventHandler::EventHandlerType::Quest:
{ {
auto questInfo = g_exdData.getQuestInfo( eventId ); auto questInfo = g_exdDataGen.getQuest( eventId );
if( !questInfo ) if( !questInfo )
return unknown + "Quest"; return unknown + "Quest";
std::string name = questInfo->name_intern; std::string name = questInfo->id;
std::size_t pos = name.find_first_of( "_" ); std::size_t pos = name.find_first_of( "_" );
return questInfo->name_intern.substr( 0, pos ); return name.substr( 0, pos );
} }
case EventType::CustomTalk: case Event::EventHandler::EventHandlerType::CustomTalk:
{ {
auto customTalkInfo = g_exdData.getCustomTalkInfo( eventId ); auto customTalkInfo = g_exdDataGen.getCustomTalk( eventId );
if( !customTalkInfo ) if( !customTalkInfo )
return unknown + "CustomTalk"; return unknown + "CustomTalk";
std::string name = customTalkInfo->name_intern; std::string name = customTalkInfo->name;
std::size_t pos = name.find_first_of( "_" ); std::size_t pos = name.find_first_of( "_" );
return customTalkInfo->name_intern.substr( 0, pos ); return customTalkInfo->name.substr( 0, pos );
} }
case EventType::Opening: case Event::EventHandler::EventHandlerType::Opening:
{ {
auto openingInfo = g_exdData.getOpeningInfo( eventId ); auto openingInfo = g_exdDataGen.getOpening( eventId );
if( openingInfo ) if( openingInfo )
return openingInfo->name; return openingInfo->name;
return unknown + "Opening"; return unknown + "Opening";
} }
case EventType::Aetheryte: case Event::EventHandler::EventHandlerType::Aetheryte:
{ {
auto aetherInfo = g_exdData.getAetheryteInfo( eventId & 0xFFFF ); auto aetherInfo = g_exdDataGen.getAetheryte( eventId & 0xFFFF );
if( aetherInfo->isAetheryte ) if( aetherInfo->isAetheryte )
return "Aetheryte"; return "Aetheryte";
return "Aethernet"; return "Aethernet";
} }
case EventType::ChocoPort:
case Event::EventHandler::EventHandlerType::Warp:
{ {
return "ChocoboTaxi"; return "ChocoboTaxi";
} }
@ -64,9 +65,9 @@ std::string Core::Event::getEventName( uint32_t eventId )
uint32_t Core::Event::mapEventActorToRealActor( uint32_t eventActorId ) uint32_t Core::Event::mapEventActorToRealActor( uint32_t eventActorId )
{ {
auto levelInfo = g_exdData.getLevelInfo( eventActorId ); auto levelInfo = g_exdDataGen.getLevel( eventActorId );
if( levelInfo ) if( levelInfo )
return levelInfo->actor_id; return levelInfo->objectKey;
return 0; return 0;
} }

View file

@ -37,7 +37,8 @@ namespace Core
namespace Event namespace Event
{ {
TYPE_FORWARD( Event ); TYPE_FORWARD( Director );
TYPE_FORWARD( EventHandler );
} }
namespace Action namespace Action
@ -72,7 +73,6 @@ namespace Core
namespace Scripting namespace Scripting
{ {
class NativeScriptManager; class NativeScriptManager;
typedef std::function< void( Entity::Player&, uint32_t, uint16_t, uint16_t, uint16_t ) > EventReturnCallback;
} }
typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback; typedef std::function< void( Entity::Player&, uint32_t, uint64_t ) > ActionCallback;

View file

@ -1,6 +1,6 @@
#include <common/Network/PacketDef/Zone/ServerZoneDef.h> #include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Database/DatabaseDef.h> #include <common/Database/DatabaseDef.h>
@ -21,7 +21,7 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network; using namespace Core::Network;
@ -135,11 +135,11 @@ Core::ItemPtr Core::Inventory::getItemAt( uint16_t containerId, uint8_t slotId )
Core::ItemPtr Core::Inventory::createItem( uint32_t catalogId, uint8_t quantity ) Core::ItemPtr Core::Inventory::createItem( uint32_t catalogId, uint8_t quantity )
{ {
auto itemInfo = g_exdData.getItemInfo( catalogId ); auto itemInfo = g_exdDataGen.getItem( catalogId );
uint8_t itemAmount = quantity; uint8_t itemAmount = quantity;
if( itemInfo->stack_size == 1 ) if( itemInfo->stackSize == 1 )
itemAmount = 1; itemAmount = 1;
if( !itemInfo ) if( !itemInfo )
@ -153,8 +153,8 @@ Core::ItemPtr Core::Inventory::createItem( uint32_t catalogId, uint8_t quantity
pItem->setStackSize( itemAmount ); pItem->setStackSize( itemAmount );
pItem->setUId( getNextUId() ); pItem->setUId( getNextUId() );
pItem->setModelIds( itemInfo->model_primary, itemInfo->model_secondary ); pItem->setModelIds( itemInfo->modelMain, itemInfo->modelSub );
pItem->setCategory( static_cast< ItemUICategory >( itemInfo->ui_category ) ); pItem->setCategory( static_cast< ItemUICategory >( itemInfo->itemUICategory ) );
g_charaDb.execute( "INSERT INTO charaglobalitem ( CharacterId, itemId, catalogId, stack, flags ) VALUES ( " + g_charaDb.execute( "INSERT INTO charaglobalitem ( CharacterId, itemId, catalogId, stack, flags ) VALUES ( " +
std::to_string( m_pOwner->getId() ) + ", " + std::to_string( m_pOwner->getId() ) + ", " +
@ -473,10 +473,10 @@ bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity )
int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity ) int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity )
{ {
auto itemInfo = g_exdData.getItemInfo( catalogId ); auto itemInfo = g_exdDataGen.getItem( catalogId );
// if item data doesn't exist or it's a blank field // if item data doesn't exist or it's a blank field
if( !itemInfo || itemInfo->item_level == 0 ) if( !itemInfo || itemInfo->levelItem == 0 )
{ {
return -1; return -1;
} }
@ -656,13 +656,13 @@ Core::ItemPtr Core::Inventory::loadItem( uint64_t uId )
try try
{ {
auto itemInfo = g_exdData.getItemInfo( itemRes->getUInt( 1 ) ); auto itemInfo = g_exdDataGen.getItem( itemRes->getUInt( 1 ) );
bool isHq = itemRes->getUInt( 3 ) == 1 ? true : false; bool isHq = itemRes->getUInt( 3 ) == 1 ? true : false;
ItemPtr pItem( new Item( uId, ItemPtr pItem( new Item( uId,
itemInfo->id, itemRes->getUInt( 1 ),
itemInfo->model_primary, itemInfo->modelMain,
itemInfo->model_secondary, itemInfo->modelSub,
static_cast< ItemUICategory >( itemInfo->ui_category ), static_cast< ItemUICategory >( itemInfo->itemUICategory ),
isHq ) ); isHq ) );
pItem->setStackSize( itemRes->getUInt( 2 ) ); pItem->setStackSize( itemRes->getUInt( 2 ) );

View file

@ -1,8 +1,8 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include "Item.h" #include "Item.h"
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
Core::Item::Item() Core::Item::Item()
{ {
@ -24,13 +24,13 @@ Core::Item::Item( uint64_t uId, uint32_t catalogId, uint64_t model1, uint64_t mo
m_model2( model2 ), m_model2( model2 ),
m_isHq( isHq ) m_isHq( isHq )
{ {
auto itemInfo = g_exdData.getItemInfo( catalogId ); auto itemInfo = g_exdDataGen.getItem( catalogId );
m_delayMs = itemInfo->delayMs; m_delayMs = itemInfo->delayms;
m_physicalDmg = itemInfo->physical_damage; m_physicalDmg = itemInfo->damagePhys;
m_magicalDmg = itemInfo->magical_damage; m_magicalDmg = itemInfo->damageMag;
m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg; m_weaponDmg = ( m_physicalDmg != 0 ) ? m_physicalDmg : m_magicalDmg;
m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000; m_autoAttackDmg = static_cast< float >( m_weaponDmg * m_delayMs ) / 3000;
m_itemLevel = itemInfo->item_level; m_itemLevel = itemInfo->levelItem;
} }
Core::Item::~Item() Core::Item::~Item()

View file

@ -1,6 +1,6 @@
#include <cmath> #include <cmath>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Actor.h"
#include "Actor/Player.h" #include "Actor/Player.h"
@ -10,7 +10,7 @@
using namespace Core::Math; using namespace Core::Math;
using namespace Core::Entity; using namespace Core::Entity;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
/* /*
Class used for battle-related formulas and calculations. Class used for battle-related formulas and calculations.
@ -30,14 +30,13 @@ extern Core::Data::ExdData g_exdData;
uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency ) uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency )
{ {
auto classInfoIt = g_exdData.m_classJobInfoMap.find( static_cast< uint8_t >( pPlayer->getClass() ) ); auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
if ( classInfoIt == g_exdData.m_classJobInfoMap.end() || if ( !classInfo || !paramGrowthInfo )
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end())
return 0; return 0;
auto jobModVal = classInfoIt->second; //auto jobModVal = classInfoIt->second;
// consider 3% variation // consider 3% variation
return potency / 10; return potency / 10;

View file

@ -1,6 +1,6 @@
#include <cmath> #include <cmath>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Actor.h"
#include "Actor/Player.h" #include "Actor/Player.h"
@ -11,7 +11,7 @@
using namespace Core::Math; using namespace Core::Math;
using namespace Core::Entity; using namespace Core::Entity;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
/* /*
Class used for battle-related formulas and calculations. Class used for battle-related formulas and calculations.
@ -61,19 +61,18 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
// Is there any way to pull reliable BaseHP without having to manually use a pet for every level, and using the values from a table? // Is there any way to pull reliable BaseHP without having to manually use a pet for every level, and using the values from a table?
// More info here: https://docs.google.com/spreadsheets/d/1de06KGT0cNRUvyiXNmjNgcNvzBCCQku7jte5QxEQRbs/edit?usp=sharing // More info here: https://docs.google.com/spreadsheets/d/1de06KGT0cNRUvyiXNmjNgcNvzBCCQku7jte5QxEQRbs/edit?usp=sharing
auto classInfoIt = g_exdData.m_classJobInfoMap.find( static_cast< uint8_t >( pPlayer->getClass() ) ); auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
if ( classInfoIt == g_exdData.m_classJobInfoMap.end() || if ( !classInfo || !paramGrowthInfo )
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end() )
return 0; return 0;
uint8_t level = pPlayer->getLevel(); uint8_t level = pPlayer->getLevel();
float baseStat = calculateBaseStat( pPlayer ); float baseStat = calculateBaseStat( pPlayer );
uint16_t vitStat = pPlayer->getStats().vit; uint16_t vitStat = pPlayer->getStats().vit;
uint16_t hpMod = paramGrowthInfoIt->second.hp_mod; uint16_t hpMod = paramGrowthInfo->hpModifier;
uint16_t jobModHp = classInfoIt->second.mod_hp; uint16_t jobModHp = classInfo->modifierHitPoints;
float approxBaseHp = 0.0f; // Read above float approxBaseHp = 0.0f; // Read above
// These values are not precise. // These values are not precise.
@ -83,7 +82,7 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
else if ( level >= 50 ) else if ( level >= 50 )
approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) ); approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) );
else else
approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7667f; approxBaseHp = paramGrowthInfo->mpModifier * 0.7667f;
uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) ) ); uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) ) );
@ -95,18 +94,17 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
uint32_t CalcStats::calculateMaxMp( PlayerPtr pPlayer ) uint32_t CalcStats::calculateMaxMp( PlayerPtr pPlayer )
{ {
auto classInfoIt = g_exdData.m_classJobInfoMap.find( static_cast< uint8_t >( pPlayer->getClass() ) ); auto classInfo = g_exdDataGen.getClassJob( static_cast< uint8_t >( pPlayer->getClass() ) );
auto paramGrowthInfoIt = g_exdData.m_paramGrowthInfoMap.find( pPlayer->getLevel() ); auto paramGrowthInfo = g_exdDataGen.getParamGrow( pPlayer->getLevel() );
if ( classInfoIt == g_exdData.m_classJobInfoMap.end() || if ( !classInfo || !paramGrowthInfo )
paramGrowthInfoIt == g_exdData.m_paramGrowthInfoMap.end() )
return 0; return 0;
float baseStat = calculateBaseStat( pPlayer ); float baseStat = calculateBaseStat( pPlayer );
uint16_t piety = pPlayer->getStats().pie; uint16_t piety = pPlayer->getStats().pie;
uint16_t pietyScalar = paramGrowthInfoIt->second.mp_mod; uint16_t pietyScalar = paramGrowthInfo->mpModifier;
uint16_t jobModMp = classInfoIt->second.mod_mpcpgp; uint16_t jobModMp = classInfo->modifierManaPoints;
uint16_t baseMp = paramGrowthInfoIt->second.mp_const; uint16_t baseMp = paramGrowthInfo->mpModifier;
uint16_t result = static_cast< uint16_t >( floor( floor( piety - baseStat ) * ( pietyScalar / 100 ) + baseMp ) * jobModMp / 100 ); uint16_t result = static_cast< uint16_t >( floor( floor( piety - baseStat ) * ( pietyScalar / 100 ) + baseMp ) * jobModMp / 100 );

View file

@ -76,17 +76,17 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
setZoneHandler( ClientZoneIpcType::InventoryModifyHandler,"InventoryModifyHandler", &GameConnection::inventoryModifyHandler ); setZoneHandler( ClientZoneIpcType::InventoryModifyHandler,"InventoryModifyHandler", &GameConnection::inventoryModifyHandler );
setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk );
setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote );
setZoneHandler( ClientZoneIpcType::WithinRangeEventHandler, "EventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::WithinRangeEventHandler, "EventHandlerWithinRange", &GameConnection::eventHandlerWithinRange );
setZoneHandler( ClientZoneIpcType::OutOfRangeEventHandler, "EventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::OutOfRangeEventHandler, "EventHandlerOutsideRange", &GameConnection::eventHandlerOutsideRange );
setZoneHandler( ClientZoneIpcType::EnterTeriEventHandler, "EventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::EnterTeriEventHandler, "EventHandlerEnterTeri", &GameConnection::eventHandlerEnterTerritory );
setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::ReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandlerReturn );
setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::TradeReturnEventHandler, "EventHandlerReturn", &GameConnection::eventHandlerReturn );
setZoneHandler( ClientZoneIpcType::LinkshellEventHandler, "LinkshellEventHandler", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::LinkshellEventHandler, "LinkshellEventHandler", &GameConnection::eventHandlerLinkshell );
setZoneHandler( ClientZoneIpcType::LinkshellEventHandler1, "LinkshellEventHandler1", &GameConnection::eventHandler ); setZoneHandler( ClientZoneIpcType::LinkshellEventHandler1, "LinkshellEventHandler1", &GameConnection::eventHandlerLinkshell );
setZoneHandler( ClientZoneIpcType::CFDutyInfoHandler, "CFDutyInfoRequest", &GameConnection::cfDutyInfoRequest ); setZoneHandler( ClientZoneIpcType::CFDutyInfoHandler, "CFDutyInfoRequest", &GameConnection::cfDutyInfoRequest );
setZoneHandler( ClientZoneIpcType::CFRegisterDuty, "CFRegisterDuty", &GameConnection::cfRegisterDuty ); setZoneHandler( ClientZoneIpcType::CFRegisterDuty, "CFRegisterDuty", &GameConnection::cfRegisterDuty );

View file

@ -101,7 +101,14 @@ public:
DECLARE_HANDLER( actionHandler ); DECLARE_HANDLER( actionHandler );
DECLARE_HANDLER( inventoryModifyHandler ); DECLARE_HANDLER( inventoryModifyHandler );
DECLARE_HANDLER( discoveryHandler ); DECLARE_HANDLER( discoveryHandler );
DECLARE_HANDLER( eventHandler ); DECLARE_HANDLER( eventHandlerTalk );
DECLARE_HANDLER( eventHandlerEmote );
DECLARE_HANDLER( eventHandlerWithinRange );
DECLARE_HANDLER( eventHandlerOutsideRange );
DECLARE_HANDLER( eventHandlerEnterTerritory );
DECLARE_HANDLER( eventHandlerReturn );
DECLARE_HANDLER( eventHandlerLinkshell );
DECLARE_HANDLER( logoutHandler ); DECLARE_HANDLER( logoutHandler );
DECLARE_HANDLER( cfDutyInfoRequest ); DECLARE_HANDLER( cfDutyInfoRequest );

View file

@ -2,7 +2,7 @@
#include <common/Network/CommonNetwork.h> #include <common/Network/CommonNetwork.h>
#include <common/Network/GamePacketNew.h> #include <common/Network/GamePacketNew.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <boost/format.hpp> #include <boost/format.hpp>
@ -13,7 +13,6 @@
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "ServerZone.h" #include "ServerZone.h"
#include "Zone/ZoneMgr.h"
#include "Network/PacketWrappers/InitUIPacket.h" #include "Network/PacketWrappers/InitUIPacket.h"
#include "Network/PacketWrappers/PingPacket.h" #include "Network/PacketWrappers/PingPacket.h"
@ -37,8 +36,7 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr; extern Core::DebugCommandHandler g_gameCommandMgr;
using namespace Core::Common; using namespace Core::Common;
@ -196,22 +194,21 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
player.unsetStateFlag( PlayerStateFlag::BetweenAreas ); player.unsetStateFlag( PlayerStateFlag::BetweenAreas );
player.unsetStateFlag( PlayerStateFlag::BetweenAreas1 ); player.unsetStateFlag( PlayerStateFlag::BetweenAreas1 );
player.sendStateFlags();
break; break;
} }
case 0xCA: // Teleport case 0xCA: // Teleport
{ {
// TODO: only register this action if enough gil is in possession // TODO: only register this action if enough gil is in possession
auto targetAetheryte = g_exdData.getAetheryteInfo( param11 ); auto targetAetheryte = g_exdDataGen.getAetheryte( param11 );
if( targetAetheryte ) if( targetAetheryte )
{ {
auto fromAetheryte = g_exdData.getAetheryteInfo( g_exdData.m_zoneInfoMap[player.getZoneId()].aetheryte_index ); auto fromAetheryte = g_exdDataGen.getAetheryte( g_exdDataGen.getTerritoryType( player.getZoneId() )->aetheryte );
// calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets
auto cost = static_cast< uint16_t > ( ( sqrt( pow( fromAetheryte->map_coord_x - targetAetheryte->map_coord_x, 2 ) + auto cost = static_cast< uint16_t > ( ( sqrt( pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) +
pow( fromAetheryte->map_coord_y - targetAetheryte->map_coord_y, 2 ) ) / 2 ) + 100 ); pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 );
// cap at 999 gil // cap at 999 gil
cost = cost > uint16_t{999} ? uint16_t{999} : cost; cost = cost > uint16_t{999} ? uint16_t{999} : cost;

View file

@ -1,4 +1,5 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdDataGenerated.h>
#include <common/Network/CommonNetwork.h> #include <common/Network/CommonNetwork.h>
#include <common/Network/GamePacketNew.h> #include <common/Network/GamePacketNew.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
@ -20,138 +21,192 @@
#include "Forwards.h" #include "Forwards.h"
#include "Event/EventHelper.h" #include "Event/EventHelper.h"
extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server; using namespace Core::Network::Packets::Server;
void Core::Network::GameConnection::eventHandler( const Packets::GamePacket& inPacket, void Core::Network::GameConnection::eventHandlerTalk( const Packets::GamePacket& inPacket, Entity::Player& player )
{
auto actorId = inPacket.getValAt< uint64_t >( 0x20 );
auto eventId = inPacket.getValAt< uint32_t >( 0x28 );
auto eventType = static_cast< uint16_t >( eventId >> 16 );
std::string eventName = "onTalk";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " +
std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " +
std::to_string( eventId ) +
" (0x" + boost::str( boost::format( "%|08X|" )
% static_cast< uint64_t >( eventId & 0xFFFFFFF ) ) + ")" );
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::EventHandler::Talk, 0, 0 );
if( !g_scriptMgr.onTalk( player, actorId, eventId ) &&
eventType == Event::EventHandler::EventHandlerType::Quest )
{
auto questInfo = g_exdDataGen.getQuest( eventId );
if ( questInfo )
player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->id + ")" );
}
player.checkEvent( eventId );
}
void Core::Network::GameConnection::eventHandlerEmote( const Packets::GamePacket& inPacket, Entity::Player& player )
{
auto actorId = inPacket.getValAt< uint64_t >( 0x20 );
auto eventId = inPacket.getValAt< uint32_t >( 0x28 );
auto emoteId = inPacket.getValAt< uint16_t >( 0x2C );
auto eventType = static_cast< uint16_t >( eventId >> 16 );
std::string eventName = "onEmote";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " +
std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " +
std::to_string( eventId ) +
" (0x" + boost::str( boost::format( "%|08X|" )
% static_cast< uint64_t >( eventId & 0xFFFFFFF ) ) + ")" );
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::EventHandler::Emote, 0, emoteId );
if( !g_scriptMgr.onEmote( player, actorId, eventId, static_cast< uint8_t >( emoteId ) ) &&
eventType == Event::EventHandler::EventHandlerType::Quest )
{
auto questInfo = g_exdDataGen.getQuest( eventId );
if( questInfo )
player.sendUrgent( "Quest not implemented: " + questInfo->name );
}
player.checkEvent( eventId );
}
void Core::Network::GameConnection::eventHandlerWithinRange( const Packets::GamePacket& inPacket,
Entity::Player& player ) Entity::Player& player )
{ {
uint16_t eventHandlerId = inPacket.getValAt< uint16_t >( 0x12 );
// we need to abort the event in case it has not been scripted so the player wont be locked up auto eventId = inPacket.getValAt< uint32_t >( 0x24 );
auto abortEventFunc = []( Core::Entity::Player& player, uint64_t actorId, uint32_t eventId ) auto param1 = inPacket.getValAt< uint32_t >( 0x20 );
{ auto x = inPacket.getValAt< float >( 0x28 );
player.queuePacket( EventStartPacket( player.getId(), actorId, eventId, 1, 0, 0 ) ); auto y = inPacket.getValAt< float >( 0x2C );
player.queuePacket( EventFinishPacket( player.getId(), eventId, 1, 0 ) ); auto z = inPacket.getValAt< float >( 0x30 );
// this isn't ideal as it will also reset any other status that might be active
player.queuePacket( PlayerStateFlagsPacket( player, PlayerStateFlagList{} ) );
};
std::string eventIdStr = boost::str( boost::format( "%|04X|" ) % static_cast< uint32_t >( eventHandlerId & 0xFFFF ) ); std::string eventName = "onWithinRange";
player.sendDebug( "---------------------------------------" ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "EventHandler ( " + eventIdStr + " )" ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) +
" p1: " + std::to_string( param1 ) );
switch( eventHandlerId ) player.eventStart( player.getId(), eventId, Event::EventHandler::WithinRange, 1, param1 );
{
case ClientZoneIpcType::TalkEventHandler: // Talk event g_scriptMgr.onWithinRange( player, eventId, param1, x, y, z );
{
uint64_t actorId = inPacket.getValAt< uint64_t >( 0x20 );
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x28 );
if( !g_scriptMgr.onTalk( player, actorId, eventId ) ) player.checkEvent( eventId );
abortEventFunc( player, actorId, eventId ); }
break;
}
case ClientZoneIpcType::EmoteEventHandler: // Emote event void Core::Network::GameConnection::eventHandlerOutsideRange( const Packets::GamePacket& inPacket,
{ Entity::Player& player )
uint64_t actorId = inPacket.getValAt< uint64_t >( 0x20 ); {
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x28 );
uint16_t emoteId = inPacket.getValAt< uint16_t >( 0x2C ); auto eventId = inPacket.getValAt< uint32_t >( 0x24 );
auto param1 = inPacket.getValAt< uint32_t >( 0x20 );
auto x = inPacket.getValAt< float >( 0x28 );
auto y = inPacket.getValAt< float >( 0x2C );
auto z = inPacket.getValAt< float >( 0x30 );
std::string eventName = "onOutsideRange";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) +
" p1: " + std::to_string( param1 ) );
player.eventStart( player.getId(), eventId, Event::EventHandler::WithinRange, 1, param1 );
g_scriptMgr.onOutsideRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
}
void Core::Network::GameConnection::eventHandlerEnterTerritory( const Packets::GamePacket &inPacket,
Entity::Player &player )
{
auto eventId = inPacket.getValAt< uint32_t >( 0x20 );
auto param1 = inPacket.getValAt< uint16_t >( 0x24 );
auto param2 = inPacket.getValAt< uint16_t >( 0x26 );
std::string eventName = "onEnterTerritory";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
player.eventStart( player.getId(), eventId, Event::EventHandler::EnterTerritory, 0, player.getZoneId() );
g_scriptMgr.onEnterTerritory( player, eventId, param1, param2 );
player.checkEvent( eventId );
}
void Core::Network::GameConnection::eventHandlerReturn( const Packets::GamePacket &inPacket,
Entity::Player &player )
{
auto eventId = inPacket.getValAt< uint32_t >( 0x20 );
auto scene = inPacket.getValAt< uint16_t >( 0x24 );
auto param1 = inPacket.getValAt< uint16_t >( 0x26 );
auto param2 = inPacket.getValAt< uint16_t >( 0x28 );
auto param3 = inPacket.getValAt< uint16_t >( 0x2C );
std::string eventName = Event::getEventName( eventId ); std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onEmote( player, actorId, eventId, static_cast< uint8_t >( emoteId ) ) ) player.sendDebug( "eventId: " +
abortEventFunc( player, actorId, eventId ); std::to_string( eventId ) +
break; " ( 0x" + boost::str( boost::format( "%|08X|" ) % ( uint64_t ) ( eventId & 0xFFFFFFF ) ) + " ) " +
" scene: " + std::to_string( scene ) +
" p1: " + std::to_string( param1 ) +
" p2: " + std::to_string( param2 ) +
" p3: " + std::to_string( param3 ) );
auto pEvent = player.getEvent( eventId );
if( pEvent )
{
pEvent->setPlayedScene( false );
// try to retrieve a stored callback
auto eventCallback = pEvent->getEventReturnCallback();
// if there is one, proceed to call it
if( eventCallback )
eventCallback( player, eventId, param1, param2, param3 );
} }
player.checkEvent( eventId );
case ClientZoneIpcType::WithinRangeEventHandler: }
{
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x24 );
uint32_t eventParam1 = inPacket.getValAt< uint32_t >( 0x20 );
float x = inPacket.getValAt< float >( 0x28 );
float y = inPacket.getValAt< float >( 0x2C );
float z = inPacket.getValAt< float >( 0x30 );
std::string eventName = Event::getEventName( eventId ); void Core::Network::GameConnection::eventHandlerLinkshell( const Packets::GamePacket &inPacket,
Entity::Player &player )
if( !g_scriptMgr.onWithinRange( player, eventId, eventParam1, x, y, z ) ) {
abortEventFunc( player, 0, eventId ); auto eventId = inPacket.getValAt< uint32_t >( 0x20 );
break; auto scene = inPacket.getValAt< uint16_t >( 0x24 );
} auto lsName = inPacket.getStringAt( 0x27 );
case ClientZoneIpcType::OutOfRangeEventHandler:
{
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x24 );
uint32_t eventParam1 = inPacket.getValAt< uint32_t >( 0x20 );
float x = inPacket.getValAt< float >( 0x28 );
float y = inPacket.getValAt< float >( 0x2C );
float z = inPacket.getValAt< float >( 0x30 );
std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onOutsideRange( player, eventId, eventParam1, x, y, z ) )
abortEventFunc( player, 0, eventId );
break;
}
case ClientZoneIpcType::EnterTeriEventHandler:
{
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x20 );
uint16_t eventParam1 = inPacket.getValAt< uint16_t >( 0x24 );
uint16_t eventParam2 = inPacket.getValAt< uint16_t >( 0x26 );
std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onEnterTerritory( player, eventId, eventParam1, eventParam2 ) )
abortEventFunc( player, 0, eventId );
break;
}
case ClientZoneIpcType::ReturnEventHandler:
case ClientZoneIpcType::TradeReturnEventHandler:
{
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x20 );
uint16_t subEvent = inPacket.getValAt< uint16_t >( 0x24 );
uint16_t param1 = inPacket.getValAt< uint16_t >( 0x26 );
uint16_t param2 = inPacket.getValAt< uint16_t >( 0x28 );
uint16_t param3 = inPacket.getValAt< uint16_t >( 0x2C );
std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onEventHandlerReturn( player, eventId, subEvent, param1, param2, param3 ) )
abortEventFunc( player, 0, eventId );
break;
}
case ClientZoneIpcType::LinkshellEventHandler:
case ClientZoneIpcType::LinkshellEventHandler1:
{
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x20 );
uint16_t subEvent = inPacket.getValAt< uint16_t >( 0x24 );
std::string lsName = inPacket.getStringAt( 0x27 );
ZoneChannelPacket< FFXIVIpcEventLinkshell > linkshellEvent( player.getId() ); ZoneChannelPacket< FFXIVIpcEventLinkshell > linkshellEvent( player.getId() );
linkshellEvent.data().eventId = eventId; linkshellEvent.data().eventId = eventId;
linkshellEvent.data().scene = static_cast< uint8_t >( subEvent ); linkshellEvent.data().scene = static_cast< uint8_t >( scene );
linkshellEvent.data().param3 = 1; linkshellEvent.data().param3 = 1;
linkshellEvent.data().unknown1 = 0x15a; linkshellEvent.data().unknown1 = 0x15a;
player.queuePacket( linkshellEvent ); player.queuePacket( linkshellEvent );
// abortEventFunc( pPlayer, 0, eventId );
break;
}
}
} }

View file

@ -10,10 +10,10 @@
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
#include "Session.h" #include "Session.h"
#include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "ServerZone.h" #include "ServerZone.h"
#include "Zone/ZoneMgr.h"
#include "Network/PacketWrappers/InitUIPacket.h" #include "Network/PacketWrappers/InitUIPacket.h"
#include "Network/PacketWrappers/PingPacket.h" #include "Network/PacketWrappers/PingPacket.h"
@ -37,7 +37,7 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr; extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr; extern Core::DebugCommandHandler g_gameCommandMgr;
@ -403,16 +403,27 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
} }
case GmCommand::Teri: case GmCommand::Teri:
{ {
auto zoneInfo = g_zoneMgr.getZone( param1 ); if( auto instance = g_territoryMgr.getInstanceZonePtr( param1 ) )
if ( !zoneInfo ) {
player.sendDebug( "Found instance: " + instance->getName() + ", id: " + std::to_string( param1 ) );
player.setInstance( instance );
}
else if( !g_territoryMgr.isValidTerritory( param1 ) )
{ {
player.sendUrgent( "Invalid zone " + std::to_string( param1 ) ); player.sendUrgent( "Invalid zone " + std::to_string( param1 ) );
} }
else else
{ {
auto pZone = g_territoryMgr.getZoneByTerriId( param1 );
if( !pZone )
{
player.sendUrgent( "No zone instance found for " + std::to_string( param1 ) );
break;
}
targetPlayer->setPosition( targetPlayer->getPos() ); targetPlayer->setPosition( targetPlayer->getPos() );
targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 ); targetPlayer->performZoning( param1, targetPlayer->getPos(), 0 );
player.sendNotice( targetPlayer->getName() + " was warped to zone " + std::to_string( param1 ) + " (" + zoneInfo->getName( ) + ")" ); player.sendNotice( targetPlayer->getName() + " was warped to zone " + std::to_string( param1 ) + " (" + pZone->getName() + ")" );
} }
break; break;
} }

View file

@ -13,7 +13,6 @@
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "ServerZone.h" #include "ServerZone.h"
#include "Zone/ZoneMgr.h"
#include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/ServerNoticePacket.h"
#include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket142.h"
@ -27,7 +26,6 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr; extern Core::DebugCommandHandler g_gameCommandMgr;

View file

@ -12,10 +12,10 @@
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
#include "Session.h" #include "Session.h"
#include "ServerZone.h"
#include "Zone/TerritoryMgr.h"
#include "Zone/Zone.h" #include "Zone/Zone.h"
#include "Zone/ZonePosition.h" #include "Zone/ZonePosition.h"
#include "ServerZone.h"
#include "Zone/ZoneMgr.h"
#include "Network/PacketWrappers/InitUIPacket.h" #include "Network/PacketWrappers/InitUIPacket.h"
#include "Network/PacketWrappers/PingPacket.h" #include "Network/PacketWrappers/PingPacket.h"
@ -41,7 +41,7 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::ZoneMgr g_zoneMgr; extern Core::TerritoryMgr g_territoryMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdData g_exdData;
extern Core::DebugCommandHandler g_gameCommandMgr; extern Core::DebugCommandHandler g_gameCommandMgr;
extern Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr; extern Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr;
@ -299,7 +299,7 @@ void Core::Network::GameConnection::zoneLineHandler( const Packets::GamePacket&
auto pZone = player.getCurrentZone(); auto pZone = player.getCurrentZone();
auto pLine = g_zoneMgr.getZonePosition( zoneLineId ); auto pLine = g_territoryMgr.getTerritoryPosition( zoneLineId );
Common::FFXIVARR_POSITION3 targetPos{}; Common::FFXIVARR_POSITION3 targetPos{};
uint32_t targetZone; uint32_t targetZone;
@ -326,7 +326,7 @@ void Core::Network::GameConnection::zoneLineHandler( const Packets::GamePacket&
targetPos.x = 0; targetPos.x = 0;
targetPos.y = 0; targetPos.y = 0;
targetPos.z = 0; targetPos.z = 0;
targetZone = pZone->getId(); targetZone = pZone->getTerritoryId();
} }
player.performZoning( targetZone, targetPos, rotation); player.performZoning( targetZone, targetPos, rotation);
@ -444,7 +444,7 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
int32_t entrysizes = sizeof( listPacket.data().entries ); int32_t entrysizes = sizeof( listPacket.data().entries );
memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) ); memset( listPacket.data().entries, 0, sizeof( listPacket.data().entries ) );
listPacket.data().entries[0].bytes[2] = player.getCurrentZone()->getId(); listPacket.data().entries[0].bytes[2] = player.getCurrentZone()->getTerritoryId();
listPacket.data().entries[0].bytes[3] = 0x80; listPacket.data().entries[0].bytes[3] = 0x80;
listPacket.data().entries[0].bytes[4] = 0x02; listPacket.data().entries[0].bytes[4] = 0x02;
listPacket.data().entries[0].bytes[6] = 0x3B; listPacket.data().entries[0].bytes[6] = 0x3B;
@ -452,8 +452,8 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
listPacket.data().entries[0].classJob = player.getClass(); listPacket.data().entries[0].classJob = player.getClass();
listPacket.data().entries[0].contentId = player.getContentId(); listPacket.data().entries[0].contentId = player.getContentId();
listPacket.data().entries[0].level = player.getLevel(); listPacket.data().entries[0].level = player.getLevel();
listPacket.data().entries[0].zoneId = player.getCurrentZone()->getId(); listPacket.data().entries[0].zoneId = player.getCurrentZone()->getTerritoryId();
//listPacket.data().entries[0].zoneId1 = 0x0100; listPacket.data().entries[0].zoneId1 = 0x0100;
// TODO: no idea what this does // TODO: no idea what this does
//listPacket.data().entries[0].one = 1; //listPacket.data().entries[0].one = 1;

View file

@ -1,6 +1,6 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Network/CommonNetwork.h> #include <common/Network/CommonNetwork.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/GamePacketNew.h> #include <common/Network/GamePacketNew.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
@ -32,7 +32,7 @@
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Logger g_log; extern Core::Logger g_log;
using namespace Core::Common; using namespace Core::Common;
@ -60,7 +60,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
std::string actionIdStr = boost::str( boost::format( "%|04X|" ) % action ); std::string actionIdStr = boost::str( boost::format( "%|04X|" ) % action );
player.sendDebug( "---------------------------------------" ); player.sendDebug( "---------------------------------------" );
player.sendDebug( "ActionHandler ( " + actionIdStr + " | " + player.sendDebug( "ActionHandler ( " + actionIdStr + " | " +
g_exdData.getActionInfo( action )->name + g_exdDataGen.getAction( action )->name +
" | " + std::to_string( targetId ) + " )" ); " | " + std::to_string( targetId ) + " )" );
player.queuePacket( ActorControlPacket142( player.getId(), ActorControlType::ActionStart, 0x01, action ) ); player.queuePacket( ActorControlPacket142( player.getId(), ActorControlType::ActionStart, 0x01, action ) );
@ -100,11 +100,11 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
} }
else if( action < 3000000 ) // item action else if( action < 3000000 ) // item action
{ {
auto info = g_exdData.getEventItemInfo( action ); auto info = g_exdDataGen.getEventItem( action );
if( info ) if( info )
{ {
g_log.debug( info->name ); g_log.debug( info->name );
g_scriptMgr.onEventItem( player, action, info->eventId, info->castTime, targetId ); g_scriptMgr.onEventItem( player, action, info->quest, info->castTime, targetId );
} }
} }
else if( action > 3000000 ) // unknown else if( action > 3000000 ) // unknown

View file

@ -2,6 +2,9 @@
#define NATIVE_SCRIPT_API #define NATIVE_SCRIPT_API
#include <string> #include <string>
#include <typeinfo>
#include <typeindex>
#include <Actor/Actor.h> #include <Actor/Actor.h>
#include <Actor/Player.h> #include <Actor/Player.h>
#include <StatusEffect/StatusEffect.h> #include <StatusEffect/StatusEffect.h>
@ -18,41 +21,24 @@ using namespace Core;
#define EVENTSCRIPT_AETHERYTE_ID 0x50000 #define EVENTSCRIPT_AETHERYTE_ID 0x50000
#define EVENTSCRIPT_AETHERNET_ID 0x50001 #define EVENTSCRIPT_AETHERNET_ID 0x50001
enum ScriptType
{
None,
ScriptedStatusEffect,
ScriptedAction,
ScriptedEvent,
ScriptedBattleNpc,
ScriptedZone
};
class ScriptObject class ScriptObject
{ {
protected: protected:
std::string m_scriptName;
uint32_t m_id; uint32_t m_id;
ScriptType m_type; std::size_t m_type;
public: public:
ScriptObject( std::string name, uint32_t id, ScriptType type ) : ScriptObject( uint32_t id, std::size_t type ) :
m_scriptName( name ),
m_id( id ), m_id( id ),
m_type( type ) m_type( type )
{ } { }
virtual const std::string& getName() const
{
return m_scriptName;
}
virtual uint32_t getId() const virtual uint32_t getId() const
{ {
return m_id; return m_id;
} }
virtual ScriptType getType() const virtual std::size_t getType() const
{ {
return m_type; return m_type;
} }
@ -62,8 +48,8 @@ public:
class StatusEffectScript : public ScriptObject class StatusEffectScript : public ScriptObject
{ {
public: public:
StatusEffectScript( std::string name, uint32_t effectId ) : StatusEffectScript( uint32_t effectId ) :
ScriptObject( name, effectId, ScriptType::ScriptedStatusEffect ) ScriptObject( effectId, typeid( StatusEffectScript ).hash_code() )
{ } { }
virtual void onTick( Entity::Actor& actor ) { } virtual void onTick( Entity::Actor& actor ) { }
@ -80,8 +66,8 @@ public:
class ActionScript : public ScriptObject class ActionScript : public ScriptObject
{ {
public: public:
ActionScript( std::string name, uint32_t abilityId ) : ActionScript( uint32_t abilityId ) :
ScriptObject( name, abilityId, ScriptType::ScriptedAction ) ScriptObject( abilityId, typeid( ActionScript ).hash_code() )
{ } { }
virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { } virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { }
@ -93,8 +79,8 @@ public:
class EventScript : public ScriptObject class EventScript : public ScriptObject
{ {
public: public:
EventScript( std::string name, uint32_t questId ) : EventScript( uint32_t questId ) :
ScriptObject( name, questId, ScriptType::ScriptedEvent ) ScriptObject( questId, typeid( EventScript ).hash_code() )
{ } { }
virtual void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) { } virtual void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) { }
@ -111,16 +97,16 @@ public:
class BattleNpcScript : public ScriptObject class BattleNpcScript : public ScriptObject
{ {
public: public:
BattleNpcScript( std::string name, uint32_t npcId ) : BattleNpcScript( uint32_t npcId ) :
ScriptObject( name, npcId, ScriptType::ScriptedBattleNpc ) ScriptObject( npcId, typeid( BattleNpcScript ).hash_code() )
{ } { }
}; };
class ZoneScript : public ScriptObject class ZoneScript : public ScriptObject
{ {
public: public:
ZoneScript( std::string name, uint32_t zoneId ) : ZoneScript( uint32_t zoneId ) :
ScriptObject( name, zoneId, ScriptType::ScriptedZone ) ScriptObject( zoneId, typeid( ZoneScript ).hash_code() )
{ } { }
virtual void onZoneInit() { } virtual void onZoneInit() { }

View file

@ -19,7 +19,7 @@ namespace Scripting {
class NativeScriptManager class NativeScriptManager
{ {
protected: protected:
std::unordered_map< ScriptType, std::unordered_map< uint32_t, ScriptObject* > > m_scripts; std::unordered_map< std::size_t, std::unordered_map< uint32_t, ScriptObject* > > m_scripts;
ScriptLoader m_loader; ScriptLoader m_loader;
@ -40,11 +40,11 @@ namespace Scripting {
const std::string getModuleExtension(); const std::string getModuleExtension();
bool isModuleLoaded( const std::string& name ); bool isModuleLoaded( const std::string& name );
// todo: use some template magic (type_traits is_same?) to avoid ScriptType param
// not sure if worthwhile given that it adds an extra place where script types need to be managed
template< typename T > template< typename T >
T* getScript( ScriptType type, uint32_t scriptId ) T* getScript( uint32_t scriptId )
{ {
auto type = typeid( T ).hash_code();
auto script = m_scripts[type].find( scriptId ); auto script = m_scripts[type].find( scriptId );
if( script == m_scripts[type].end() ) if( script == m_scripts[type].end() )
return nullptr; return nullptr;

View file

@ -26,7 +26,6 @@ namespace Scripting {
ModuleHandle handle; ModuleHandle handle;
std::vector< ScriptObject* > scripts; std::vector< ScriptObject* > scripts;
ScriptType type;
}; };
} }
} }

View file

@ -1,5 +1,5 @@
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Config/XMLConfig.h> #include <common/Config/XMLConfig.h>
#include "NativeScriptManager.h" #include "NativeScriptManager.h"
@ -8,7 +8,7 @@
#include "Actor/Player.h" #include "Actor/Player.h"
#include "Actor/BattleNpc.h" #include "Actor/BattleNpc.h"
#include "ServerZone.h" #include "ServerZone.h"
#include "Event/Event.h" #include "Event/EventHandler.h"
#include "Event/EventHelper.h" #include "Event/EventHelper.h"
#include "StatusEffect/StatusEffect.h" #include "StatusEffect/StatusEffect.h"
#include "Network/PacketWrappers/ServerNoticePacket.h" #include "Network/PacketWrappers/ServerNoticePacket.h"
@ -26,7 +26,7 @@
#include <libraries/external/watchdog/Watchdog.h> #include <libraries/external/watchdog/Watchdog.h>
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
Core::Scripting::ScriptManager::ScriptManager() : Core::Scripting::ScriptManager::ScriptManager() :
@ -74,6 +74,10 @@ bool Core::Scripting::ScriptManager::init()
void Core::Scripting::ScriptManager::watchDirectories() void Core::Scripting::ScriptManager::watchDirectories()
{ {
auto shouldWatch = g_serverZone.getConfig()->getValue< bool >( "Settings.General.Scripts.HotSwap.Enabled", true );
if( !shouldWatch )
return;
Watchdog::watchMany( g_serverZone.getConfig()->getValue< std::string >( "Settings.General.Scripts.Path", "./compiledscripts/" ) + "*" + m_nativeScriptManager->getModuleExtension(), Watchdog::watchMany( g_serverZone.getConfig()->getValue< std::string >( "Settings.General.Scripts.Path", "./compiledscripts/" ) + "*" + m_nativeScriptManager->getModuleExtension(),
[ this ]( const std::vector< ci::fs::path >& paths ) [ this ]( const std::vector< ci::fs::path >& paths )
{ {
@ -143,159 +147,63 @@ bool Core::Scripting::ScriptManager::registerBnpcTemplate( std::string templateN
bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t actorId, uint32_t eventId ) bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t actorId, uint32_t eventId )
{ {
std::string eventName = "onTalk";
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " +
std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " +
std::to_string( eventId ) +
" (0x" + boost::str( boost::format( "%|08X|" )
% static_cast< uint64_t >( eventId & 0xFFFFFFF ) ) + ")" );
uint16_t eventType = eventId >> 16; uint16_t eventType = eventId >> 16;
uint32_t scriptId = eventId; uint32_t scriptId = eventId;
// aethernet/aetherytes need to be handled separately // aethernet/aetherytes need to be handled separately
if( eventType == Common::EventType::Aetheryte ) if( eventType == Event::EventHandler::EventHandlerType::Aetheryte )
{ {
auto aetherInfo = g_exdData.getAetheryteInfo( eventId & 0xFFFF ); auto aetherInfo = g_exdDataGen.getAetheryte( eventId & 0xFFFF );
scriptId = EVENTSCRIPT_AETHERYTE_ID; scriptId = EVENTSCRIPT_AETHERYTE_ID;
if( !aetherInfo->isAetheryte ) if( !aetherInfo->isAetheryte )
scriptId = EVENTSCRIPT_AETHERNET_ID; scriptId = EVENTSCRIPT_AETHERNET_ID;
} }
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, scriptId ); auto script = m_nativeScriptManager->getScript< EventScript >( scriptId );
if( script ) if( !script )
{
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::Event::Talk, 0, 0 );
script->onTalk( eventId, player, actorId );
player.checkEvent( eventId );
}
else
{
if ( eventType == Common::EventType::Quest )
{
auto questInfo = g_exdData.getQuestInfo( eventId );
if ( questInfo )
{
player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->name_intern + ")" );
}
}
return false; return false;
} script->onTalk( eventId, player, actorId );
return true; return true;
} }
bool Core::Scripting::ScriptManager::onEnterTerritory( Entity::Player& player, uint32_t eventId, bool Core::Scripting::ScriptManager::onEnterTerritory( Entity::Player& player, uint32_t eventId,
uint16_t param1, uint16_t param2 ) uint16_t param1, uint16_t param2 )
{ {
std::string eventName = "onEnterTerritory"; auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
std::string objName = Event::getEventName( eventId ); if( !script )
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::Event::EnterTerritory, 0, player.getZoneId() );
script->onEnterZone( player, eventId, param1, param2 );
player.checkEvent( eventId );
return true;
}
return false; return false;
script->onEnterZone( player, eventId, param1, param2 );
return true;
} }
bool Core::Scripting::ScriptManager::onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1, bool Core::Scripting::ScriptManager::onWithinRange( Entity::Player& player, uint32_t eventId, uint32_t param1,
float x, float y, float z ) float x, float y, float z )
{ {
auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
std::string eventName = "onWithinRange"; if( !script )
std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) + " p1: " + std::to_string( param1 ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 );
script->onWithinRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
return true;
}
return false; return false;
script->onWithinRange( player, eventId, param1, x, y, z );
return true;
} }
bool Core::Scripting::ScriptManager::onOutsideRange( Entity::Player& player, uint32_t eventId, uint32_t param1, bool Core::Scripting::ScriptManager::onOutsideRange( Entity::Player& player, uint32_t eventId, uint32_t param1,
float x, float y, float z ) float x, float y, float z )
{ {
std::string eventName = "onOutsideRange"; auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
std::string objName = Event::getEventName( eventId ); if( !script )
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.eventStart( player.getId(), eventId, Event::Event::WithinRange, 1, param1 );
script->onOutsideRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
return true;
}
return false; return false;
script->onOutsideRange( player, eventId, param1, x, y, z );
return true;
} }
bool Core::Scripting::ScriptManager::onEmote( Entity::Player& player, uint64_t actorId, bool Core::Scripting::ScriptManager::onEmote( Entity::Player& player, uint64_t actorId,
uint32_t eventId, uint8_t emoteId ) uint32_t eventId, uint8_t emoteId )
{ {
std::string eventName = "onEmote"; auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
std::string objName = Event::getEventName( eventId ); if( !script )
return false;
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId );
if( script )
{
player.sendDebug( "Calling: " + objName + "." + eventName );
player.eventStart( actorId, eventId, Event::Event::Emote, 0, emoteId );
script->onEmote( actorId, eventId, emoteId, player ); script->onEmote( actorId, eventId, emoteId, player );
player.checkEvent( eventId );
}
else
{
uint16_t eventType = eventId >> 16;
if( eventType == Common::EventType::Quest )
{
auto questInfo = g_exdData.getQuestInfo( eventId );
if( questInfo )
{
player.sendUrgent( "Quest not implemented: " + questInfo->name );
return false;
}
}
return false;
}
return true; return true;
} }
@ -304,53 +212,16 @@ bool Core::Scripting::ScriptManager::onEventHandlerReturn( Entity::Player& playe
uint16_t param3 ) uint16_t param3 )
{ {
player.sendDebug( "eventId: " +
std::to_string( eventId ) +
" ( 0x" + boost::str( boost::format( "%|08X|" ) % ( uint64_t ) ( eventId & 0xFFFFFFF ) ) + " ) " +
" scene: " + std::to_string( subEvent ) +
" p1: " + std::to_string( param1 ) +
" p2: " + std::to_string( param2 ) +
" p3: " + std::to_string( param3 ) );
try
{
auto pEvent = player.getEvent( eventId );
if( pEvent )
{
pEvent->setPlayedScene( false );
// try to retrieve a stored callback
auto eventCallback = pEvent->getEventReturnCallback();
// if there is one, proceed to call it
if( eventCallback )
{
eventCallback( player, eventId, param1, param2, param3 );
if( !pEvent->hasPlayedScene() )
player.eventFinish( eventId, 1 );
else
pEvent->setPlayedScene( false );
}
// else, finish the event.
else
player.eventFinish( eventId, 1 );
}
}
catch( std::exception& e )
{
player.sendNotice( e.what() );
return false; return false;
}
return true;
} }
bool Core::Scripting::ScriptManager::onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId, bool Core::Scripting::ScriptManager::onEventHandlerTradeReturn( Entity::Player& player, uint32_t eventId,
uint16_t subEvent, uint16_t param, uint32_t catalogId ) uint16_t subEvent, uint16_t param, uint32_t catalogId )
{ {
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
if( script ) if( script )
{ {
script->onEventHandlerTradeReturn( player, eventId, subEvent, param, catalogId ); script->onEventHandlerTradeReturn( player, eventId, subEvent, param, catalogId );
return true; return true;
} }
@ -364,13 +235,12 @@ bool Core::Scripting::ScriptManager::onEventItem( Entity::Player& player, uint32
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) ); player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId ); auto script = m_nativeScriptManager->getScript< EventScript >( eventId );
if( script ) if( script )
{ {
player.eventStart( targetId, eventId, Event::Event::Item, 0, 0 ); player.eventStart( targetId, eventId, Event::EventHandler::Item, 0, 0 );
script->onEventItem( player, eventItemId, eventId, castTime, targetId ); script->onEventItem( player, eventItemId, eventId, castTime, targetId );
return true; return true;
} }
@ -391,7 +261,7 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
uint16_t questId = activeQuests->c.questId; uint16_t questId = activeQuests->c.questId;
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, questId ); auto script = m_nativeScriptManager->getScript< EventScript >( questId );
if( script ) if( script )
{ {
std::string objName = Event::getEventName( 0x00010000 | questId ); std::string objName = Event::getEventName( 0x00010000 | questId );
@ -407,17 +277,16 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId ) bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId )
{ {
auto script = m_nativeScriptManager->getScript< ActionScript >( ScriptType::ScriptedAction, actionId ); auto script = m_nativeScriptManager->getScript< ActionScript >( actionId );
if( script ) if( script )
script->onCastFinish( player, *pTarget ); script->onCastFinish( player, *pTarget );
return true; return true;
} }
bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId );
if( script ) if( script )
{ {
@ -425,7 +294,6 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
pActor->getAsPlayer()->sendDebug( "Calling status receive for statusid: " + std::to_string( effectId ) ); pActor->getAsPlayer()->sendDebug( "Calling status receive for statusid: " + std::to_string( effectId ) );
script->onApply( *pActor ); script->onApply( *pActor );
return true; return true;
} }
@ -434,14 +302,13 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect ) bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effect.getId() ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effect.getId() );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) ); pActor->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) );
script->onTick( *pActor ); script->onTick( *pActor );
return true; return true;
} }
@ -450,14 +317,13 @@ bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core
bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( ScriptType::ScriptedStatusEffect, effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pActor->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) ); pActor->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) );
script->onExpire( *pActor ); script->onExpire( *pActor );
return true; return true;
} }
@ -466,11 +332,10 @@ bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, u
bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone ) bool Core::Scripting::ScriptManager::onZoneInit( ZonePtr pZone )
{ {
auto script = m_nativeScriptManager->getScript< ZoneScript >( ScriptType::ScriptedZone, pZone->getId() ); auto script = m_nativeScriptManager->getScript< ZoneScript >(pZone->getTerritoryId() );
if( script ) if( script )
{ {
script->onZoneInit(); script->onZoneInit();
return true; return true;
} }

View file

@ -3,7 +3,7 @@
class CmnDefCutSceneReplay : public EventScript class CmnDefCutSceneReplay : public EventScript
{ {
public: public:
CmnDefCutSceneReplay() : EventScript( "CmnDefCutSceneReplay", 721028 ) CmnDefCutSceneReplay() : EventScript( 721028 )
{} {}
void Scene00000( Entity::Player& player ) void Scene00000( Entity::Player& player )

View file

@ -3,7 +3,7 @@
class CmnDefInnBed : public EventScript class CmnDefInnBed : public EventScript
{ {
public: public:
CmnDefInnBed() : EventScript( "CmnDefInnBed", 720916 ) CmnDefInnBed() : EventScript( 720916 )
{} {}
// menu // menu

View file

@ -7,7 +7,7 @@
class CmnDefLinkShell : public EventScript class CmnDefLinkShell : public EventScript
{ {
public: public:
CmnDefLinkShell() : EventScript( "CmnDefLinkShell", 0xB0006 ) CmnDefLinkShell() : EventScript( 0xB0006 )
{} {}
void Scene00001( Entity::Player& player ) void Scene00001( Entity::Player& player )

View file

@ -3,7 +3,7 @@
class HouFurOrchestrion : public EventScript class HouFurOrchestrion : public EventScript
{ {
public: public:
HouFurOrchestrion() : EventScript( "HouFurOrchestrion", 721226 ) HouFurOrchestrion() : EventScript( 721226 )
{} {}
void Scene00000( Entity::Player& player ) void Scene00000( Entity::Player& player )

View file

@ -1,4 +1,5 @@
#include <vector> #include <vector>
#include <Script/NativeScriptApi.h>
class ScriptObject; class ScriptObject;

View file

@ -3,7 +3,7 @@
class ActionSprint3 : public ActionScript class ActionSprint3 : public ActionScript
{ {
public: public:
ActionSprint3() : ActionScript( "ActionSprint3", 3 ) ActionSprint3() : ActionScript( 3 )
{} {}
void onCastFinish( Core::Entity::Player& player, Core::Entity::Actor& targetActor ) override void onCastFinish( Core::Entity::Player& player, Core::Entity::Actor& targetActor ) override

View file

@ -12,7 +12,7 @@
class Aethernet : public EventScript class Aethernet : public EventScript
{ {
public: public:
Aethernet() : EventScript( "Aethernet", EVENTSCRIPT_AETHERNET_ID ) Aethernet() : EventScript( EVENTSCRIPT_AETHERNET_ID )
{} {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override

View file

@ -13,7 +13,7 @@
class Aetheryte : public EventScript class Aetheryte : public EventScript
{ {
public: public:
Aetheryte() : EventScript( "Aetheryte", EVENTSCRIPT_AETHERYTE_ID ) Aetheryte() : EventScript( EVENTSCRIPT_AETHERYTE_ID )
{} {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override

View file

@ -65,7 +65,7 @@ private:
} }
public: public:
OpeningGridania() : EventScript( "OpeningGridania", 1245186 ) OpeningGridania() : EventScript( 1245186 )
{} {}
void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override

View file

@ -81,7 +81,7 @@ private:
public: public:
OpeningLimsa() : EventScript( "OpeningLimsa", 1245185 ) {} OpeningLimsa() : EventScript( 1245185 ) {}
void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override
{ {

View file

@ -65,7 +65,7 @@ private:
public: public:
OpeningUldah() : EventScript( "OpeningUldah", 1245187 ) {} OpeningUldah() : EventScript( 1245187 ) {}
void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override void onEnterZone( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) override
{ {

View file

@ -90,7 +90,7 @@ private:
} }
public: public:
ManFst001() : EventScript( "ManFst001", 65575 ) {} ManFst001() : EventScript( 65575 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -189,7 +189,7 @@ private:
} }
public: public:
ManFst002() : EventScript( "ManFst002", 65621 ) {} ManFst002() : EventScript( 65621 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -12,7 +12,7 @@ private:
public: public:
ManFst003() : EventScript( "ManFst003", 65659 ) {} ManFst003() : EventScript( 65659 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -71,7 +71,7 @@ class ManFst004 : public EventScript
static constexpr auto UnlockDesion = 14; static constexpr auto UnlockDesion = 14;
public: public:
ManFst004() : EventScript( "Close to Home", 65660 ){}; ManFst004() : EventScript( 65660 ){};
~ManFst004(){}; ~ManFst004(){};
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

View file

@ -145,7 +145,7 @@ private:
} }
public: public:
ManSea001() : EventScript( "ManSea001", 65643 ) {} ManSea001() : EventScript( 65643 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -136,7 +136,7 @@ private:
player.eventPlay( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback ); player.eventPlay( getId(), 50, FADE_OUT | CONDITION_CUTSCENE | HIDE_UI, 0, 0, callback );
} }
public: public:
ManSea002() : EventScript( "ManSea002", 65644 ) {} ManSea002() : EventScript( 65644 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -129,7 +129,7 @@ private:
public: public:
ManWil001() : EventScript( "ManWil001", 66130 ) {} ManWil001() : EventScript( 66130 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -144,7 +144,7 @@ private:
public: public:
ManWil002() : EventScript( "ManWil002", 66104 ) { } ManWil002() : EventScript( 66104 ) { }
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -60,7 +60,7 @@ private:
public: public:
SubFst001() : EventScript( "SubFst001", 65560 ) {} SubFst001() : EventScript( 65560 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -46,7 +46,7 @@ private:
} }
public: public:
SubFst002() : EventScript( "SubFst002", 65561 ) {} SubFst002() : EventScript( 65561 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -42,7 +42,7 @@ private:
} }
public: public:
SubFst010() : EventScript( "SubFst010", 65537 ) {} SubFst010() : EventScript( 65537 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -148,7 +148,7 @@ private:
public: public:
SubFst013() : EventScript( "SubFst013", 65576 ) {} SubFst013() : EventScript( 65576 ) {}
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override
{ {

View file

@ -11,7 +11,7 @@
#include <common/Network/Connection.h> #include <common/Network/Connection.h>
#include <common/Network/Hive.h> #include <common/Network/Hive.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Database/DbLoader.h> #include <common/Database/DbLoader.h>
#include <common/Database/CharaDbConnection.h> #include <common/Database/CharaDbConnection.h>
@ -21,7 +21,7 @@
#include "Network/GameConnection.h" #include "Network/GameConnection.h"
#include "Session.h" #include "Session.h"
#include "Zone/ZoneMgr.h" #include "Zone/TerritoryMgr.h"
#include "DebugCommand/DebugCommandHandler.h" #include "DebugCommand/DebugCommandHandler.h"
@ -35,12 +35,13 @@
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <thread> #include <thread>
#include <common/Util/Util.h>
Core::Logger g_log; Core::Logger g_log;
Core::DebugCommandHandler g_gameCommandMgr; Core::DebugCommandHandler g_gameCommandMgr;
Core::Scripting::ScriptManager g_scriptMgr; Core::Scripting::ScriptManager g_scriptMgr;
Core::Data::ExdData g_exdData; Core::Data::ExdDataGenerated g_exdDataGen;
Core::ZoneMgr g_zoneMgr; Core::TerritoryMgr g_territoryMgr;
Core::LinkshellMgr g_linkshellMgr; Core::LinkshellMgr g_linkshellMgr;
Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb; Core::Db::DbWorkerPool< Core::Db::CharaDbConnection > g_charaDb;
Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr; Core::Social::SocialMgr< Core::Social::FriendList > g_friendListMgr;
@ -164,10 +165,10 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
} }
} }
g_log.info( "Setting up EXD data" ); g_log.info( "Setting up generated EXD data" );
if( !g_exdData.init( m_pConfig->getValue< std::string >( "Settings.General.DataPath", "" ) ) ) if( !g_exdDataGen.init( m_pConfig->getValue< std::string >( "Settings.General.DataPath", "" ) ) )
{ {
g_log.fatal( "Error setting up EXD data " ); g_log.fatal( "Error setting up generated EXD data " );
return false; return false;
} }
@ -206,15 +207,6 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
return; return;
} }
g_exdData.loadZoneInfo();
g_exdData.loadClassJobInfo();
g_exdData.loadParamGrowInfo();
g_exdData.loadEventActionInfo();
g_exdData.loadActionInfo();
g_exdData.loadStatusEffectInfo();
g_exdData.loadAetheryteInfo();
g_exdData.loadTribeInfo();
g_log.info( "LinkshellMgr: Caching linkshells" ); g_log.info( "LinkshellMgr: Caching linkshells" );
if( !g_linkshellMgr.loadLinkshells() ) if( !g_linkshellMgr.loadLinkshells() )
{ {
@ -229,8 +221,8 @@ void Core::ServerZone::run( int32_t argc, char* argv[] )
g_scriptMgr.init(); g_scriptMgr.init();
g_log.info( "ZoneMgr: Setting up zones" ); g_log.info( "TerritoryMgr: Setting up zones" );
g_zoneMgr.createZones(); g_territoryMgr.init();
std::vector< std::thread > thread_list; std::vector< std::thread > thread_list;
thread_list.emplace_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) ); thread_list.emplace_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) );
@ -263,12 +255,13 @@ void Core::ServerZone::mainLoop()
{ {
this_thread::sleep_for( chrono::milliseconds( 50 ) ); this_thread::sleep_for( chrono::milliseconds( 50 ) );
g_zoneMgr.updateZones();
auto currTime = Util::getTimeSeconds();
g_territoryMgr.updateTerritoryInstances( currTime );
g_scriptMgr.update(); g_scriptMgr.update();
auto currTime = static_cast< uint32_t >( time( nullptr ) );
lock_guard< std::mutex > lock( this->m_sessionMutex ); lock_guard< std::mutex > lock( this->m_sessionMutex );
for( auto sessionIt : this->m_sessionMapById ) for( auto sessionIt : this->m_sessionMapById )
{ {
@ -294,7 +287,7 @@ void Core::ServerZone::mainLoop()
auto it = this->m_sessionMapById.begin(); auto it = this->m_sessionMapById.begin();
for( ; it != this->m_sessionMapById.end(); ) for( ; it != this->m_sessionMapById.end(); )
{ {
uint32_t diff = currTime - it->second->getLastDataTime(); auto diff = std::difftime( currTime, it->second->getLastDataTime() );
auto pPlayer = it->second->getPlayer(); auto pPlayer = it->second->getPlayer();
@ -314,7 +307,8 @@ void Core::ServerZone::mainLoop()
// remove sessions that simply timed out // remove sessions that simply timed out
if( diff > 20 ) if( diff > 20 )
{ {
g_log.info("[" + std::to_string(it->second->getId() ) + "] Session time out" ); g_log.info("[" + std::to_string( it->second->getId() ) + "] Session time out" );
it->second->close(); it->second->close();
// if( it->second.unique() ) // if( it->second.unique() )
{ {

View file

@ -51,7 +51,7 @@ namespace Core {
uint16_t m_port; uint16_t m_port;
std::string m_ip; std::string m_ip;
uint32_t m_lastDBPingTime; int64_t m_lastDBPingTime;
bool m_bRunning; bool m_bRunning;

View file

@ -11,16 +11,12 @@
extern Core::Logger g_log; extern Core::Logger g_log;
Core::Session::Session( uint32_t sessionId ) Core::Session::Session( uint32_t sessionId ) :
: m_sessionId( sessionId ) m_sessionId( sessionId ),
, m_lastDataTime( static_cast< uint32_t >( Util::getTimeSeconds() ) ) m_lastDataTime( Util::getTimeSeconds() ),
, m_lastSqlTime( static_cast< uint32_t >( Util::getTimeSeconds() ) ) m_lastSqlTime( Util::getTimeSeconds() ),
, m_isValid( false ) m_isValid( false )
{ {
// boost::posix_time::ptime now = boost::date_time::not_a_date_time;
// now = boost::posix_time::microsec_clock::universal_time();
} }
Core::Session::~Session() Core::Session::~Session()
@ -86,12 +82,12 @@ uint32_t Core::Session::getId() const
return m_sessionId; return m_sessionId;
} }
uint32_t Core::Session::getLastDataTime() const int64_t Core::Session::getLastDataTime() const
{ {
return m_lastDataTime; return m_lastDataTime;
} }
uint32_t Core::Session::getLastSqlTime() const int64_t Core::Session::getLastSqlTime() const
{ {
return m_lastSqlTime; return m_lastSqlTime;
} }
@ -103,12 +99,12 @@ bool Core::Session::isValid() const
void Core::Session::updateLastDataTime() void Core::Session::updateLastDataTime()
{ {
m_lastDataTime = static_cast< uint32_t >( Util::getTimeSeconds() ); m_lastDataTime = Util::getTimeSeconds();
} }
void Core::Session::updateLastSqlTime() void Core::Session::updateLastSqlTime()
{ {
m_lastSqlTime = static_cast< uint32_t >( Util::getTimeSeconds() ); m_lastSqlTime = Util::getTimeSeconds();
} }
void Core::Session::startReplay( const std::string& path ) void Core::Session::startReplay( const std::string& path )

View file

@ -20,8 +20,8 @@ namespace Core {
Network::GameConnectionPtr getZoneConnection() const; Network::GameConnectionPtr getZoneConnection() const;
Network::GameConnectionPtr getChatConnection() const; Network::GameConnectionPtr getChatConnection() const;
uint32_t getLastDataTime() const; int64_t getLastDataTime() const;
uint32_t getLastSqlTime() const; int64_t getLastSqlTime() const;
void updateLastDataTime(); void updateLastDataTime();
void updateLastSqlTime(); void updateLastSqlTime();
@ -48,9 +48,9 @@ namespace Core {
Entity::PlayerPtr m_pPlayer; Entity::PlayerPtr m_pPlayer;
uint32_t m_lastDataTime; int64_t m_lastDataTime;
uint32_t m_lastSqlTime; int64_t m_lastSqlTime;
bool m_isValid; bool m_isValid;
bool m_isReplaying; bool m_isReplaying;

View file

@ -1,4 +1,4 @@
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Util/Util.h> #include <common/Util/Util.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h> #include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
@ -13,7 +13,7 @@
#include "Script/ScriptManager.h" #include "Script/ScriptManager.h"
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
using namespace Core::Common; using namespace Core::Common;
using namespace Core::Network::Packets; using namespace Core::Network::Packets;
@ -31,8 +31,8 @@ Core::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::ActorPtr so
, m_tickRate( tickRate ) , m_tickRate( tickRate )
, m_lastTick( 0 ) , m_lastTick( 0 )
{ {
auto& entry = g_exdData.m_statusEffectInfoMap[id]; auto entry = g_exdDataGen.getStatus( id );
m_name = entry.name; m_name = entry->name;
std::replace( m_name.begin(), m_name.end(), ' ', '_' ); std::replace( m_name.begin(), m_name.end(), ' ', '_' );
std::replace( m_name.begin(), m_name.end(), ':', '_' ); std::replace( m_name.begin(), m_name.end(), ':', '_' );

View file

@ -0,0 +1,29 @@
#include "InstanceContent.h"
Core::InstanceContent::InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent,
uint32_t guId,
const std::string& internalName,
const std::string& contentName,
uint32_t instanceContentId )
: Zone( pInstanceContent->territoryType, guId, internalName, contentName ),
m_instanceContentInfo( pInstanceContent ),
m_instanceContentId( instanceContentId ),
m_state( Created )
{
}
Core::InstanceContent::~InstanceContent()
{
}
uint32_t Core::InstanceContent::getInstanceContentId() const
{
return m_instanceContentId;
}
boost::shared_ptr< Core::Data::InstanceContent > Core::InstanceContent::getInstanceContentInfo() const
{
return m_instanceContentInfo;
}

View file

@ -0,0 +1,41 @@
#ifndef SAPPHIRE_INSTANCECONTENT_H
#define SAPPHIRE_INSTANCECONTENT_H
#include "Zone.h"
#include "Forwards.h"
#include <common/Exd/ExdDataGenerated.h>
namespace Core
{
class InstanceContent : public Zone
{
public:
enum InstanceContentState
{
Created,
DutyStarted,
DutyFinished
};
InstanceContent( boost::shared_ptr< Core::Data::InstanceContent > pInstanceContent,
uint32_t guId,
const std::string& internalName,
const std::string& contentName,
uint32_t instanceContentId );
virtual ~InstanceContent();
boost::shared_ptr< Core::Data::InstanceContent > getInstanceContentInfo() const;
uint32_t getInstanceContentId() const;
private:
Event::DirectorPtr m_pDirector;
boost::shared_ptr< Core::Data::InstanceContent > m_instanceContentInfo;
uint32_t m_instanceContentId;
InstanceContentState m_state;
};
}
#endif //SAPPHIRE_INSTANCECONTENT_H

View file

@ -0,0 +1,349 @@
#include "TerritoryMgr.h"
#include <common/Logging/Logger.h>
#include <common/Database/DatabaseDef.h>
#include <common/Exd/ExdDataGenerated.h>
#include "Actor/Player.h"
#include "Zone.h"
#include "ZonePosition.h"
#include "InstanceContent.h"
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
extern Core::Data::ExdDataGenerated g_exdDataGen;
Core::TerritoryMgr::TerritoryMgr() :
m_lastInstanceId( 10000 )
{
}
void Core::TerritoryMgr::loadTerritoryTypeDetailCache()
{
auto idList = g_exdDataGen.getTerritoryTypeIdList();
for( auto id : idList )
{
auto teri1 = g_exdDataGen.getTerritoryType( id );
if( !teri1->name.empty() )
m_territoryTypeDetailCacheMap[id] = teri1;
}
}
bool Core::TerritoryMgr::isValidTerritory( uint32_t territoryTypeId ) const
{
return !( m_territoryTypeDetailCacheMap.find( territoryTypeId ) == m_territoryTypeDetailCacheMap.end() );
}
bool Core::TerritoryMgr::init()
{
loadTerritoryTypeDetailCache();
loadTerritoryPositionMap();
createDefaultTerritories();
return true;
}
uint32_t Core::TerritoryMgr::getNextInstanceId()
{
return ++m_lastInstanceId;
}
Core::Data::TerritoryTypePtr Core::TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const
{
auto tIt = m_territoryTypeDetailCacheMap.find( territoryTypeId );
if( tIt == m_territoryTypeDetailCacheMap.end() )
return nullptr;
return tIt->second;
}
bool Core::TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const
{
auto pTeri = getTerritoryDetail( territoryTypeId );
if( !pTeri )
return false;
return pTeri->territoryIntendedUse == TerritoryIntendedUse::AllianceRaid ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::BeforeTrialDung ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Trial ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Dungeon ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorldInstanceBattle ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::PalaceOfTheDead ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::RaidFights ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Raids ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::TreasureMapInstance;
}
bool Core::TerritoryMgr::isPrivateTerritory( uint32_t territoryTypeId ) const
{
auto pTeri = getTerritoryDetail( territoryTypeId );
if( !pTeri )
return false;
return pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::HousingPrivateArea ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::JailArea ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::MSQPrivateArea;
}
bool Core::TerritoryMgr::createDefaultTerritories()
{
// for each entry in territoryTypeExd, check if it is a normal and if so, add the zone object
for( const auto& territory : m_territoryTypeDetailCacheMap )
{
auto territoryId = territory.first;
auto territoryInfo = territory.second;
// if the zone has no name set
if( territoryInfo->name.empty() )
continue;
auto pPlaceName = g_exdDataGen.getPlaceName( territoryInfo->placeName );
if( !pPlaceName || pPlaceName->name.empty() || !isDefaultTerritory( territoryId ) )
continue;
uint32_t guid = getNextInstanceId();
g_log.Log( LoggingSeverity::info, std::to_string( territoryId ) +
"\t" + std::to_string( guid ) +
"\t" + std::to_string( territoryInfo->territoryIntendedUse ) +
"\t" + territoryInfo->name +
"\t" + pPlaceName->name );
ZonePtr pZone( new Zone( territoryId, guid, territoryInfo->name, pPlaceName->name ) );
pZone->init();
InstanceIdToZonePtrMap instanceMap;
instanceMap[guid] = pZone;
m_instanceIdToZonePtrMap[guid] = pZone;
m_territoryInstanceMap[territoryId] = instanceMap;
m_zoneSet.insert( { pZone } );
}
return true;
}
Core::ZonePtr Core::TerritoryMgr::createTerritoryInstance( uint32_t territoryTypeId )
{
if( !isValidTerritory( territoryTypeId ) )
return nullptr;
if( isInstanceContentTerritory( territoryTypeId ) )
return nullptr;
auto pTeri = getTerritoryDetail( territoryTypeId );
auto pPlaceName = g_exdDataGen.getPlaceName( pTeri->placeName );
if( !pTeri || !pPlaceName )
return nullptr;
g_log.debug( "Starting instance for territory: " + std::to_string( territoryTypeId ) + " (" + pPlaceName->name + ")" );
ZonePtr pZone = ZonePtr( new Zone( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name ) );
pZone->init();
m_territoryInstanceMap[pZone->getTerritoryId()][pZone->getGuId()] = pZone;
m_instanceIdToZonePtrMap[pZone->getGuId()] = pZone;
return pZone;
}
Core::ZonePtr Core::TerritoryMgr::createInstanceContent( uint32_t instanceContentId )
{
auto pInstanceContent = g_exdDataGen.getInstanceContent( instanceContentId );
if( !pInstanceContent )
return nullptr;
if( !isInstanceContentTerritory( pInstanceContent->territoryType ) )
return nullptr;
auto pTeri = getTerritoryDetail( pInstanceContent->territoryType );
if( !pTeri || pInstanceContent->name.empty() )
return nullptr;
g_log.debug( "Starting instance for InstanceContent id: " + std::to_string( instanceContentId ) +
" (" + pInstanceContent->name + ")" );
ZonePtr pZone = ZonePtr( new InstanceContent( pInstanceContent, getNextInstanceId(), pTeri->name,
pInstanceContent->name, instanceContentId ) );
pZone->init();
m_instanceContentToInstanceMap[instanceContentId][pZone->getGuId()] = pZone;
m_instanceIdToZonePtrMap[pZone->getGuId()] = pZone;
m_instanceZoneSet.insert( { pZone } );
return pZone;
}
bool Core::TerritoryMgr::removeTerritoryInstance( uint32_t instanceId )
{
ZonePtr pZone;
if( ( pZone = getInstanceZonePtr( instanceId ) ) == nullptr )
return false;
m_instanceIdToZonePtrMap.erase( pZone->getGuId() );
if( m_instanceZoneSet.count( pZone ) )
m_instanceZoneSet.erase( pZone );
if( isInstanceContentTerritory( pZone->getTerritoryId() ) )
{
auto instance = boost::dynamic_pointer_cast< InstanceContent >( pZone );
m_instanceContentToInstanceMap[instance->getInstanceContentId()].erase( pZone->getGuId() );
}
else
m_territoryInstanceMap[pZone->getTerritoryId()].erase( pZone->getGuId() );
return true;
}
Core::ZonePtr Core::TerritoryMgr::getInstanceZonePtr( uint32_t instanceId ) const
{
auto it = m_instanceIdToZonePtrMap.find( instanceId );
if( it == m_instanceIdToZonePtrMap.end() )
return nullptr;
return it->second;
}
void Core::TerritoryMgr::loadTerritoryPositionMap()
{
auto pQR = g_charaDb.query( "SELECT id, target_zone_id, pos_x, pos_y, pos_z, pos_o, radius FROM zonepositions;" );
while( pQR->next() )
{
uint32_t id = pQR->getUInt( 1 );
uint32_t targetZoneId = pQR->getUInt( 2 );
Common::FFXIVARR_POSITION3 pos{};
pos.x = pQR->getFloat( 3 );
pos.y = pQR->getFloat( 4 );
pos.z = pQR->getFloat( 5 );
float posO = pQR->getFloat( 6 );
uint32_t radius = pQR->getUInt( 7 );
m_territoryPositionMap[id] = ZonePositionPtr( new ZonePosition( id, targetZoneId, pos, radius, posO ) );
}
}
bool Core::TerritoryMgr::isDefaultTerritory( uint32_t territoryTypeId ) const
{
auto pTeri = getTerritoryDetail( territoryTypeId );
if( !pTeri )
return false;
return pTeri->territoryIntendedUse == TerritoryIntendedUse::Inn ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::Town ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpenWorld ||
pTeri->territoryIntendedUse == TerritoryIntendedUse::OpeningArea;
}
Core::ZonePositionPtr Core::TerritoryMgr::getTerritoryPosition( uint32_t territoryPositionId ) const
{
auto it = m_territoryPositionMap.find( territoryPositionId );
if( it != m_territoryPositionMap.end() )
return it->second;
return nullptr;
}
Core::ZonePtr Core::TerritoryMgr::getZoneByTerriId( uint32_t territoryId ) const
{
auto zoneMap = m_territoryInstanceMap.find( territoryId );
if( zoneMap == m_territoryInstanceMap.end() )
return nullptr;
// TODO: actually select the proper one
return zoneMap->second.begin()->second;
}
void Core::TerritoryMgr::updateTerritoryInstances( uint32_t currentTime )
{
for( auto& zone : m_zoneSet )
{
zone->runZoneLogic( currentTime );
}
for( auto& zone : m_instanceZoneSet )
{
zone->runZoneLogic( currentTime );
}
}
Core::TerritoryMgr::InstanceIdList Core::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const
{
std::vector< uint32_t > idList;
auto zoneMap = m_instanceContentToInstanceMap.find( instanceContentId );
if( zoneMap == m_instanceContentToInstanceMap.end() )
return idList;
for( auto& entry : zoneMap->second )
{
idList.push_back( entry.first );
}
return idList;
}
bool Core::TerritoryMgr::movePlayer( uint32_t territoryId, Core::Entity::PlayerPtr pPlayer )
{
auto pZone = getZoneByTerriId( territoryId );
if( !pZone )
{
g_log.error( "Zone " + std::to_string( territoryId ) + " not found on this server." );
return false;
}
pPlayer->setTerritoryId( territoryId );
// mark character as zoning in progress
pPlayer->setLoadingComplete( false );
if( pPlayer->getLastPing() != 0 )
pPlayer->getCurrentZone()->removeActor( pPlayer );
pPlayer->setCurrentZone( pZone );
pZone->pushActor( pPlayer );
return true;
}
bool Core::TerritoryMgr::movePlayer( ZonePtr pZone, Core::Entity::PlayerPtr pPlayer )
{
if( !pZone )
{
g_log.error( "Zone not found on this server." );
return false;
}
pPlayer->setTerritoryId( pZone->getTerritoryId() );
// mark character as zoning in progress
pPlayer->setLoadingComplete( false );
if( pPlayer->getLastPing() != 0 )
pPlayer->getCurrentZone()->removeActor( pPlayer );
pPlayer->setCurrentZone( pZone );
pZone->pushActor( pPlayer );
return true;
}

View file

@ -0,0 +1,157 @@
#ifndef SAPPHIRE_TERRITORYMGR_H
#define SAPPHIRE_TERRITORYMGR_H
#include <common/Exd/ExdData.h>
#include "Forwards.h"
#include <set>
namespace Core
{
namespace Data
{
// TODO: this should actually not be here but should be generated in exdData aswell
struct PlaceName;
struct TerritoryType;
struct InstanceContent;
using PlaceNamePtr = boost::shared_ptr< PlaceName >;
using TerritoryTypePtr = boost::shared_ptr< TerritoryType >;
using InstanceContentPtr = boost::shared_ptr< InstanceContent >;
}
/*!
\class TerritoryMgr_c
\brief A class managing zones
This class manages persistent and temporary instances alike.
*/
class TerritoryMgr
{
public:
enum TerritoryIntendedUse : 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,
FreeCompanyGarrison = 30,
PalaceOfTheDead = 31,
TreasureMapInstance = 33,
EventArea = 40,
};
TerritoryMgr();
/*! initializes the territoryMgr */
bool init();
bool createDefaultTerritories();
/*! caches TerritoryType details into m_territoryTypeMap */
void loadTerritoryTypeDetailCache();
/*! List of positions for zonelines */
void loadTerritoryPositionMap();
/*! returns true if the given territoryTypeId is in fact a valid zone
based on informations in the dats ( checks if an entry in the dats exists trhough cache ) */
bool isValidTerritory( uint32_t territoryTypeId ) const;
/*! returns the next available instanceId */
uint32_t getNextInstanceId();
/*! returns true if the territoryType in question is not a persistant zone */
bool isInstanceContentTerritory( uint32_t territoryTypeId ) const;
/*! returns true if the territoryType in question is not a private zone */
bool isPrivateTerritory( uint32_t territoryTypeId ) const;
/*! returns true if the territoryType is a default non-instanced zone */
bool isDefaultTerritory( uint32_t territoryTypeId ) const;
/*! creates a new instance for a given territoryTypeId */
ZonePtr createTerritoryInstance( uint32_t territoryTypeId );
ZonePtr createInstanceContent( uint32_t instanceContentId );
/*! removes instance by instanceId, return true if successful */
bool removeTerritoryInstance( uint32_t territoryTypeId );
/*! returns a ZonePtr to the instance or nullptr if not found */
ZonePtr getInstanceZonePtr( uint32_t instanceId ) const;
/*! returns the cached detail of a territory, nullptr if not found */
Data::TerritoryTypePtr getTerritoryDetail( uint32_t territoryTypeId ) const;
/*! loop for processing territory logic, iterating all existing instances */
void updateTerritoryInstances( uint32_t currentTime );
/*! returns a ZonePositionPtr if found, else nullptr */
ZonePositionPtr getTerritoryPosition( uint32_t territoryPositionId ) const;
/*! returns a default Zone by territoryId
TODO: Mind multiple instances?! */
ZonePtr getZoneByTerriId( uint32_t territoryId ) const;
bool movePlayer( uint32_t territoryId, Entity::PlayerPtr pPlayer );
bool movePlayer( ZonePtr, Entity::PlayerPtr pPlayer );
private:
using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >;
using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >;
using TerritoryIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >;
using InstanceContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >;
using PlayerIdToInstanceIdMap = std::unordered_map< uint32_t, uint32_t >;
using PositionMap = std::unordered_map< int32_t, ZonePositionPtr >;
using InstanceIdList = std::vector< uint32_t >;
/*! map holding details for territory templates */
TerritoryTypeDetailCache m_territoryTypeDetailCacheMap;
/*! map holding actual instances of default territories */
TerritoryIdToInstanceMap m_territoryInstanceMap;
/*! map holding actual instances of InstanceContent */
InstanceContentIdToInstanceMap m_instanceContentToInstanceMap;
/*! flat map for easier lookup of instances by guid */
InstanceIdToZonePtrMap m_instanceIdToZonePtrMap;
/*! map holding positions for zonelines */
PositionMap m_territoryPositionMap;
/*! internal counter for instanceIds */
uint32_t m_lastInstanceId;
/*! set of ZonePtrs for quick iteration*/
std::set< ZonePtr > m_zoneSet;
/*! set of ZonePtrs for quick iteration*/
std::set< ZonePtr > m_instanceZoneSet;
public:
/*! returns a list of instanceContent InstanceIds currently active */
InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const;
};
}
#endif // SAPPHIRE_TERRITORYMGR_H

View file

@ -6,14 +6,14 @@
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include <common/Network/GamePacket.h> #include <common/Network/GamePacket.h>
#include <common/Network/GamePacketNew.h> #include <common/Network/GamePacketNew.h>
#include <common/Exd/ExdData.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Network/CommonNetwork.h> #include <common/Network/CommonNetwork.h>
#include <common/Network/PacketDef/Zone/ServerZoneDef.h> #include <common/Network/PacketDef/Zone/ServerZoneDef.h>
#include <common/Network/PacketContainer.h> #include <common/Network/PacketContainer.h>
#include <common/Database/DatabaseDef.h> #include <common/Database/DatabaseDef.h>
#include "Zone.h" #include "Zone.h"
#include "ZoneMgr.h" #include "TerritoryMgr.h"
#include "Session.h" #include "Session.h"
#include "Actor/Actor.h" #include "Actor/Actor.h"
@ -33,7 +33,7 @@
extern Core::Logger g_log; extern Core::Logger g_log;
extern Core::ServerZone g_serverZone; extern Core::ServerZone g_serverZone;
extern Core::Data::ExdData g_exdData; extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
namespace Core { namespace Core {
@ -42,30 +42,48 @@ namespace Core {
* \brief * \brief
*/ */
Zone::Zone() Zone::Zone()
: m_zoneId( 0 ) : m_territoryId( 0 )
, m_layoutId( 0 ) , m_guId( 0 )
, m_bPrivate( false )
, m_type( Common::RegionType::normal ) , m_type( Common::RegionType::normal )
, m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) ) , m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) )
, m_weatherOverride( 0 ) , m_weatherOverride( 0 )
, m_lastMobUpdate( 0 ) , m_lastMobUpdate( 0 )
, m_currentFestivalId( 0 )
{ {
} }
Zone::Zone( uint16_t zoneId, uint32_t layoutId, std::string name, std::string interName, bool bPrivate = false ) Zone::Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName, const std::string& placeName )
: m_type( Common::RegionType::normal ) : m_type( Common::RegionType::normal )
, m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) ) , m_currentWeather( static_cast< uint8_t >( Common::Weather::FairSkies ) )
{ {
m_layoutId = layoutId; m_guId = guId;
m_zoneId = zoneId; m_territoryId = territoryId;
m_zoneCode = name; m_internalName = internalName;
m_zoneName = interName; m_placeName = placeName;
m_bPrivate = bPrivate;
m_lastMobUpdate = 0; m_lastMobUpdate = 0;
m_currentWeather = getNextWeather();
m_weatherOverride = 0; m_weatherOverride = 0;
m_territoryTypeInfo = g_exdDataGen.getTerritoryType( territoryId );
uint8_t weatherRateId = m_territoryTypeInfo->weatherRate > g_exdDataGen.getWeatherRateIdList().size() ?
uint8_t{ 0 } : m_territoryTypeInfo->weatherRate;
uint8_t sumPc = 0;
auto weatherRateFields = g_exdDataGen.m_WeatherRateDat.get_row( weatherRateId );
for( size_t i = 0; i < 16; )
{
int32_t weatherId = boost::get< int32_t >( weatherRateFields[i] );
if( weatherId == 0 )
break;
sumPc += boost::get< uint8_t >( weatherRateFields[i + 1] );
m_weatherRateMap[sumPc] = weatherId;
i += 2;
}
m_currentWeather = getNextWeather();
} }
Zone::~Zone() Zone::~Zone()
@ -101,6 +119,16 @@ uint8_t Zone::getCurrentWeather() const
return m_currentWeather; return m_currentWeather;
} }
uint16_t Zone::getCurrentFestival() const
{
return m_currentFestivalId;
}
void Zone::setCurrentFestival( uint16_t festivalId )
{
m_currentFestivalId = festivalId;
}
CellCache* Zone::getCellCacheList( uint32_t cellx, uint32_t celly ) CellCache* Zone::getCellCacheList( uint32_t cellx, uint32_t celly )
{ {
assert( cellx < _sizeX ); assert( cellx < _sizeX );
@ -151,7 +179,7 @@ void Zone::loadCellCache()
"Look," "Look,"
"Models," "Models,"
"type " "type "
"FROM battlenpc WHERE ZoneId = " + std::to_string( getId() ) + ";" ); "FROM battlenpc WHERE ZoneId = " + std::to_string(getTerritoryId() ) + ";" );
std::vector< Entity::BattleNpcPtr > cache; std::vector< Entity::BattleNpcPtr > cache;
@ -176,10 +204,7 @@ void Zone::loadCellCache()
uint32_t modelId = pQR->getUInt( 17 ); uint32_t modelId = pQR->getUInt( 17 );
uint32_t type = pQR->getUInt( 18 ); uint32_t type = pQR->getUInt( 18 );
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos{ posX, posY, posZ };
pos.x = posX;
pos.y = posY;
pos.z = posZ;
Entity::BattleNpcPtr pBNpc( new Entity::BattleNpc( modelId, nameId, pos, Entity::BattleNpcPtr pBNpc( new Entity::BattleNpc( modelId, nameId, pos,
sizeId, type, level, behaviour, mobType ) ); sizeId, type, level, behaviour, mobType ) );
pBNpc->setRotation( static_cast< float >( rotation ) ); pBNpc->setRotation( static_cast< float >( rotation ) );
@ -191,8 +216,8 @@ void Zone::loadCellCache()
for( auto entry : cache ) for( auto entry : cache )
{ {
// get cell position // get cell position
uint32_t cellX = CellHandler< ZoneMgr >::getPosX( entry->getPos().x ); uint32_t cellX = CellHandler< TerritoryMgr >::getPosX( entry->getPos().x );
uint32_t cellY = CellHandler< ZoneMgr >::getPosY( entry->getPos().z ); uint32_t cellY = CellHandler< TerritoryMgr >::getPosY( entry->getPos().z );
// find the right cell, create it if not existing yet // find the right cell, create it if not existing yet
if( m_pCellCache[cellX] == nullptr ) if( m_pCellCache[cellX] == nullptr )
@ -212,9 +237,7 @@ void Zone::loadCellCache()
uint8_t Zone::getNextWeather() uint8_t Zone::getNextWeather()
{ {
auto zoneInfo = g_exdData.m_zoneInfoMap[ getLayoutId() ]; uint32_t unixTime = static_cast< uint32_t >( Util::getTimeSeconds() );
uint32_t unixTime = static_cast< uint32_t >( time( nullptr ) );
// Get Eorzea hour for weather start // Get Eorzea hour for weather start
uint32_t bell = unixTime / 175; uint32_t bell = unixTime / 175;
// Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16 // Do the magic 'cause for calculations 16:00 is 0, 00:00 is 8 and 08:00 is 16
@ -228,12 +251,12 @@ uint8_t Zone::getNextWeather()
uint32_t step1 = ( calcBase << 0xB ) ^ calcBase; uint32_t step1 = ( calcBase << 0xB ) ^ calcBase;
uint32_t step2 = ( step1 >> 8 ) ^ step1; uint32_t step2 = ( step1 >> 8 ) ^ step1;
uint8_t rate = static_cast< uint8_t >(step2 % 0x64); auto rate = static_cast< uint8_t >( step2 % 0x64 );
for( auto entry : zoneInfo.weather_rate_map ) for( auto entry : m_weatherRateMap )
{ {
uint8_t sRate = entry.first; uint8_t sRate = entry.first;
int32_t weatherId = entry.second; auto weatherId = static_cast< uint8_t >( entry.second );
if( rate <= sRate ) if( rate <= sRate )
return weatherId; return weatherId;
@ -281,7 +304,7 @@ void Zone::pushActor( Entity::ActorPtr pActor )
if( pActor->isPlayer() ) if( pActor->isPlayer() )
{ {
g_log.debug( "[Zone:" + m_zoneCode + "] Adding player [" + std::to_string( pActor->getId() ) + "]" ); g_log.debug( "[Zone:" + m_internalName + "] Adding player [" + std::to_string( pActor->getId() ) + "]" );
auto pPlayer = pActor->getAsPlayer(); auto pPlayer = pActor->getAsPlayer();
auto pSession = g_serverZone.getSession( pPlayer->getId() ); auto pSession = g_serverZone.getSession( pPlayer->getId() );
@ -299,7 +322,7 @@ void Zone::pushActor( Entity::ActorPtr pActor )
pBNpc->setPosition( pBNpc->getPos() ); pBNpc->setPosition( pBNpc->getPos() );
} }
else if( pActor->getAsEventNpc() ) else if( pActor->isEventNpc() )
{ {
Entity::EventNpcPtr pENpc = pActor->getAsEventNpc(); Entity::EventNpcPtr pENpc = pActor->getAsEventNpc();
m_EventNpcMap[pENpc->getId()] = pENpc; m_EventNpcMap[pENpc->getId()] = pENpc;
@ -320,7 +343,7 @@ void Zone::removeActor( Entity::ActorPtr pActor )
if( pActor->isPlayer() ) if( pActor->isPlayer() )
{ {
g_log.debug( "[Zone:" + m_zoneCode + "] Removing player [" + std::to_string( pActor->getId() ) + "]" ); g_log.debug( "[Zone:" + m_internalName + "] Removing player [" + std::to_string( pActor->getId() ) + "]" );
// If it's a player and he's inside boundaries - update his nearby cells // If it's a player and he's inside boundaries - update his nearby cells
if( pActor->getPos().x <= _maxX && pActor->getPos().x >= _minX && if( pActor->getPos().x <= _maxX && pActor->getPos().x >= _minX &&
pActor->getPos().z <= _maxY && pActor->getPos().z >= _minY ) pActor->getPos().z <= _maxY && pActor->getPos().z >= _minY )
@ -372,9 +395,9 @@ void Zone::queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range,
} }
} }
uint32_t Zone::getId() uint32_t Zone::getTerritoryId()
{ {
return m_zoneId; return m_territoryId;
} }
Common::RegionType Zone::getType() const Common::RegionType Zone::getType() const
@ -382,9 +405,9 @@ Common::RegionType Zone::getType() const
return m_type; return m_type;
} }
uint16_t Zone::getLayoutId() const uint16_t Zone::getGuId() const
{ {
return m_layoutId; return m_guId;
} }
bool Zone::isInstance() const bool Zone::isInstance() const
@ -394,12 +417,12 @@ bool Zone::isInstance() const
const std::string& Zone::getName() const const std::string& Zone::getName() const
{ {
return m_zoneName; return m_placeName;
} }
const std::string& Zone::getInternalName() const const std::string& Zone::getInternalName() const
{ {
return m_zoneCode; return m_internalName;
} }
std::size_t Zone::getPopCount() const std::size_t Zone::getPopCount() const
@ -414,7 +437,7 @@ bool Zone::checkWeather()
if ( m_weatherOverride != m_currentWeather ) if ( m_weatherOverride != m_currentWeather )
{ {
m_currentWeather = m_weatherOverride; m_currentWeather = m_weatherOverride;
g_log.debug( "[Zone:" + m_zoneCode + "] overriding weather to : " + std::to_string( m_weatherOverride ) ); g_log.debug( "[Zone:" + m_internalName + "] overriding weather to : " + std::to_string( m_weatherOverride ) );
return true; return true;
} }
} }
@ -424,7 +447,7 @@ bool Zone::checkWeather()
if ( nextWeather != m_currentWeather ) if ( nextWeather != m_currentWeather )
{ {
m_currentWeather = nextWeather; m_currentWeather = nextWeather;
g_log.debug( "[Zone:" + m_zoneCode + "] changing weather to : " + std::to_string( nextWeather ) ); g_log.debug( "[Zone:" + m_internalName + "] changing weather to : " + std::to_string( nextWeather ) );
return true; return true;
} }
} }
@ -479,7 +502,7 @@ void Zone::updateBnpcs( int64_t tickCount )
} }
} }
bool Zone::runZoneLogic() bool Zone::runZoneLogic( uint32_t currTime )
{ {
int64_t tickCount = Util::getTimeMs(); int64_t tickCount = Util::getTimeMs();
@ -502,7 +525,7 @@ bool Zone::runZoneLogic()
// this session is not linked to this area anymore, remove it from zone session list // this session is not linked to this area anymore, remove it from zone session list
if( ( !pSession->getPlayer()->getCurrentZone() ) || ( pSession->getPlayer()->getCurrentZone() != shared_from_this() ) ) if( ( !pSession->getPlayer()->getCurrentZone() ) || ( pSession->getPlayer()->getCurrentZone() != shared_from_this() ) )
{ {
g_log.debug( "[Zone:" + m_zoneCode + "] removing session " + std::to_string( pSession->getId() ) ); g_log.debug( "[Zone:" + m_internalName + "] removing session " + std::to_string( pSession->getId() ) );
if( pSession->getPlayer()->getCell() ) if( pSession->getPlayer()->getCell() )
removeActor( pSession->getPlayer() ); removeActor( pSession->getPlayer() );

View file

@ -14,27 +14,23 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <common/Exd/ExdDataGenerated.h>
namespace Core { namespace Core {
namespace Entity
{
class Actor;
class Player;
}
class Session; class Session;
class ZonePosition; class ZonePosition;
typedef std::set< SessionPtr > SessionSet; using SessionSet = std::set< SessionPtr >;
class Zone : public CellHandler< Cell >, public boost::enable_shared_from_this< Zone > class Zone : public CellHandler< Cell >, public boost::enable_shared_from_this< Zone >
{ {
protected: protected:
uint32_t m_zoneId; uint32_t m_territoryId;
uint32_t m_layoutId; uint32_t m_guId;
std::string m_zoneName; std::string m_placeName;
std::string m_zoneCode; std::string m_internalName;
bool m_bPrivate; bool m_bPrivate;
@ -55,10 +51,15 @@ protected:
uint64_t m_lastMobUpdate; uint64_t m_lastMobUpdate;
uint16_t m_currentFestivalId;
boost::shared_ptr< Data::TerritoryType > m_territoryTypeInfo;
std::map< uint8_t, int32_t> m_weatherRateMap;
public: public:
Zone(); Zone();
Zone( uint16_t zoneId, uint32_t layoutId, std::string name, std::string interName, bool bPrivate ); Zone( uint16_t territoryId, uint32_t guId, const std::string& internalName, const std::string& placeName );
virtual ~Zone(); virtual ~Zone();
bool init(); bool init();
@ -70,6 +71,9 @@ public:
uint8_t getCurrentWeather() const; uint8_t getCurrentWeather() const;
uint16_t getCurrentFestival() const;
void setCurrentFestival( uint16_t festivalId );
CellCache* getCellCacheList( uint32_t cellx, uint32_t celly ); CellCache* getCellCacheList( uint32_t cellx, uint32_t celly );
CellCache* getCellCacheAndCreate( uint32_t cellx, uint32_t celly ); CellCache* getCellCacheAndCreate( uint32_t cellx, uint32_t celly );
@ -92,11 +96,11 @@ public:
void queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry ); void queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry );
virtual uint32_t getId(); virtual uint32_t getTerritoryId();
Common::RegionType getType() const; Common::RegionType getType() const;
uint16_t getLayoutId() const; uint16_t getGuId() const;
bool isInstance() const; bool isInstance() const;
@ -108,7 +112,7 @@ public:
bool checkWeather(); bool checkWeather();
void updateBnpcs( int64_t tickCount ); void updateBnpcs( int64_t tickCount );
bool runZoneLogic(); bool runZoneLogic( uint32_t currTime );
}; };

View file

@ -1,89 +0,0 @@
#include <common/Logging/Logger.h>
#include <common/Exd/ExdData.h>
#include <common/Database/DatabaseDef.h>
#include <boost/lexical_cast.hpp>
#include "ZoneMgr.h"
#include "Zone.h"
#include "ZonePosition.h"
extern Core::Logger g_log;
extern Core::Data::ExdData g_exdData;
namespace Core {
ZoneMgr::ZoneMgr() = default;
ZoneMgr::~ZoneMgr() = default;
void ZoneMgr::loadZonePositionMap()
{
auto pQR = g_charaDb.query( "SELECT id, target_zone_id, pos_x, pos_y, pos_z, pos_o, radius FROM zonepositions;" );
while( pQR->next() )
{
uint32_t id = pQR->getUInt( 1 );
uint32_t targetZoneId = pQR->getUInt( 2 );
Common::FFXIVARR_POSITION3 pos;
pos.x = pQR->getFloat( 3 );
pos.y = pQR->getFloat( 4 );
pos.z = pQR->getFloat( 5 );
float posO = pQR->getFloat( 6 );
uint32_t radius = pQR->getUInt( 7 );
m_zonePositionMap[id] = ZonePositionPtr( new ZonePosition( id, targetZoneId, pos, radius, posO ) );
}
}
ZonePositionPtr ZoneMgr::getZonePosition( uint32_t zonePositionId )
{
auto it = m_zonePositionMap.find( zonePositionId );
if( it != m_zonePositionMap.end() )
return it->second;
return nullptr;
}
bool ZoneMgr::createZones()
{
loadZonePositionMap();
// find zone info from exd
for( auto zone : g_exdData.m_zoneInfoMap )
{
uint32_t zoneId = zone.first;
auto info = zone.second;
g_log.Log( LoggingSeverity::info, std::to_string( info.id ) + "\t" + info.zone_str );
ZonePtr pZone( new Zone( info.id, info.layout_id, info.zone_name, info.zone_str, false ) );
pZone->init();
m_zoneMap[info.id] = pZone;
}
return true;
}
void ZoneMgr::updateZones()
{
for( auto zone : m_zoneMap )
{
zone.second->runZoneLogic();
}
}
ZonePtr ZoneMgr::getZone( uint32_t zoneId )
{
ZoneMap::iterator it;
it = m_zoneMap.find( zoneId );
if( it != m_zoneMap.end() )
return it->second;
return nullptr;
}
}

View file

@ -1,39 +0,0 @@
#ifndef _ZONEMGR_H
#define _ZONEMGR_H
#include <unordered_map>
#include <map>
#include "Forwards.h"
namespace Core {
using ZoneMap = std::unordered_map< uint32_t, ZonePtr >;
class ZoneMgr
{
public:
ZoneMgr();
~ZoneMgr();
bool createZones();
ZonePtr getZone( uint32_t zoneId );
void loadZonePositionMap();
ZonePositionPtr getZonePosition( uint32_t zonePositionId );
void updateZones();
private:
ZoneMap m_zoneMap;
std::unordered_map<int32_t, ZonePositionPtr > m_zonePositionMap;
};
}
#endif

Some files were not shown because too many files have changed in this diff Show more