1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-07 11:17:46 +00:00

Overhaul of the queued zoning system

This commit is contained in:
Mordred 2022-01-30 14:44:17 +01:00
parent abbeb5fe61
commit 0838881a5b
14 changed files with 320 additions and 124 deletions

View file

@ -595,7 +595,7 @@ int main( int argc, char** argv )
{
std::string entry( &section[ offset ] );
offset += entry.size() + 1;
offset += static_cast< uint32_t >( entry.size() + 1 );
if( entry.size() > 3
&& entry.find_first_not_of( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890_-" ) ==

View file

@ -19,6 +19,7 @@
#include "Manager/RNGMgr.h"
#include "Manager/PlayerMgr.h"
#include "Manager/PartyMgr.h"
#include "Manager/WarpMgr.h"
#include "Territory/Territory.h"
#include "Territory/InstanceContent.h"
@ -86,7 +87,6 @@ Sapphire::Entity::Player::Player() :
m_id = 0;
m_currentStance = Stance::Passive;
m_onlineStatus = 0;
m_queuedZoneing = nullptr;
m_status = ActorStatus::Idle;
m_invincibilityType = InvincibilityType::InvincibilityNone;
m_radius = 1.f;
@ -402,7 +402,8 @@ void Sapphire::Entity::Player::sendStats()
void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
{
auto& exdData = Common::Service< Data::ExdData >::ref();
auto& terriMgr = Common::Service< TerritoryMgr >::ref();
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto& warpMgr = Common::Service< WarpMgr >::ref();
auto aetherData = exdData.getRow< Excel::Aetheryte >( aetheryteId );
@ -411,8 +412,6 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
const auto& data = aetherData->data();
setStateFlag( PlayerStateFlag::BetweenAreas );
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
auto pop = instanceObjectCache.getPopRange( data.TerritoryType, data.PopRange[ 0 ] );
@ -441,35 +440,41 @@ void Sapphire::Entity::Player::teleport( uint16_t aetheryteId, uint8_t type )
aetherytePlace->getString( aetherytePlace->data().Text.SGL ),
data.TerritoryType );
// if it is a teleport in the same zone, we want to do warp instead of moveTerri
bool sameTerritory = getTerritoryTypeId() == data.TerritoryType;
WarpType warpType;
// TODO: this should be simplified and a type created in server_common/common.h.
if( type == 1 ) // teleport
if( type == 1 || type == 2 ) // teleport
{
//prepareZoning( data.TerritoryType, true, 1, 0 ); // TODO: Really?
sendToInRangeSet( makeActorControl( getId(), WarpStart, Common::WarpType::WARP_TYPE_TELEPO ), true );
sendToInRangeSet( makeActorControl( getId(), ActorDespawnEffect, 0x04 ) );
setZoningType( Common::ZoneingType::Teleport );
}
else if( type == 2 ) // aethernet
{
//prepareZoning( data.TerritoryType, true, 1, 112 );
sendToInRangeSet( makeActorControl( getId(), WarpStart, Common::WarpType::WARP_TYPE_TELEPO ), true );
sendToInRangeSet( makeActorControl( getId(), ActorDespawnEffect, 0x04 ) );
warpType = WarpType::WARP_TYPE_TELEPO;
setZoningType( Common::ZoneingType::Teleport );
}
else if( type == 3 ) // return
{
//prepareZoning( data.TerritoryType, true, 1, 111 );
sendToInRangeSet( makeActorControl( getId(), WarpStart, Common::WarpType::WARP_TYPE_HOME_POINT ), true );
sendToInRangeSet( makeActorControl( getId(), ActorDespawnEffect, 0x03 ) );
warpType = WarpType::WARP_TYPE_HOME_POINT;
setZoningType( Common::ZoneingType::Return );
}
m_queuedZoneing = std::make_shared< QueuedZoning >( data.TerritoryType, 0, pos, Util::getTimeMs(), rot );
if( sameTerritory )
warpMgr.requestWarp( *this, warpType, pos, rot );
else
{
auto pTeri = teriMgr.getZoneByTerritoryTypeId( data.TerritoryType );
if( !pTeri )
return;
warpMgr.requestMoveTerritory( *this, warpType, pTeri->getGuId(), pos, rot );
}
}
void Sapphire::Entity::Player::forceZoneing( uint32_t zoneId )
{
m_queuedZoneing = std::make_shared< QueuedZoning >( zoneId, 0, getPos(), Util::getTimeMs(), 0.f );
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto& warpMgr = Common::Service< WarpMgr >::ref();
auto pTeri = teriMgr.getZoneByTerritoryTypeId( zoneId );
if( !pTeri )
return;
warpMgr.requestMoveTerritory( *this, WarpType::WARP_TYPE_NORMAL, pTeri->getGuId(), getPos(), getRot() );
}
void Sapphire::Entity::Player::performZoning( uint16_t territoryTypeId, uint32_t territoryId, const Common::FFXIVARR_POSITION3& pos, float rotation )
@ -478,7 +483,7 @@ void Sapphire::Entity::Player::performZoning( uint16_t territoryTypeId, uint32_t
setRot( rotation );
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
m_onEnterEventDone = false;
setOnEnterEventDone( false );
TerritoryPtr pZone;
if( territoryId != 0 )
@ -499,35 +504,10 @@ void Sapphire::Entity::Player::performZoning( uint16_t territoryTypeId, uint32_t
}
}
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;
// zoning within the same zone won't cause the prev data to be overwritten
if( instance->getTerritoryTypeId() != m_territoryTypeId )
{
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
m_prevTerritoryTypeId = pZone->getTerritoryTypeId();
m_prevTerritoryId = getTerritoryId();
m_prevPos = m_pos;
m_prevRot = m_rot;
}
m_queuedZoneing = std::make_shared< QueuedZoning >( instance->getTerritoryTypeId(), territoryId, m_pos, Util::getTimeMs(), m_rot );
m_pos = pos;
return true;
}
bool Sapphire::Entity::Player::exitInstance()
{
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
auto& warpMgr = Common::Service< WarpMgr >::ref();
resetHp();
resetMp();
@ -537,7 +517,7 @@ bool Sapphire::Entity::Player::exitInstance()
m_territoryTypeId = m_prevTerritoryTypeId;
m_territoryId = m_prevTerritoryId;
m_queuedZoneing = std::make_shared< QueuedZoning >( m_territoryTypeId, getTerritoryId(), m_pos, Util::getTimeMs(), m_rot );
warpMgr.requestMoveTerritory( *this, WarpType::WARP_TYPE_CONTENT_END_RETURN, m_prevTerritoryId, m_prevPos, m_prevRot );
return true;
}
@ -691,8 +671,9 @@ void Sapphire::Entity::Player::resetDiscovery()
void Sapphire::Entity::Player::changePosition( float x, float y, float z, float o )
{
auto& warpMgr = Common::Service< WarpMgr >::ref();
Common::FFXIVARR_POSITION3 pos{ x, y, z };
m_queuedZoneing = std::make_shared< QueuedZoning >( getTerritoryTypeId(), 0, pos, Util::getTimeMs(), o );
warpMgr.requestWarp( *this, Common::WARP_TYPE_NORMAL, pos, getRot() );
}
void Sapphire::Entity::Player::setSystemActionUnlocked( Common::UnlockEntry unlockId )
@ -1046,24 +1027,6 @@ void Sapphire::Entity::Player::unsetStateFlag( Common::PlayerStateFlag flag )
void Sapphire::Entity::Player::update( uint64_t tickCount )
{
// a zoning is pending, lets do it
if( m_queuedZoneing && ( tickCount - m_queuedZoneing->m_queueTime ) > 800 )
{
Common::FFXIVARR_POSITION3 targetPos = m_queuedZoneing->m_targetPosition;
if( getTerritoryTypeId() != m_queuedZoneing->m_targetTerritoryTypeId )
{
Logger::debug( "{}_{}", m_queuedZoneing->m_targetTerritoryTypeId, m_queuedZoneing->m_targetTerritoryId );
performZoning( m_queuedZoneing->m_targetTerritoryTypeId, m_queuedZoneing->m_targetTerritoryId, targetPos, m_queuedZoneing->m_targetRotation );
}
else
{
setPos( targetPos );
sendToInRangeSet( makeWarp( *this, WARP_TYPE_TELEPO, targetPos, m_queuedZoneing->m_targetRotation ), true );
}
m_queuedZoneing.reset();
return;
}
if( m_hp <= 0 && m_status != ActorStatus::Dead )
die();
@ -2198,3 +2161,16 @@ void Sapphire::Entity::Player::setConnected( bool isConnected )
{
m_bIsConnected = isConnected;
}
void Sapphire::Entity::Player::updatePrevTerritory()
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
if( teriMgr.isDefaultTerritory( getTerritoryTypeId() ) )
{
m_prevTerritoryTypeId = getTerritoryTypeId();
m_prevTerritoryId = getTerritoryId();
m_prevPos = m_pos;
m_prevRot = m_rot;
}
}

View file

@ -18,25 +18,6 @@
namespace Sapphire::Entity
{
struct QueuedZoning
{
uint16_t m_targetTerritoryTypeId;
uint32_t m_targetTerritoryId;
Common::FFXIVARR_POSITION3 m_targetPosition;
float m_targetRotation;
uint64_t m_queueTime;
QueuedZoning( uint16_t targetZone, uint32_t targetTerritoryId, const Common::FFXIVARR_POSITION3& targetPosition,
uint64_t queuedTime, float targetRotation ) :
m_targetTerritoryTypeId( targetZone ),
m_targetTerritoryId( targetTerritoryId ),
m_targetPosition( targetPosition ),
m_queueTime( queuedTime ),
m_targetRotation( targetRotation )
{
}
};
/** Class representing the Player
* Inheriting from Actor
*
@ -189,13 +170,13 @@ namespace Sapphire::Entity
/*! return the current amount of crystals of type */
uint32_t getCrystal( uint8_t type ) const;
void updateModels( Common::GearSetSlot equipSlotId, const Sapphire::Item& item );
void updateModels( Common::GearSetSlot equipSlotId, const Item& item );
Common::GearModelSlot equipSlotToModelSlot( Common::GearSetSlot slot );
bool getFreeInventoryContainerSlot( Inventory::InventoryContainerPair& containerPair ) const;
void insertInventoryItem( Common::InventoryType type, uint16_t slot, const Sapphire::ItemPtr item );
void insertInventoryItem( Common::InventoryType type, uint16_t slot, const ItemPtr item );
/*!
* Collect real item handins from container
@ -304,15 +285,14 @@ namespace Sapphire::Entity
/*! return current online status depending on current state / activity */
Common::OnlineStatus getOnlineStatus() const;
/*! sets the players instance & initiates zoning process */
bool setInstance( uint32_t territoryId, Sapphire::Common::FFXIVARR_POSITION3 pos );
/*! returns the player to their position before zoning into an instance */
bool exitInstance();
/*! gets the players territoryTypeId */
uint32_t getPrevTerritoryTypeId() const;
void updatePrevTerritory();
void forceZoneing( uint32_t zoneId );
/*! change position, sends update too */
@ -625,7 +605,7 @@ namespace Sapphire::Entity
const std::map< uint32_t, uint8_t >& getActorIdToHateSlotMap();
Sapphire::Entity::GameObjectPtr lookupTargetById( uint64_t targetId );
Entity::GameObjectPtr lookupTargetById( uint64_t targetId );
bool isLogin() const;
@ -730,7 +710,7 @@ namespace Sapphire::Entity
InvSlotPair getFreeBagSlot();
Sapphire::ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false, bool canMerge = true );
ItemPtr addItem( uint32_t catalogId, uint32_t quantity = 1, bool isHq = false, bool slient = false, bool canMerge = true );
void moveItem( uint16_t fromInventoryId, uint16_t fromSlotId, uint16_t toInventoryId, uint16_t toSlot );
@ -781,7 +761,7 @@ namespace Sapphire::Entity
void setActiveLand( uint8_t land, uint8_t ward );
Common::ActiveLand getActiveLand() const;
Sapphire::ItemPtr dropInventoryItem( Common::InventoryType storageId, uint8_t slotId );
ItemPtr dropInventoryItem( Common::InventoryType storageId, uint8_t slotId );
//////////////////////////////////////////////////////////////////////////////////////////////////////
@ -823,7 +803,7 @@ namespace Sapphire::Entity
/*! queue a packet for the player */
void queuePacket( Network::Packets::FFXIVPacketBasePtr pPacket );
using InventoryMap = std::map< uint16_t, Sapphire::ItemContainerPtr >;
using InventoryMap = std::map< uint16_t, ItemContainerPtr >;
uint64_t m_lastDBWrite;
@ -928,7 +908,6 @@ namespace Sapphire::Entity
bool m_bNewAdventurer{};
uint64_t m_onlineStatus;
uint64_t m_onlineStatusCustom;
std::shared_ptr< QueuedZoning > m_queuedZoneing;
// search info
char m_searchMessage[193]{}; // searchmessage to show in profile

View file

@ -15,7 +15,7 @@
#include "Territory/QuestBattle.h"
#include "TerritoryMgr.h"
#include "HousingMgr.h"
#include "WarpMgr.h"
#include "Linkshell/Linkshell.h"
#include "Territory/Land.h"
@ -658,8 +658,8 @@ void TerritoryMgr::createAndJoinQuestBattle( Entity::Player& player, uint16_t qu
if( !qb )
return;
//player.setInstance( qb->getGuId(), { 0, 0, 0 } );
auto& warpMgr = Common::Service< WarpMgr >::ref();
warpMgr.requestMoveTerritory( player, Common::WARP_TYPE_INSTANCE_CONTENT, qb->getGuId(), { 0, 0, 0 }, 0 );
}
bool TerritoryMgr::joinWorld( Entity::Player& player )

View file

@ -3,6 +3,76 @@
#include "TaskMgr.h"
#include "WarpMgr.h"
#include "TerritoryMgr.h"
#include <WorldServer.h>
#include "Task/MoveTerritoryTask.h"
#include "Task/WarpTask.h"
#include <Network/CommonActorControl.h>
#include "Territory/Territory.h"
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
#include "Network/PacketWrappers/ActorControlPacket.h"
#include "Network/PacketWrappers/WarpPacket.h"
#include "Actor/Player.h"
using namespace Sapphire::World::Manager;
using namespace Sapphire::World;
using namespace Sapphire;
using namespace Sapphire::Common;
using namespace Sapphire::Network::ActorControl;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType warpType,
uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot )
{
m_entityIdToWarpInfoMap[ player.getId() ] = { targetTerritoryId, warpType, targetPos, targetRot };
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto& server = Common::Service< WorldServer >::ref();
auto pTeri = teriMgr.getTerritoryByGuId( targetTerritoryId );
if( !pTeri )
return;
player.updatePrevTerritory();
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, pTeri->getTerritoryTypeId() ), true );
player.sendToInRangeSet( makeActorControl( player.getId(), ActorDespawnEffect, warpType ) );
player.setStateFlag( PlayerStateFlag::BetweenAreas );
auto moveTerritoryPacket = makeZonePacket< FFXIVIpcMoveTerritory >( player.getId() );
moveTerritoryPacket->data().index = -1;
moveTerritoryPacket->data().territoryType = pTeri->getTerritoryTypeId();
moveTerritoryPacket->data().zoneId = player.getTerritoryTypeId();
moveTerritoryPacket->data().worldId = server.getWorldId();
moveTerritoryPacket->data().worldId1 = server.getWorldId();
moveTerritoryPacket->data().landId = -1;
moveTerritoryPacket->data().landSetId = -1;
moveTerritoryPacket->data().landTerritoryId = -1;
strcpy( moveTerritoryPacket->data().worldName, "Sapphire" );
server.queueForPlayer( player.getCharacterId(), moveTerritoryPacket );
// create warp task
auto& taskMgr = Common::Service< TaskMgr >::ref();
taskMgr.queueTask( makeMoveTerritoryTask( player, warpType, targetTerritoryId, targetPos, targetRot, 2000 ) );
}
void WarpMgr::finishWarp( Entity::Player& player )
{
}
void WarpMgr::requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot )
{
m_entityIdToWarpInfoMap[ player.getId() ] = { 0, warpType, targetPos, targetRot };
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto& server = Common::Service< WorldServer >::ref();
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, player.getTerritoryTypeId(), 1 ), true );
player.sendToInRangeSet( makeActorControl( player.getId(), ActorDespawnEffect, warpType ) );
auto& taskMgr = Common::Service< TaskMgr >::ref();
taskMgr.queueTask( makeWarpTask( player, warpType, targetPos, targetRot, 1000 ) );
}

View file

@ -11,17 +11,22 @@ namespace Sapphire::World::Manager
struct WarpInfo
{
uint32_t targetTerritoryId;
uint32_t m_targetTerritoryId;
Common::WarpType m_warpType;
Common::FFXIVARR_POSITION3 m_targetPos;
float m_targetRot;
};
class WarpMgr
{
public:
WarpMgr() = default;
void requestMoveTerritory( Entity::Player& player, Common::WarpType warpType, uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
void requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
void finishWarp( Entity::Player& player );
private:
std::unordered_map< uint32_t, std::shared_ptr< WarpInfo > > m_entityIdToWarpInfoMap;
std::unordered_map< uint32_t, WarpInfo > m_entityIdToWarpInfoMap;
};

View file

@ -14,6 +14,7 @@
#include "Manager/TerritoryMgr.h"
#include "Manager/PlayerMgr.h"
#include "Manager/WarpMgr.h"
#include "Territory/Territory.h"
#include "Territory/InstanceContent.h"
@ -471,6 +472,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
case GmCommand::Teri:
{
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
auto& warpMgr = Common::Service< WarpMgr >::ref();
if( auto instance = teriMgr.getTerritoryByGuId( param1 ) )
{
PlayerMgr::sendDebug( player, "Found instance: {0}, id#{1}", instance->getName(), param1 );
@ -485,8 +487,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
PlayerMgr::sendUrgent( player, "Player not bound! ( run !instance bind <instanceId> first ) {0}", param1 );
break;
}
player.setInstance( param1, { 0, 0, 0 } );
warpMgr.requestMoveTerritory( player, WarpType::WARP_TYPE_INSTANCE_CONTENT, param1, { 0.f, 0.f, 0.f }, 0.f );
}
else if( !teriMgr.isValidTerritory( param1 ) )
{

View file

@ -50,6 +50,7 @@
#include "Manager/LinkshellMgr.h"
#include "Manager/PartyMgr.h"
#include "Manager/PlayerMgr.h"
#include "Manager/WarpMgr.h"
#include "Action/Action.h"
@ -337,27 +338,17 @@ void Sapphire::Network::GameConnection::zoneJumpHandler( const Packets::FFXIVARR
pPopRange->header.transform.rotation.z,
rotation );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), WarpStart,
Common::WarpType::WARP_TYPE_EXIT_RANGE, player.getId(), 0x01, targetZone ) );
auto moveTerritoryPacket = makeZonePacket< FFXIVIpcMoveTerritory >( player.getId() );
moveTerritoryPacket->data().index = -1;
moveTerritoryPacket->data().territoryType = targetZone;
moveTerritoryPacket->data().zoneId = player.getTerritoryTypeId();
moveTerritoryPacket->data().worldId = server.getWorldId();
moveTerritoryPacket->data().worldId1 = server.getWorldId();
moveTerritoryPacket->data().landId = -1;
moveTerritoryPacket->data().landSetId = -1;
moveTerritoryPacket->data().landTerritoryId = -1;
strcpy( moveTerritoryPacket->data().worldName, "Sapphire" );
server.queueForPlayer( player.getCharacterId(), moveTerritoryPacket );
}
}
PlayerMgr::sendDebug( player, "Walking ZoneLine#{0}", exitBoxId );
auto pTargetTeri = teriMgr.getZoneByTerritoryTypeId( targetZone );
if( !pTargetTeri )
return;
auto& warpMgr = Common::Service< WarpMgr >::ref();
warpMgr.requestMoveTerritory( player, Common::WARP_TYPE_EXIT_RANGE, pTargetTeri->getGuId(), targetPos, rotation );
player.performZoning( targetZone, 0, targetPos, rotation );
}

View file

@ -6,6 +6,7 @@
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Common.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
namespace Sapphire::Network::Packets::WorldPackets::Server
{
@ -16,14 +17,14 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
class WarpPacket : public ZoneChannelPacket< FFXIVIpcWarp >
{
public:
WarpPacket( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3& targetPos, float rotation ) :
ZoneChannelPacket< FFXIVIpcWarp >( player.getId(), player.getId() )
WarpPacket( uint32_t playerId, Common::WarpType warpType, Common::FFXIVARR_POSITION3& targetPos, float rotation ) :
ZoneChannelPacket< FFXIVIpcWarp >( playerId, playerId )
{
initialize( player, warpType, targetPos, rotation );
initialize( warpType, targetPos, rotation );
};
private:
void initialize( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3& targetPos, float rotation )
void initialize( Common::WarpType warpType, Common::FFXIVARR_POSITION3& targetPos, float rotation )
{
m_data.Dir = Sapphire::Common::Util::floatToUInt16Rot( rotation );
m_data.Type = warpType;

View file

@ -0,0 +1,58 @@
#include "MoveTerritoryTask.h"
#include <Logging/Logger.h>
#include <Actor/Player.h>
#include <WorldServer.h>
#include <Service.h>
#include <Manager/TerritoryMgr.h>
using namespace Sapphire::World;
using namespace Sapphire::World::Manager;
MoveTerritoryTask::MoveTerritoryTask( Entity::Player& player, Common::WarpType warpType,
uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot, uint64_t delayTime ) : Task( delayTime )
{
m_playerId = player.getId();
m_warpInfo = { targetTerritoryId, warpType, targetPos, targetRot };
}
void MoveTerritoryTask::onQueue()
{
Logger::debug( { __FUNCTION__ } );
}
void MoveTerritoryTask::execute()
{
auto& server = Common::Service< WorldServer >::ref();
auto pPlayer = server.getPlayer( m_playerId );
if( !pPlayer )
return;
pPlayer->setPos( m_warpInfo.m_targetPos, false );
pPlayer->setRot( m_warpInfo.m_targetRot );
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
pPlayer->setOnEnterEventDone( false );
TerritoryPtr pZone;
if( m_warpInfo.m_targetTerritoryId != 0 )
pZone = teriMgr.getTerritoryByGuId( m_warpInfo.m_targetTerritoryId );
if( !teriMgr.movePlayer( pZone, *pPlayer ) )
{
// todo: this will require proper handling, for now just return the player to their previous area
pPlayer->setPos( pPlayer->getPrevPos(), false );
auto pZone1 = teriMgr.getZoneByTerritoryTypeId( pPlayer->getPrevTerritoryTypeId() );
if( !teriMgr.movePlayer( pZone1, *pPlayer ) )
return;
}
}
std::string MoveTerritoryTask::toString()
{
return fmt::format( "MoveTerritoryTask: Player#{}, TerritoryId#{}, ElapsedTimeMs: {}", m_playerId, m_warpInfo.m_targetTerritoryId, getDelayTimeMs() );
}

View file

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <string>
#include <ForwardsZone.h>
#include "Task.h"
#include "Manager/WarpMgr.h"
namespace Sapphire::World
{
class MoveTerritoryTask : public Task
{
public:
MoveTerritoryTask( Entity::Player& player, Common::WarpType warpType,
uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot, uint64_t delayTime );
void onQueue() override;
void execute() override;
std::string toString() override;
private:
Manager::WarpInfo m_warpInfo;
uint32_t m_playerId;
};
template< typename... Args >
std::shared_ptr< MoveTerritoryTask > makeMoveTerritoryTask( Args... args )
{
return std::make_shared< MoveTerritoryTask >( args... );
}
}

View file

@ -0,0 +1,44 @@
#include "WarpTask.h"
#include <Logging/Logger.h>
#include <Actor/Player.h>
#include <WorldServer.h>
#include <Service.h>
#include <Network/PacketWrappers/WarpPacket.h>
#include <Manager/TerritoryMgr.h>
using namespace Sapphire::World;
using namespace Sapphire::World::Manager;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::WorldPackets::Server;
WarpTask::WarpTask( Entity::Player& player, Common::WarpType warpType,
Common::FFXIVARR_POSITION3 targetPos, float targetRot, uint64_t delayTime ) : Task( delayTime )
{
m_playerId = player.getId();
m_warpInfo = { 0, warpType, targetPos, targetRot };
}
void WarpTask::onQueue()
{
Logger::debug( { __FUNCTION__ } );
}
void WarpTask::execute()
{
auto& server = Common::Service< WorldServer >::ref();
auto pPlayer = server.getPlayer( m_playerId );
if( !pPlayer )
return;
pPlayer->setPos( m_warpInfo.m_targetPos, false );
pPlayer->sendToInRangeSet( makeWarp( pPlayer->getId(), m_warpInfo.m_warpType, m_warpInfo.m_targetPos, m_warpInfo.m_targetRot ), true );
}
std::string WarpTask::toString()
{
return fmt::format( "WarpTask: Player#{}, TerritoryId#{}, ElapsedTimeMs: {}", m_playerId, m_warpInfo.m_targetTerritoryId, getDelayTimeMs() );
}

34
src/world/Task/WarpTask.h Normal file
View file

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <string>
#include <ForwardsZone.h>
#include "Task.h"
#include "Manager/WarpMgr.h"
namespace Sapphire::World
{
class WarpTask : public Task
{
public:
WarpTask( Entity::Player& player, Common::WarpType warpType,
Common::FFXIVARR_POSITION3 targetPos, float targetRot, uint64_t delayTime );
void onQueue() override;
void execute() override;
std::string toString() override;
private:
Manager::WarpInfo m_warpInfo;
uint32_t m_playerId;
};
template< typename... Args >
std::shared_ptr< WarpTask > makeWarpTask( Args... args )
{
return std::make_shared< WarpTask >( args... );
}
}

View file

@ -47,6 +47,7 @@
#include "Manager/PartyMgr.h"
#include "Manager/FriendListMgr.h"
#include "Manager/BlacklistMgr.h"
#include "Manager/WarpMgr.h"
#include "ContentFinder/ContentFinder.h"
@ -247,6 +248,7 @@ void WorldServer::run( int32_t argc, char* argv[] )
auto pBlacklistMgr = std::make_shared< Manager::BlacklistMgr >();
auto contentFinder = std::make_shared< ContentFinder >();
auto taskMgr = std::make_shared< Manager::TaskMgr >();
auto warpMgr = std::make_shared< Manager::WarpMgr >();
Common::Service< DebugCommandMgr >::set( pDebugCom );
Common::Service< Manager::PlayerMgr >::set( pPlayerMgr );
@ -260,6 +262,7 @@ void WorldServer::run( int32_t argc, char* argv[] )
Common::Service< Manager::BlacklistMgr >::set( pBlacklistMgr );
Common::Service< ContentFinder >::set( contentFinder );
Common::Service< Manager::TaskMgr >::set( taskMgr );
Common::Service< Manager::WarpMgr >::set( warpMgr );
Logger::info( "World server running on {0}:{1}", m_ip, m_port );