1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-25 14:07:46 +00:00

Merge branch 'ThreePointThree' of https://github.com/SapphireServer/Sapphire into ThreePointThree

This commit is contained in:
Lucy 2023-01-27 21:32:22 +01:00
commit fe82d50288
12 changed files with 216 additions and 187 deletions

View file

@ -2004,11 +2004,11 @@ struct FFXIVIpcEorzeaTimeOffset : FFXIVIpcBasePacket< TimeOffset >
struct FFXIVIpcInterior : FFXIVIpcBasePacket< Interior >
{
uint8_t Window;
uint8_t WindowColor;
uint8_t Door;
uint8_t DoorColor;
uint16_t Interior[10];
uint16_t Window;
uint16_t WindowColor;
uint16_t Door;
uint16_t DoorColor;
uint32_t Interior[10];
};
struct FFXIVIpcHousingAuction : FFXIVIpcBasePacket< HousingAuction >
@ -2073,18 +2073,30 @@ struct FFXIVIpcEorzeaTimeOffset : FFXIVIpcBasePacket< TimeOffset >
struct FFXIVIpcFurnitureListS : FFXIVIpcBasePacket< FurnitureListS >
{
Common::LandIdent LandId;
int8_t u1; //Outdoor -1 / Indoor 0 - probably indicator
uint8_t packetNum;
uint8_t packetTotal;
uint8_t u2; //Outdoor 0 / Indoor 100(?)
Common::Furniture Furnitures[100];
};
struct FFXIVIpcFurnitureListM : FFXIVIpcBasePacket< FurnitureListM >
{
Common::LandIdent LandId;
int8_t u1; //Outdoor -1 / Indoor 0 - probably indicator
uint8_t packetNum;
uint8_t packetTotal;
uint8_t u2; //Outdoor 0 / Indoor 100(?)
Common::Furniture Furnitures[150];
};
struct FFXIVIpcFurnitureListL : FFXIVIpcBasePacket< FurnitureListL >
{
Common::LandIdent LandId;
int8_t u1; //Outdoor -1 / Indoor 0 - probably indicator
uint8_t packetNum;
uint8_t packetTotal;
uint8_t u2; //Outdoor 0 / Indoor 100(?)
Common::Furniture Furnitures[200];
};

View file

@ -1526,86 +1526,6 @@ uint32_t Player::getPrevTerritoryTypeId() const
return m_prevTerritoryTypeId;
}
void Player::sendZonePackets()
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto pZone = teriMgr.getTerritoryByGuId( getTerritoryId() );
auto initPacket = makeZonePacket< FFXIVIpcLogin >( getId() );
initPacket->data().playerActorId = getId();
queuePacket( initPacket );
sendInventory();
if( isLogin() )
{
queuePacket( makeActorControlSelf( getId(), SetCharaGearParamUI, m_equipDisplayFlags, 1 ) );
queuePacket( makeActorControlSelf( getId(), SetMaxGearSets, m_equippedMannequin ) );
}
// set flags, will be reset automatically by zoning ( only on client side though )
//setStateFlag( PlayerStateFlag::BetweenAreas );
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
if( hasReward( Common::UnlockEntry::HuntingLog ) )
sendHuntingLog();
sendStats();
// only initialize the UI if the player in fact just logged in.
if( isLogin() )
{
auto contentFinderList = makeZonePacket< FFXIVIpcContentAttainFlags >( getId() );
std::memset( &contentFinderList->data(), 0xFF, sizeof( contentFinderList->data() ) );
queuePacket( contentFinderList );
auto statusPacket = makePlayerSetup( *this );
queuePacket( statusPacket );
Service< World::Manager::PlayerMgr >::ref().onPlayerStatusUpdate( *this );
sendItemLevel();
clearSoldItems();
}
auto& housingMgr = Common::Service< HousingMgr >::ref();
if( Sapphire::LandPtr pLand = housingMgr.getLandByOwnerId( getCharacterId() ) )
{
uint32_t state = 0;
if( pLand->getHouse() )
{
state |= LandFlags::CHARA_HOUSING_LAND_DATA_FLAG_HOUSE;
// todo: remove this, debug for now
state |= LandFlags::CHARA_HOUSING_LAND_DATA_FLAG_AETHERYTE;
}
setLandFlags( LandFlagsSlot::Private, state, pLand->getLandIdent() );
}
sendLandFlags();
queuePacket( makeInitZone( *this, *pZone ) );
pZone->onPlayerZoneIn( *this );
if( isLogin() )
{
queuePacket( makeZonePacket< FFXIVIpcQuestRepeatFlags >( getId() ) );
queuePacket( makeZonePacket< FFXIVIpcDailyQuests >( getId() ) );
}
if( getPartyId() != 0 )
{
auto& partyMgr = Common::Service< World::Manager::PartyMgr >::ref();
partyMgr.onMoveZone( *this );
}
}
void Player::setDirectorInitialized( bool isInitialized )
{
m_directorInitialized = isInitialized;
@ -1760,44 +1680,6 @@ void Player::setLandFlags( uint8_t flagSlot, uint32_t landFlags, Common::LandIde
m_charaLandData[ flagSlot ].landFlags = landFlags;
}
void Player::sendLandFlags()
{
auto landFlags = makeZonePacket< FFXIVIpcCharaHousing >( getId() );
landFlags->data().FcLands = m_charaLandData[ Common::LandFlagsSlot::FreeCompany ];
landFlags->data().CharaLands = m_charaLandData[ Common::LandFlagsSlot::Private ];
queuePacket( landFlags );
}
void Player::sendLandFlagsSlot( Common::LandFlagsSlot slot )
{
auto landFlags = makeZonePacket< FFXIVIpcCharaHousingLandData >( getId() );
LandType type;
switch( slot )
{
case LandFlagsSlot::Private:
type = LandType::Private;
break;
case LandFlagsSlot::FreeCompany:
type = LandType::FreeCompany;
break;
default:
// todo: other/unsupported land types
return;
}
landFlags->data().Index = static_cast< uint32_t >( type );
landFlags->data().LandData.landId = m_charaLandData[ slot ].landId;
landFlags->data().LandData.landFlags = m_charaLandData[ slot ].landFlags;
queuePacket( landFlags );
}
Sapphire::Common::HuntingLogEntry& Player::getHuntingLogEntry( uint8_t index )
{
assert( index < m_huntingLogEntries.size() );
@ -2143,3 +2025,8 @@ void Player::updatePrevTerritory()
m_prevRot = m_rot;
}
}
const CharaLandData& Entity::Player::getCharaLandData( Common::LandFlagsSlot slot ) const
{
return m_charaLandData[ slot ];
}

View file

@ -582,8 +582,6 @@ namespace Sapphire::Entity
/*! set the loading complete bool */
void setLoadingComplete( bool bComplete );
void sendZonePackets();
Common::ZoneingType getZoningType() const;
void setZoningType( Common::ZoneingType zoneingType );
@ -604,9 +602,6 @@ namespace Sapphire::Entity
//////////////////////////////////////////////////////////////////////////////////////////////////////
void setLandFlags( uint8_t permissionSet, uint32_t landFlags, Common::LandIdent ident );
void sendLandFlags();
void sendLandFlagsSlot( Common::LandFlagsSlot slot );
// Player Battle Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void initHateSlotQueue();
@ -816,6 +811,8 @@ namespace Sapphire::Entity
bool isConnected() const;
void setConnected( bool isConnected );
const Common::CharaLandData& getCharaLandData( Common::LandFlagsSlot slot ) const;
private:
/*! queue a packet for the player */
void queuePacket( Network::Packets::FFXIVPacketBasePtr pPacket );
@ -940,6 +937,8 @@ namespace Sapphire::Entity
// housing info
Common::CharaLandData m_charaLandData[2]{};
private:
Common::ActiveLand m_activeLand{};
// gc info

View file

@ -169,12 +169,12 @@ Common::AchievementDataKey AchievementMgr::getKeyFromType( Common::Achievement::
return dataKey;
}
const std::vector< uint32_t >& AchievementMgr::getAchievementIdByType( Common::Achievement::Type type ) const
std::vector< uint32_t > AchievementMgr::getAchievementIdByType( Common::Achievement::Type type ) const
{
return getAchievementIdByType( static_cast< uint32_t >( type ) );
}
const std::vector< uint32_t >& AchievementMgr::getAchievementIdByType( uint32_t type ) const
std::vector< uint32_t > AchievementMgr::getAchievementIdByType( uint32_t type ) const
{
auto it = m_achievementKeyCacheMap.find( type );

View file

@ -77,8 +77,8 @@ namespace Sapphire::World::Manager
AchievementKeyCache m_achievementKeyCacheMap;
std::shared_ptr< Excel::ExcelStruct< Excel::Achievement > > getAchievementDetail( uint32_t achvId ) const;
const std::vector< uint32_t >& getAchievementIdByType( Common::Achievement::Type type ) const;
const std::vector< uint32_t >& getAchievementIdByType( uint32_t type ) const;
std::vector< uint32_t > getAchievementIdByType( Common::Achievement::Type type ) const;
std::vector< uint32_t > getAchievementIdByType( uint32_t type ) const;
/// <summary>
/// get a key for merged achievements (type:subtype) that have progress data
@ -125,7 +125,7 @@ namespace Sapphire::World::Manager
auto achvExdData = pAchv->data();
if( achvExdData.ConditionArg[ 1 ] <= achvDataList[ dataKey.u32 ] )
if( achvExdData.ConditionArg[ 1 ] <= static_cast< int32_t >( achvDataList[ dataKey.u32 ] ) )
unlockAchievement( player, achvId );
}
}
@ -157,9 +157,8 @@ namespace Sapphire::World::Manager
auto achvExdData = pAchv->data();
if( achvExdData.ConditionArg[ 1 ] <= achvDataList[ dataKey.u32 ] )
if( achvExdData.ConditionArg[ 1 ] <= static_cast< int32_t >( achvDataList[ dataKey.u32 ] ) )
unlockAchievement( player, achvId );
}
}

View file

@ -345,8 +345,7 @@ void HousingMgr::sendLandSignOwned( Entity::Player& player, const Common::LandId
memcpy( &landInfoSignPacket->data().OwnerName, playerName.c_str(), playerName.size() );
auto pSession = server.getSession( player.getCharacterId() );
pSession->getZoneConnection()->queueOutPacket( landInfoSignPacket );
server.queueForPlayer( player.getCharacterId(), landInfoSignPacket );
}
void HousingMgr::sendLandSignFree( Entity::Player& player, const Common::LandIdent ident )
@ -367,8 +366,7 @@ void HousingMgr::sendLandSignFree( Entity::Player& player, const Common::LandIde
plotPricePacket->data().Price = land->getCurrentPrice();
plotPricePacket->data().Timer = land->getDevaluationTime();
auto pSession = server.getSession( player.getCharacterId() );
pSession->getZoneConnection()->queueOutPacket( plotPricePacket );
server.queueForPlayer( player.getCharacterId(), plotPricePacket );
}
LandPurchaseResult HousingMgr::purchaseLand( Entity::Player& player, HousingZone& zone, uint8_t plot, uint8_t state )
@ -408,7 +406,7 @@ LandPurchaseResult HousingMgr::purchaseLand( Entity::Player& player, HousingZone
player.setLandFlags( Common::LandFlagsSlot::Private, 0x00, pLand->getLandIdent() );
player.sendLandFlagsSlot( Common::LandFlagsSlot::Private );
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
//pLand->setLandName( "Private Estate" + std::to_string( pHousing->getWardNum() ) + "-" + std::to_string( plot ) );
pLand->updateLandDb();
@ -426,8 +424,6 @@ LandPurchaseResult HousingMgr::purchaseLand( Entity::Player& player, HousingZone
bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint8_t plot )
{
auto& server = Common::Service< World::WorldServer >::ref();
auto pSession = server.getSession( player.getCharacterId() );
// TODO: Fix "permissions" being sent incorrectly
// TODO: Add checks for land state before relinquishing
@ -439,7 +435,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
if( !hasPermission( player, *pLand, 0 ) )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3304, 0 );
pSession->getZoneConnection()->queueOutPacket( msgPkt );
server.queueForPlayer( player.getCharacterId(), msgPkt );
return false;
}
@ -448,7 +444,7 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
if( pLand->getHouse() )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3315, 0 );
pSession->getZoneConnection()->queueOutPacket( msgPkt );
server.queueForPlayer( player.getCharacterId(), msgPkt );
return false;
}
@ -462,11 +458,11 @@ bool HousingMgr::relinquishLand( Entity::Player& player, HousingZone& zone, uint
player.setLandFlags( Common::LandFlagsSlot::Private, 0x00, ident );
player.sendLandFlagsSlot( Common::LandFlagsSlot::Private );
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
auto screenMsgPkt2 = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3351, 0x1AA,
pLand->getLandIdent().wardNum + 1, plot + 1 );
pSession->getZoneConnection()->queueOutPacket( screenMsgPkt2 );
server.queueForPlayer( player.getCharacterId(), screenMsgPkt2 );
zone.sendLandUpdate( plot );
return true;
@ -537,7 +533,7 @@ void HousingMgr::sendWardLandInfo( Entity::Player& player, uint8_t wardId, uint1
// todo: check if estate allows public entry
}
pSession->getZoneConnection()->queueOutPacket( wardInfoPacket );
server.queueForPlayer( player.getCharacterId(), wardInfoPacket );
}
void HousingMgr::sendEstateGreeting( Entity::Player& player, const Common::LandIdent ident )
@ -566,8 +562,7 @@ void HousingMgr::sendEstateGreeting( Entity::Player& player, const Common::LandI
auto greeting = house->getHouseGreeting();
memcpy( &greetingPacket->data().Greeting, greeting.c_str(), greeting.size() );
auto pSession = server.getSession( player.getCharacterId() );
pSession->getZoneConnection()->queueOutPacket( greetingPacket );
server.queueForPlayer( player.getCharacterId(), greetingPacket );
}
bool HousingMgr::initHouseModels( Entity::Player& player, LandPtr land, uint32_t presetCatalogId )
@ -575,12 +570,6 @@ bool HousingMgr::initHouseModels( Entity::Player& player, LandPtr land, uint32_t
auto house = land->getHouse();
assert( house );
auto itemMax = land->getInventoryItemMax();
// type, maxSize, tableName, isMultiStorage
// auto intContainer = make_ItemContainer( Common::InventoryType::HousingInteriorAppearance, itemMax.second, "houseiteminventory", true );
// auto extContainer = make_ItemContainer( Common::InventoryType::HousingExteriorAppearance, itemMax.first, "houseiteminventory", true );
// add containers to inv collection
auto& houseInventory = getEstateInventory( house->getLandIdent() );
houseInventory[ Common::InventoryType::HousingInteriorAppearance ];// = intContainer;
@ -724,7 +713,7 @@ void HousingMgr::buildPresetEstate( Entity::Player& player, HousingZone& zone, u
auto pSuccessBuildingPacket = makeActorControl( player.getId(), ActorControl::BuildPresetResponse, plotNum );
pSession->getZoneConnection()->queueOutPacket( pSuccessBuildingPacket );
server.queueForPlayer( player.getCharacterId(), pSuccessBuildingPacket );
pLand->updateLandDb();
@ -734,7 +723,7 @@ void HousingMgr::buildPresetEstate( Entity::Player& player, HousingZone& zone, u
eventMgr.playScene( player, 0x000B0095, 0, static_cast< uint32_t >( SET_BASE | HIDE_HOTBAR ), { 1, plotNum } );
player.setLandFlags( Common::LandFlagsSlot::Private, Common::HOUSING_LAND_STATUS::HOUSING_LAND_STATUS_BUILDHOUSE, ident );
player.sendLandFlagsSlot( Common::LandFlagsSlot::Private );
sendLandFlagsSlot( player, Common::LandFlagsSlot::Private );
zone.registerEstateEntranceEObj( plotNum );
}
@ -763,7 +752,7 @@ void HousingMgr::requestEstateRename( Entity::Player& player, const Common::Land
landRenamePacket->data().LandId = ident;
memcpy( &landRenamePacket->data().Name, house->getHouseName().c_str(), 20 );
pSession->getZoneConnection()->queueOutPacket( landRenamePacket );
server.queueForPlayer( player.getCharacterId(), landRenamePacket );
}
void HousingMgr::requestEstateEditGreeting( Entity::Player& player, const Common::LandIdent ident )
@ -792,7 +781,7 @@ void HousingMgr::requestEstateEditGreeting( Entity::Player& player, const Common
estateGreetingPacket->data().LandId = ident;
memcpy( &estateGreetingPacket->data().Greeting, house->getHouseGreeting().c_str(), sizeof( estateGreetingPacket->data().Greeting ) );
pSession->getZoneConnection()->queueOutPacket( estateGreetingPacket );
server.queueForPlayer( player.getCharacterId(), estateGreetingPacket );
}
void HousingMgr::updateEstateGreeting( Entity::Player& player, const Common::LandIdent ident, const std::string& greeting )
@ -846,7 +835,7 @@ void HousingMgr::requestEstateEditGuestAccess( Entity::Player& player, const Com
packet->data().LandId = ident;
packet->data().Welcome = land->getSharing();
pSession->getZoneConnection()->queueOutPacket( packet );
server.queueForPlayer( player.getCharacterId(), packet );
}
Common::LandIdent HousingMgr::clientTriggerParamsToLandIdent( uint32_t param11, uint32_t param12, bool use16bits ) const
@ -1083,7 +1072,7 @@ void HousingMgr::reqPlaceHousingItem( Entity::Player& player, uint16_t landId, u
status = placeInteriorItem( player, item );
if( status )
pSession->getZoneConnection()->queueOutPacket( makeActorControlSelf( player.getId(), 0x3f3 ) );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), 0x3f3 ) );
else
PlayerMgr::sendUrgent( player, "An internal error occurred when placing the item." );
}
@ -1362,7 +1351,7 @@ bool HousingMgr::moveInternalItem( Entity::Player& player, Common::LandIdent ide
// send confirmation to player
uint32_t param1 = static_cast< uint32_t >( ( ident.landId << 16 ) | containerId );
pSession->getZoneConnection()->queueOutPacket( makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slotIdx ) );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slotIdx ) );
return true;
}
@ -1397,8 +1386,7 @@ bool HousingMgr::moveExternalItem( Entity::Player& player, Common::LandIdent ide
terri.updateYardObjectPos( player, slot, static_cast< uint16_t >( ident.landId ), *item );
uint32_t param1 = static_cast< uint32_t >( ( ident.landId << 16 ) | Common::InventoryType::HousingExteriorPlacedItems );
pSession->getZoneConnection()->queueOutPacket( makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slot ) );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), ActorControl::HousingItemMoveConfirm, param1, slot ) );
return true;
}
@ -1637,7 +1625,7 @@ void HousingMgr::reqEstateExteriorRemodel( Entity::Player& player, uint16_t plot
invMgr.sendInventoryContainer( player, it->second );
auto pkt = makeActorControlSelf( player.getId(), Network::ActorControl::ShowEstateExternalAppearanceUI, plot );
pSession->getZoneConnection()->queueOutPacket( pkt );
server.queueForPlayer( player.getCharacterId(), pkt );
}
@ -1677,7 +1665,7 @@ void HousingMgr::reqEstateInteriorRemodel( Entity::Player& player )
invMgr.sendInventoryContainer( player, it->second );
auto pkt = makeActorControlSelf( player.getId(), Network::ActorControl::ShowEstateInternalAppearanceUI );
pSession->getZoneConnection()->queueOutPacket( pkt );
server.queueForPlayer( player.getCharacterId(), pkt );
}
bool HousingMgr::hasPermission( Entity::Player& player, Sapphire::Land& land, uint32_t permission )
@ -1722,7 +1710,7 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot )
if( !hasPermission( player, *pLand, 0 ) )
{
auto msgPkt = makeActorControlSelf( player.getId(), ActorControl::LogMsg, 3305, 0 );
pSession->getZoneConnection()->queueOutPacket( msgPkt );
server.queueForPlayer( player.getCharacterId(), msgPkt );
return;
}
@ -1758,7 +1746,7 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot )
invMgr.sendInventoryContainer( player, interiorContainer );
invMgr.saveHousingContainer( land->getLandIdent(), interiorContainer );
for( auto entry : changedContainerSet )
for( auto& entry : changedContainerSet )
{
invMgr.sendInventoryContainer( player, entry.second );
invMgr.saveHousingContainer( land->getLandIdent(), entry.second );
@ -1776,3 +1764,44 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot )
terri->removeEstateEntranceEObj( plot );
return;
}
void HousingMgr::sendLandFlagsSlot( Entity::Player& player, Common::LandFlagsSlot slot )
{
auto& server = Common::Service< World::WorldServer >::ref();
auto landFlags = makeZonePacket< FFXIVIpcCharaHousingLandData >( player.getId() );
Common::LandType type;
switch( slot )
{
case Common::LandFlagsSlot::Private:
type = Common::LandType::Private;
break;
case Common::LandFlagsSlot::FreeCompany:
type = Common::LandType::FreeCompany;
break;
default:
// todo: other/unsupported land types
return;
}
auto landData = player.getCharaLandData( slot );
landFlags->data().Index = static_cast< uint32_t >( type );
landFlags->data().LandData.landId = landData.landId;
landFlags->data().LandData.landFlags = landData.landFlags;
server.queueForPlayer( player.getCharacterId(), landFlags );
}
void HousingMgr::sendLandFlags( Entity::Player& player )
{
auto landFlags = makeZonePacket< FFXIVIpcCharaHousing >( player.getId() );
landFlags->data().FcLands = player.getCharaLandData( Common::LandFlagsSlot::FreeCompany );
landFlags->data().CharaLands = player.getCharaLandData( Common::LandFlagsSlot::Private );
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( player.getCharacterId(), landFlags );
}

View file

@ -98,6 +98,8 @@ namespace Sapphire::World::Manager
void sendEstateGreeting( Entity::Player& player, const Common::LandIdent ident );
void sendLandFlagsSlot( Entity::Player& player, Common::LandFlagsSlot slot );
void sendLandFlags( Entity::Player& player );
/*!
* @brief Updates the cached models on a house from the relevant apperance inventories.
* Does not send the subsequent update to clients.

View file

@ -5,9 +5,12 @@
#include <Exd/ExdData.h>
#include <Territory/Territory.h>
#include <Territory/Land.h>
#include <Manager/TerritoryMgr.h>
#include <Manager/AchievementMgr.h>
#include <Manager/PartyMgr.h>
#include <Manager/HousingMgr.h>
#include "Script/ScriptMgr.h"
#include "WorldServer.h"
@ -20,7 +23,9 @@
#include <Network/PacketWrappers/ActorControlPacket.h>
#include <Network/PacketWrappers/ActorControlSelfPacket.h>
#include "Network/PacketWrappers/ActorControlTargetPacket.h"
#include "Network/PacketWrappers/InitZonePacket.h"
#include <Network/PacketWrappers/ModelEquipPacket.h>
#include "Network/PacketWrappers/PlayerSetupPacket.h"
#include <Network/PacketWrappers/PlayerStateFlagsPacket.h>
#include <Network/PacketWrappers/UpdateHpMpTpPacket.h>
#include "Network/PacketWrappers/ServerNoticePacket.h"
@ -132,11 +137,10 @@ void PlayerMgr::onSendStats( Entity::Player& player )
statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) );
}
auto& server = Common::Service< World::WorldServer >::ref();
auto statPacket = makeZonePacket< FFXIVIpcBaseParam >( player.getId() );
memcpy( statPacket->data().Param, statParams.data(), sizeof( uint32_t ) * statParams.size() );
auto& server = Common::Service< World::WorldServer >::ref();
server.queueForPlayer( player.getCharacterId(), statPacket );
}
@ -317,7 +321,7 @@ void PlayerMgr::onLogin( Entity::Player &player )
std::string msg;
while( std::getline( ss, msg, ';' ) )
{
PlayerMgr::sendServerNotice( player, msg );
sendServerNotice( player, msg );
}
}
@ -327,6 +331,93 @@ void PlayerMgr::onDeath( Entity::Player &player )
scriptMgr.onPlayerDeath( player );
}
void PlayerMgr::onZone( Sapphire::Entity::Player& player )
{
auto& teriMgr = Common::Service< World::Manager::TerritoryMgr >::ref();
auto& housingMgr = Common::Service< HousingMgr >::ref();
auto& partyMgr = Common::Service< World::Manager::PartyMgr >::ref();
auto& server = Common::Service< World::WorldServer >::ref();
auto pZone = teriMgr.getTerritoryByGuId( player.getTerritoryId() );
if( !pZone )
{
Logger::error( "Territory GuID#{} not found!", player.getTerritoryId() );
return;
}
auto& teri = *pZone;
auto initPacket = makeZonePacket< FFXIVIpcLogin >( player.getId() );
initPacket->data().playerActorId = player.getId();
server.queueForPlayer( player.getCharacterId(), initPacket );
player.sendInventory();
if( player.isLogin() )
{
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetCharaGearParamUI, player.getEquipDisplayFlags(), 1 ) );
server.queueForPlayer( player.getCharacterId(), makeActorControlSelf( player.getId(), SetMaxGearSets, player.getMaxGearSets() ) );
}
// set flags, will be reset automatically by zoning ( only on client side though )
//setStateFlag( PlayerStateFlag::BetweenAreas );
//setStateFlag( PlayerStateFlag::BetweenAreas1 );
if( player.hasReward( Common::UnlockEntry::HuntingLog ) )
player.sendHuntingLog();
player.sendStats();
// only initialize the UI if the player in fact just logged in.
if( player.isLogin() )
{
auto contentFinderList = makeZonePacket< FFXIVIpcContentAttainFlags >( player.getId() );
std::memset( &contentFinderList->data(), 0xFF, sizeof( contentFinderList->data() ) );
server.queueForPlayer( player.getCharacterId(), { contentFinderList, makePlayerSetup( player ) } );
onPlayerStatusUpdate( player );
player.sendItemLevel();
player.clearSoldItems();
}
if( Sapphire::LandPtr pLand = housingMgr.getLandByOwnerId( player.getCharacterId() ) )
{
uint32_t state = 0;
if( pLand->getHouse() )
{
state |= Common::LandFlags::CHARA_HOUSING_LAND_DATA_FLAG_HOUSE;
// todo: remove this, debug for now
state |= Common::LandFlags::CHARA_HOUSING_LAND_DATA_FLAG_AETHERYTE;
}
player.setLandFlags( Common::LandFlagsSlot::Private, state, pLand->getLandIdent() );
}
housingMgr.sendLandFlags( player );
server.queueForPlayer( player.getCharacterId(), makeInitZone( player, teri ) );
teri.onPlayerZoneIn( player );
if( player.isLogin() )
{
server.queueForPlayer( player.getCharacterId(),
{
makeZonePacket< FFXIVIpcQuestRepeatFlags >( player.getId() ),
makeZonePacket< FFXIVIpcDailyQuests >( player.getId() )
} );
}
if( player.getPartyId() != 0 )
{
partyMgr.onMoveZone( player );
}
}
////////// Helper ///////////

View file

@ -56,6 +56,8 @@ class PlayerMgr
void onDeath( Sapphire::Entity::Player& player );
void onZone( Sapphire::Entity::Player& player );
//////////// Helpers
static void sendServerNotice( Sapphire::Entity::Player& player, const std::string& message );

View file

@ -15,6 +15,7 @@
#include "TerritoryMgr.h"
#include "HousingMgr.h"
#include "WarpMgr.h"
#include "PlayerMgr.h"
#include "Linkshell/Linkshell.h"
#include "Territory/Land.h"
@ -585,13 +586,9 @@ TerritoryMgr::InstanceIdList TerritoryMgr::getInstanceContentIdList( uint16_t in
return idList;
}
bool TerritoryMgr::movePlayer( const TerritoryPtr& pZone, Entity::Player& player )
bool TerritoryMgr::movePlayer( Sapphire::Territory& teri, Entity::Player& player )
{
if( !pZone )
{
Logger::error( "Territory not found on this server." );
return false;
}
auto& playerMgr = Common::Service< Manager::PlayerMgr >::ref();
auto pPrevZone = getTerritoryByGuId( player.getTerritoryId() );
@ -599,8 +596,8 @@ bool TerritoryMgr::movePlayer( const TerritoryPtr& pZone, Entity::Player& player
player.initSpawnIdQueue();
player.setTerritoryTypeId( pZone->getTerritoryTypeId() );
player.setTerritoryId( pZone->getGuId() );
player.setTerritoryTypeId( teri.getTerritoryTypeId() );
player.setTerritoryId( teri.getGuId() );
bool playerLoaded = player.isLoadingComplete();
@ -610,13 +607,13 @@ bool TerritoryMgr::movePlayer( const TerritoryPtr& pZone, Entity::Player& player
if( playerLoaded && pPrevZone )
pPrevZone->removeActor( player.getAsPlayer() );
pZone->pushActor( player.getAsPlayer() );
teri.pushActor( player.getAsPlayer() );
// map player to instanceId so it can be tracked.
m_playerIdToInstanceMap[ player.getId() ] = pZone->getGuId();
m_playerIdToInstanceMap[ player.getId() ] = teri.getGuId();
pZone->onBeforePlayerZoneIn( player );
player.sendZonePackets();
teri.onBeforePlayerZoneIn( player );
playerMgr.onZone( player );
return true;
}
@ -712,7 +709,7 @@ bool TerritoryMgr::joinWorld( Entity::Player& player )
return false;
}
if( !movePlayer( pCurrZone, player ) )
if( !movePlayer( *pCurrZone, player ) )
return false;
return true;

View file

@ -16,6 +16,11 @@ namespace Sapphire::Data
using InstanceContentPtr = std::shared_ptr< InstanceContent >;
}
namespace Sapphire
{
class Territory;
}
namespace Sapphire::World::Manager
{
/*!
@ -132,7 +137,7 @@ namespace Sapphire::World::Manager
TODO: Mind multiple instances?! */
TerritoryPtr getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const;
bool movePlayer( const TerritoryPtr&, Entity::Player& player );
bool movePlayer( Sapphire::Territory& teri, Entity::Player& player );
/*! returns an instancePtr if the player is still bound to an isntance */
TerritoryPtr getLinkedInstance( uint32_t playerId ) const;

View file

@ -39,13 +39,19 @@ void MoveTerritoryTask::execute()
if( m_warpInfo.m_targetTerritoryId != 0 )
pZone = teriMgr.getTerritoryByGuId( m_warpInfo.m_targetTerritoryId );
if( !teriMgr.movePlayer( pZone, *pPlayer ) )
if( !pZone )
{
Logger::error( "Territory typeId#{} not found!", m_warpInfo.m_targetTerritoryId );
return;
}
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 ) )
if( !teriMgr.movePlayer( *pZone1, *pPlayer ) )
return;
}
}