1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 00:27:44 +00:00

Reconnecting during an instance now possible

This commit is contained in:
Mordred 2018-02-04 17:46:46 +01:00
parent eadc2e77b6
commit 9cc5f9ffb3
4 changed files with 57 additions and 44 deletions

View file

@ -356,17 +356,6 @@ void Core::Entity::Player::returnToHomepoint()
void Core::Entity::Player::setZone( uint32_t zoneId )
{
if( !g_territoryMgr.movePlayer( zoneId, getAsPlayer() ) )
{
// todo: this will require proper handling, for now just return the player to their previous area
m_pos = m_prevPos;
m_rot = m_prevRot;
m_zoneId = m_prevZoneId;
if( !g_territoryMgr.movePlayer( m_zoneId, getAsPlayer() ) )
return;
}
sendZonePackets();
}

View file

@ -60,7 +60,40 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_prevZoneId = res->getUInt( "OTerritoryId" );
m_prevZoneType = res->getUInt( "OTerritoryType" );
ZonePtr pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
// Position
m_pos.x = res->getFloat( "PosX" );
m_pos.y = res->getFloat( "PosY" );
m_pos.z = res->getFloat( "PosZ" );
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" );
ZonePtr pCurrZone = nullptr;
// if the zone is an instanceContent zone, we need to actually find the instance
if( g_territoryMgr.isInstanceContentTerritory( zoneId ) )
{
// try to find an instance actually linked to this player
pCurrZone = g_territoryMgr.getLinkedInstance( m_id );
// if none found, revert to previous zone and position
if( !pCurrZone )
{
zoneId = m_prevZoneId;
m_pos.x = m_prevPos.x;
m_pos.y = m_prevPos.y;
m_pos.z = m_prevPos.z;
setRotation( m_prevRot );
pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
}
}
else
{
pCurrZone = g_territoryMgr.getZoneByTerriId( zoneId );
}
m_zoneId = zoneId;
// TODO: logic for instances needs to be added here
@ -86,20 +119,8 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
m_mp = res->getUInt( "Mp" );
m_tp = 0;
// Position
m_pos.x = res->getFloat( "PosX" );
m_pos.y = res->getFloat( "PosY" );
m_pos.z = res->getFloat( "PosZ" );
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
auto custom = res->getBlobVector( "Customize" );
memcpy( reinterpret_cast< char* >( m_customize ), custom.data(), custom.size() );
@ -219,6 +240,9 @@ bool Core::Entity::Player::load( uint32_t charId, SessionPtr pSession )
if( !m_playerIdToSpawnIdMap.empty() )
m_playerIdToSpawnIdMap.clear();
if( !g_territoryMgr.movePlayer( pCurrZone, getAsPlayer() ) )
return false;
return true;
}

View file

@ -302,25 +302,7 @@ Core::TerritoryMgr::InstanceIdList Core::TerritoryMgr::getInstanceContentIdList(
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;
return movePlayer( pZone, pPlayer );
}
bool Core::TerritoryMgr::movePlayer( ZonePtr pZone, Core::Entity::PlayerPtr pPlayer )
@ -342,8 +324,21 @@ bool Core::TerritoryMgr::movePlayer( ZonePtr pZone, Core::Entity::PlayerPtr pPla
pPlayer->setCurrentZone( pZone );
pZone->pushActor( pPlayer );
// map player to instanceId so it can be tracked.
m_playerIdToInstanceMap[pPlayer->getId()] = pZone->getGuId();
return true;
}
Core::ZonePtr Core::TerritoryMgr::getLinkedInstance( uint32_t playerId ) const
{
auto it = m_playerIdToInstanceMap.find( playerId );
if( it != m_playerIdToInstanceMap.end() )
{
return getInstanceZonePtr( it->second );
}
return nullptr;
}

View file

@ -109,10 +109,12 @@ 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 );
/*! returns an instancePtr if the player is still bound to an isntance */
ZonePtr getLinkedInstance( uint32_t playerId ) const;
private:
using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >;
using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >;
@ -137,6 +139,9 @@ namespace Core
/*! map holding positions for zonelines */
PositionMap m_territoryPositionMap;
/*! map storing playerIds to instanceIds, used for instanceContent */
PlayerIdToInstanceIdMap m_playerIdToInstanceMap;
/*! internal counter for instanceIds */
uint32_t m_lastInstanceId;