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 uint32_t unkown1; //12
}; };
struct YardObject struct HousingObject
{ {
uint32_t itemId; uint32_t itemId;
uint16_t itemRotation; uint16_t itemRotation;

View file

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

View file

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

View file

@ -1010,16 +1010,17 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity
auto ident = land->getLandIdent(); auto ident = land->getLandIdent();
bool status = false;
if( isOutside ) if( isOutside )
{ status = placeExternalItem( player, item, ident );
if( !placeExternalItem( player, item, ident ) )
player.sendUrgent( "An internal error occurred when placing the item." );
}
else else
{ status = placeInteriorItem( player, item );
if( !placeInteriorItem( player, item ) )
player.sendUrgent( "An internal error occurred when placing the item." ); if( status )
} player.queuePacket( Server::makeActorControl143( player.getId(), 0x3f3 ) );
else
player.sendUrgent( "An internal error occurred when placing the item." );
} }
bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player, bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& player,
@ -1051,7 +1052,7 @@ bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& pl
auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() );
assert( zone ); assert( zone );
zone->spawnYardObject( ident.landId, freeSlot, item ); zone->spawnYardObject( ident.landId, freeSlot, *item );
return true; 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() ); auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() );
assert( zone ); assert( zone );
zone->spawnYardObject( containerIdx, freeSlot, containerId, item ); zone->spawnHousingObject( containerIdx, freeSlot, containerId, item );
return true; return true;
} }
@ -1107,9 +1108,9 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl
return false; 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.pos = item->getPos();
obj.itemRotation = item->getRot(); 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() ) ) 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 >(); auto invMgr = g_fw.get< InventoryMgr >();
invMgr->updateHousingItemPosition( item ); invMgr->updateHousingItemPosition( item );
terri.updateObjectPosition( slot, item->getPos(), item->getRot() ); terri.updateHousingObjectPosition( slot, item->getPos(), item->getRot() );
// send confirmation to player // send confirmation to player
uint32_t param1 = ( ident.landId << 16 ) | containerId; 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, bool Sapphire::World::Manager::HousingMgr::moveExternalItem( Entity::Player& player,
Common::LandIdent ident, uint16_t slot, 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; return true;
} }

View file

@ -163,7 +163,7 @@ namespace Sapphire::World::Manager
* @param item The item to convert into a YardObject * @param item The item to convert into a YardObject
* @return The resultant 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, void reqMoveHousingItem( Entity::Player& player, Common::LandIdent ident, uint16_t slot,
@ -186,7 +186,7 @@ namespace Sapphire::World::Manager
* @return * @return
*/ */
bool moveExternalItem( Entity::Player& player, Common::LandIdent ident, uint16_t slot, 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 * @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() bool Sapphire::World::Territory::Housing::HousingInteriorTerritory::init()
{ {
updateYardObjects(); updateHousingObjects();
return true; return true;
} }
@ -86,8 +86,8 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
objectInitPacket->data().packetNum = yardPacketNum; objectInitPacket->data().packetNum = yardPacketNum;
objectInitPacket->data().packetTotal = yardPacketTotal; objectInitPacket->data().packetTotal = yardPacketTotal;
auto yardObjectSize = sizeof( Common::YardObject ); auto yardObjectSize = sizeof( Common::HousingObject );
memcpy( &objectInitPacket->data().object, m_yardObjects.data() + ( yardPacketNum * 100 ), yardObjectSize * 100 ); memcpy( &objectInitPacket->data().object, m_housingObjects.data() + ( yardPacketNum * 100 ), yardObjectSize * 100 );
player.queuePacket( objectInitPacket ); player.queuePacket( objectInitPacket );
} }
@ -110,7 +110,7 @@ const Common::LandIdent Sapphire::World::Territory::Housing::HousingInteriorTerr
return m_landIdent; return m_landIdent;
} }
void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardObjects() void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateHousingObjects()
{ {
auto housingMgr = g_fw.get< Manager::HousingMgr >(); auto housingMgr = g_fw.get< Manager::HousingMgr >();
@ -128,9 +128,9 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardOb
// zero out the array // zero out the array
// there's some really weird behaviour where *some* values will cause the linkshell invite notification to pop up // there's some really weird behaviour where *some* values will cause the linkshell invite notification to pop up
// for some reason // for some reason
Common::YardObject obj {}; Common::HousingObject obj {};
memset( &obj, 0x0, sizeof( Common::YardObject ) ); memset( &obj, 0x0, sizeof( Common::HousingObject ) );
m_yardObjects.fill( obj ); m_housingObjects.fill( obj );
auto containers = housingMgr->getEstateInventory( getLandIdent() ); auto containers = housingMgr->getEstateInventory( getLandIdent() );
@ -151,24 +151,24 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::updateYardOb
auto obj = housingMgr->getYardObjectForItem( housingItem ); auto obj = housingMgr->getYardObjectForItem( housingItem );
m_yardObjects[ offset ] = obj; m_housingObjects[ offset ] = obj;
} }
containerIdx++; 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 slot,
uint16_t containerType, uint16_t containerType,
Inventory::HousingItemPtr item ) Inventory::HousingItemPtr item )
{ {
auto housingMgr = g_fw.get< Manager::HousingMgr >(); auto housingMgr = g_fw.get< Manager::HousingMgr >();
auto offset = ( containerIdx * 50 ) + slot; auto offset = ( containerIdx * 50 ) + slot;
auto obj = housingMgr->getYardObjectForItem( item ); auto obj = housingMgr->getYardObjectForItem( item );
m_yardObjects[ offset ] = obj; m_housingObjects[ offset ] = obj;
for( const auto& player : m_playerMap ) 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, Sapphire::Common::FFXIVARR_POSITION3_U16 pos,
uint16_t rot ) uint16_t rot )
{ {
auto& obj = m_yardObjects[ slot ]; auto& obj = m_housingObjects[ slot ];
obj.pos = pos; obj.pos = pos;
obj.itemRotation = rot; obj.itemRotation = rot;

View file

@ -24,14 +24,15 @@ namespace Sapphire::World::Territory::Housing
const Common::LandIdent getLandIdent() const; const Common::LandIdent getLandIdent() const;
void updateYardObjects(); void updateHousingObjects();
void spawnYardObject( uint8_t containerIdx, uint16_t slot, uint16_t containerType, Inventory::HousingItemPtr item ); void spawnHousingObject( uint8_t containerIdx, uint16_t slot, uint16_t containerType,
void updateObjectPosition( uint16_t slot, Common::FFXIVARR_POSITION3_U16 pos, uint16_t rot ); Inventory::HousingItemPtr item );
void updateHousingObjectPosition( uint16_t slot, Common::FFXIVARR_POSITION3_U16 pos, uint16_t rot );
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; 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 :^) // zero out the yard obj arrays so we don't leak memory like SE does :^)
Common::YardObject obj {}; Common::HousingObject obj {};
memset( &obj, 0x0, sizeof( Common::YardObject ) ); memset( &obj, 0x0, sizeof( Common::HousingObject ) );
for( auto& arr : m_yardObjects ) for( auto& arr : m_yardObjects )
{ {
@ -175,7 +175,7 @@ void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player )
housingObjectInit->data().packetNum = yardPacketNum; housingObjectInit->data().packetNum = yardPacketNum;
housingObjectInit->data().packetTotal = yardPacketTotal; housingObjectInit->data().packetTotal = yardPacketTotal;
auto yardObjectSize = sizeof( Common::YardObject ); auto yardObjectSize = sizeof( Common::HousingObject );
auto& objects = m_yardObjects[ isInSubdivision ? 1 : 0 ]; 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 bounds = m_yardObjectArrayBounds[ landId ];
auto offset = bounds.first + slotId; auto offset = bounds.first + slotId;
Common::YardObject obj {}; Common::HousingObject obj {};
obj.itemId = item->getAdditionalData(); obj.itemId = item.getAdditionalData();
obj.itemRotation = item->getRot(); obj.itemRotation = item.getRot();
obj.pos = item->getPos(); obj.pos = item.getPos();
// link obj // link obj
auto yardMapIndex = landId <= 29 ? 0 : 1; auto yardMapIndex = landId <= 29 ? 0 : 1;
@ -370,6 +370,31 @@ void Sapphire::HousingZone::spawnYardObject( uint8_t landId, uint16_t slotId, In
packet->data().objectArray = static_cast< uint8_t >( slotId ); packet->data().objectArray = static_cast< uint8_t >( slotId );
packet->data().object = obj; packet->data().object = obj;
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 ); player.second->queuePacket( packet );
} }
} }

View file

@ -55,11 +55,12 @@ namespace Sapphire
Entity::EventObjectPtr registerEstateEntranceEObj( uint8_t landId ); Entity::EventObjectPtr registerEstateEntranceEObj( uint8_t landId );
void updateYardObjects( Common::LandIdent ident ); 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: private:
using LandPtrMap = std::unordered_map< uint8_t, Sapphire::LandPtr >; 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 >; using YardObjectSubdivisionArray = std::array< YardObjectArray, 2 >;
/*! /*!