From 57da97236f83c2cf43bbf784a23167b60ec31e04 Mon Sep 17 00:00:00 2001 From: Mordred Date: Fri, 21 Jan 2022 22:55:14 +0100 Subject: [PATCH] Some more cleanup in regards of zones --- src/common/Common.h | 11 ++++ .../common/eobj/HousingEstateEntrance.cpp | 2 +- src/world/Actor/Player.cpp | 66 +++++++++---------- src/world/Actor/Player.h | 2 +- src/world/Manager/TerritoryMgr.cpp | 26 ++++---- .../Network/Handlers/GMCommandHandlers.cpp | 52 +-------------- src/world/Territory/Territory.cpp | 6 ++ src/world/Territory/Territory.h | 4 ++ 8 files changed, 69 insertions(+), 100 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 5375c46c..1a8139e2 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -1341,6 +1341,17 @@ namespace Sapphire::Common int16_t worldId; //06 }; + union TerritoryIdent + { + struct + { + uint16_t instanceId; + uint16_t territoryTypeId; + }; + + uint32_t id; + }; + struct House { uint8_t size; diff --git a/src/scripts/common/eobj/HousingEstateEntrance.cpp b/src/scripts/common/eobj/HousingEstateEntrance.cpp index a0fbbd08..d058e124 100644 --- a/src/scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/scripts/common/eobj/HousingEstateEntrance.cpp @@ -82,7 +82,7 @@ public: return; } - player.setInstance( internalZone, pos ); + //player.setInstance( internalZone->getGuId(), pos ); } ); } }; diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 6103184d..512908fb 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -473,14 +473,39 @@ void Sapphire::Entity::Player::forceZoneing( uint32_t zoneId ) m_queuedZoneing = std::make_shared< QueuedZoning >( zoneId, getPos(), Util::getTimeMs(), 0.f ); } -bool Sapphire::Entity::Player::setInstance( const TerritoryPtr& instance, Common::FFXIVARR_POSITION3 pos ) +void Sapphire::Entity::Player::performZoning( uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation ) { + m_pos = pos; + m_territoryTypeId = zoneId; + m_bMarkedForZoning = true; + setRot( rotation ); + + auto& teriMgr = Common::Service< TerritoryMgr >::ref(); + m_onEnterEventDone = false; + + auto pZone = teriMgr.getZoneByTerritoryTypeId( zoneId ); + if( !teriMgr.movePlayer( pZone, *this ) ) + { + // todo: this will require proper handling, for now just return the player to their previous area + m_pos = m_prevPos; + m_rot = m_prevRot; + m_territoryTypeId = m_prevTerritoryTypeId; + + auto pZone1 = teriMgr.getZoneByTerritoryTypeId( m_territoryTypeId ); + if( !teriMgr.movePlayer( pZone1, *this ) ) + return; + } +} + +bool Sapphire::Entity::Player::setInstance( uint32_t territoryId, Common::FFXIVARR_POSITION3 pos ) +{ + auto& teriMgr = Common::Service< TerritoryMgr >::ref(); + auto instance = teriMgr.getTerritoryByGuId( territoryId ); + m_onEnterEventDone = false; if( !instance ) return false; - auto& teriMgr = Common::Service< TerritoryMgr >::ref(); - // zoning within the same zone won't cause the prev data to be overwritten if( instance->getTerritoryTypeId() != m_territoryTypeId ) { @@ -491,20 +516,17 @@ bool Sapphire::Entity::Player::setInstance( const TerritoryPtr& instance, Common m_prevRot = m_rot; } - if( teriMgr.movePlayer( instance, *this ) ) - { - m_pos = pos; - return true; - } + if( !teriMgr.movePlayer( instance, *this ) ) + return false; - return false; + m_pos = pos; + return true; } bool Sapphire::Entity::Player::exitInstance() { auto& teriMgr = Common::Service< TerritoryMgr >::ref(); auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() ); - auto pInstance = pZone->getAsInstanceContent(); resetHp(); resetMp(); @@ -1207,30 +1229,6 @@ void Sapphire::Entity::Player::setLoadingComplete( bool bComplete ) m_bLoadingComplete = bComplete; } -void Sapphire::Entity::Player::performZoning( uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation ) -{ - m_pos = pos; - m_territoryTypeId = zoneId; - m_bMarkedForZoning = true; - setRot( rotation ); - - auto& teriMgr = Common::Service< TerritoryMgr >::ref(); - m_onEnterEventDone = false; - - auto pZone = teriMgr.getZoneByTerritoryTypeId( zoneId ); - if( !teriMgr.movePlayer( pZone, *this ) ) - { - // todo: this will require proper handling, for now just return the player to their previous area - m_pos = m_prevPos; - m_rot = m_prevRot; - m_territoryTypeId = m_prevTerritoryTypeId; - - auto pZone1 = teriMgr.getZoneByTerritoryTypeId( m_territoryTypeId ); - if( !teriMgr.movePlayer( pZone1, *this ) ) - return; - } -} - bool Sapphire::Entity::Player::isMarkedForZoning() const { return m_bMarkedForZoning; diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index e1020a1c..1360477d 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -303,7 +303,7 @@ namespace Sapphire::Entity Common::OnlineStatus getOnlineStatus() const; /*! sets the players instance & initiates zoning process */ - bool setInstance( const Sapphire::TerritoryPtr& instance, Sapphire::Common::FFXIVARR_POSITION3 pos ); + bool setInstance( uint32_t territoryId, Sapphire::Common::FFXIVARR_POSITION3 pos ); /*! returns the player to their position before zoning into an instance */ bool exitInstance(); diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index e01f719f..faa44507 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -41,7 +41,7 @@ void Sapphire::World::Manager::TerritoryMgr::loadTerritoryTypeDetailCache() { auto teri1 = exdData.getRow< Component::Excel::TerritoryType >( id ); - if( !teri1->getString( teri1->data().Name ).empty() ) + if( !teri1->getString( teri1->data().Name ).empty() && id > 90 ) m_territoryTypeDetailCacheMap[ id ] = teri1; } @@ -205,7 +205,7 @@ bool Sapphire::World::Manager::TerritoryMgr::createDefaultTerritories() bool hasNaviMesh = pZone->getNaviProvider() != nullptr; Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}", - territoryTypeId, + territoryTypeId < 10 ? std::to_string( territoryTypeId ) + "\t" : std::to_string( territoryTypeId ), guid, territoryData.IntendedUse, territoryInfo->getString( territoryData.Name ), @@ -660,7 +660,7 @@ void Sapphire::World::Manager::TerritoryMgr::createAndJoinQuestBattle( Entity::P if( !qb ) return; - player.setInstance( qb, { 0, 0, 0 } ); + //player.setInstance( qb->getGuId(), { 0, 0, 0 } ); } @@ -669,49 +669,49 @@ bool Sapphire::World::Manager::TerritoryMgr::joinWorld( Sapphire::Entity::Player TerritoryPtr pCurrZone = nullptr; - auto zoneId = player.getTerritoryTypeId(); + auto territoryTypeId = player.getTerritoryTypeId(); // if the zone is an instanceContent zone, we need to actually find the instance - if( isInstanceContentTerritory( zoneId ) ) + if( isInstanceContentTerritory( territoryTypeId ) ) { // try to find an instance actually linked to this player pCurrZone = getLinkedInstance( player.getId() ); // if none found, revert to previous zone and position if( !pCurrZone ) { - zoneId = player.getPrevTerritoryTypeId(); + territoryTypeId = player.getPrevTerritoryTypeId(); auto prevPos = player.getPrevPos(); player.setPos( prevPos, false ); player.setRot( player.getPrevRot() ); - pCurrZone = getZoneByTerritoryTypeId( zoneId ); + pCurrZone = getZoneByTerritoryTypeId( territoryTypeId ); } } - else if( isInternalEstateTerritory( zoneId ) ) + else if( isInternalEstateTerritory( territoryTypeId ) ) { // todo: this needs to go to the area just outside of the plot door pCurrZone = getTerritoryByGuId( player.getPrevTerritoryId() ); - zoneId = player.getPrevTerritoryTypeId(); + territoryTypeId = player.getPrevTerritoryTypeId(); auto prevPos = player.getPrevPos(); player.setPos( prevPos, false ); player.setRot( player.getPrevRot() ); } - else if( isHousingTerritory( zoneId ) ) + else if( isHousingTerritory( territoryTypeId ) ) { pCurrZone = getTerritoryByGuId( player.getTerritoryId() ); } else { - pCurrZone = getZoneByTerritoryTypeId( zoneId ); + pCurrZone = getZoneByTerritoryTypeId( territoryTypeId ); } - player.setTerritoryTypeId( zoneId ); + player.setTerritoryTypeId( territoryTypeId ); // TODO: logic for instances needs to be added here // see if a valid zone could be found for the character if( !pCurrZone ) { - Logger::error( "[{0}] Territory #{1} not found!", player.getCharacterId(), zoneId ); + Logger::error( "[{0}] Territory #{1} not found!", player.getCharacterId(), territoryTypeId ); Logger::error( "[{0}] Setting default zone instead", player.getCharacterId() ); // default to new gridania diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index 3bb4b9e5..448eeddf 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -486,7 +486,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR break; } - player.setInstance( instance, { 0, 0, 0 } ); + //player.setInstance( param1, { 0, 0, 0 } ); } else if( !teriMgr.isValidTerritory( param1 ) ) { @@ -651,56 +651,6 @@ void Sapphire::Network::GameConnection::gmCommandNameHandler( const Packets::FFX PlayerMgr::sendServerNotice( player, "Raised {0}", targetPlayer->getName()); break; } - case GmCommand::Jump: - { - - if( targetPlayer->getTerritoryId() != player.getTerritoryId() ) - { - if( pPlayerTerri->getAsInstanceContent() ) - player.exitInstance(); - - // Checks if the target player is in an InstanceContent to avoid binding to a Territory or PublicContent - auto pInstanceContent = pTargetActorTerri->getAsInstanceContent(); - if( pInstanceContent ) - { - // Not sure if GMs actually get bound to an instance they jump to on retail. It's mostly here to avoid a crash for now - pInstanceContent->bindPlayer( player.getId() ); - player.setInstance( pInstanceContent, { targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z } ); - } - } - else - { - player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRot() ); - player.sendZoneInPackets( 0x00, false ); - } - PlayerMgr::sendServerNotice( player, "Jumping to {0}", targetPlayer->getName() ); - break; - } - case GmCommand::Call: - { - // We shouldn't be able to call a player into an instance, only call them out of one - if( pPlayerTerri->getAsInstanceContent() ) - { - PlayerMgr::sendUrgent( player, "You are unable to call a player while bound to a battle instance." ); - return; - } - - if( targetPlayer->getTerritoryId() != player.getTerritoryId() ) - { - if( pTargetActorTerri->getAsInstanceContent() ) - targetPlayer->exitInstance(); - - targetPlayer->setInstance( pTargetActorTerri->getAsInstanceContent(), { player.getPos().x, player.getPos().y, player.getPos().z } ); - } - else - { - targetPlayer->changePosition( player.getPos().x, player.getPos().y, player.getPos().z, player.getRot() ); - targetPlayer->sendZoneInPackets( 0x00, false ); - } - - PlayerMgr::sendServerNotice( player, "Calling {0}", targetPlayer->getName() ); - break; - } default: PlayerMgr::sendUrgent( player, "GM2 Command not implemented: {0}", commandId ); break; diff --git a/src/world/Territory/Territory.cpp b/src/world/Territory/Territory.cpp index 87c16c8a..2d460d57 100644 --- a/src/world/Territory/Territory.cpp +++ b/src/world/Territory/Territory.cpp @@ -83,6 +83,7 @@ Sapphire::Territory::Territory( uint16_t territoryTypeId, uint32_t guId, const s m_territoryTypeInfo = exdData.getRow< Component::Excel::TerritoryType >( territoryTypeId ); m_bgPath = m_territoryTypeInfo->getString( m_territoryTypeInfo->data().LVB ); + m_ident.territoryTypeId = territoryTypeId; loadWeatherRates(); loadBNpcs(); @@ -966,3 +967,8 @@ void Sapphire::Territory::onEventHandlerOrder( Sapphire::Entity::Player& player, { } + +const TerritoryIdent& Sapphire::Territory::getTerritoryIdent() const +{ + return m_ident; +} diff --git a/src/world/Territory/Territory.h b/src/world/Territory/Territory.h index 259a0f29..ebe84910 100644 --- a/src/world/Territory/Territory.h +++ b/src/world/Territory/Territory.h @@ -74,6 +74,8 @@ namespace Sapphire std::vector< World::Action::EffectResultPtr > m_effectResults; + Common::TerritoryIdent m_ident; + public: Territory(); @@ -81,6 +83,8 @@ namespace Sapphire virtual ~Territory(); + const Common::TerritoryIdent& getTerritoryIdent() const; + /*! overrides the zone's weather, set to 0 to unlock */ void setWeatherOverride( Common::Weather weather );