mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-29 07:37:45 +00:00
Merge pull request #708 from collett8192/housing_fix
Housing bug fixes and implement house exterior editing.
This commit is contained in:
commit
17ca2c950a
14 changed files with 161 additions and 22 deletions
|
@ -194,6 +194,15 @@ namespace Sapphire::Network::Packets
|
||||||
EventPlay128 = 0x038A, // updated 5.35 hotfix
|
EventPlay128 = 0x038A, // updated 5.35 hotfix
|
||||||
EventPlay255 = 0x034B, // updated 5.35 hotfix
|
EventPlay255 = 0x034B, // updated 5.35 hotfix
|
||||||
|
|
||||||
|
EventYield = 0x037D, // updated 5.35 hotfix
|
||||||
|
//EventYield4 = 0x0000,
|
||||||
|
//EventYield8 = 0x0000,
|
||||||
|
//EventYield16 = 0x0000,
|
||||||
|
//EventYield32 = 0x0000,
|
||||||
|
//EventYield64 = 0x0000,
|
||||||
|
//EventYield128 = 0x0000,
|
||||||
|
//EventYield255 = 0x0000,
|
||||||
|
|
||||||
EventStart = 0x009A, // updated 5.35 hotfix
|
EventStart = 0x009A, // updated 5.35 hotfix
|
||||||
EventFinish = 0x007E, // updated 5.35 hotfix
|
EventFinish = 0x007E, // updated 5.35 hotfix
|
||||||
|
|
||||||
|
@ -374,7 +383,7 @@ namespace Sapphire::Network::Packets
|
||||||
OutOfRangeEventHandler = 0x0319, // updated 5.35 hotfix
|
OutOfRangeEventHandler = 0x0319, // updated 5.35 hotfix
|
||||||
EnterTeriEventHandler = 0x0192, // updated 5.35 hotfix
|
EnterTeriEventHandler = 0x0192, // updated 5.35 hotfix
|
||||||
ShopEventHandler = 0x01F6, // updated 5.35 hotfix
|
ShopEventHandler = 0x01F6, // updated 5.35 hotfix
|
||||||
|
EventYieldHandler = 0x0128, // updated 5.35 hotfix
|
||||||
ReturnEventHandler = 0x02B4, // updated 5.35 hotfix
|
ReturnEventHandler = 0x02B4, // updated 5.35 hotfix
|
||||||
TradeReturnEventHandler = 0x00A4, // updated 5.35 hotfix
|
TradeReturnEventHandler = 0x00A4, // updated 5.35 hotfix
|
||||||
TradeMultipleReturnEventHander = 0x035C, // updated 5.35 hotfix
|
TradeMultipleReturnEventHander = 0x035C, // updated 5.35 hotfix
|
||||||
|
@ -387,6 +396,7 @@ namespace Sapphire::Network::Packets
|
||||||
LandRenameHandler = 0x0155, // updated 5.35 hotfix
|
LandRenameHandler = 0x0155, // updated 5.35 hotfix
|
||||||
HousingUpdateHouseGreeting = 0x02EA, // updated 5.35 hotfix
|
HousingUpdateHouseGreeting = 0x02EA, // updated 5.35 hotfix
|
||||||
HousingUpdateObjectPosition = 0x00D5, // updated 5.35 hotfix
|
HousingUpdateObjectPosition = 0x00D5, // updated 5.35 hotfix
|
||||||
|
HousingEditExterior = 0x0098, // updated 5.35 hotfix
|
||||||
|
|
||||||
SetSharedEstateSettings = 0x017B, // updated 5.0
|
SetSharedEstateSettings = 0x017B, // updated 5.0
|
||||||
|
|
||||||
|
|
|
@ -426,6 +426,18 @@ struct FFXIVIpcDive :
|
||||||
uint32_t padding;
|
uint32_t padding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FFXIVIpcHousingEditExterior :
|
||||||
|
FFXIVIpcBasePacket< HousingEditExterior >
|
||||||
|
{
|
||||||
|
uint16_t landId;
|
||||||
|
uint8_t unknown[6];
|
||||||
|
uint8_t removeFlag;
|
||||||
|
uint8_t unknown2;
|
||||||
|
uint16_t container[9];
|
||||||
|
uint16_t slot[9];
|
||||||
|
uint16_t padding;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
#endif //_CORE_NETWORK_PACKETS_ZONE_CLIENT_IPC_H
|
||||||
|
|
|
@ -92,7 +92,10 @@ Sapphire::ItemPtr Sapphire::ItemContainer::getItem( uint8_t slotId )
|
||||||
void Sapphire::ItemContainer::setItem( uint8_t slotId, ItemPtr pItem )
|
void Sapphire::ItemContainer::setItem( uint8_t slotId, ItemPtr pItem )
|
||||||
{
|
{
|
||||||
if( slotId > m_size )
|
if( slotId > m_size )
|
||||||
|
{
|
||||||
|
Logger::error( "Slot out of range {0}", slotId );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_itemMap[ slotId ] = pItem;
|
m_itemMap[ slotId ] = pItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -702,10 +702,12 @@ void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& pl
|
||||||
|
|
||||||
pLand->updateLandDb();
|
pLand->updateLandDb();
|
||||||
|
|
||||||
// start house built event
|
// start house built event - disabled because it fucks your audio device
|
||||||
// CmnDefHousingBuildHouse_00149
|
// CmnDefHousingBuildHouse_00149
|
||||||
player.eventStart( player.getId(), 0x000B0095, Event::EventHandler::EventType::Housing, 1, 1 );
|
//player.eventStart( player.getId(), 0x000B0095, Event::EventHandler::EventType::Housing, 1, 1 );
|
||||||
player.playScene( 0x000B0095, 0, static_cast< uint32_t >( SET_BASE | HIDE_HOTBAR ) , 0, 1, plotNum, nullptr );
|
//player.playScene( 0x000B0095, 0, static_cast< uint32_t >( SET_BASE | HIDE_HOTBAR ) , 0, 1, plotNum, nullptr );
|
||||||
|
// instead we do a fake zone to unlock the client
|
||||||
|
Common::Service< TerritoryMgr >::ref().movePlayer( player.getCurrentTerritory(), player.getAsPlayer() );
|
||||||
|
|
||||||
player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, ident );
|
player.setLandFlags( LandFlagsSlot::Private, EstateBuilt, ident );
|
||||||
player.sendLandFlagsSlot( LandFlagsSlot::Private );
|
player.sendLandFlagsSlot( LandFlagsSlot::Private );
|
||||||
|
@ -903,6 +905,8 @@ void Sapphire::World::Manager::HousingMgr::updateHouseModels( Sapphire::HousePtr
|
||||||
{
|
{
|
||||||
assert( house );
|
assert( house );
|
||||||
|
|
||||||
|
house->clearModelCache();
|
||||||
|
|
||||||
auto& containers = getEstateInventory( house->getLandIdent() );
|
auto& containers = getEstateInventory( house->getLandIdent() );
|
||||||
|
|
||||||
auto extContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingExteriorAppearance ) );
|
auto extContainer = containers.find( static_cast< uint16_t >( InventoryType::HousingExteriorAppearance ) );
|
||||||
|
@ -1627,3 +1631,59 @@ Sapphire::Inventory::HousingItemPtr Sapphire::World::Manager::HousingMgr::getHou
|
||||||
|
|
||||||
return Inventory::make_HousingItem( tmpItem->getUId(), tmpItem->getId() );
|
return Inventory::make_HousingItem( tmpItem->getUId(), tmpItem->getId() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::World::Manager::HousingMgr::editExterior( Sapphire::Entity::Player& player, uint16_t plot, std::vector< uint16_t > containerList, std::vector< uint8_t> slotList, uint8_t removeFlag )
|
||||||
|
{
|
||||||
|
auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() );
|
||||||
|
if( !terri )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto land = terri->getLand( static_cast< uint8_t >( plot ) );
|
||||||
|
if( !land )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( !hasPermission( player, *land, 0 ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& exteriorAppearenceContainer = getEstateInventory( land->getLandIdent() )[ InventoryType::HousingExteriorAppearance ];
|
||||||
|
|
||||||
|
auto& invMgr = Service< InventoryMgr >::ref();
|
||||||
|
|
||||||
|
for( int i = 0; i < 9; i++ )
|
||||||
|
{
|
||||||
|
auto container = containerList.at( i );
|
||||||
|
auto slot = slotList.at( i );
|
||||||
|
if( container == 0x270F || slot == 0xFF )
|
||||||
|
{
|
||||||
|
if( i >= 5 )
|
||||||
|
{
|
||||||
|
auto removed = ( ( removeFlag >> ( i - 5 ) ) & 1 ) > 0;
|
||||||
|
if( removed )
|
||||||
|
{
|
||||||
|
auto oldItem = exteriorAppearenceContainer->getItem( i );
|
||||||
|
if( oldItem )
|
||||||
|
{
|
||||||
|
exteriorAppearenceContainer->removeItem( i );
|
||||||
|
invMgr.removeItemFromHousingContainer( land->getLandIdent(), exteriorAppearenceContainer->getId(), i );
|
||||||
|
player.addItem( oldItem, false, false, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto item = getHousingItemFromPlayer( player, static_cast< Sapphire::Common::InventoryType >( container ), slot );
|
||||||
|
if( item )
|
||||||
|
{
|
||||||
|
auto oldItem = exteriorAppearenceContainer->getItem( i );
|
||||||
|
exteriorAppearenceContainer->setItem( i, item );
|
||||||
|
if( oldItem )
|
||||||
|
{
|
||||||
|
player.insertInventoryItem( static_cast< Sapphire::Common::InventoryType >( container ), slot, oldItem );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
invMgr.sendInventoryContainer( player, exteriorAppearenceContainer );
|
||||||
|
invMgr.saveHousingContainer( land->getLandIdent(), exteriorAppearenceContainer );
|
||||||
|
updateHouseModels( land->getHouse() );
|
||||||
|
std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() )->sendLandUpdate( plot );
|
||||||
|
}
|
|
@ -181,6 +181,8 @@ namespace Sapphire::World::Manager
|
||||||
|
|
||||||
bool hasPermission( Entity::Player& player, Land& land, uint32_t permission );
|
bool hasPermission( Entity::Player& player, Land& land, uint32_t permission );
|
||||||
|
|
||||||
|
void editExterior( Sapphire::Entity::Player& player, uint16_t plot, std::vector< uint16_t > containerList, std::vector< uint8_t > slotList, uint8_t removeFlag );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Inventory::HousingItemPtr getHousingItemFromPlayer( Entity::Player& player, Common::InventoryType type, uint8_t slot );
|
Inventory::HousingItemPtr getHousingItemFromPlayer( Entity::Player& player, Common::InventoryType type, uint8_t slot );
|
||||||
|
|
|
@ -143,15 +143,15 @@ void Sapphire::World::Manager::InventoryMgr::updateHousingItemPosition( Sapphire
|
||||||
|
|
||||||
stmt->setUInt64( 1, item->getUId() );
|
stmt->setUInt64( 1, item->getUId() );
|
||||||
|
|
||||||
stmt->setUInt( 2, pos.x );
|
stmt->setDouble( 2, static_cast< double >( pos.x ) );
|
||||||
stmt->setUInt( 3, pos.y );
|
stmt->setDouble( 3, static_cast< double >( pos.y ) );
|
||||||
stmt->setUInt( 4, pos.z );
|
stmt->setDouble( 4, static_cast< double >( pos.z ) );
|
||||||
stmt->setInt( 5, rot );
|
stmt->setDouble( 5, static_cast< double >( rot ) );
|
||||||
|
|
||||||
stmt->setUInt( 6, pos.x );
|
stmt->setDouble( 6, static_cast< double >( pos.x ) );
|
||||||
stmt->setUInt( 7, pos.y );
|
stmt->setDouble( 7, static_cast< double >( pos.y ) );
|
||||||
stmt->setUInt( 8, pos.z );
|
stmt->setDouble( 8, static_cast< double >( pos.z ) );
|
||||||
stmt->setInt( 9, rot );
|
stmt->setDouble( 9, static_cast< double >( rot ) );
|
||||||
|
|
||||||
db.execute( stmt );
|
db.execute( stmt );
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,6 +540,7 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t
|
||||||
|
|
||||||
// remove zone from maps
|
// remove zone from maps
|
||||||
m_territorySet.erase( zone );
|
m_territorySet.erase( zone );
|
||||||
|
m_guIdToTerritoryPtrMap.erase( zone->getGuId() );
|
||||||
it = m_landIdentToTerritoryPtrMap.erase( it );
|
it = m_landIdentToTerritoryPtrMap.erase( it );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -627,14 +628,27 @@ bool Sapphire::World::Manager::TerritoryMgr::movePlayer( TerritoryPtr pZone, Sap
|
||||||
// mark character as zoning in progress
|
// mark character as zoning in progress
|
||||||
pPlayer->setLoadingComplete( false );
|
pPlayer->setLoadingComplete( false );
|
||||||
|
|
||||||
|
bool zoneChanged = true;
|
||||||
if( pPlayer->getLastPing() != 0 && pPlayer->getCurrentTerritory() )
|
if( pPlayer->getLastPing() != 0 && pPlayer->getCurrentTerritory() )
|
||||||
|
{
|
||||||
|
zoneChanged = pPlayer->getCurrentTerritory()->getGuId() != pZone->getGuId();
|
||||||
|
if( zoneChanged )
|
||||||
pPlayer->getCurrentTerritory()->removeActor( pPlayer );
|
pPlayer->getCurrentTerritory()->removeActor( pPlayer );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( zoneChanged )
|
||||||
|
{
|
||||||
pPlayer->setCurrentZone( pZone );
|
pPlayer->setCurrentZone( pZone );
|
||||||
pZone->pushActor( pPlayer );
|
pZone->pushActor( pPlayer );
|
||||||
|
|
||||||
// map player to instanceId so it can be tracked.
|
// map player to instanceId so it can be tracked.
|
||||||
m_playerIdToInstanceMap[ pPlayer->getId() ] = pZone->getGuId();
|
m_playerIdToInstanceMap[ pPlayer->getId() ] = pZone->getGuId();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPlayer->removeFromInRange();
|
||||||
|
pPlayer->clearInRangeSet();
|
||||||
|
}
|
||||||
|
|
||||||
pPlayer->sendZonePackets();
|
pPlayer->sendZonePackets();
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ Sapphire::Network::GameConnection::GameConnection( Sapphire::Network::HivePtr pH
|
||||||
setZoneHandler( ClientZoneIpcType::ReqPlaceHousingItem, "ReqPlaceHousingItem", &GameConnection::reqPlaceHousingItem );
|
setZoneHandler( ClientZoneIpcType::ReqPlaceHousingItem, "ReqPlaceHousingItem", &GameConnection::reqPlaceHousingItem );
|
||||||
setZoneHandler( ClientZoneIpcType::HousingUpdateObjectPosition, "HousingUpdateObjectPosition",
|
setZoneHandler( ClientZoneIpcType::HousingUpdateObjectPosition, "HousingUpdateObjectPosition",
|
||||||
&GameConnection::reqMoveHousingItem );
|
&GameConnection::reqMoveHousingItem );
|
||||||
|
setZoneHandler( ClientZoneIpcType::HousingEditExterior, "HousingEditExterior", &GameConnection::housingEditExterior );
|
||||||
|
|
||||||
setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk );
|
setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk );
|
||||||
setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote );
|
setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote );
|
||||||
|
|
|
@ -181,6 +181,8 @@ namespace Sapphire::Network
|
||||||
|
|
||||||
DECLARE_HANDLER( reqMoveHousingItem );
|
DECLARE_HANDLER( reqMoveHousingItem );
|
||||||
|
|
||||||
|
DECLARE_HANDLER( housingEditExterior );
|
||||||
|
|
||||||
DECLARE_HANDLER( marketBoardSearch );
|
DECLARE_HANDLER( marketBoardSearch );
|
||||||
|
|
||||||
DECLARE_HANDLER( marketBoardRequestItemInfo );
|
DECLARE_HANDLER( marketBoardRequestItemInfo );
|
||||||
|
|
|
@ -691,6 +691,23 @@ void Sapphire::Network::GameConnection::reqMoveHousingItem( const Packets::FFXIV
|
||||||
housingMgr.reqMoveHousingItem( player, data.ident, data.slot, data.pos, data.rotation );
|
housingMgr.reqMoveHousingItem( player, data.ident, data.slot, data.pos, data.rotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::Network::GameConnection::housingEditExterior( const Packets::FFXIVARR_PACKET_RAW& inPacket, Entity::Player& player )
|
||||||
|
{
|
||||||
|
auto& housingMgr = Common::Service< HousingMgr >::ref();
|
||||||
|
const auto packet = ZoneChannelPacket< Client::FFXIVIpcHousingEditExterior >( inPacket );
|
||||||
|
|
||||||
|
std::vector< uint16_t > containerList;
|
||||||
|
std::vector< uint8_t > slotList;
|
||||||
|
for( int i = 0; i < 9; i++ )
|
||||||
|
{
|
||||||
|
auto container = packet.data().container[i];
|
||||||
|
containerList.push_back( container );
|
||||||
|
slotList.push_back( container != 0x270F ? static_cast< uint8_t >( packet.data().slot[i] ) : 0xFF );
|
||||||
|
}
|
||||||
|
|
||||||
|
housingMgr.editExterior( player, packet.data().landId, containerList, slotList, packet.data().removeFlag );
|
||||||
|
}
|
||||||
|
|
||||||
void Sapphire::Network::GameConnection::marketBoardSearch( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
void Sapphire::Network::GameConnection::marketBoardSearch( const Packets::FFXIVARR_PACKET_RAW& inPacket,
|
||||||
Entity::Player& player )
|
Entity::Player& player )
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,6 +64,11 @@ Sapphire::House::ExteriorModelsArray const& Sapphire::House::getHouseModels() co
|
||||||
return m_exteriorModelCache;
|
return m_exteriorModelCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::House::clearModelCache()
|
||||||
|
{
|
||||||
|
m_exteriorModelCache.fill( std::make_pair( 0, 0 ) );
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& Sapphire::House::getHouseName() const
|
const std::string& Sapphire::House::getHouseName() const
|
||||||
{
|
{
|
||||||
return m_estateName;
|
return m_estateName;
|
||||||
|
|
|
@ -41,6 +41,8 @@ namespace Sapphire
|
||||||
|
|
||||||
ExteriorModelsArray const& getHouseModels() const;
|
ExteriorModelsArray const& getHouseModels() const;
|
||||||
|
|
||||||
|
void clearModelCache();
|
||||||
|
|
||||||
void updateHouseDb();
|
void updateHouseDb();
|
||||||
|
|
||||||
void setHasAetheryte( bool hasAetheryte );
|
void setHasAetheryte( bool hasAetheryte );
|
||||||
|
|
|
@ -240,5 +240,20 @@ void Sapphire::Land::update( uint64_t tickCount )
|
||||||
|
|
||||||
Sapphire::Land::InvMaxItemsPair Sapphire::Land::getInventoryItemMax() const
|
Sapphire::Land::InvMaxItemsPair Sapphire::Land::getInventoryItemMax() const
|
||||||
{
|
{
|
||||||
return std::make_pair( m_maxPlacedExternalItems, m_maxPlacedInternalItems );
|
switch( m_size )
|
||||||
|
{
|
||||||
|
case HouseSize::Cottage:
|
||||||
|
{
|
||||||
|
return std::make_pair( 20, 200 );
|
||||||
|
}
|
||||||
|
case HouseSize::House:
|
||||||
|
{
|
||||||
|
return std::make_pair( 30, 300 );
|
||||||
|
}
|
||||||
|
case HouseSize::Mansion:
|
||||||
|
{
|
||||||
|
return std::make_pair( 40, 400 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert( false );
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,10 +86,6 @@ namespace Sapphire
|
||||||
|
|
||||||
Sapphire::HousePtr m_pHouse;
|
Sapphire::HousePtr m_pHouse;
|
||||||
|
|
||||||
//item storage
|
|
||||||
uint16_t m_maxPlacedExternalItems;
|
|
||||||
uint16_t m_maxPlacedInternalItems;
|
|
||||||
|
|
||||||
//price
|
//price
|
||||||
uint32_t m_initPrice;
|
uint32_t m_initPrice;
|
||||||
uint32_t m_nextDrop;
|
uint32_t m_nextDrop;
|
||||||
|
|
Loading…
Add table
Reference in a new issue