mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 00:47:45 +00:00
spawn internal house items from db
This commit is contained in:
parent
7da03ef6f0
commit
d238696832
6 changed files with 145 additions and 50 deletions
|
@ -1681,7 +1681,7 @@ struct FFXIVIpcLandSetInitialize : FFXIVIpcBasePacket< LandSetInitialize >
|
||||||
|
|
||||||
struct FFXIVIpcYardObjectSpawn : FFXIVIpcBasePacket<YardObjectSpawn>
|
struct FFXIVIpcYardObjectSpawn : FFXIVIpcBasePacket<YardObjectSpawn>
|
||||||
{
|
{
|
||||||
uint8_t landSetId;
|
uint8_t landId;
|
||||||
uint8_t objectArray;
|
uint8_t objectArray;
|
||||||
uint16_t unknown1;
|
uint16_t unknown1;
|
||||||
Common::YardObject object;
|
Common::YardObject object;
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
|
||||||
{
|
{
|
||||||
auto invMgr = g_fw.get< InventoryMgr >();
|
auto invMgr = g_fw.get< InventoryMgr >();
|
||||||
|
|
||||||
auto containers = {
|
auto containerIds = {
|
||||||
InventoryType::HousingInteriorPlacedItems1,
|
InventoryType::HousingInteriorPlacedItems1,
|
||||||
InventoryType::HousingInteriorPlacedItems2,
|
InventoryType::HousingInteriorPlacedItems2,
|
||||||
InventoryType::HousingInteriorPlacedItems3,
|
InventoryType::HousingInteriorPlacedItems3,
|
||||||
|
@ -1056,7 +1056,7 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
|
||||||
|
|
||||||
// find first free container
|
// find first free container
|
||||||
uint8_t containerIdx = 0;
|
uint8_t containerIdx = 0;
|
||||||
for( auto containerId : containers )
|
for( auto containerId : containerIds )
|
||||||
{
|
{
|
||||||
auto& container = getEstateInventory( ident )[ containerId ];
|
auto& container = getEstateInventory( ident )[ containerId ];
|
||||||
|
|
||||||
|
@ -1079,9 +1079,24 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
|
||||||
invMgr->saveHousingContainer( ident, container );
|
invMgr->saveHousingContainer( ident, container );
|
||||||
invMgr->updateHousingItemPosition( item );
|
invMgr->updateHousingItemPosition( item );
|
||||||
|
|
||||||
break;
|
auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() );
|
||||||
|
assert( zone );
|
||||||
|
|
||||||
|
zone->spawnYardObject( containerIdx, freeSlot, item );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
Sapphire::Common::YardObject Sapphire::World::Manager::HousingMgr::getYardObjectForItem( Inventory::HousingItemPtr item ) const
|
||||||
|
{
|
||||||
|
Sapphire::Common::YardObject obj {};
|
||||||
|
|
||||||
|
obj.pos = item->getPos();
|
||||||
|
obj.itemRotation = item->getRot();
|
||||||
|
obj.itemId = item->getAdditionalData();
|
||||||
|
|
||||||
|
return obj;
|
||||||
}
|
}
|
|
@ -149,6 +149,13 @@ namespace Sapphire::World::Manager
|
||||||
void reqPlaceHousingItem( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId,
|
void reqPlaceHousingItem( Entity::Player& player, uint16_t landId, uint16_t containerId, uint16_t slotId,
|
||||||
Common::FFXIVARR_POSITION3 pos, float rotation );
|
Common::FFXIVARR_POSITION3 pos, float rotation );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief Returns the equivalent YardObject for a HousingItem
|
||||||
|
* @param item The item to convert into a YardObject
|
||||||
|
* @return The resultant YardObject
|
||||||
|
*/
|
||||||
|
Common::YardObject getYardObjectForItem( Inventory::HousingItemPtr item ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include "Manager/HousingMgr.h"
|
#include "Manager/HousingMgr.h"
|
||||||
#include "Territory/Land.h"
|
#include "Territory/Land.h"
|
||||||
#include "Territory/House.h"
|
#include "Territory/House.h"
|
||||||
|
#include "Inventory/ItemContainer.h"
|
||||||
|
#include "Inventory/HousingItem.h"
|
||||||
|
|
||||||
#include "Forwards.h"
|
#include "Forwards.h"
|
||||||
#include "HousingInteriorTerritory.h"
|
#include "HousingInteriorTerritory.h"
|
||||||
|
@ -28,27 +30,27 @@ using namespace Sapphire::World::Manager;
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::World::Territory;
|
using namespace Sapphire::World::Territory;
|
||||||
|
|
||||||
Housing::HousingInteriorTerritory::HousingInteriorTerritory( Common::LandIdent ident, uint16_t territoryTypeId,
|
Sapphire::World::Territory::Housing::HousingInteriorTerritory::HousingInteriorTerritory( Common::LandIdent ident,
|
||||||
uint32_t guId,
|
uint16_t territoryTypeId,
|
||||||
const std::string& internalName,
|
uint32_t guId,
|
||||||
const std::string& contentName ) :
|
const std::string& internalName,
|
||||||
|
const std::string& contentName ) :
|
||||||
Zone( territoryTypeId, guId, internalName, contentName ),
|
Zone( territoryTypeId, guId, internalName, contentName ),
|
||||||
m_landIdent( ident )
|
m_landIdent( ident )
|
||||||
{
|
{
|
||||||
m_lastActivityTime = static_cast< uint32_t >( Util::getTimeSeconds() );
|
m_lastActivityTime = static_cast< uint32_t >( Util::getTimeSeconds() );
|
||||||
}
|
}
|
||||||
|
|
||||||
Housing::HousingInteriorTerritory::~HousingInteriorTerritory()
|
Housing::HousingInteriorTerritory::~HousingInteriorTerritory() = default;
|
||||||
{
|
|
||||||
|
|
||||||
|
bool Sapphire::World::Territory::Housing::HousingInteriorTerritory::init()
|
||||||
|
{
|
||||||
|
updateYardObjects();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Housing::HousingInteriorTerritory::init()
|
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player )
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player )
|
|
||||||
{
|
{
|
||||||
auto pHousingMgr = g_fw.get< HousingMgr >();
|
auto pHousingMgr = g_fw.get< HousingMgr >();
|
||||||
auto pLog = g_fw.get< Logger >();
|
auto pLog = g_fw.get< Logger >();
|
||||||
|
@ -56,7 +58,7 @@ void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player )
|
||||||
"HousingInteriorTerritory::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryTypeId() ) +
|
"HousingInteriorTerritory::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryTypeId() ) +
|
||||||
", Entity#" + std::to_string( player.getId() ) );
|
", Entity#" + std::to_string( player.getId() ) );
|
||||||
|
|
||||||
auto indoorInitPacket = makeZonePacket< FFXIVIpcHousingIndoorInitialize >( player.getId() );
|
auto indoorInitPacket = makeZonePacket< Server::FFXIVIpcHousingIndoorInitialize >( player.getId() );
|
||||||
indoorInitPacket->data().u1 = 0;
|
indoorInitPacket->data().u1 = 0;
|
||||||
indoorInitPacket->data().u2 = 0;
|
indoorInitPacket->data().u2 = 0;
|
||||||
indoorInitPacket->data().u3 = 0;
|
indoorInitPacket->data().u3 = 0;
|
||||||
|
@ -72,40 +74,109 @@ void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player )
|
||||||
static_cast< Common::HousingInteriorSlot >( i ) );
|
static_cast< Common::HousingInteriorSlot >( i ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t yardPacketNum;
|
|
||||||
uint32_t yardPacketTotal = 2 + pLand->getSize();
|
|
||||||
|
|
||||||
player.queuePacket( indoorInitPacket );
|
player.queuePacket( indoorInitPacket );
|
||||||
|
|
||||||
for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ )
|
auto yardPacketTotal = static_cast< uint8_t >( 2 + pLand->getSize() );
|
||||||
|
for( uint8_t yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ )
|
||||||
{
|
{
|
||||||
auto objectInitPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() );
|
auto objectInitPacket = makeZonePacket< Server::FFXIVIpcHousingObjectInitialize >( player.getId() );
|
||||||
memcpy( &objectInitPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) );
|
memcpy( &objectInitPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) );
|
||||||
objectInitPacket->data().u1 = 0;
|
objectInitPacket->data().u1 = 0;
|
||||||
objectInitPacket->data().u2 = 100;
|
objectInitPacket->data().u2 = 100;
|
||||||
objectInitPacket->data().packetNum = yardPacketNum;
|
objectInitPacket->data().packetNum = yardPacketNum;
|
||||||
objectInitPacket->data().packetTotal = yardPacketTotal;
|
objectInitPacket->data().packetTotal = yardPacketTotal;
|
||||||
|
|
||||||
//TODO: Add Objects here
|
auto yardObjectSize = sizeof( Common::YardObject );
|
||||||
|
memcpy( &objectInitPacket->data().object, m_yardObjects.data() + ( yardPacketNum * 100 ), yardObjectSize * 100 );
|
||||||
|
|
||||||
player.queuePacket( objectInitPacket );
|
player.queuePacket( objectInitPacket );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Housing::HousingInteriorTerritory::onUpdate( uint32_t currTime )
|
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onUpdate( uint32_t currTime )
|
||||||
{
|
{
|
||||||
if( m_playerMap.size() > 0 )
|
if( m_playerMap.size() > 0 )
|
||||||
m_lastActivityTime = currTime;
|
m_lastActivityTime = currTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Housing::HousingInteriorTerritory::getLastActivityTime() const
|
uint32_t Sapphire::World::Territory::Housing::HousingInteriorTerritory::getLastActivityTime() const
|
||||||
{
|
{
|
||||||
return m_lastActivityTime;
|
return m_lastActivityTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Common::LandIdent Housing::HousingInteriorTerritory::getLandIdent() const
|
const Common::LandIdent Sapphire::World::Territory::Housing::HousingInteriorTerritory::getLandIdent() const
|
||||||
{
|
{
|
||||||
return m_landIdent;
|
return m_landIdent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardObjects()
|
||||||
|
{
|
||||||
|
auto housingMgr = g_fw.get< Manager::HousingMgr >();
|
||||||
|
|
||||||
|
auto containerIds = {
|
||||||
|
InventoryType::HousingInteriorPlacedItems1,
|
||||||
|
InventoryType::HousingInteriorPlacedItems2,
|
||||||
|
InventoryType::HousingInteriorPlacedItems3,
|
||||||
|
InventoryType::HousingInteriorPlacedItems4,
|
||||||
|
InventoryType::HousingInteriorPlacedItems5,
|
||||||
|
InventoryType::HousingInteriorPlacedItems6,
|
||||||
|
InventoryType::HousingInteriorPlacedItems7,
|
||||||
|
InventoryType::HousingInteriorPlacedItems8,
|
||||||
|
};
|
||||||
|
|
||||||
|
// zero out the array
|
||||||
|
// there's some really weird behaviour where *some* values will cause the linkshell invite notification to pop up
|
||||||
|
// for some reason
|
||||||
|
Common::YardObject obj {};
|
||||||
|
memset( &obj, 0x0, sizeof( Common::YardObject ) );
|
||||||
|
m_yardObjects.fill( obj );
|
||||||
|
|
||||||
|
auto containers = housingMgr->getEstateInventory( getLandIdent() );
|
||||||
|
|
||||||
|
uint8_t containerIdx = 0;
|
||||||
|
for( auto containerId : containerIds )
|
||||||
|
{
|
||||||
|
auto container = containers.find( containerId );
|
||||||
|
if( container == containers.end() )
|
||||||
|
// no more containers left
|
||||||
|
break;
|
||||||
|
|
||||||
|
for( const auto& item : container->second->getItemMap() )
|
||||||
|
{
|
||||||
|
auto housingItem = std::dynamic_pointer_cast< Inventory::HousingItem >( item.second );
|
||||||
|
assert( housingItem );
|
||||||
|
|
||||||
|
auto offset = item.first + ( containerIdx * 50 );
|
||||||
|
|
||||||
|
auto obj = housingMgr->getYardObjectForItem( housingItem );
|
||||||
|
|
||||||
|
m_yardObjects[ offset ] = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
containerIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::spawnYardObject( uint8_t containerIdx,
|
||||||
|
uint16_t slot,
|
||||||
|
Inventory::HousingItemPtr item )
|
||||||
|
{
|
||||||
|
auto housingMgr = g_fw.get< Manager::HousingMgr >();
|
||||||
|
|
||||||
|
auto offset = ( containerIdx * 50 ) + slot;
|
||||||
|
auto obj = housingMgr->getYardObjectForItem( item );
|
||||||
|
|
||||||
|
m_yardObjects[ offset ] = obj;
|
||||||
|
|
||||||
|
// for( const auto& player : m_playerMap )
|
||||||
|
// {
|
||||||
|
// auto packet = makeZonePacket< Server::FFXIVIpcYardObjectSpawn >( player.second->getId() );
|
||||||
|
//
|
||||||
|
// packet->data().landSetId = 0;
|
||||||
|
// packet->data().objectArray = static_cast< uint8_t >( offset );
|
||||||
|
// packet->data().object = obj;
|
||||||
|
//
|
||||||
|
// player.second->queuePacket( packet );
|
||||||
|
// }
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
#include "ForwardsZone.h"
|
#include "ForwardsZone.h"
|
||||||
#include "Territory/Zone.h"
|
#include "Territory/Zone.h"
|
||||||
|
#include "Common.h"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace Sapphire::World::Territory::Housing
|
namespace Sapphire::World::Territory::Housing
|
||||||
{
|
{
|
||||||
|
@ -22,8 +24,13 @@ namespace Sapphire::World::Territory::Housing
|
||||||
|
|
||||||
const Common::LandIdent getLandIdent() const;
|
const Common::LandIdent getLandIdent() const;
|
||||||
|
|
||||||
|
void updateYardObjects();
|
||||||
|
void spawnYardObject( uint8_t containerIdx, uint16_t slot, Inventory::HousingItemPtr item );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::LandIdent m_landIdent;
|
Common::LandIdent m_landIdent;
|
||||||
uint32_t m_lastActivityTime;
|
uint32_t m_lastActivityTime;
|
||||||
|
|
||||||
|
std::array< Sapphire::Common::YardObject, 400 > m_yardObjects;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -103,6 +103,14 @@ bool Sapphire::HousingZone::init()
|
||||||
cursor += itemMax;
|
cursor += itemMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// zero out the yard obj arrays so we don't leak memory like SE does :^)
|
||||||
|
Common::YardObject obj {};
|
||||||
|
memset( &obj, 0x0, sizeof( Common::YardObject ) );
|
||||||
|
|
||||||
|
for( auto& arr : m_yardObjects )
|
||||||
|
{
|
||||||
|
arr.fill( obj );
|
||||||
|
}
|
||||||
|
|
||||||
auto housingMgr = g_fw.get< World::Manager::HousingMgr >();
|
auto housingMgr = g_fw.get< World::Manager::HousingMgr >();
|
||||||
auto landCache = housingMgr->getLandCacheMap();
|
auto landCache = housingMgr->getLandCacheMap();
|
||||||
|
@ -137,27 +145,7 @@ bool Sapphire::HousingZone::init()
|
||||||
if( entry.m_houseId > 0 )
|
if( entry.m_houseId > 0 )
|
||||||
registerEstateEntranceEObj( entry.m_landId );
|
registerEstateEntranceEObj( entry.m_landId );
|
||||||
|
|
||||||
// add items to yard object array
|
updateYardObjects( land->getLandIdent() );
|
||||||
auto& inventory = housingMgr->getEstateInventory( land->getLandIdent() );
|
|
||||||
auto& externalContainer = inventory[ InventoryType::HousingExteriorPlacedItems ];
|
|
||||||
|
|
||||||
auto arrayBounds = m_yardObjectArrayBounds[ entry.m_landId ];
|
|
||||||
auto yardMapIndex = entry.m_landId <= 29 ? 0 : 1;
|
|
||||||
|
|
||||||
for( auto& item : externalContainer->getItemMap() )
|
|
||||||
{
|
|
||||||
Common::YardObject obj{};
|
|
||||||
|
|
||||||
auto housingItem = std::dynamic_pointer_cast< Inventory::HousingItem >( item.second );
|
|
||||||
assert( housingItem );
|
|
||||||
|
|
||||||
obj.itemId = housingItem->getAdditionalData();
|
|
||||||
obj.itemRotation = housingItem->getRot();
|
|
||||||
obj.pos = housingItem->getPos();
|
|
||||||
|
|
||||||
auto idx = item.first + arrayBounds.first;
|
|
||||||
m_yardObjects[ yardMapIndex ][ idx ] = obj;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -344,9 +332,16 @@ void Sapphire::HousingZone::updateYardObjects( Sapphire::Common::LandIdent ident
|
||||||
|
|
||||||
auto yardContainer = landStorage[ InventoryType::HousingExteriorPlacedItems ];
|
auto yardContainer = landStorage[ InventoryType::HousingExteriorPlacedItems ];
|
||||||
|
|
||||||
|
auto arrayBounds = m_yardObjectArrayBounds[ ident.landId ];
|
||||||
|
auto yardMapIndex = ident.landId <= 29 ? 0 : 1;
|
||||||
|
|
||||||
for( const auto& item : yardContainer->getItemMap() )
|
for( const auto& item : yardContainer->getItemMap() )
|
||||||
{
|
{
|
||||||
|
auto housingItem = std::dynamic_pointer_cast< Inventory::HousingItem >( item.second );
|
||||||
|
assert( housingItem );
|
||||||
|
|
||||||
|
auto idx = item.first + arrayBounds.first;
|
||||||
|
m_yardObjects[ yardMapIndex ][ idx ] = housingMgr->getYardObjectForItem( housingItem );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +366,7 @@ void Sapphire::HousingZone::spawnYardObject( uint8_t landId, uint16_t slotId, In
|
||||||
{
|
{
|
||||||
auto packet = makeZonePacket< Server::FFXIVIpcYardObjectSpawn >( player.second->getId() );
|
auto packet = makeZonePacket< Server::FFXIVIpcYardObjectSpawn >( player.second->getId() );
|
||||||
|
|
||||||
packet->data().landSetId = landId;
|
packet->data().landId = landId;
|
||||||
packet->data().objectArray = static_cast< uint8_t >( slotId );
|
packet->data().objectArray = static_cast< uint8_t >( slotId );
|
||||||
packet->data().object = obj;
|
packet->data().object = obj;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue