1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 08:07:46 +00:00

Merge remote-tracking branch 'origin/event_rewrite'

Conflicts:
	src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp
This commit is contained in:
Mordred Admin 2018-01-30 07:53:15 +01:00
commit 2a6c505f9f
76 changed files with 1567 additions and 1025 deletions

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

@ -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

@ -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

@ -1,76 +1,76 @@
#include "../../../ScriptObject.h" #include "../../../ScriptObject.h"
// Quest Script: SubFst002_00025 // Quest Script: SubFst002_00025
// Quest Name: Quarrels with Squirrels // Quest Name: Quarrels with Squirrels
// Quest ID: 65561 // Quest ID: 65561
// Start NPC: 1000263 // Start NPC: 1000263
// End NPC: 1000263 // End NPC: 1000263
class SubFst002 : public EventScript class SubFst002 : public EventScript
{ {
private: private:
static constexpr auto SEQ_0 = 0; static constexpr auto SEQ_0 = 0;
static constexpr auto SEQ_1 = 1; static constexpr auto SEQ_1 = 1;
static constexpr auto SEQ_2 = 2; static constexpr auto SEQ_2 = 2;
static constexpr auto SEQ_FINISH = 255; static constexpr auto SEQ_FINISH = 255;
static constexpr auto ACTOR0 = 1000263; static constexpr auto ACTOR0 = 1000263;
static constexpr auto ENEMY0 = 37; static constexpr auto ENEMY0 = 37;
static constexpr auto SEQ_0_ACTOR0 = 0; static constexpr auto SEQ_0_ACTOR0 = 0;
static constexpr auto SEQ_2_ACTOR0 = 1; static constexpr auto SEQ_2_ACTOR0 = 1;
void Scene00000( Entity::Player& player ) void Scene00000( Entity::Player& player )
{ {
auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 )
{ {
if( param2 == 1 ) // accept quest if( param2 == 1 ) // accept quest
{ {
player.updateQuest( getId(), SEQ_1 ); player.updateQuest( getId(), SEQ_1 );
} }
}; };
player.eventPlay( getId (), 0, NONE, callback ); player.eventPlay( getId (), 0, NONE, callback );
} }
void Scene00001(Entity::Player& player) void Scene00001(Entity::Player& player)
{ {
auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 ) auto callback = [&]( Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2, uint16_t param3 )
{ {
if( param2 == 1 ) // finish quest if( param2 == 1 ) // finish quest
{ {
if( player.giveQuestRewards( getId(), 0 ) ) if( player.giveQuestRewards( getId(), 0 ) )
player.finishQuest( getId() ); player.finishQuest( getId() );
} }
}; };
player.eventPlay( getId(), 1, NONE, callback ); player.eventPlay( getId(), 1, NONE, callback );
} }
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
{ {
auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ); auto actor = Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) );
if( actor == ACTOR0 && !player.hasQuest( getId() ) ) if( actor == ACTOR0 && !player.hasQuest( getId() ) )
Scene00000( player ); Scene00000( player );
else if( actor == ACTOR0 && player.getQuestSeq( getId() ) == SEQ_FINISH ) else if( actor == ACTOR0 && player.getQuestSeq( getId() ) == SEQ_FINISH )
Scene00001( player ); Scene00001( player );
} }
void onNpcKill( uint32_t npcId, Entity::Player& player ) override void onNpcKill( uint32_t npcId, Entity::Player& player ) override
{ {
if( npcId != ENEMY0 ) if( npcId != ENEMY0 )
return; return;
auto currentKC = player.getQuestUI8AL( getId() ) + 1; auto currentKC = player.getQuestUI8AL( getId() ) + 1;
if( currentKC >= 6 ) if( currentKC >= 6 )
player.updateQuest( getId(), SEQ_FINISH ); player.updateQuest( getId(), SEQ_FINISH );
else else
{ {
player.setQuestUI8AL( getId(), currentKC ); player.setQuestUI8AL( getId(), currentKC );
player.sendQuestMessage( getId(), 0, 2, currentKC, 6 ); player.sendQuestMessage( getId(), 0, 2, currentKC, 6 );
} }
} }
}; };

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

@ -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

@ -162,29 +162,6 @@ namespace Common {
instance, instance,
}; };
enum TerritoryIntendedUseType : uint8_t //ToDo: Add The Rest of The Territory Types and Have Better Names For Them
{
Town = 0,
OpenWorld = 1,
Inn = 2,
Dungeon = 3,
JailArea = 5,
OpeningArea = 6,
BeforeTrialDung = 7,
AllianceRaid = 8,
OpenWorldInstanceBattle = 9,
Trial = 10,
HousingArea = 13,
HousingPrivateArea = 14,
MSQPrivateArea = 15,
Raids = 16,
RaidFights = 17,
ChocoboTutorial = 21,
Wedding = 22,
BeginnerTutorial = 27,
PalaceOfTheDead = 31,
};
enum CharaLook : uint8_t enum CharaLook : uint8_t
{ {
Race = 0x00, Race = 0x00,
@ -319,25 +296,6 @@ namespace Common {
}; };
enum EventType : uint16_t
{
Quest = 0x0001,
ChocoRent = 0x0002,
Shop = 0x0004,
Aetheryte = 0x0005,
GuildLeveAssign = 0x0006,
DefaultTalk = 0x0009,
CustomTalk = 0x000B,
CraftLeve = 0x000E,
ChocoPort = 0x0012,
Opening = 0x0013,
GCShop = 0x0016,
GuildOrderGuide = 0x0017,
GuildOrderOfficer = 0x0018,
Stories = 0x001A,
FcTalk = 0x001F,
};
enum struct ActionAspect : uint8_t enum struct ActionAspect : uint8_t
{ {
None = 0, // Doesn't imply unaspected None = 0, // Doesn't imply unaspected

View file

@ -61,7 +61,7 @@ uint32_t Core::Db::DbConnection::open()
try try
{ {
m_pConnection = base->connect( m_connectionInfo.host, m_connectionInfo.user, m_connectionInfo.password, m_pConnection = base->connect( m_connectionInfo.host, m_connectionInfo.user, m_connectionInfo.password,
options, m_connectionInfo.port ); options, m_connectionInfo.port );
m_pConnection->setSchema( m_connectionInfo.database ); m_pConnection->setSchema( m_connectionInfo.database );
} }
@ -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; )

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

@ -3532,6 +3532,7 @@
placeNameZone = exdData->getField< uint16_t >( row, 4 ); placeNameZone = exdData->getField< uint16_t >( row, 4 );
placeName = exdData->getField< uint16_t >( row, 5 ); placeName = exdData->getField< uint16_t >( row, 5 );
map = exdData->getField< uint16_t >( row, 6 ); map = exdData->getField< uint16_t >( row, 6 );
territoryIntendedUse = exdData->getField< uint8_t >( row, 9 );
weatherRate = exdData->getField< uint8_t >( row, 12 ); weatherRate = exdData->getField< uint8_t >( row, 12 );
aetheryte = exdData->getField< int32_t >( row, 23 ); aetheryte = exdData->getField< int32_t >( row, 23 );
} }

View file

@ -1,5 +1,5 @@
#ifndef _EXDDATA_H #ifndef _EXDDATAGENERATED_H
#define _EXDDATA_H #define _EXDDATAGENERATED_H
/* This file has been automatically generated. /* This file has been automatically generated.
Changes will be lost upon regeneration. Changes will be lost upon regeneration.
@ -3020,12 +3020,12 @@ struct TerritoryType
uint16_t placeNameZone; uint16_t placeNameZone;
uint16_t placeName; uint16_t placeName;
uint16_t map; uint16_t map;
uint8_t territoryIntendedUse;
uint8_t weatherRate; uint8_t weatherRate;
int32_t aetheryte; int32_t aetheryte;
TerritoryType( uint32_t row_id, Core::Data::ExdDataGenerated* exdData ); TerritoryType( uint32_t row_id, Core::Data::ExdDataGenerated* exdData );
}; };
struct TextCommand struct TextCommand
{ {
std::string command; std::string command;

View file

@ -365,7 +365,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;

@ -1 +1 @@
Subproject commit f4d3c5b38d13a15efc42686c9bac768c2be28be1 Subproject commit 978d3d2a336b97bb6ea0d95dc7000cbc1618a8cc

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

@ -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

@ -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

@ -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

@ -6,7 +6,7 @@
#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::ExdData g_exdData;
@ -54,7 +54,6 @@ void Core::Action::EventAction::onStart()
{ {
m_pSource->sendToInRangeSet( control, true ); m_pSource->sendToInRangeSet( control, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag );
m_pSource->getAsPlayer()->sendStateFlags();
} }
else else
m_pSource->sendToInRangeSet( control ); m_pSource->sendToInRangeSet( control );
@ -84,7 +83,6 @@ void Core::Action::EventAction::onFinish()
if( m_pSource->isPlayer() ) if( m_pSource->isPlayer() )
{ {
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag );
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

@ -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

@ -11,7 +11,7 @@
#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"
@ -32,7 +32,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"
@ -43,7 +43,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::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
@ -308,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->levelId );
Common::FFXIVARR_POSITION3 pos; Common::FFXIVARR_POSITION3 pos;
pos.x = 0; pos.x = 0;
@ -366,101 +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
return; m_pos = m_prevPos;
m_rot = m_prevRot;
m_zoneId = m_prevZoneId;
if( !g_territoryMgr.movePlayer( m_zoneId, getAsPlayer() ) )
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 );
m_itemLevel = getInventory()->calculateEquippedGearItemLevel(); return true;
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
@ -542,7 +502,7 @@ 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_exdData.m_zoneInfoMap[getCurrentZone()->getTerritoryId()];
if( info.is_two_byte ) if( info.is_two_byte )
offset = 4 + 2 * info.discovery_index; offset = 4 + 2 * info.discovery_index;
else else
@ -580,7 +540,6 @@ void Core::Entity::Player::setNewAdventurer( bool state )
//{ //{
// setStateFlag( PlayerStateFlag::NewAdventurer ); // setStateFlag( PlayerStateFlag::NewAdventurer );
//} //}
sendStateFlags();
m_bNewAdventurer = state; m_bNewAdventurer = state;
} }
@ -972,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;
@ -979,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 );
} }
@ -986,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;
} }
} }
@ -1006,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;
@ -1013,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 )
@ -1023,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);
} }
@ -1596,3 +1565,89 @@ 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 );
ZoneChannelPacket< FFXIVGCAffiliation > gcAffPacket( getId() );
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 );
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().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

@ -7,6 +7,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>
@ -50,31 +51,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 );
@ -306,6 +309,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 */
@ -468,10 +481,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 );
@ -553,6 +568,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;
@ -600,7 +620,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

@ -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,7 +30,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;
@ -47,7 +47,7 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
stmt->setUInt( 1, charId ); stmt->setUInt( 1, charId );
auto res = g_charaDb.query( stmt ); auto res = g_charaDb.query( stmt );
if( !res->next() ) if( !res->next() )
return false; return false;
@ -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" );
@ -155,7 +162,7 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
auto orchestrion = res->getBlobVector( "Orchestrion" ); auto orchestrion = res->getBlobVector( "Orchestrion" );
memcpy( reinterpret_cast< char* >( m_orchestrion ), orchestrion.data(), orchestrion.size() ); memcpy( reinterpret_cast< char* >( m_orchestrion ), orchestrion.data(), orchestrion.size() );
auto gcRank = res->getBlobVector( "GrandCompanyRank" ); auto gcRank = res->getBlobVector( "GrandCompanyRank" );
memcpy( reinterpret_cast< char* >( m_gcRank ), gcRank.data(), gcRank.size() ); memcpy( reinterpret_cast< char* >( m_gcRank ), gcRank.data(), gcRank.size() );
@ -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() ) );

View file

@ -37,11 +37,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::ExdData g_exdData;
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()
@ -58,6 +60,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
@ -477,7 +480,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_exdData.m_zoneInfoMap[player.getCurrentZone()->getTerritoryId()].map_id;
player.sendNotice( "Pos:\n" + player.sendNotice( "Pos:\n" +
std::to_string( player.getPos().x ) + "\n" + std::to_string( player.getPos().x ) + "\n" +
@ -485,7 +488,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
{ {
@ -555,7 +558,7 @@ void Core::DebugCommandHandler::replay( char * data, Entity::Player& player, boo
player.sendUrgent( subCommand + " is not a valid replay command." ); player.sendUrgent( subCommand + " is not a valid replay command." );
} }
} }
void Core::DebugCommandHandler::nudge( char * data, Entity::Player& player, boost::shared_ptr< DebugCommand > command ) void Core::DebugCommandHandler::nudge( char * data, Entity::Player& player, boost::shared_ptr< DebugCommand > command )
@ -713,3 +716,50 @@ void Core::DebugCommandHandler::script( char* data, Entity::Player &player, boos
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();
}
}

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,5 +1,5 @@
#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/ExdData.h>
@ -15,7 +15,7 @@ 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_exdData.getQuestInfo( eventId );
if( !questInfo ) if( !questInfo )
@ -26,7 +26,7 @@ std::string Core::Event::getEventName( uint32_t eventId )
return questInfo->name_intern.substr( 0, pos ); return questInfo->name_intern.substr( 0, pos );
} }
case EventType::CustomTalk: case Event::EventHandler::EventHandlerType::CustomTalk:
{ {
auto customTalkInfo = g_exdData.getCustomTalkInfo( eventId ); auto customTalkInfo = g_exdData.getCustomTalkInfo( eventId );
if( !customTalkInfo ) if( !customTalkInfo )
@ -37,21 +37,22 @@ std::string Core::Event::getEventName( uint32_t eventId )
return customTalkInfo->name_intern.substr( 0, pos ); return customTalkInfo->name_intern.substr( 0, pos );
} }
case EventType::Opening: case Event::EventHandler::EventHandlerType::Opening:
{ {
auto openingInfo = g_exdData.getOpeningInfo( eventId ); auto openingInfo = g_exdData.getOpeningInfo( 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_exdData.getAetheryteInfo( 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";
} }

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

@ -75,17 +75,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

@ -99,7 +99,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

@ -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,7 +36,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;
@ -196,7 +194,6 @@ 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;
} }

View file

@ -1,4 +1,5 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdData.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::ExdData g_exdData;
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 )
Entity::Player& player )
{ {
uint16_t eventHandlerId = inPacket.getValAt< uint16_t >( 0x12 ); auto actorId = inPacket.getValAt< uint64_t >( 0x20 );
auto eventId = inPacket.getValAt< uint32_t >( 0x28 );
auto eventType = static_cast< uint16_t >( eventId >> 16 );
// we need to abort the event in case it has not been scripted so the player wont be locked up std::string eventName = "onTalk";
auto abortEventFunc = []( Core::Entity::Player& player, uint64_t actorId, uint32_t eventId ) 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 )
{ {
player.queuePacket( EventStartPacket( player.getId(), actorId, eventId, 1, 0, 0 ) ); auto questInfo = g_exdData.getQuestInfo( eventId );
player.queuePacket( EventFinishPacket( player.getId(), eventId, 1, 0 ) ); if ( questInfo )
// this isn't ideal as it will also reset any other status that might be active player.sendUrgent( "Quest not implemented: " + questInfo->name + " (" + questInfo->name_intern + ")" );
player.queuePacket( PlayerStateFlagsPacket( player, PlayerStateFlagList{} ) );
};
std::string eventIdStr = boost::str( boost::format( "%|04X|" ) % static_cast< uint32_t >( eventHandlerId & 0xFFFF ) );
player.sendDebug( "---------------------------------------" );
player.sendDebug( "EventHandler ( " + eventIdStr + " )" );
switch( eventHandlerId )
{
case ClientZoneIpcType::TalkEventHandler: // Talk event
{
uint64_t actorId = inPacket.getValAt< uint64_t >( 0x20 );
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x28 );
if( !g_scriptMgr.onTalk( player, actorId, eventId ) )
abortEventFunc( player, actorId, eventId );
break;
} }
case ClientZoneIpcType::EmoteEventHandler: // Emote event 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 )
{ {
uint64_t actorId = inPacket.getValAt< uint64_t >( 0x20 ); auto questInfo = g_exdData.getQuestInfo( eventId );
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x28 ); if( questInfo )
uint16_t emoteId = inPacket.getValAt< uint16_t >( 0x2C ); player.sendUrgent( "Quest not implemented: " + questInfo->name );
std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onEmote( player, actorId, eventId, static_cast< uint8_t >( emoteId ) ) )
abortEventFunc( player, actorId, eventId );
break;
} }
player.checkEvent( eventId );
}
case ClientZoneIpcType::WithinRangeEventHandler: void Core::Network::GameConnection::eventHandlerWithinRange( const Packets::GamePacket& inPacket,
Entity::Player& player )
{
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 = "onWithinRange";
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.onWithinRange( player, eventId, param1, x, y, z );
player.checkEvent( eventId );
}
void Core::Network::GameConnection::eventHandlerOutsideRange( const Packets::GamePacket& inPacket,
Entity::Player& player )
{
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 = Event::getEventName( eventId );
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 );
player.sendDebug( "eventId: " +
std::to_string( eventId ) +
" ( 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 )
{ {
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x24 ); pEvent->setPlayedScene( false );
uint32_t eventParam1 = inPacket.getValAt< uint32_t >( 0x20 ); // try to retrieve a stored callback
float x = inPacket.getValAt< float >( 0x28 ); auto eventCallback = pEvent->getEventReturnCallback();
float y = inPacket.getValAt< float >( 0x2C ); // if there is one, proceed to call it
float z = inPacket.getValAt< float >( 0x30 ); if( eventCallback )
eventCallback( player, eventId, param1, param2, param3 );
std::string eventName = Event::getEventName( eventId );
if( !g_scriptMgr.onWithinRange( player, eventId, eventParam1, x, y, z ) )
abortEventFunc( player, 0, eventId );
break;
} }
case ClientZoneIpcType::OutOfRangeEventHandler: player.checkEvent( eventId );
{
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 ) ) void Core::Network::GameConnection::eventHandlerLinkshell( const Packets::GamePacket &inPacket,
abortEventFunc( player, 0, eventId ); Entity::Player &player )
break; {
} auto eventId = inPacket.getValAt< uint32_t >( 0x20 );
auto scene = inPacket.getValAt< uint16_t >( 0x24 );
auto lsName = inPacket.getStringAt( 0x27 );
case ClientZoneIpcType::EnterTeriEventHandler: ZoneChannelPacket< FFXIVIpcEventLinkshell > linkshellEvent( player.getId() );
{ linkshellEvent.data().eventId = eventId;
uint32_t eventId = inPacket.getValAt< uint32_t >( 0x20 ); linkshellEvent.data().scene = static_cast< uint8_t >( scene );
uint16_t eventParam1 = inPacket.getValAt< uint16_t >( 0x24 ); linkshellEvent.data().param3 = 1;
uint16_t eventParam2 = inPacket.getValAt< uint16_t >( 0x26 ); linkshellEvent.data().unknown1 = 0x15a;
player.queuePacket( linkshellEvent );
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() );
linkshellEvent.data().eventId = eventId;
linkshellEvent.data().scene = static_cast< uint8_t >( subEvent );
linkshellEvent.data().param3 = 1;
linkshellEvent.data().unknown1 = 0x15a;
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;
} }
@ -438,7 +449,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
player.sendNotice( "Jumping to " + targetPlayer->getName() + " in range." ); player.sendNotice( "Jumping to " + targetPlayer->getName() + " in range." );
break; break;
} }
default: default:
player.sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) ); player.sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) );
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"
@ -40,7 +40,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;
@ -297,7 +297,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;
@ -324,7 +324,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);
@ -442,7 +442,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;
@ -450,7 +450,7 @@ void Core::Network::GameConnection::socialListHandler( const Packets::GamePacket
listPacket.data().entries[0].classJob = static_cast< uint8_t >( player.getClass() ); listPacket.data().entries[0].classJob = static_cast< uint8_t >( 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

@ -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

@ -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"
@ -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,22 +147,12 @@ 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_exdData.getAetheryteInfo( eventId & 0xFFFF );
scriptId = EVENTSCRIPT_AETHERYTE_ID; scriptId = EVENTSCRIPT_AETHERYTE_ID;
@ -166,136 +160,50 @@ bool Core::Scripting::ScriptManager::onTalk( Entity::Player& player, uint64_t ac
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 )
return false;
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) ); script->onEnterZone( player, eventId, param1, param2 );
return true;
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;
} }
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 ); return false;
player.sendDebug( "Calling: " + objName + "." + eventName + " - " + std::to_string( eventId ) + " p1: " + std::to_string( param1 ) ); script->onWithinRange( player, eventId, param1, x, y, z );
return true;
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;
} }
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 ) ); return false;
script->onOutsideRange( player, eventId, param1, x, y, z );
auto script = m_nativeScriptManager->getScript< EventScript >( ScriptType::ScriptedEvent, eventId ); return true;
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;
} }
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 )
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 );
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 false;
} script->onEmote( actorId, eventId, emoteId, player );
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: " + return false;
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 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

@ -12,6 +12,7 @@
#include <common/Network/Hive.h> #include <common/Network/Hive.h>
#include <common/Exd/ExdData.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 +22,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"
@ -33,12 +34,14 @@
#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::ExdData g_exdData;
Core::ZoneMgr g_zoneMgr; Core::Data::ExdDataGenerated g_exdDataGen;
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;
@ -168,6 +171,13 @@ bool Core::ServerZone::loadSettings( int32_t argc, char* argv[] )
return false; return false;
} }
g_log.info( "Setting up generated EXD data" );
if( !g_exdDataGen.init( m_pConfig->getValue< std::string >( "Settings.General.DataPath", "" ) ) )
{
g_log.fatal( "Error setting up generated EXD data " );
return false;
}
Core::Db::DbLoader loader; Core::Db::DbLoader loader;
Core::Db::ConnectionInfo info; Core::Db::ConnectionInfo info;
@ -224,8 +234,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() ) ) );
@ -258,12 +268,13 @@ void Core::ServerZone::mainLoop()
{ {
this_thread::sleep_for( chrono::milliseconds( 50 ) ); this_thread::sleep_for( chrono::milliseconds( 50 ) );
g_zoneMgr.updateZones();
auto currTime = static_cast< uint32_t >( 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 )
{ {

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,346 @@
#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;
}
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;
return pZone;
}
bool Core::TerritoryMgr::removeTerritoryInstance( uint32_t instanceId )
{
ZonePtr pZone;
if( ( pZone = getInstanceZonePtr( instanceId ) ) == nullptr )
return false;
m_instanceIdToZonePtrMap.erase( pZone->getGuId() );
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 zoneMap : m_territoryInstanceMap )
{
for( auto zone : zoneMap.second )
zone.second->runZoneLogic( currentTime );
}
for( auto zoneMap : m_instanceContentToInstanceMap )
{
for( auto zone: zoneMap.second )
zone.second->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,150 @@
#ifndef SAPPHIRE_TERRITORYMGR_H
#define SAPPHIRE_TERRITORYMGR_H
#include <common/Exd/ExdData.h>
#include "Forwards.h"
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;
public:
/*! returns a list of instanceContent InstanceIds currently active */
InstanceIdList getInstanceContentIdList( uint16_t instanceContentId ) const;
};
}
#endif // SAPPHIRE_TERRITORYMGR_H

View file

@ -13,7 +13,7 @@
#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"
@ -42,9 +42,8 @@ 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 )
@ -52,16 +51,15 @@ Zone::Zone()
{ {
} }
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_currentWeather = getNextWeather();
@ -151,7 +149,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 +174,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 +186,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 +207,9 @@ void Zone::loadCellCache()
uint8_t Zone::getNextWeather() uint8_t Zone::getNextWeather()
{ {
auto zoneInfo = g_exdData.m_zoneInfoMap[ getLayoutId() ]; auto zoneInfo = g_exdData.m_zoneInfoMap[getTerritoryId()];
uint32_t unixTime = static_cast< uint32_t >( time( nullptr ) ); uint32_t unixTime = static_cast< uint32_t >( Util::getTimeSeconds() );
// 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 +223,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 : zoneInfo.weather_rate_map )
{ {
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 +276,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() );
@ -320,7 +315,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 +367,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 +377,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 +389,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 +409,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 +419,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;
} }
} }
@ -462,7 +457,7 @@ void Zone::updateBnpcs( int64_t tickCount )
for( auto entry : m_BattleNpcMap ) for( auto entry : m_BattleNpcMap )
{ {
Entity::BattleNpcPtr pBNpc = entry.second; Entity::BattleNpcPtr pBNpc = entry.second;
if( !pBNpc ) if( !pBNpc )
continue; continue;
@ -472,27 +467,27 @@ void Zone::updateBnpcs( int64_t tickCount )
m_BattleNpcDeadMap.insert( pBNpc ); m_BattleNpcDeadMap.insert( pBNpc );
break; break;
} }
pBNpc->update( tickCount ); pBNpc->update( tickCount );
} }
} }
} }
bool Zone::runZoneLogic() bool Zone::runZoneLogic( uint32_t currTime )
{ {
int64_t tickCount = Util::getTimeMs(); int64_t tickCount = Util::getTimeMs();
bool changedWeather = checkWeather(); bool changedWeather = checkWeather();
auto it = m_sessionSet.begin(); auto it = m_sessionSet.begin();
// update sessions in this zone // update sessions in this zone
for( ; it != m_sessionSet.end(); ) for( ; it != m_sessionSet.end(); )
{ {
auto pSession = ( *it ); auto pSession = ( *it );
if( !pSession ) if( !pSession )
{ {
it = m_sessionSet.erase( it ); it = m_sessionSet.erase( it );
@ -502,7 +497,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() );
@ -641,8 +636,8 @@ void Zone::changeActorPosition( Entity::ActorPtr pActor )
pActor->removeInRangeActor( *iter2 ); pActor->removeInRangeActor( *iter2 );
// @TODO FIXME! // @TODO FIXME!
// this break is more or less a hack, iteration will break otherwise after removing // this break is more or less a hack, iteration will break otherwise after removing
break; break;
} }
} }

View file

@ -15,26 +15,21 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.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;
@ -58,7 +53,7 @@ protected:
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();
@ -92,11 +87,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 +103,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

View file

@ -9,7 +9,7 @@
#include <iostream> #include <iostream>
#include <cctype> #include <cctype>
#include <set> #include <set>
#include "ExdDataGenerated.h" #include <common/Exd/ExdDataGenerated.h>
#include <common/Logging/Logger.h> #include <common/Logging/Logger.h>
#include <boost/range/algorithm/remove_if.hpp> #include <boost/range/algorithm/remove_if.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>