1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-01 08:27:46 +00:00

Merge pull request #907 from Moydow/6.x_housing

6.x housing updates
This commit is contained in:
Mordred 2023-03-05 21:32:23 +01:00 committed by GitHub
commit 294f1aa498
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 1191 additions and 17 deletions

File diff suppressed because it is too large Load diff

View file

@ -993,9 +993,10 @@ namespace Sapphire::Common
{ {
FreeCompany, FreeCompany,
Private, Private,
Apartment, FreeCompanyChambers,
SharedHouse1, SharedHouse1,
SharedHouse2 SharedHouse2,
Apartment
}; };
enum class LandType : uint8_t enum class LandType : uint8_t
@ -1014,6 +1015,38 @@ namespace Sapphire::Common
UNKNOWN_3 = 0x10, 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 struct LandIdent
{ {
int16_t landId; //00 int16_t landId; //00

View file

@ -257,6 +257,7 @@ namespace Sapphire::Network::Packets
LandSetInitialize = 0x69, // updated 6.31h LandSetInitialize = 0x69, // updated 6.31h
LandUpdate = 0x32a, // updated 6.31h LandUpdate = 0x32a, // updated 6.31h
LandAvailability = 0x8f, // updated 6.31h
YardObjectSpawn = 0x183, // updated 6.31h YardObjectSpawn = 0x183, // updated 6.31h
HousingIndoorInitialize = 0x206, // updated 6.31h HousingIndoorInitialize = 0x206, // updated 6.31h
LandPriceUpdate = 0x330, // updated 6.31h LandPriceUpdate = 0x330, // updated 6.31h

View file

@ -1868,11 +1868,11 @@ namespace Sapphire::Network::Packets::Server
uint64_t unknown1; uint64_t unknown1;
Common::LandFlagSet privateHouse; // 24 Common::LandFlagSet privateHouse; // 24
uint64_t unknown2; uint64_t unknown2;
Common::LandFlagSet apartment; // 48 Common::LandFlagSet freeCompanyChambers; // 48
uint64_t unknown3; uint64_t unknown3;
Common::LandFlagSet sharedHouse[2]; //72 Common::LandFlagSet sharedHouse[2]; //72
uint64_t unknown4; uint64_t unknown4;
Common::LandFlagSet unknownHouse; Common::LandFlagSet apartment;
uint64_t unknown5; uint64_t unknown5;
}; };
@ -1902,6 +1902,26 @@ namespace Sapphire::Network::Packets::Server
uint32_t timeLeft; 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 > struct FFXIVIpcLandInfoSign : FFXIVIpcBasePacket< LandInfoSign >
{ {
Common::LandIdent landIdent; Common::LandIdent landIdent;

View file

@ -78,7 +78,7 @@ public:
return; return;
} }
player.setInstance( internalZone, pos, player.getRot() ); player.setInstance( internalZone, pos, 3.14f );
} ); } );
} }
}; };

View file

@ -2,6 +2,7 @@
#include <Actor/Player.h> #include <Actor/Player.h>
#include <Territory/HousingZone.h> #include <Territory/HousingZone.h>
#include <Manager/HousingMgr.h> #include <Manager/HousingMgr.h>
#include <Network/PacketDef/Zone/ServerZoneDef.h>
#include <Network/PacketWrappers/ActorControlSelfPacket.h> #include <Network/PacketWrappers/ActorControlSelfPacket.h>
#include <Network/CommonActorControl.h> #include <Network/CommonActorControl.h>
#include <Exd/ExdDataGenerated.h> #include <Exd/ExdDataGenerated.h>
@ -84,6 +85,10 @@ public:
void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override 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 ); Scene00000( player );
} }
}; };

View file

@ -102,7 +102,7 @@ Sapphire::Entity::Player::Player() :
memset( m_classArray, 0, sizeof( m_classArray ) ); memset( m_classArray, 0, sizeof( m_classArray ) );
memset( m_expArray, 0, sizeof( m_expArray ) ); memset( m_expArray, 0, sizeof( m_expArray ) );
for ( uint8_t i = 0; i < 5; i++ ) for ( uint8_t i = 0; i < 6; i++ )
{ {
memset( &m_landFlags[i], 0xFF, 8 ); memset( &m_landFlags[i], 0xFF, 8 );
memset( &m_landFlags[i].landFlags, 0, 8 ); memset( &m_landFlags[i].landFlags, 0, 8 );
@ -2126,9 +2126,10 @@ void Sapphire::Entity::Player::sendLandFlags()
landFlags->data().freeCompanyHouse = m_landFlags[ Common::LandFlagsSlot::FreeCompany ]; landFlags->data().freeCompanyHouse = m_landFlags[ Common::LandFlagsSlot::FreeCompany ];
landFlags->data().privateHouse = m_landFlags[ Common::LandFlagsSlot::Private ]; landFlags->data().privateHouse = m_landFlags[ Common::LandFlagsSlot::Private ];
landFlags->data().apartment = m_landFlags[ Common::LandFlagsSlot::Apartment ]; landFlags->data().freeCompanyChambers = m_landFlags[ Common::LandFlagsSlot::FreeCompanyChambers ];
landFlags->data().sharedHouse[ 0 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse1 ]; landFlags->data().sharedHouse[ 0 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse1 ];
landFlags->data().sharedHouse[ 1 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse2 ]; landFlags->data().sharedHouse[ 1 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse2 ];
landFlags->data().apartment = m_landFlags[ Common::LandFlagsSlot::Apartment ];
queuePacket( landFlags ); queuePacket( landFlags );
} }

View file

@ -1153,7 +1153,7 @@ namespace Sapphire::Entity
uint8_t m_searchSelectClass; // class selected to show up in profile uint8_t m_searchSelectClass; // class selected to show up in profile
// housing info // housing info
Common::LandFlagSet m_landFlags[5]; Common::LandFlagSet m_landFlags[6];
Common::ActiveLand m_activeLand; Common::ActiveLand m_activeLand;

View file

@ -77,8 +77,8 @@ bool Sapphire::World::Manager::HousingMgr::init()
Logger::info( "HousingMgr: Caching housing land init data" ); Logger::info( "HousingMgr: Caching housing land init data" );
//LAND_SEL_ALL //LAND_SEL_ALL
// 18 wards per territory, 4 territories // 18 wards per territory, 5 territories
m_landCache.reserve( 18 * 4 ); m_landCache.reserve( 18 * 5 );
initLandCache(); initLandCache();
@ -307,6 +307,16 @@ Sapphire::LandPtr Sapphire::World::Manager::HousingMgr::getLandByOwnerId( uint32
return hZone->getLand( static_cast< uint8_t >( res->getUInt( 2 ) ) ); 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 ) void Sapphire::World::Manager::HousingMgr::sendLandSignOwned( Entity::Player& player, const Common::LandIdent ident )
{ {
auto& serverMgr = Common::Service< World::ServerMgr >::ref(); auto& serverMgr = Common::Service< World::ServerMgr >::ref();

View file

@ -77,6 +77,8 @@ namespace Sapphire::World::Manager
Sapphire::Data::HousingZonePtr getHousingZoneByLandSetId( uint32_t id ); Sapphire::Data::HousingZonePtr getHousingZoneByLandSetId( uint32_t id );
Sapphire::LandPtr getLandByOwnerId( 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 sendLandSignOwned( Entity::Player& player, const Common::LandIdent ident );
void sendLandSignFree( 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 ); LandPurchaseResult purchaseLand( Entity::Player& player, uint8_t plot, uint8_t state );

View file

@ -502,6 +502,10 @@ Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousi
territoryTypeId = 649; territoryTypeId = 649;
break; break;
case 979: // Empyreum
territoryTypeId = 980;
break;
default: default:
return nullptr; return nullptr;
} }

View file

@ -74,7 +74,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
player.queuePacket( indoorInitPacket ); player.queuePacket( indoorInitPacket );
bool isFcHouse = pLand->getStatus() == Common::HouseStatus::PrivateEstate; bool isFcHouse = pLand->getStatus() == Common::HouseStatus::FreeCompanyEstate;
auto yardPacketTotal = static_cast< uint8_t >( 2 + pLand->getSize() ); auto yardPacketTotal = static_cast< uint8_t >( 2 + pLand->getSize() );
for( uint8_t yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) for( uint8_t yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ )
@ -82,7 +82,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
auto objectInitPacket = makeZonePacket< Server::FFXIVIpcHousingObjectInitialize >( player.getId() ); auto objectInitPacket = makeZonePacket< Server::FFXIVIpcHousingObjectInitialize >( player.getId() );
memcpy( &objectInitPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) ); memcpy( &objectInitPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) );
if( isFcHouse ) if( !isFcHouse )
objectInitPacket->data().u1 = 2; // 2 = actrl 0x400 will hide the fc door, otherwise it will stay there objectInitPacket->data().u1 = 2; // 2 = actrl 0x400 will hide the fc door, otherwise it will stay there
else else
objectInitPacket->data().u1 = 0; objectInitPacket->data().u1 = 0;
@ -97,7 +97,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone
player.queuePacket( objectInitPacket ); player.queuePacket( objectInitPacket );
} }
if( isFcHouse ) if( !isFcHouse )
player.queuePacket( player.queuePacket(
Server::makeActorControlSelf( player.getId(), Network::ActorControl::HideAdditionalChambersDoor ) ); Server::makeActorControlSelf( player.getId(), Network::ActorControl::HideAdditionalChambersDoor ) );
} }

View file

@ -62,7 +62,7 @@ bool Sapphire::HousingZone::init()
housingIndex = 2; housingIndex = 2;
else if( m_territoryTypeId == 641 ) else if( m_territoryTypeId == 641 )
housingIndex = 3; housingIndex = 3;
else if (m_territoryTypeId == 979 ) else if( m_territoryTypeId == 979 )
housingIndex = 4; housingIndex = 4;
auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); auto& exdData = Common::Service< Data::ExdDataGenerated >::ref();
@ -279,7 +279,7 @@ void Sapphire::HousingZone::sendLandUpdate( uint8_t landId )
bool Sapphire::HousingZone::isPlayerSubInstance( Entity::Player& player ) bool Sapphire::HousingZone::isPlayerSubInstance( Entity::Player& player )
{ {
return player.getPos().x < -15000.0f; //ToDo: get correct pos return player.getPos().x < -400.0f && player.getPos().z < -400.0f; //ToDo: get correct pos
} }
void Sapphire::HousingZone::onUpdate( uint64_t tickCount ) void Sapphire::HousingZone::onUpdate( uint64_t tickCount )