mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 16:57:47 +00:00
move teleport to warpmgr; more player to playermgr; cleanup;
This commit is contained in:
parent
2b57b73471
commit
88f8c7c19a
17 changed files with 184 additions and 120 deletions
|
@ -587,7 +587,7 @@ namespace Sapphire::Common
|
||||||
WaterCluster = 0x12
|
WaterCluster = 0x12
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct ZoneingType : uint8_t
|
enum struct ZoningType : uint8_t
|
||||||
{
|
{
|
||||||
None = 1,
|
None = 1,
|
||||||
Teleport = 2,
|
Teleport = 2,
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <ScriptObject.h>
|
#include <ScriptObject.h>
|
||||||
#include <Actor/Player.h>
|
#include <Actor/Player.h>
|
||||||
#include <Action/Action.h>
|
#include <Action/Action.h>
|
||||||
|
#include <Manager/PlayerMgr.h>
|
||||||
|
#include <Service.h>
|
||||||
|
|
||||||
class ActionReturn6 :
|
class ActionReturn6 :
|
||||||
public Sapphire::ScriptAPI::ActionScript
|
public Sapphire::ScriptAPI::ActionScript
|
||||||
|
@ -17,7 +19,9 @@ public:
|
||||||
if( !action.getSourceChara()->isPlayer() )
|
if( !action.getSourceChara()->isPlayer() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
action.getSourceChara()->getAsPlayer()->teleport( action.getSourceChara()->getAsPlayer()->getHomepoint(), 3 );
|
auto pPlayer = action.getSourceChara()->getAsPlayer();
|
||||||
|
|
||||||
|
warpMgr().requestPlayerTeleport( *pPlayer, pPlayer->getHomepoint(), 3 );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,26 +16,27 @@ public:
|
||||||
|
|
||||||
void onExecute( Sapphire::World::Action::Action& action ) override
|
void onExecute( Sapphire::World::Action::Action& action ) override
|
||||||
{
|
{
|
||||||
auto player = action.getSourceChara()->getAsPlayer();
|
auto pPlayer = action.getSourceChara()->getAsPlayer();
|
||||||
|
|
||||||
if( !player )
|
if( !pPlayer )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto teleportQuery = player->getTeleportQuery();
|
auto teleportQuery = pPlayer->getTeleportQuery();
|
||||||
|
|
||||||
if( player->getCurrency( Common::CurrencyType::Gil ) < teleportQuery.cost ||
|
if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < teleportQuery.cost ||
|
||||||
teleportQuery.targetAetheryte == 0 )
|
teleportQuery.targetAetheryte == 0 )
|
||||||
{
|
{
|
||||||
action.interrupt();
|
action.interrupt();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
player->removeCurrency( Common::CurrencyType::Gil, teleportQuery.cost );
|
pPlayer->removeCurrency( Common::CurrencyType::Gil, teleportQuery.cost );
|
||||||
|
|
||||||
player->setZoningType( Common::ZoneingType::Teleport );
|
pPlayer->setZoningType( Common::ZoningType::Teleport );
|
||||||
player->teleport( teleportQuery.targetAetheryte );
|
|
||||||
|
|
||||||
player->clearTeleportQuery();
|
warpMgr().requestPlayerTeleport( *pPlayer, teleportQuery.targetAetheryte, 1 );
|
||||||
|
|
||||||
|
pPlayer->clearTeleportQuery();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
auto destination = result.getResult( 0 );
|
auto destination = result.getResult( 0 );
|
||||||
if( result.numOfResults == 1 && destination != 0 )
|
if( result.numOfResults == 1 && destination != 0 )
|
||||||
{
|
{
|
||||||
player.teleport( destination, 2 );
|
warpMgr().requestPlayerTeleport( player, destination, 2 );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ public:
|
||||||
auto data = result.getResult( 1 );
|
auto data = result.getResult( 1 );
|
||||||
if( cmd == 4 && data != 0 )
|
if( cmd == 4 && data != 0 )
|
||||||
{
|
{
|
||||||
player.teleport( data, 2 );
|
warpMgr().requestPlayerTeleport( player, data, 2 );
|
||||||
}
|
}
|
||||||
else if( cmd == 2 ) // register favored destination
|
else if( cmd == 2 ) // register favored destination
|
||||||
{
|
{
|
||||||
|
|
|
@ -101,8 +101,8 @@ private:
|
||||||
|
|
||||||
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
void Scene00001Return( World::Quest& quest, Entity::Player& player, const Event::SceneResult& result )
|
||||||
{
|
{
|
||||||
player.setGc( OrderOfTwinAdder );
|
playerMgr().onSetGc( player, OrderOfTwinAdder );
|
||||||
player.setGcRankAt( OrderOfTwinAdder, 1 );
|
playerMgr().onSetGcRank( player, OrderOfTwinAdder, 1 );
|
||||||
Scene00002( quest, player );
|
Scene00002( quest, player );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ Player::Player() :
|
||||||
m_lastActionTick( 0 ),
|
m_lastActionTick( 0 ),
|
||||||
m_bInCombat( false ),
|
m_bInCombat( false ),
|
||||||
m_bLoadingComplete( false ),
|
m_bLoadingComplete( false ),
|
||||||
m_zoningType( Common::ZoneingType::None ),
|
m_zoningType( Common::ZoningType::None ),
|
||||||
m_bAutoattack( false ),
|
m_bAutoattack( false ),
|
||||||
m_markedForRemoval( false ),
|
m_markedForRemoval( false ),
|
||||||
m_mount( 0 ),
|
m_mount( 0 ),
|
||||||
|
@ -403,72 +403,6 @@ void Player::sendStats()
|
||||||
Service< World::Manager::PlayerMgr >::ref().onSendStats( *this );
|
Service< World::Manager::PlayerMgr >::ref().onSendStats( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::teleport( uint16_t aetheryteId, uint8_t type )
|
|
||||||
{
|
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
|
||||||
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
|
|
||||||
auto& warpMgr = Common::Service< WarpMgr >::ref();
|
|
||||||
|
|
||||||
auto aetherData = exdData.getRow< Excel::Aetheryte >( aetheryteId );
|
|
||||||
|
|
||||||
if( !aetherData )
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto& data = aetherData->data();
|
|
||||||
|
|
||||||
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
|
|
||||||
auto pop = instanceObjectCache.getPopRangeInfo( data.PopRange[ 0 ] );
|
|
||||||
|
|
||||||
Common::FFXIVARR_POSITION3 pos{ 0.f, 0.f, 0.f };
|
|
||||||
|
|
||||||
float rot = 0.f;
|
|
||||||
|
|
||||||
if( pop )
|
|
||||||
{
|
|
||||||
PlayerMgr::sendDebug( *this, "Teleport: popRange {0} found!", data.PopRange[ 0 ] );
|
|
||||||
pos = pop->m_pos;
|
|
||||||
rot = pop->m_rotation;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PlayerMgr::sendDebug( *this, "Teleport: popRange {0} not found in {1}!", data.PopRange[ 0 ], data.TerritoryType );
|
|
||||||
}
|
|
||||||
|
|
||||||
auto townPlace = exdData.getRow< Excel::PlaceName >( data.TelepoName );
|
|
||||||
auto aetherytePlace = exdData.getRow< Excel::PlaceName >( data.TransferName );
|
|
||||||
|
|
||||||
PlayerMgr::sendDebug( *this, "Teleport: {0} - {1} ({2})",
|
|
||||||
townPlace->getString( townPlace->data().Text.SGL ),
|
|
||||||
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 = WarpType::WARP_TYPE_NORMAL;
|
|
||||||
// TODO: this should be simplified and a type created in server_common/common.h.
|
|
||||||
if( type == 1 || type == 2 ) // teleport
|
|
||||||
{
|
|
||||||
warpType = WarpType::WARP_TYPE_TELEPO;
|
|
||||||
setZoningType( Common::ZoneingType::Teleport );
|
|
||||||
}
|
|
||||||
else if( type == 3 ) // return
|
|
||||||
{
|
|
||||||
warpType = WarpType::WARP_TYPE_HOME_POINT;
|
|
||||||
setZoningType( Common::ZoneingType::Return );
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Player::forceZoneing( uint32_t zoneId )
|
void Player::forceZoneing( uint32_t zoneId )
|
||||||
{
|
{
|
||||||
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
|
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
|
||||||
|
@ -733,6 +667,7 @@ void Player::levelUp()
|
||||||
|
|
||||||
void Player::sendStatusUpdate()
|
void Player::sendStatusUpdate()
|
||||||
{
|
{
|
||||||
|
// todo: overrides are funky
|
||||||
Service< World::Manager::PlayerMgr >::ref().onPlayerHpMpTpChanged( *this );
|
Service< World::Manager::PlayerMgr >::ref().onPlayerHpMpTpChanged( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -924,15 +859,11 @@ void Player::setVoiceId( uint8_t voiceId )
|
||||||
void Player::setGc( uint8_t gc )
|
void Player::setGc( uint8_t gc )
|
||||||
{
|
{
|
||||||
m_gc = gc;
|
m_gc = gc;
|
||||||
|
|
||||||
Service< World::Manager::PlayerMgr >::ref().onGcUpdate( *this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setGcRankAt( uint8_t index, uint8_t rank )
|
void Player::setGcRankAt( uint8_t index, uint8_t rank )
|
||||||
{
|
{
|
||||||
m_gcRank[ index ] = rank;
|
m_gcRank[ index ] = rank;
|
||||||
|
|
||||||
Service< World::Manager::PlayerMgr >::ref().onGcUpdate( *this );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Player::StateFlags& Player::getStateFlags() const
|
const Player::StateFlags& Player::getStateFlags() const
|
||||||
|
@ -1134,12 +1065,12 @@ void Player::setLoadingComplete( bool bComplete )
|
||||||
m_bLoadingComplete = bComplete;
|
m_bLoadingComplete = bComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZoneingType Player::getZoningType() const
|
ZoningType Player::getZoningType() const
|
||||||
{
|
{
|
||||||
return m_zoningType;
|
return m_zoningType;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::setZoningType( Common::ZoneingType zoneingType )
|
void Player::setZoningType( Common::ZoningType zoneingType )
|
||||||
{
|
{
|
||||||
m_zoningType = zoneingType;
|
m_zoningType = zoneingType;
|
||||||
}
|
}
|
||||||
|
@ -1552,7 +1483,8 @@ void Player::dyeItemFromDyeingInfo()
|
||||||
uint32_t dyeBagContainer = m_dyeingInfo.dyeBagContainer;
|
uint32_t dyeBagContainer = m_dyeingInfo.dyeBagContainer;
|
||||||
uint32_t dyeBagSlot = m_dyeingInfo.dyeBagSlot;
|
uint32_t dyeBagSlot = m_dyeingInfo.dyeBagSlot;
|
||||||
|
|
||||||
sendStateFlags(); // Retail sends all 0s to unlock player after a dye? Possibly not setting a flag when the action is started in the backend..?
|
Service< World::Manager::PlayerMgr >::ref().onSendStateFlags( *this, true ); // Retail sends all 0s to unlock player after a dye? Possibly not setting a flag when the action is started in the backend..?
|
||||||
|
|
||||||
auto itemToDye = getItemAt( itemToDyeContainer, itemToDyeSlot );
|
auto itemToDye = getItemAt( itemToDyeContainer, itemToDyeSlot );
|
||||||
auto dyeToUse = getItemAt( dyeBagContainer, dyeBagSlot );
|
auto dyeToUse = getItemAt( dyeBagContainer, dyeBagSlot );
|
||||||
|
|
||||||
|
|
|
@ -347,9 +347,6 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
uint64_t getFullOnlineStatusMask() const;
|
uint64_t getFullOnlineStatusMask() const;
|
||||||
|
|
||||||
/*! perform a teleport of a specified type ( teleport,return,aethernet ) */
|
|
||||||
void teleport( uint16_t aetheryteId, uint8_t type = 1 );
|
|
||||||
|
|
||||||
/*! query teleport of a specified type */
|
/*! query teleport of a specified type */
|
||||||
void teleportQuery( uint16_t aetheryteId );
|
void teleportQuery( uint16_t aetheryteId );
|
||||||
|
|
||||||
|
@ -574,9 +571,6 @@ namespace Sapphire::Entity
|
||||||
/*! send current models ( equipment ) */
|
/*! send current models ( equipment ) */
|
||||||
void sendModel();
|
void sendModel();
|
||||||
|
|
||||||
/*! send active state flags */
|
|
||||||
void sendStateFlags( bool updateInRange = true );
|
|
||||||
|
|
||||||
/*! send status update */
|
/*! send status update */
|
||||||
void sendStatusUpdate() override;
|
void sendStatusUpdate() override;
|
||||||
|
|
||||||
|
@ -589,9 +583,9 @@ namespace Sapphire::Entity
|
||||||
/*! set the loading complete bool */
|
/*! set the loading complete bool */
|
||||||
void setLoadingComplete( bool bComplete );
|
void setLoadingComplete( bool bComplete );
|
||||||
|
|
||||||
Common::ZoneingType getZoningType() const;
|
Common::ZoningType getZoningType() const;
|
||||||
|
|
||||||
void setZoningType( Common::ZoneingType zoneingType );
|
void setZoningType( Common::ZoningType zoneingType );
|
||||||
|
|
||||||
void setSearchInfo( uint8_t selectRegion, uint8_t selectClass, const char* searchMessage );
|
void setSearchInfo( uint8_t selectRegion, uint8_t selectClass, const char* searchMessage );
|
||||||
|
|
||||||
|
@ -926,7 +920,7 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
bool m_bIsConnected;
|
bool m_bIsConnected;
|
||||||
|
|
||||||
Common::ZoneingType m_zoningType;
|
Common::ZoningType m_zoningType;
|
||||||
|
|
||||||
bool m_bNewAdventurer{};
|
bool m_bNewAdventurer{};
|
||||||
uint64_t m_onlineStatus;
|
uint64_t m_onlineStatus;
|
||||||
|
|
|
@ -132,7 +132,7 @@ namespace Sapphire::World::Manager
|
||||||
if( !pAchv )
|
if( !pAchv )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto achvExdData = pAchv->data();
|
auto& achvExdData = pAchv->data();
|
||||||
|
|
||||||
if( achvExdData.ConditionArg[ 1 ] <= static_cast< int32_t >( achvData.progressData[ dataKey.u32 ] ) )
|
if( achvExdData.ConditionArg[ 1 ] <= static_cast< int32_t >( achvData.progressData[ dataKey.u32 ] ) )
|
||||||
unlockAchievement( player, achvId );
|
unlockAchievement( player, achvId );
|
||||||
|
|
|
@ -217,7 +217,7 @@ void DebugCommandMgr::set( char* data, Entity::Player& player, std::shared_ptr<
|
||||||
int32_t aetheryteId;
|
int32_t aetheryteId;
|
||||||
sscanf( params.c_str(), "%i", &aetheryteId );
|
sscanf( params.c_str(), "%i", &aetheryteId );
|
||||||
|
|
||||||
player.teleport( static_cast< uint16_t >( aetheryteId ) );
|
Common::Service< WarpMgr >::ref().requestPlayerTeleport( player, static_cast< uint16_t >( aetheryteId ), 1 );
|
||||||
}
|
}
|
||||||
else if( ( subCommand == "discovery" ) && ( !params.empty() ) )
|
else if( ( subCommand == "discovery" ) && ( !params.empty() ) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -231,14 +231,30 @@ void PlayerMgr::onChangeGear( Entity::Player& player )
|
||||||
void PlayerMgr::onGcUpdate( Entity::Player& player )
|
void PlayerMgr::onGcUpdate( Entity::Player& player )
|
||||||
{
|
{
|
||||||
auto& server = Common::Service< World::WorldServer >::ref();
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
|
|
||||||
auto gcAffPacket = makeZonePacket< FFXIVIpcGrandCompany >( player.getId() );
|
auto gcAffPacket = makeZonePacket< FFXIVIpcGrandCompany >( player.getId() );
|
||||||
gcAffPacket->data().ActiveCompanyId = player.getGc();
|
gcAffPacket->data().ActiveCompanyId = player.getGc();
|
||||||
gcAffPacket->data().MaelstromRank = player.getGcRankArray()[ 0 ];
|
gcAffPacket->data().MaelstromRank = player.getGcRankArray()[ 0 ];
|
||||||
gcAffPacket->data().TwinAdderRank = player.getGcRankArray()[ 1 ];
|
gcAffPacket->data().TwinAdderRank = player.getGcRankArray()[ 1 ];
|
||||||
gcAffPacket->data().ImmortalFlamesRank = player.getGcRankArray()[ 2 ];
|
gcAffPacket->data().ImmortalFlamesRank = player.getGcRankArray()[ 2 ];
|
||||||
|
|
||||||
server.queueForPlayer( player.getCharacterId(), gcAffPacket );
|
server.queueForPlayer( player.getCharacterId(), gcAffPacket );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlayerMgr::onSetGc( Entity::Player& player, uint8_t gc )
|
||||||
|
{
|
||||||
|
player.setGc( gc );
|
||||||
|
|
||||||
|
onGcUpdate( player );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerMgr::onSetGcRank( Entity::Player& player, uint8_t gc, uint8_t rank )
|
||||||
|
{
|
||||||
|
player.setGcRankAt( gc, rank );
|
||||||
|
|
||||||
|
onGcUpdate( player );
|
||||||
|
}
|
||||||
|
|
||||||
void PlayerMgr::onCompanionUpdate( Entity::Player& player, uint8_t companionId )
|
void PlayerMgr::onCompanionUpdate( Entity::Player& player, uint8_t companionId )
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
|
@ -326,13 +342,13 @@ void PlayerMgr::onHateListChanged( Entity::Player& player )
|
||||||
server.queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } );
|
server.queueForPlayer( player.getCharacterId(), { hateListPacket, hateRankPacket } );
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerMgr::onChangeClass( Entity::Player &player )
|
void PlayerMgr::onChangeClass( Entity::Player& player )
|
||||||
{
|
{
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ClassJobChange, 0x04 ), true );
|
player.sendToInRangeSet( makeActorControl( player.getId(), ClassJobChange, 0x04 ), true );
|
||||||
player.sendStatusUpdate();
|
onPlayerHpMpTpChanged( player );
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerMgr::onLogin( Entity::Player &player )
|
void PlayerMgr::onLogin( Entity::Player& player )
|
||||||
{
|
{
|
||||||
auto& server = Common::Service< World::WorldServer >::ref();
|
auto& server = Common::Service< World::WorldServer >::ref();
|
||||||
|
|
||||||
|
@ -346,7 +362,7 @@ void PlayerMgr::onLogin( Entity::Player &player )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerMgr::onDeath( Entity::Player &player )
|
void PlayerMgr::onDeath( Entity::Player& player )
|
||||||
{
|
{
|
||||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||||
scriptMgr.onPlayerDeath( player );
|
scriptMgr.onPlayerDeath( player );
|
||||||
|
|
|
@ -44,6 +44,10 @@ class PlayerMgr
|
||||||
|
|
||||||
void onGcUpdate( Sapphire::Entity::Player& player );
|
void onGcUpdate( Sapphire::Entity::Player& player );
|
||||||
|
|
||||||
|
void onSetGc( Sapphire::Entity::Player& player, uint8_t gc );
|
||||||
|
|
||||||
|
void onSetGcRank( Sapphire::Entity::Player& player, uint8_t gc, uint8_t rank );
|
||||||
|
|
||||||
void onCompanionUpdate( Entity::Player& player, uint8_t companionId );
|
void onCompanionUpdate( Entity::Player& player, uint8_t companionId );
|
||||||
|
|
||||||
void onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountId );
|
void onMountUpdate( Sapphire::Entity::Player& player, uint32_t mountId );
|
||||||
|
|
|
@ -6,14 +6,20 @@
|
||||||
|
|
||||||
#include <WorldServer.h>
|
#include <WorldServer.h>
|
||||||
#include <Logging/Logger.h>
|
#include <Logging/Logger.h>
|
||||||
|
#include <Exd/ExdData.h>
|
||||||
|
|
||||||
#include "Task/MoveTerritoryTask.h"
|
#include "Task/MoveTerritoryTask.h"
|
||||||
#include "Task/WarpTask.h"
|
#include "Task/WarpTask.h"
|
||||||
|
|
||||||
#include <Network/CommonActorControl.h>
|
#include <Network/CommonActorControl.h>
|
||||||
|
#include <Network/PacketWrappers/ActorControlSelfPacket.h>
|
||||||
|
#include <Network/PacketWrappers/ActorControlPacket.h>
|
||||||
|
|
||||||
|
#include <Manager/PlayerMgr.h>
|
||||||
|
|
||||||
#include "Territory/Territory.h"
|
#include "Territory/Territory.h"
|
||||||
#include "Network/PacketWrappers/ActorControlSelfPacket.h"
|
|
||||||
#include "Network/PacketWrappers/ActorControlPacket.h"
|
|
||||||
#include "Actor/Player.h"
|
#include "Actor/Player.h"
|
||||||
|
#include <Territory/InstanceObjectCache.h>
|
||||||
|
|
||||||
using namespace Sapphire::World::Manager;
|
using namespace Sapphire::World::Manager;
|
||||||
using namespace Sapphire::World;
|
using namespace Sapphire::World;
|
||||||
|
@ -42,7 +48,7 @@ void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType war
|
||||||
|
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, pTeri->getTerritoryTypeId() ), true );
|
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, pTeri->getTerritoryTypeId() ), true );
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ActorDespawnEffect, warpType ) );
|
player.sendToInRangeSet( makeActorControl( player.getId(), ActorDespawnEffect, warpType ) );
|
||||||
player.setStateFlag( PlayerStateFlag::BetweenAreas );
|
Common::Service< PlayerMgr >::ref().onSetStateFlag( player, PlayerStateFlag::BetweenAreas );
|
||||||
|
|
||||||
auto moveTerritoryPacket = makeZonePacket< FFXIVIpcMoveTerritory >( player.getId() );
|
auto moveTerritoryPacket = makeZonePacket< FFXIVIpcMoveTerritory >( player.getId() );
|
||||||
moveTerritoryPacket->data().index = -1;
|
moveTerritoryPacket->data().index = -1;
|
||||||
|
@ -61,6 +67,17 @@ void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType war
|
||||||
taskMgr.queueTask( makeMoveTerritoryTask( player, warpType, targetTerritoryId, targetPos, targetRot, 2000 ) );
|
taskMgr.queueTask( makeMoveTerritoryTask( player, warpType, targetTerritoryId, targetPos, targetRot, 2000 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WarpMgr::requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot )
|
||||||
|
{
|
||||||
|
m_entityIdToWarpInfoMap[ player.getId() ] = { 0, warpType, targetPos, targetRot };
|
||||||
|
|
||||||
|
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, 0, 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 ) );
|
||||||
|
}
|
||||||
|
|
||||||
void WarpMgr::finishWarp( Entity::Player& player )
|
void WarpMgr::finishWarp( Entity::Player& player )
|
||||||
{
|
{
|
||||||
WarpType warpType = WarpType::WARP_TYPE_NORMAL;
|
WarpType warpType = WarpType::WARP_TYPE_NORMAL;
|
||||||
|
@ -85,7 +102,7 @@ void WarpMgr::finishWarp( Entity::Player& player )
|
||||||
auto zoneInPacket = makeActorControlSelf( player.getId(), Appear, warpType, 0, 0, 0 );
|
auto zoneInPacket = makeActorControlSelf( player.getId(), Appear, warpType, 0, 0, 0 );
|
||||||
auto SetStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
|
auto SetStatusPacket = makeActorControl( player.getId(), SetStatus, static_cast< uint8_t >( Common::ActorStatus::Idle ) );
|
||||||
|
|
||||||
player.setZoningType( Common::ZoneingType::None );
|
player.setZoningType( Common::ZoningType::None );
|
||||||
|
|
||||||
if( !player.getGmInvis() )
|
if( !player.getGmInvis() )
|
||||||
player.sendToInRangeSet( zoneInPacket );
|
player.sendToInRangeSet( zoneInPacket );
|
||||||
|
@ -99,13 +116,73 @@ void WarpMgr::finishWarp( Entity::Player& player )
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WarpMgr::requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot )
|
void WarpMgr::requestPlayerTeleport( Entity::Player& player, uint16_t aetheryteId, uint8_t teleportType )
|
||||||
{
|
{
|
||||||
m_entityIdToWarpInfoMap[ player.getId() ] = { 0, warpType, targetPos, targetRot };
|
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||||
|
auto& teriMgr = Common::Service< TerritoryMgr >::ref();
|
||||||
|
auto& warpMgr = Common::Service< WarpMgr >::ref();
|
||||||
|
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), WarpStart, warpType, 1, 0, player.getTerritoryTypeId(), 1 ), true );
|
auto aetherData = exdData.getRow< Excel::Aetheryte >( aetheryteId );
|
||||||
player.sendToInRangeSet( makeActorControl( player.getId(), ActorDespawnEffect, warpType ) );
|
|
||||||
|
|
||||||
auto& taskMgr = Common::Service< TaskMgr >::ref();
|
if( !aetherData )
|
||||||
taskMgr.queueTask( makeWarpTask( player, warpType, targetPos, targetRot, 1000 ) );
|
return;
|
||||||
}
|
|
||||||
|
const auto& data = aetherData->data();
|
||||||
|
|
||||||
|
auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref();
|
||||||
|
auto pop = instanceObjectCache.getPopRangeInfo( data.PopRange[ 0 ] );
|
||||||
|
|
||||||
|
Common::FFXIVARR_POSITION3 pos{ 0.f, 0.f, 0.f };
|
||||||
|
|
||||||
|
float rot = 0.f;
|
||||||
|
|
||||||
|
if( pop )
|
||||||
|
{
|
||||||
|
PlayerMgr::sendDebug( player, "Teleport: popRange {0} found!", data.PopRange[ 0 ] );
|
||||||
|
pos = pop->m_pos;
|
||||||
|
rot = pop->m_rotation;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PlayerMgr::sendDebug( player, "Teleport: popRange {0} not found in {1}!", data.PopRange[ 0 ], data.TerritoryType );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto townPlace = exdData.getRow< Excel::PlaceName >( data.TelepoName );
|
||||||
|
auto aetherytePlace = exdData.getRow< Excel::PlaceName >( data.TransferName );
|
||||||
|
|
||||||
|
PlayerMgr::sendDebug( player, "Teleport: {0} - {1} ({2})",
|
||||||
|
townPlace->getString( townPlace->data().Text.SGL ),
|
||||||
|
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 = player.getTerritoryTypeId() == data.TerritoryType;
|
||||||
|
|
||||||
|
WarpType warpType = WarpType::WARP_TYPE_NORMAL;
|
||||||
|
// TODO: should teleport type be a separate enum?
|
||||||
|
if( teleportType == 1 || teleportType == 2 ) // teleport
|
||||||
|
{
|
||||||
|
warpType = WarpType::WARP_TYPE_TELEPO;
|
||||||
|
player.setZoningType( Common::ZoningType::Teleport );
|
||||||
|
}
|
||||||
|
else if( teleportType == 3 ) // return
|
||||||
|
{
|
||||||
|
warpType = WarpType::WARP_TYPE_HOME_POINT;
|
||||||
|
player.setZoningType( Common::ZoningType::Return );
|
||||||
|
}
|
||||||
|
else if( teleportType == 4 ) // return
|
||||||
|
{
|
||||||
|
warpType = WarpType::WARP_TYPE_HOME_POINT;
|
||||||
|
player.setZoningType( Common::ZoningType::ReturnDead );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sameTerritory )
|
||||||
|
warpMgr.requestWarp( player, warpType, pos, rot );
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pTeri = teriMgr.getZoneByTerritoryTypeId( data.TerritoryType );
|
||||||
|
if( !pTeri )
|
||||||
|
return;
|
||||||
|
warpMgr.requestMoveTerritory( player, warpType, pTeri->getGuId(), pos, rot );
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,10 +21,40 @@ namespace Sapphire::World::Manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WarpMgr() = default;
|
WarpMgr() = default;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// request to move a player to specified territorytype and position, with given WarpType
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player"></param>
|
||||||
|
/// <param name="warpType"></param>
|
||||||
|
/// <param name="targetTerritoryId"></param>
|
||||||
|
/// <param name="targetPos"></param>
|
||||||
|
/// <param name="targetRot"></param>
|
||||||
void requestMoveTerritory( Entity::Player& player, Common::WarpType warpType, uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
|
void requestMoveTerritory( Entity::Player& player, Common::WarpType warpType, uint32_t targetTerritoryId, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// handle player state pre-warp and tells client to warp player
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player"></param>
|
||||||
|
/// <param name="warpType"></param>
|
||||||
|
/// <param name="targetPos"></param>
|
||||||
|
/// <param name="targetRot"></param>
|
||||||
void requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
|
void requestWarp( Entity::Player& player, Common::WarpType warpType, Common::FFXIVARR_POSITION3 targetPos, float targetRot );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// handle player state post-warp after client is done loading
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player"></param>
|
||||||
void finishWarp( Entity::Player& player );
|
void finishWarp( Entity::Player& player );
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// teleport a player to specified aetheryte and teleport type (teleport, return, etc)
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="player"></param>
|
||||||
|
/// <param name="aetheryteId"></param>
|
||||||
|
/// <param name="teleportType"></param>
|
||||||
|
void requestPlayerTeleport( Entity::Player& player, uint16_t aetheryteId, uint8_t teleportType );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unordered_map< uint32_t, WarpInfo > m_entityIdToWarpInfoMap;
|
std::unordered_map< uint32_t, WarpInfo > m_entityIdToWarpInfoMap;
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPlayer->setGc( static_cast< uint8_t >( param1 ) );
|
Service< World::Manager::PlayerMgr >::ref().onSetGc( player, static_cast< uint8_t >( param1 ) );
|
||||||
|
|
||||||
// if we're changing them to a GC, check if they have a rank and if not, set it to the lowest rank
|
// if we're changing them to a GC, check if they have a rank and if not, set it to the lowest rank
|
||||||
if( param1 > 0 )
|
if( param1 > 0 )
|
||||||
|
@ -442,7 +442,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPlayer->setGcRankAt( static_cast< uint8_t >( gcId ), static_cast< uint8_t >( param1 ) );
|
Service< World::Manager::PlayerMgr >::ref().onSetGcRank( player, static_cast< uint8_t >( gcId ), static_cast< uint8_t >( param1 ) );
|
||||||
PlayerMgr::sendServerNotice( player, "GC Rank for {0} for GC {1} was set to {2}", targetPlayer->getName(), targetPlayer->getGc(),
|
PlayerMgr::sendServerNotice( player, "GC Rank for {0} for GC {1} was set to {2}", targetPlayer->getName(), targetPlayer->getGc(),
|
||||||
targetPlayer->getGcRankArray()[ targetPlayer->getGc() - 1 ] );
|
targetPlayer->getGcRankArray()[ targetPlayer->getGc() - 1 ] );
|
||||||
break;
|
break;
|
||||||
|
@ -533,7 +533,7 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR
|
||||||
}
|
}
|
||||||
if( doTeleport )
|
if( doTeleport )
|
||||||
{
|
{
|
||||||
player.teleport( teleport );
|
warpMgr.requestPlayerTeleport( player, teleport, 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -583,14 +583,15 @@ void Sapphire::Network::GameConnection::commandHandler( const Packets::FFXIVARR_
|
||||||
}
|
}
|
||||||
case PacketCommand::REVIVE: // return dead / accept raise
|
case PacketCommand::REVIVE: // return dead / accept raise
|
||||||
{
|
{
|
||||||
|
auto& warpMgr = Service< WarpMgr >::ref();
|
||||||
switch( static_cast < ResurrectType >( param1 ) )
|
switch( static_cast < ResurrectType >( param1 ) )
|
||||||
{
|
{
|
||||||
case ResurrectType::RaiseSpell:
|
case ResurrectType::RaiseSpell:
|
||||||
// todo: handle raise case (set position to raiser, apply weakness status, set hp/mp/tp as well as packet)
|
// todo: handle raise case (set position to raiser, apply weakness status, set hp/mp/tp as well as packet)
|
||||||
player.teleport( player.getHomepoint(), 3 );
|
warpMgr.requestPlayerTeleport( player, player.getHomepoint(), 5 );
|
||||||
break;
|
break;
|
||||||
case ResurrectType::Return:
|
case ResurrectType::Return:
|
||||||
player.teleport( player.getHomepoint(), 3 );
|
warpMgr.requestPlayerTeleport( player, player.getHomepoint(), 4 );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -110,7 +110,7 @@ namespace Sapphire::Network::Packets::WorldPackets::Server
|
||||||
m_data.ActiveType = player.getStance();
|
m_data.ActiveType = player.getStance();
|
||||||
m_data.Flag = 0;
|
m_data.Flag = 0;
|
||||||
|
|
||||||
if( player.getZoningType() != Common::ZoneingType::None || player.getGmInvis() )
|
if( player.getZoningType() != Common::ZoningType::None || player.getGmInvis() )
|
||||||
{
|
{
|
||||||
m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::Invisible );
|
m_data.Flag |= static_cast< uint16_t >( Common::DisplayFlags::Invisible );
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,6 +138,11 @@ namespace Sapphire::ScriptAPI
|
||||||
virtual void onExecute( Sapphire::World::Action::Action& action );
|
virtual void onExecute( Sapphire::World::Action::Action& action );
|
||||||
|
|
||||||
virtual void onInterrupt( Sapphire::World::Action::Action& action );
|
virtual void onInterrupt( Sapphire::World::Action::Action& action );
|
||||||
|
|
||||||
|
World::Manager::WarpMgr& warpMgr()
|
||||||
|
{
|
||||||
|
return Common::Service< World::Manager::WarpMgr >::ref();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Add table
Reference in a new issue