From 445597a639f5bf8b0da0a771dafb6f9433683586 Mon Sep 17 00:00:00 2001 From: Moydow <28638419+Moydow@users.noreply.github.com> Date: Sat, 4 Mar 2023 00:11:02 +0000 Subject: [PATCH] add LandAvailability packet New packet introduced in 6.1 that tells the client on clicking on a housing placard, whether the property is available by lottery or first-come-first-served, private or FC, etc. --- src/common/Common.h | 32 +++++++++++++++++++ src/common/Network/PacketDef/Ipcs.h | 1 + .../Network/PacketDef/Zone/ServerZoneDef.h | 20 ++++++++++++ .../common/housing/CmnDefHousingSignboard.cpp | 5 +++ src/world/Manager/HousingMgr.cpp | 10 ++++++ src/world/Manager/HousingMgr.h | 2 ++ 6 files changed, 70 insertions(+) diff --git a/src/common/Common.h b/src/common/Common.h index 7f0067b0..fcc8d4e9 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -1015,6 +1015,38 @@ namespace Sapphire::Common UNKNOWN_3 = 0x10, }; + enum class LandSellMode : uint8_t + { + Unavailable, + FirstComeFirstServed, + Lottery, + }; + + enum class LandAvailableTo : uint8_t + { + All, + FreeCompany, + Private, + }; + + enum class LandLotteryStatus : uint8_t + { + FirstComeFirstServed, + Available, + Results, + Unavailable, + }; + + enum class LandLotteryPlayerResult : uint8_t + { + NoEntry, + Entered, + Winner, + WinnerForfeit, + Loser, + RefundExpired, + }; + struct LandIdent { int16_t landId; //00 diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 3458741d..3c7a3913 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -257,6 +257,7 @@ namespace Sapphire::Network::Packets LandSetInitialize = 0x69, // updated 6.31h LandUpdate = 0x32a, // updated 6.31h + LandAvailability = 0x8f, // updated 6.31h YardObjectSpawn = 0x183, // updated 6.31h HousingIndoorInitialize = 0x206, // updated 6.31h LandPriceUpdate = 0x330, // updated 6.31h diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 5d9d9ff0..5a10a71f 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1902,6 +1902,26 @@ namespace Sapphire::Network::Packets::Server uint32_t timeLeft; }; + /** + * Sent when the client clicks a housing placard + * to indicate if the plot is available to FCs or private housing or both, + * lottery or first-come-first-served, and lottery status/results + */ + struct FFXIVIpcLandAvailability : FFXIVIpcBasePacket< LandAvailability > + { + Common::LandSellMode sellMode; + Common::LandAvailableTo availableTo; + Common::LandLotteryStatus lotteryStatus; + Common::LandLotteryPlayerResult lotteryPlayerResult; + uint32_t lotteryUpdateTime; + uint32_t refundExpiryTime; + uint32_t lotteryEntries; + uint32_t lotteryWinningNumber; + uint32_t lotteryPlayerNumber; + uint32_t refundAmount; + uint32_t unknown; + }; + struct FFXIVIpcLandInfoSign : FFXIVIpcBasePacket< LandInfoSign > { Common::LandIdent landIdent; diff --git a/src/scripts/common/housing/CmnDefHousingSignboard.cpp b/src/scripts/common/housing/CmnDefHousingSignboard.cpp index 3de38035..886943ee 100644 --- a/src/scripts/common/housing/CmnDefHousingSignboard.cpp +++ b/src/scripts/common/housing/CmnDefHousingSignboard.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,10 @@ public: void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override { + // maybe not the best place to put this, but looks to be where it goes on retail + auto& pHouMgr = Common::Service< HousingMgr >::ref(); + pHouMgr.sendLandAvailability( player, player.getActiveLand() ); + Scene00000( player ); } }; diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 982710d3..cd6b1993 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -307,6 +307,16 @@ Sapphire::LandPtr Sapphire::World::Manager::HousingMgr::getLandByOwnerId( uint32 return hZone->getLand( static_cast< uint8_t >( res->getUInt( 2 ) ) ); } +void Sapphire::World::Manager::HousingMgr::sendLandAvailability( Entity::Player& player, Common::ActiveLand activeLand ) +{ + // to do: make these properties of the land database + auto landAvailabilityPacket = makeZonePacket< FFXIVIpcLandAvailability >( player.getId() ); + landAvailabilityPacket->data().sellMode = Common::LandSellMode::FirstComeFirstServed; + landAvailabilityPacket->data().availableTo = Common::LandAvailableTo::Private; + landAvailabilityPacket->data().lotteryStatus = Common::LandLotteryStatus::FirstComeFirstServed; + player.queuePacket( landAvailabilityPacket ); +} + void Sapphire::World::Manager::HousingMgr::sendLandSignOwned( Entity::Player& player, const Common::LandIdent ident ) { auto& serverMgr = Common::Service< World::ServerMgr >::ref(); diff --git a/src/world/Manager/HousingMgr.h b/src/world/Manager/HousingMgr.h index 9fd8c215..b5d76178 100644 --- a/src/world/Manager/HousingMgr.h +++ b/src/world/Manager/HousingMgr.h @@ -77,6 +77,8 @@ namespace Sapphire::World::Manager Sapphire::Data::HousingZonePtr getHousingZoneByLandSetId( uint32_t id ); Sapphire::LandPtr getLandByOwnerId( uint32_t id ); + void sendLandAvailability( Entity::Player& player, const Common::ActiveLand activeLand ); + void sendLandSignOwned( Entity::Player& player, const Common::LandIdent ident ); void sendLandSignFree( Entity::Player& player, const Common::LandIdent ident ); LandPurchaseResult purchaseLand( Entity::Player& player, uint8_t plot, uint8_t state );