diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index c4c82786..62522203 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -314,7 +314,7 @@ namespace Sapphire::Network::Packets LandRenameHandler = 0x0171, // updated 4.4 HousingUpdateHouseGreeting = 0x0172, // updated 4.4 - HousingUpdateObjectRotation = 0x0173, // updated 4.4 + HousingUpdateObjectPosition = 0x0173, // updated 4.4 SetSharedEstateSettings = 0x0177, // updated 4.4 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 2cf8c863..011fd400 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -256,6 +256,19 @@ struct FFXIVIpcReqPlaceHousingItem : /* 0020 */ uint32_t unknown4[2]; // always 0 it looks like }; +struct FFXIVIpcHousingUpdateObjectPosition : + FFXIVIpcBasePacket< HousingUpdateObjectPosition > +{ + /* 0000 */ Common::LandIdent ident; + /* 0008 */ uint16_t slot; + /* 000A */ uint16_t containerId; + + /* 000C */ Common::FFXIVARR_POSITION3 pos; + /* 0018 */ float rotation; + + /* 001C */ uint32_t padding; +}; + } } } diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 2971830f..c41094ca 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -39,13 +39,13 @@ extern Sapphire::Framework g_fw; Sapphire::World::Manager::HousingMgr::HousingMgr() { m_containerMap[ 0 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 1 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 2 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 3 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 4 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 5 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 6 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); - m_containerMap[ 7 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems1, InventoryType::HousingInteriorStoreroom1 ); + m_containerMap[ 1 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems2, InventoryType::HousingInteriorStoreroom2 ); + m_containerMap[ 2 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems3, InventoryType::HousingInteriorStoreroom3 ); + m_containerMap[ 3 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems4, InventoryType::HousingInteriorStoreroom4 ); + m_containerMap[ 4 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems5, InventoryType::HousingInteriorStoreroom5 ); + m_containerMap[ 5 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems6, InventoryType::HousingInteriorStoreroom6 ); + m_containerMap[ 6 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems7, InventoryType::HousingInteriorStoreroom7 ); + m_containerMap[ 7 ] = std::make_pair( InventoryType::HousingInteriorPlacedItems8, InventoryType::HousingInteriorStoreroom8 ); m_internalPlacedItemContainers = { @@ -247,7 +247,7 @@ void Sapphire::World::Manager::HousingMgr::initLandCache() uint16_t count = 0; for( int i = 0; i < 8; ++i ) { - if( count >= entry.m_maxPlacedInternalItems ) + if( count > entry.m_maxPlacedInternalItems ) break; auto& pair = m_containerMap[ i ]; @@ -978,6 +978,9 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity if( land->getOwnerId() != player.getId() ) return; + // todo: check item position and make sure it's not outside the plot + // retail uses a radius based check + // unlink item Inventory::HousingItemPtr item; @@ -1063,12 +1066,17 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl auto ident = zone->getLandIdent(); + auto& containers = getEstateInventory( ident ); + // find first free container uint8_t containerIdx = 0; for( auto containerId : m_internalPlacedItemContainers ) { - auto& container = getEstateInventory( ident )[ containerId ]; + auto needle = containers.find( containerId ); + if( needle == containers.end() ) + continue; + auto container = needle->second; auto freeSlot = container->getFreeSlot(); if( freeSlot == -1 ) { @@ -1137,4 +1145,23 @@ void Sapphire::World::Manager::HousingMgr::sendInternalEstateInventoryBatch( Sap invMgr->sendInventoryContainer( player, container->second ); } +} + +void Sapphire::World::Manager::HousingMgr::reqMoveHousingItem( Entity::Player& player, + Common::LandIdent ident, uint16_t slot, + uint16_t container, + Common::FFXIVARR_POSITION3 pos, float rot ) +{ + auto landSet = toLandSetId( ident.territoryTypeId, ident.wardNum ); + auto land = getHousingZoneByLandSetId( landSet )->getLand( ident.landId ); + + if( !land ) + return; + + // todo: proper perms checks + if( land->getOwnerId() != player.getId() ) + return; + + // update item in db + } \ No newline at end of file diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 4506fe1c..14ca5009 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -165,6 +165,11 @@ namespace Sapphire::World::Manager */ Common::YardObject getYardObjectForItem( Inventory::HousingItemPtr item ) const; + + void reqMoveHousingItem( Entity::Player& player, Common::LandIdent ident, uint16_t slot, + uint16_t container, Common::FFXIVARR_POSITION3 pos, float rot ); + + private: /*! diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index cf16b7db..7530d2b5 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -89,6 +89,8 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH setZoneHandler( ClientZoneIpcType::HousingUpdateHouseGreeting, "HousingUpdateHouseGreeting", &GameConnection::housingUpdateGreetingHandler ); setZoneHandler( ClientZoneIpcType::ReqPlaceHousingItem, "ReqPlaceHousingItem", &GameConnection::reqPlaceHousingItem ); + setZoneHandler( ClientZoneIpcType::HousingUpdateObjectPosition, "HousingUpdateObjectPosition", + &GameConnection::reqMoveHousingItem ); setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk ); setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote ); diff --git a/src/world/Network/GameConnection.h b/src/world/Network/GameConnection.h index 60710546..b6fa0738 100644 --- a/src/world/Network/GameConnection.h +++ b/src/world/Network/GameConnection.h @@ -173,6 +173,8 @@ namespace Sapphire::Network DECLARE_HANDLER( reqPlaceHousingItem ); + DECLARE_HANDLER( reqMoveHousingItem ); + }; } diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index e3207a63..daab3cdb 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -715,4 +715,16 @@ void Sapphire::Network::GameConnection::reqPlaceHousingItem( const Packets::FFXI housingMgr->reqPlaceHousingItem( player, data.landId, data.sourceInvContainerId, data.sourceInvSlotId, data.position, data.rotation ); +} + +void Sapphire::Network::GameConnection::reqMoveHousingItem( const Packets::FFXIVARR_PACKET_RAW& inPacket, + Entity::Player& player ) +{ + auto housingMgr = g_fw.get< HousingMgr >(); + + const auto packet = ZoneChannelPacket< Client::FFXIVIpcHousingUpdateObjectPosition >( inPacket ); + const auto& data = packet.data(); + + housingMgr->reqMoveHousingItem( player, data.ident, data.slot, data.containerId, data.pos, data.rotation ); + } \ No newline at end of file