1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 22:57:45 +00:00

Some more cleanup in regards of zones

This commit is contained in:
Mordred 2022-01-21 22:55:14 +01:00
parent 7e8209c11b
commit 57da97236f
8 changed files with 69 additions and 100 deletions

View file

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

View file

@ -82,7 +82,7 @@ public:
return;
}
player.setInstance( internalZone, pos );
//player.setInstance( internalZone->getGuId(), pos );
} );
}
};

View file

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

View file

@ -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();

View file

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

View file

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

View file

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

View file

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