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:
commit
fe82d50288
12 changed files with 216 additions and 187 deletions
|
@ -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];
|
||||
};
|
||||
|
||||
|
|
|
@ -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 ];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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 ///////////
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue