1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-27 06:47:45 +00:00

a bit of refactoring, partially working yard item movement

This commit is contained in:
NotAdam 2018-12-27 22:28:31 +11:00
parent 858b243e3b
commit 851446f4d8
9 changed files with 123 additions and 57 deletions

View file

@ -851,7 +851,7 @@ namespace Sapphire::Common
uint32_t unkown1; //12
};
struct YardObject
struct HousingObject
{
uint32_t itemId;
uint16_t itemRotation;

View file

@ -215,6 +215,11 @@ enum ActorControlType : uint16_t
ShowBuildPresetUI = 0x3E9,
BuildPresetResponse = 0x3ED,
/*!
* param1 = object array index
*/
RemoveInteriorHousingItem = 0x3F1,
/*!
* param1 = identity shit
* u16 1 - container id
@ -223,6 +228,7 @@ enum ActorControlType : uint16_t
* u16 1 - slot
*/
HousingItemMoveConfirm = 0x3F9,
OpenEstateSettingsUI = 0x3FF,
/*!
* param1 = outdoor furnishings

View file

@ -1684,17 +1684,15 @@ struct FFXIVIpcYardObjectSpawn : FFXIVIpcBasePacket<YardObjectSpawn>
uint8_t landId;
uint8_t objectArray;
uint16_t unknown1;
Common::YardObject object;
Common::HousingObject object;
};
struct FFXIVIpcYardObjectMove : FFXIVIpcBasePacket< YardObjectMove >
{
uint16_t itemRotation;
uint8_t objectArray;
uint8_t landSetId;
uint16_t pos_x;
uint16_t pos_y;
uint16_t pos_z;
uint8_t landId;
Common::FFXIVARR_POSITION3_U16 pos;
uint16_t unknown1;
uint16_t unknown2;
uint16_t unknown3;
@ -1707,7 +1705,7 @@ struct FFXIVIpcHousingObjectInitialize : FFXIVIpcBasePacket< HousingObjectInitia
uint8_t packetNum;
uint8_t packetTotal;
uint8_t u2; //Outdoor 0 / Indoor 100(?)
Common::YardObject object[100];
Common::HousingObject object[100];
uint32_t unknown4; //unused
};

View file

@ -1010,17 +1010,18 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
auto ident = land->getLandIdent();
bool status = false;
if( isOutside )
{
if( !placeExternalItem( player, item, ident ) )
player.sendUrgent( "An internal error occurred when placing the item." );
}
status = placeExternalItem( player, item, ident );
else
status = placeInteriorItem( player, item );
if( status )
player.queuePacket( Server::makeActorControl143( player.getId(), 0x3f3 ) );
else
{
if( !placeInteriorItem( player, item ) )
player.sendUrgent( "An internal error occurred when placing the item." );
}
}
bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player,
Inventory::HousingItemPtr item,
@ -1051,7 +1052,7 @@ bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& pl
auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() );
assert( zone );
zone->spawnYardObject( ident.landId, freeSlot, item );
zone->spawnYardObject( ident.landId, freeSlot, *item );
return true;
}
@ -1099,7 +1100,7 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() );
assert( zone );
zone->spawnYardObject( containerIdx, freeSlot, containerId, item );
zone->spawnHousingObject( containerIdx, freeSlot, containerId, item );
return true;
}
@ -1107,9 +1108,9 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
return false;
}
Sapphire::Common::YardObject Sapphire::World::Manager::HousingMgr::getYardObjectForItem( Inventory::HousingItemPtr item ) const
Sapphire::Common::HousingObject Sapphire::World::Manager::HousingMgr::getYardObjectForItem( Inventory::HousingItemPtr item ) const
{
Sapphire::Common::YardObject obj {};
Sapphire::Common::HousingObject obj {};
obj.pos = item->getPos();
obj.itemRotation = item->getRot();
@ -1169,7 +1170,7 @@ void Sapphire::World::Manager::HousingMgr::reqMoveHousingItem( Entity::Player& p
}
else if( auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) )
{
moveExternalItem( player, ident, slot, pos, rot );
moveExternalItem( player, ident, slot, *terri, pos, rot );
}
}
@ -1214,7 +1215,7 @@ bool Sapphire::World::Manager::HousingMgr::moveInternalItem( Entity::Player& pla
auto invMgr = g_fw.get< InventoryMgr >();
invMgr->updateHousingItemPosition( item );
terri.updateObjectPosition( slot, item->getPos(), item->getRot() );
terri.updateHousingObjectPosition( slot, item->getPos(), item->getRot() );
// send confirmation to player
uint32_t param1 = ( ident.landId << 16 ) | containerId;
@ -1228,8 +1229,42 @@ bool Sapphire::World::Manager::HousingMgr::moveInternalItem( Entity::Player& pla
bool Sapphire::World::Manager::HousingMgr::moveExternalItem( Entity::Player& player,
Common::LandIdent ident, uint16_t slot,
Common::FFXIVARR_POSITION3 pos, float rot )
Sapphire::HousingZone& terri, Common::FFXIVARR_POSITION3 pos,
float rot )
{
auto land = terri.getLand( ident.landId );
// todo: add proper perms check
if( land->getOwnerId() != player.getId() )
return false;
auto& containers = getEstateInventory( ident );
auto needle = containers.find( InventoryType::HousingExteriorPlacedItems );
if( needle == containers.end() )
return false;
auto container = needle->second;
auto item = std::dynamic_pointer_cast< Inventory::HousingItem >( container->getItem( slot ) );
if( !item )
return false;
item->setPos( {
Util::floatToUInt16( pos.x ),
Util::floatToUInt16( pos.y ),
Util::floatToUInt16( pos.z )
} );
item->setRot( Util::floatToUInt16Rot( rot ) );
auto invMgr = g_fw.get< InventoryMgr >();
invMgr->updateHousingItemPosition( item );
terri.updateYardObjectPos( slot, ident.landId, *item );
// todo: something is sent to the player here to indicate the move has finished successfully
// currently they can move one item and then can't move any more
return true;
}

View file

@ -163,7 +163,7 @@ namespace Sapphire::World::Manager
* @param item The item to convert into a YardObject
* @return The resultant YardObject
*/
Common::YardObject getYardObjectForItem( Inventory::HousingItemPtr item ) const;
Common::HousingObject getYardObjectForItem( Inventory::HousingItemPtr item ) const;
void reqMoveHousingItem( Entity::Player& player, Common::LandIdent ident, uint16_t slot,
@ -186,7 +186,7 @@ namespace Sapphire::World::Manager
* @return
*/
bool moveExternalItem( Entity::Player& player, Common::LandIdent ident, uint16_t slot,
Common::FFXIVARR_POSITION3 pos, float rot );
Sapphire::HousingZone& terri, Common::FFXIVARR_POSITION3 pos, float rot );
/*!
* @brief Processes the movement of an item placed inside a HousingInteriorTerritory

View file

@ -45,7 +45,7 @@ Housing::HousingInteriorTerritory::~HousingInteriorTerritory() = default;
bool Sapphire::World::Territory::Housing::HousingInteriorTerritory::init()
{
updateYardObjects();
updateHousingObjects();
return true;
}
@ -86,8 +86,8 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
objectInitPacket->data().packetNum = yardPacketNum;
objectInitPacket->data().packetTotal = yardPacketTotal;
auto yardObjectSize = sizeof( Common::YardObject );
memcpy( &objectInitPacket->data().object, m_yardObjects.data() + ( yardPacketNum * 100 ), yardObjectSize * 100 );
auto yardObjectSize = sizeof( Common::HousingObject );
memcpy( &objectInitPacket->data().object, m_housingObjects.data() + ( yardPacketNum * 100 ), yardObjectSize * 100 );
player.queuePacket( objectInitPacket );
}
@ -110,7 +110,7 @@ const Common::LandIdent Sapphire::World::Territory::Housing::HousingInteriorTerr
return m_landIdent;
}
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardObjects()
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateHousingObjects()
{
auto housingMgr = g_fw.get< Manager::HousingMgr >();
@ -128,9 +128,9 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardOb
// 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 );
Common::HousingObject obj {};
memset( &obj, 0x0, sizeof( Common::HousingObject ) );
m_housingObjects.fill( obj );
auto containers = housingMgr->getEstateInventory( getLandIdent() );
@ -151,14 +151,14 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardOb
auto obj = housingMgr->getYardObjectForItem( housingItem );
m_yardObjects[ offset ] = obj;
m_housingObjects[ offset ] = obj;
}
containerIdx++;
}
}
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::spawnYardObject( uint8_t containerIdx,
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::spawnHousingObject( uint8_t containerIdx,
uint16_t slot,
uint16_t containerType,
Inventory::HousingItemPtr item )
@ -168,7 +168,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::spawnYardObj
auto offset = ( containerIdx * 50 ) + slot;
auto obj = housingMgr->getYardObjectForItem( item );
m_yardObjects[ offset ] = obj;
m_housingObjects[ offset ] = obj;
for( const auto& player : m_playerMap )
{
@ -185,11 +185,11 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::spawnYardObj
}
}
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateObjectPosition( uint16_t slot,
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateHousingObjectPosition( uint16_t slot,
Sapphire::Common::FFXIVARR_POSITION3_U16 pos,
uint16_t rot )
{
auto& obj = m_yardObjects[ slot ];
auto& obj = m_housingObjects[ slot ];
obj.pos = pos;
obj.itemRotation = rot;

View file

@ -24,14 +24,15 @@ namespace Sapphire::World::Territory::Housing
const Common::LandIdent getLandIdent() const;
void updateYardObjects();
void spawnYardObject( uint8_t containerIdx, uint16_t slot, uint16_t containerType, Inventory::HousingItemPtr item );
void updateObjectPosition( uint16_t slot, Common::FFXIVARR_POSITION3_U16 pos, uint16_t rot );
void updateHousingObjects();
void spawnHousingObject( uint8_t containerIdx, uint16_t slot, uint16_t containerType,
Inventory::HousingItemPtr item );
void updateHousingObjectPosition( uint16_t slot, Common::FFXIVARR_POSITION3_U16 pos, uint16_t rot );
private:
Common::LandIdent m_landIdent;
uint32_t m_lastActivityTime;
std::array< Sapphire::Common::YardObject, 400 > m_yardObjects;
std::array< Sapphire::Common::HousingObject, 400 > m_housingObjects;
};
}

View file

@ -104,8 +104,8 @@ bool Sapphire::HousingZone::init()
}
// zero out the yard obj arrays so we don't leak memory like SE does :^)
Common::YardObject obj {};
memset( &obj, 0x0, sizeof( Common::YardObject ) );
Common::HousingObject obj {};
memset( &obj, 0x0, sizeof( Common::HousingObject ) );
for( auto& arr : m_yardObjects )
{
@ -175,7 +175,7 @@ void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player )
housingObjectInit->data().packetNum = yardPacketNum;
housingObjectInit->data().packetTotal = yardPacketTotal;
auto yardObjectSize = sizeof( Common::YardObject );
auto yardObjectSize = sizeof( Common::HousingObject );
auto& objects = m_yardObjects[ isInSubdivision ? 1 : 0 ];
@ -345,17 +345,17 @@ void Sapphire::HousingZone::updateYardObjects( Sapphire::Common::LandIdent ident
}
}
void Sapphire::HousingZone::spawnYardObject( uint8_t landId, uint16_t slotId, Inventory::HousingItemPtr item )
void Sapphire::HousingZone::spawnYardObject( uint8_t landId, uint16_t slotId, Inventory::HousingItem& item )
{
auto bounds = m_yardObjectArrayBounds[ landId ];
auto offset = bounds.first + slotId;
Common::YardObject obj {};
Common::HousingObject obj {};
obj.itemId = item->getAdditionalData();
obj.itemRotation = item->getRot();
obj.itemId = item.getAdditionalData();
obj.itemRotation = item.getRot();
obj.pos = item->getPos();
obj.pos = item.getPos();
// link obj
auto yardMapIndex = landId <= 29 ? 0 : 1;
@ -373,3 +373,28 @@ void Sapphire::HousingZone::spawnYardObject( uint8_t landId, uint16_t slotId, In
player.second->queuePacket( packet );
}
}
void Sapphire::HousingZone::updateYardObjectPos( uint16_t slot, uint16_t landId, Inventory::HousingItem& item )
{
auto bounds = m_yardObjectArrayBounds[ landId ];
auto offset = bounds.first + slot;
auto yardMapIndex = landId <= 29 ? 0 : 1;
auto& obj = m_yardObjects[ yardMapIndex ][ offset ];
obj.itemRotation = item.getRot();
obj.pos = item.getPos();
for( const auto& player : m_playerMap )
{
auto packet = makeZonePacket< Server::FFXIVIpcYardObjectMove >( player.second->getId() );
packet->data().itemRotation = item.getRot();
packet->data().pos = item.getPos();
packet->data().landId = landId;
packet->data().objectArray = slot;
player.second->queuePacket( packet );
}
}

View file

@ -55,11 +55,12 @@ namespace Sapphire
Entity::EventObjectPtr registerEstateEntranceEObj( uint8_t landId );
void updateYardObjects( Common::LandIdent ident );
void spawnYardObject( uint8_t landId, uint16_t slotId, Sapphire::Inventory::HousingItemPtr item );
void spawnYardObject( uint8_t landId, uint16_t slotId, Sapphire::Inventory::HousingItem& item );
void updateYardObjectPos( uint16_t slot, uint16_t landId, Inventory::HousingItem& item );
private:
using LandPtrMap = std::unordered_map< uint8_t, Sapphire::LandPtr >;
using YardObjectArray = std::array< Common::YardObject, 800 >;
using YardObjectArray = std::array< Common::HousingObject, 800 >;
using YardObjectSubdivisionArray = std::array< YardObjectArray, 2 >;
/*!