From bccf6e200aa235db85af19e44f7cc326a81cca04 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 28 Jan 2018 22:36:43 +0100 Subject: [PATCH] Cleaning up zoneing code --- src/servers/sapphire_zone/Actor/Player.cpp | 178 +++++++++--------- src/servers/sapphire_zone/Actor/Player.h | 8 +- .../sapphire_zone/Zone/InstanceContent.h | 7 + .../sapphire_zone/Zone/TerritoryMgr.cpp | 48 +++++ src/servers/sapphire_zone/Zone/TerritoryMgr.h | 4 + 5 files changed, 154 insertions(+), 91 deletions(-) diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index ea9e2861..d99c6470 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -365,99 +365,11 @@ void Core::Entity::Player::returnToHomepoint() void Core::Entity::Player::setZone( uint32_t zoneId ) { - auto pPlayer = getAsPlayer(); - auto pZone = g_territoryMgr.getZoneByTerriId( zoneId ); - - if( !pZone /*|| ( ( pZone == m_pCurrentZone ) && m_lastPing )*/ ) - { - g_log.error( "Zone " + std::to_string( zoneId ) + " not found on this server." ); + if( !g_territoryMgr.movePlayer( zoneId, getAsPlayer() ) ) return; - } - m_zoneId = zoneId; - - // mark character as zoning in progress - setLoadingComplete( false ); - - if( m_lastPing != 0 ) - m_pCurrentZone->removeActor( shared_from_this() ); - - m_pCurrentZone = pZone; - m_pCurrentZone->pushActor( shared_from_this() ); - - 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 ) - pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas ); - pPlayer->setStateFlag( PlayerStateFlag::BetweenAreas1 ); - - pPlayer->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( *pPlayer ); - 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; + sendZonePackets(); } uint32_t Core::Entity::Player::getPlayTime() const @@ -1602,3 +1514,89 @@ void Core::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp ) // Send to single player 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; +} diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index ff5309df..ad38e93b 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -309,6 +309,10 @@ public: Common::OnlineStatus getOnlineStatus(); /*! sets the players zone, initiating a zoning process */ void setZone( uint32_t zoneId ); + /*! sets the players territoryId */ + void setTerritoryId( uint32_t territoryId ); + /*! gets the players territoryId */ + uint32_t getTerritoryId() const; void forceZoneing( uint32_t zoneId ); /*! return player to preset homepoint */ @@ -471,10 +475,12 @@ public: /*! set the loading complete bool */ void setLoadingComplete( bool bComplete ); /*! 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 */ bool isMarkedForZoning() const; + void sendZonePackets(); + Common::ZoneingType getZoningType() const; void setZoningType( Common::ZoneingType zoneingType ); diff --git a/src/servers/sapphire_zone/Zone/InstanceContent.h b/src/servers/sapphire_zone/Zone/InstanceContent.h index 306021cb..e6e877b4 100644 --- a/src/servers/sapphire_zone/Zone/InstanceContent.h +++ b/src/servers/sapphire_zone/Zone/InstanceContent.h @@ -10,6 +10,13 @@ namespace Core class InstanceContent : public Zone { public: + enum InstanceContentState + { + Created, + DutyStarted, + DutyFinished + }; + InstanceContent( uint32_t instanceContentId, uint32_t guid ); virtual ~InstanceContent(); diff --git a/src/servers/sapphire_zone/Zone/TerritoryMgr.cpp b/src/servers/sapphire_zone/Zone/TerritoryMgr.cpp index e802ca79..c36ea728 100644 --- a/src/servers/sapphire_zone/Zone/TerritoryMgr.cpp +++ b/src/servers/sapphire_zone/Zone/TerritoryMgr.cpp @@ -4,6 +4,8 @@ #include #include +#include "Actor/Player.h" + #include "Zone.h" #include "ZonePosition.h" @@ -248,5 +250,51 @@ Core::TerritoryMgr::InstanceIdList Core::TerritoryMgr::getInstanceContentIdList( 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; +} + diff --git a/src/servers/sapphire_zone/Zone/TerritoryMgr.h b/src/servers/sapphire_zone/Zone/TerritoryMgr.h index 0fbd716c..ce05982b 100644 --- a/src/servers/sapphire_zone/Zone/TerritoryMgr.h +++ b/src/servers/sapphire_zone/Zone/TerritoryMgr.h @@ -103,6 +103,10 @@ namespace Core 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 >;