1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-02 08:57:44 +00:00

Merge pull request #441 from NotAdam/housing

refactoring, make menu work good, you can rename your house, idk
This commit is contained in:
Mordred 2018-11-28 14:50:38 +01:00 committed by GitHub
commit 02301cc7ef
15 changed files with 355 additions and 101 deletions

View file

@ -758,7 +758,7 @@ namespace Core::Common
SubTag2
};
enum LandPermissionSlot
enum LandFlagsSlot
{
FreeCompany,
Private,
@ -774,6 +774,15 @@ namespace Core::Common
Private = 2,
};
enum LandFlags : uint32_t
{
ESTATE_BUILT = 0x1,
ESTATE_HAS_AETHERYTE = 0x2,
UNKNOWN_1 = 0x4,
UNKNOWN_2 = 0x8,
UNKNOWN_3 = 0x10,
};
struct LandIdent
{
int16_t landId; //00
@ -782,10 +791,10 @@ namespace Core::Common
int16_t worldId; //06
};
struct LandPermissionSet
struct LandFlagSet
{
LandIdent landIdent;
uint32_t permissionMask; //08
uint32_t landFlags; //08
uint32_t unkown1; //12
};
@ -834,7 +843,7 @@ namespace Core::Common
Venue = 11,
};
enum WardEstateFlags : uint8_t
enum WardlandFlags : uint8_t
{
IsEstateOwned = 1,
IsPublicEstate = 2,

View file

@ -193,8 +193,9 @@ namespace Core::Network::Packets
HousingEstateGreeting = 0x0227, // updated 4.4
LandPermissionSlot = 0x0228, // updated 4.4
LandPermission = 0x0229, // updated 4.4
HousingUpdateLandFlagsSlot = 0x0228, // updated 4.4
HousingLandFlags = 0x0229, // updated 4.4
HousingShowEstateGuestAccess = 0x022A, // updated 4.4
LandSetYardInitialize = 0x022C, // updated 4.4
@ -204,6 +205,8 @@ namespace Core::Network::Packets
SharedEstateSettingsResponse = 0x023C, // updated 4.4
LandUpdateHouseName = 0x024D, // updated 4.4
LandSetMap = 0x0251, // updated 4.4
//////////////////////////////////////////////////
@ -302,6 +305,7 @@ namespace Core::Network::Packets
LinkshellEventHandler1 = 0x1151, // updated 4.1 ??
LandRenameHandler = 0x0171, // updated 4.4
HousingUpdateHouseGreeting = 0x0172, // updated 4.4
SetSharedEstateSettings = 0x0177, // updated 4.4

View file

@ -199,14 +199,18 @@ struct FFXIVIpcInventoryModifyHandler :
struct FFXIVIpcRenameLandHandler :
FFXIVIpcBasePacket< LandRenameHandler >
{
/* 0000 */ uint16_t landId;
/* 0002 */ uint16_t wardNum;
/* 0004 */ uint16_t zoneId;
/* 0006 */ uint16_t worldId;
/* 0008 */ char landName[20];
/* 0000 */ Common::LandIdent ident;
/* 0008 */ char houseName[20];
/* 0028 */ uint32_t padding;
};
struct FFXIVIpcHousingUpdateHouseGreeting :
FFXIVIpcBasePacket< HousingUpdateHouseGreeting >
{
/* 0000 */ Common::LandIdent ident;
/* 0008 */ char greeting[200];
};
struct FFXIVIpcBuildPresetHandler :
FFXIVIpcBasePacket< BuildPresetHandler >
{

View file

@ -1575,24 +1575,24 @@ struct FFXIVIpcPerformNote : FFXIVIpcBasePacket< PerformNote >
uint8_t data[32];
};
struct FFXIVIpcLandPermissionSlot : FFXIVIpcBasePacket< LandPermissionSlot >
struct FFXIVIpcHousingUpdateLandFlagsSlot : FFXIVIpcBasePacket< HousingUpdateLandFlagsSlot >
{
uint32_t type;
uint32_t unknown;
Common::LandPermissionSet permissionSet;
Common::LandFlagSet flagSet;
};
struct FFXIVIpcLandPermission : FFXIVIpcBasePacket< LandPermission >
struct FFXIVIpcHousingLandFlags : FFXIVIpcBasePacket< HousingLandFlags >
{
Common::LandPermissionSet freeCompanyHouse; // 00
Common::LandFlagSet freeCompanyHouse; // 00
uint64_t unkown1;
Common::LandPermissionSet privateHouse; // 24
Common::LandFlagSet privateHouse; // 24
uint64_t unkown2;
Common::LandPermissionSet apartment; // 48
Common::LandFlagSet apartment; // 48
uint64_t unkown3;
Common::LandPermissionSet sharedHouse[2]; //72
Common::LandFlagSet sharedHouse[2]; //72
uint64_t unkown4;
Common::LandPermissionSet unkownHouse;
Common::LandFlagSet unkownHouse;
uint64_t unkown5;
};
@ -1640,10 +1640,17 @@ struct FFXIVIpcLandInfoSign : FFXIVIpcBasePacket< LandInfoSign >
struct FFXIVIpcLandRename : FFXIVIpcBasePacket< LandRename >
{
Common::LandIdent landIdent;
char landName[20];
char houseName[20];
uint32_t padding;
};
struct FFXIVIpcLandUpdateHouseName : FFXIVIpcBasePacket< LandUpdateHouseName >
{
uint32_t unknown[3];
char houseName[20];
uint32_t unknown2[2];
};
struct FFXIVIpcLandSetMap : FFXIVIpcBasePacket< LandSetMap >
{
uint8_t u1;
@ -1723,13 +1730,17 @@ struct FFXIVIpcHousingWardInfo : FFXIVIpcBasePacket< HousingWardInfo >
struct FFXIVIpcHousingEstateGreeting : FFXIVIpcBasePacket< HousingEstateGreeting >
{
uint8_t plotId;
uint8_t pad[3]; // unsure
uint16_t territoryTypeId;
uint16_t unk;
Common::LandIdent landIdent;
char message[200];
};
struct FFXIVIpcHousingShowEstateGuestAccess :
FFXIVIpcBasePacket< HousingShowEstateGuestAccess >
{
uint32_t unknown[2];
Common::LandIdent ident;
};
/**
* Structural representation of the packet sent by the server
* to show the current shared estate settings

View file

@ -94,8 +94,8 @@ Core::Entity::Player::Player() :
for ( uint8_t i = 0; i < 5; i++ )
{
memset( &m_landPermission[i], 0xFF, 8 );
memset( &m_landPermission[i].permissionMask, 0, 8 );
memset( &m_landFlags[i], 0xFF, 8 );
memset( &m_landFlags[i].landFlags, 0, 8 );
}
m_objSpawnIndexAllocator.init( MAX_DISPLAYED_EOBJS );
@ -1290,6 +1290,12 @@ void Core::Entity::Player::sendDebug( const std::string& message ) //Grey Text
queuePacket( std::make_shared< ChatPacket >( *getAsPlayer(), ChatType::ServerDebug, message ) );
}
void Core::Entity::Player::sendLogMessage( uint32_t messageId, uint32_t param2, uint32_t param3,
uint32_t param4, uint32_t param5, uint32_t param6 )
{
queuePacket( makeActorControl144( getId(), ActorControlType::LogMsg, messageId, param2, param3, param4, param5, param6 ) );
}
void Core::Entity::Player::updateHowtosSeen( uint32_t howToId )
{
uint8_t index = howToId / 8;
@ -1587,10 +1593,20 @@ void Core::Entity::Player::sendZonePackets()
auto pHousingMgr = g_fw.get< HousingMgr >();
if( Core::LandPtr pLand = pHousingMgr->getLandByOwnerId( getId() ) )
{
setLandPermissions( LandPermissionSlot::Private, 0x00, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() );
uint32_t state = 0;
if( pLand->getHouse() )
{
state |= ESTATE_BUILT;
// todo: remove this, debug for now
state |= ESTATE_HAS_AETHERYTE;
}
setLandFlags( LandFlagsSlot::Private, state, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() );
}
sendLandPermissions();
sendLandFlags();
auto initZonePacket = makeZonePacket< FFXIVIpcInitZone >( getId() );
initZonePacket->data().zoneId = getCurrentZone()->getTerritoryTypeId();
@ -1768,47 +1784,53 @@ bool Core::Entity::Player::isOnEnterEventDone() const
return m_onEnterEventDone;
}
void Core::Entity::Player::setLandPermissions( uint8_t permissionSet, uint32_t permissionMask,
void Core::Entity::Player::setLandFlags( uint8_t flagSlot, uint32_t landFlags,
int16_t landId, int16_t wardNum, int16_t zoneId )
{
m_landPermission[ permissionSet ].landIdent.landId = landId;
m_landPermission[ permissionSet ].landIdent.wardNum = wardNum;
m_landPermission[ permissionSet ].landIdent.territoryTypeId = zoneId;
m_landPermission[ permissionSet ].landIdent.worldId = 67;
m_landPermission[ permissionSet ].permissionMask = permissionMask;
m_landPermission[ permissionSet ].unkown1 = 0;
m_landFlags[ flagSlot ].landIdent.landId = landId;
m_landFlags[ flagSlot ].landIdent.wardNum = wardNum;
m_landFlags[ flagSlot ].landIdent.territoryTypeId = zoneId;
m_landFlags[ flagSlot ].landIdent.worldId = 67;
m_landFlags[ flagSlot ].landFlags = landFlags;
m_landFlags[ flagSlot ].unkown1 = 0;
}
void Core::Entity::Player::sendLandPermissions()
void Core::Entity::Player::sendLandFlags()
{
auto landPermissions = makeZonePacket< FFXIVIpcLandPermission >( getId() );
auto landFlags = makeZonePacket< FFXIVIpcHousingLandFlags >( getId() );
landPermissions->data().freeCompanyHouse = m_landPermission[Common::LandPermissionSlot::FreeCompany];
landPermissions->data().privateHouse = m_landPermission[Common::LandPermissionSlot::Private];
landPermissions->data().apartment = m_landPermission[Common::LandPermissionSlot::Apartment];
landPermissions->data().sharedHouse[0] = m_landPermission[Common::LandPermissionSlot::SharedHouse1];
landPermissions->data().sharedHouse[1] = m_landPermission[Common::LandPermissionSlot::SharedHouse2];
memset( &landPermissions->data().unkownHouse, 0xFF, 8 );
memset( &landPermissions->data().unkownHouse.permissionMask, 0, 8 );
landPermissions->data().unkownHouse.permissionMask = 2;
landPermissions->data().unkown1 = 0;
landPermissions->data().unkown2 = 0;
landPermissions->data().unkown3 = 0;
landPermissions->data().unkown4 = 0;
landPermissions->data().unkown5 = 0;
landFlags->data().freeCompanyHouse = m_landFlags[ Common::LandFlagsSlot::FreeCompany ];
landFlags->data().privateHouse = m_landFlags[ Common::LandFlagsSlot::Private ];
landFlags->data().apartment = m_landFlags[ Common::LandFlagsSlot::Apartment ];
landFlags->data().sharedHouse[ 0 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse1 ];
landFlags->data().sharedHouse[ 1 ] = m_landFlags[ Common::LandFlagsSlot::SharedHouse2 ];
queuePacket( landPermissions );
queuePacket( landFlags );
}
void Core::Entity::Player::sendLandPermissionSlot( uint8_t slotId, uint8_t landId, uint8_t wardId, uint16_t zoneId )
void Core::Entity::Player::sendLandFlagsSlot( Common::LandFlagsSlot slot )
{
auto landPermissions = makeZonePacket< FFXIVIpcLandPermissionSlot >( getId() );
landPermissions->data().type = slotId;
auto landFlags = makeZonePacket< FFXIVIpcHousingUpdateLandFlagsSlot >( getId() );
landPermissions->data().permissionSet.landIdent.landId = landId;
landPermissions->data().permissionSet.landIdent.wardNum = wardId;
landPermissions->data().permissionSet.landIdent.territoryTypeId = zoneId;
landPermissions->data().permissionSet.landIdent.worldId = 67;
landPermissions->data().permissionSet.permissionMask = 0;
queuePacket( landPermissions );
uint32_t type = 0;
switch( slot )
{
case LandFlagsSlot::Private:
type = static_cast< uint32_t >( LandType::Private );
break;
case LandFlagsSlot::FreeCompany:
type = static_cast< uint32_t >( LandType::FreeCompany );
break;
default:
// todo: other/unsupported land types
return;
}
landFlags->data().type = type;
landFlags->data().flagSet = m_landFlags[ slot ];
queuePacket( landFlags );
}

View file

@ -757,16 +757,18 @@ namespace Core::Entity
void sendDebug( const std::string& message );
void sendLogMessage( uint32_t messageId, uint32_t param2 = 0, uint32_t param3 = 0, uint32_t param4 = 0, uint32_t param5 = 0, uint32_t param6 = 0 );
bool isDirectorInitialized() const;
void setDirectorInitialized( bool isInitialized );
// Housing Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
void setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landId, int16_t wardNum, int16_t zoneId );
void setLandFlags( uint8_t permissionSet, uint32_t landFlags, int16_t landId, int16_t wardNum, int16_t zoneId );
void sendLandPermissions();
void sendLandPermissionSlot( uint8_t slotId, uint8_t landId, uint8_t wardId, uint16_t zoneId );
void sendLandFlags();
void sendLandFlagsSlot( Common::LandFlagsSlot slot );
// Player Battle Handling
//////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1025,7 +1027,7 @@ namespace Core::Entity
uint8_t m_searchSelectClass; // class selected to show up in profile
// housing info
Common::LandPermissionSet m_landPermission[5];
Common::LandFlagSet m_landFlags[5];
Common::ActiveLand m_activeLand;

View file

@ -730,7 +730,7 @@ void Core::DebugCommandHandler::script( char* data, Entity::Player& player, std:
for( auto it = scripts.begin(); it != scripts.end(); ++it )
{
auto script = *it;
player.sendDebug( " - '" + script->library_name +
player.sendDebug( " - '" + script->library_name +
", num scripts: " + std::to_string( script->scripts.size() ) );
}
}
@ -1018,8 +1018,8 @@ void Core::DebugCommandHandler::housing( char* data, Entity::Player& player, std
auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone );
if( pHousing )
{
player.setLandPermissions( permissionSet, 0, pHousing->getLandSetId(), pHousing->getWardNum(), pHousing->getTerritoryTypeId() );
player.sendLandPermissions();
player.setLandFlags( permissionSet, 0, pHousing->getLandSetId(), pHousing->getWardNum(), pHousing->getTerritoryTypeId() );
player.sendLandFlags();
}
else
player.sendDebug( "You aren't in a housing Zone." );

View file

@ -85,6 +85,9 @@ Core::Network::GameConnection::GameConnection( Core::Network::HivePtr pHive,
setZoneHandler( ClientZoneIpcType::BuildPresetHandler, "BuildPresetHandler", &GameConnection::buildPresetHandler );
setZoneHandler( ClientZoneIpcType::LandRenameHandler, "LandRenameHandler", &GameConnection::landRenameHandler );
setZoneHandler( ClientZoneIpcType::HousingUpdateHouseGreeting, "HousingUpdateHouseGreeting",
&GameConnection::housingUpdateGreetingHandler );
setZoneHandler( ClientZoneIpcType::TalkEventHandler, "EventHandlerTalk", &GameConnection::eventHandlerTalk );
setZoneHandler( ClientZoneIpcType::EmoteEventHandler, "EventHandlerEmote", &GameConnection::eventHandlerEmote );
setZoneHandler( ClientZoneIpcType::WithinRangeEventHandler, "EventHandlerWithinRange",
@ -225,7 +228,7 @@ void Core::Network::GameConnection::handleZonePacket( Core::Network::Packets::FF
else
{
pLog->debug( sessionStr + " Undefined Zone IPC : Unknown ( " +
Util::intToHexString( static_cast< uint32_t >( opcode ), 4 ) + " )" );
Util::intToHexString( static_cast< uint32_t >( opcode ), 4 ) + " )" );
pLog->debug(
"Dump:\n" + Util::binaryToHexDump( const_cast< uint8_t* >( &pPacket.data[ 0 ] ), pPacket.segHdr.size ) );
}

View file

@ -152,7 +152,7 @@ namespace Core::Network
DECLARE_HANDLER( cfRegisterRoulette );
DECLARE_HANDLER( cfDutyAccepted );
DECLARE_HANDLER( actionHandler );
DECLARE_HANDLER( gm1Handler );
@ -165,6 +165,8 @@ namespace Core::Network
DECLARE_HANDLER( landRenameHandler );
DECLARE_HANDLER( housingUpdateGreetingHandler );
DECLARE_HANDLER( buildPresetHandler );
DECLARE_HANDLER( tellHandler );

View file

@ -10,9 +10,7 @@
#include "Zone/Zone.h"
#include "Zone/ZonePosition.h"
#include "Zone/HousingZone.h"
#include "Zone/HousingMgr.h"
#include "Zone/Land.h"
#include "Network/GameConnection.h"
@ -364,31 +362,49 @@ void Core::Network::GameConnection::clientTriggerHandler( const Packets::FFXIVAR
}
case ClientTriggerType::RequestEstateRename:
{
// removed temporarly, there is no such thing as a LandName
/* auto landRenamePacket = makeZonePacket< Server::FFXIVIpcLandRename >( player.getId() );
uint16_t territoryTypeId = param11 & 0xFFFF;
uint16_t worldId = param11 >> 16;
uint8_t ward = ( param12 & 0xFF00 ) >> 8;
uint8_t plot = ( param12 & 0xFF );
auto zone = player.getCurrentZone();
auto pHousingMgr = g_fw.get< HousingMgr >();
if( !pHousingMgr )
break;
auto hZone = std::dynamic_pointer_cast< HousingZone >( zone );
pHousingMgr->requestEstateRename( player, territoryTypeId, worldId, ward, plot );
auto land = hZone->getLand( plot );
break;
}
case ClientTriggerType::RequestEstateEditGreeting:
{
uint16_t territoryTypeId = param11 & 0xFFFF;
uint16_t worldId = param11 >> 16;
if( !land )
{
auto pHousingMgr = g_fw.get< HousingMgr >();
land = pHousingMgr->getLandByOwnerId( player.getId() );
}
uint8_t ward = ( param12 & 0xFF00 ) >> 8;
uint8_t plot = ( param12 & 0xFF );
landRenamePacket->data().landId = land->getLandId();
landRenamePacket->data().wardNum = land->getWardNum();
landRenamePacket->data().worldId = 67;
landRenamePacket->data().zoneId = land->getZoneId();
memcpy( &landRenamePacket->data().landName, land->getLandName().c_str(), 20 );
auto pHousingMgr = g_fw.get< HousingMgr >();
if( !pHousingMgr )
break;
player.queuePacket( landRenamePacket ); */
pHousingMgr->requestEstateEditGreeting( player, territoryTypeId, worldId, ward, plot );
break;
}
case ClientTriggerType::RequestEstateEditGuestAccessSettings:
{
uint16_t territoryTypeId = param11 & 0xFFFF;
uint16_t worldId = param11 >> 16;
uint8_t ward = ( param12 & 0xFF00 ) >> 8;
uint8_t plot = ( param12 & 0xFF );
auto pHousingMgr = g_fw.get< HousingMgr >();
if( !pHousingMgr )
break;
pHousingMgr->requestEstateEditGuestAccess( player, territoryTypeId, worldId, ward, plot );
break;
}

View file

@ -20,6 +20,7 @@
#include "Zone/HousingMgr.h"
#include "Zone/Land.h"
#include "Zone/ZonePosition.h"
#include "Zone/House.h"
#include "Network/PacketWrappers/InitUIPacket.h"
#include "Network/PacketWrappers/PingPacket.h"
@ -657,15 +658,32 @@ void Core::Network::GameConnection::landRenameHandler( const Core::Network::Pack
{
const auto packet = ZoneChannelPacket< Client::FFXIVIpcRenameLandHandler >( inPacket );
uint32_t landSetId = ( static_cast< uint32_t >( packet.data().zoneId ) << 16 ) | packet.data().wardNum;
auto pHousingMgr = g_fw.get< HousingMgr >();
auto pLand = pHousingMgr->getHousingZoneByLandSetId( landSetId )->getLand( packet.data().landId );
auto landSetId = pHousingMgr->toLandSetId( packet.data().ident.territoryTypeId, packet.data().ident.wardNum );
auto pZone = pHousingMgr->getHousingZoneByLandSetId( landSetId );
if( !pZone )
return;
auto pLand = pZone->getLand( packet.data().ident.landId );
if( !pLand )
return;
// TODO set estate name
//pLand->setLandName( packet.data().landName );
// todo: check perms for fc houses and shit
if( pLand->getPlayerOwner() != player.getId() )
return;
auto pHouse = pLand->getHouse();
if( pHouse )
pHouse->setHouseName( packet.data().houseName );
// todo: this packet is weird, retail sends it with some unknown shit at the start but it doesn't seem to do anything
auto nameUpdatePacket = makeZonePacket< Server::FFXIVIpcLandUpdateHouseName >( player.getId() );
memcpy( &nameUpdatePacket->data().houseName, &packet.data().houseName, sizeof( packet.data().houseName ) );
// todo: who does this get sent to? just the person who renamed it?
player.queuePacket( nameUpdatePacket );
}
void Core::Network::GameConnection::buildPresetHandler( const Core::Network::Packets::FFXIVARR_PACKET_RAW& inPacket,
@ -676,3 +694,13 @@ void Core::Network::GameConnection::buildPresetHandler( const Core::Network::Pac
auto pHousingMgr = g_fw.get< HousingMgr >();
pHousingMgr->buildPresetEstate( player, packet.data().plotNum, packet.data().itemId );
}
void Core::Network::GameConnection::housingUpdateGreetingHandler( const Core::Network::Packets::FFXIVARR_PACKET_RAW& inPacket,
Entity::Player& player )
{
const auto packet = ZoneChannelPacket< Client::FFXIVIpcHousingUpdateHouseGreeting >( inPacket );
auto pHousingMgr = g_fw.get< HousingMgr >();
pHousingMgr->updateEstateGreeting( player, packet.data().ident, std::string( packet.data().greeting ) );
}

View file

@ -35,6 +35,9 @@ Core::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, uint8_
stmt->setUInt( 2, m_houseId );
pDB->execute( stmt );
// todo: make this nicer/configurable?
m_houseName = "Estate #" + std::to_string( landId + 1 );
}
else
{
@ -45,11 +48,10 @@ Core::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, uint8_
auto housePartColours = res->getBlobVector( "HousePartColours" );
auto models = reinterpret_cast< uint32_t* >( &housePartModels[ 0 ] );
auto colours = &housePartColours[ 0 ];
for( auto i = 0; i < 8; i++ )
{
m_houseParts[ i ] = { models[ i ], colours[ i ] };
m_houseParts[ i ] = { models[ i ], housePartColours[ i ] };
}
}
}
@ -143,4 +145,28 @@ uint32_t Core::House::getHousePart( Common::HousePartSlot slot ) const
Core::House::HousePartsArray const& Core::House::getHouseParts() const
{
return m_houseParts;
}
const std::string& Core::House::getHouseName() const
{
return m_houseName;
}
const std::string& Core::House::getHouseGreeting() const
{
return m_estateMessage;
}
void Core::House::setHouseGreeting( const std::string& greeting )
{
m_estateMessage = greeting;
updateHouseDb();
}
void Core::House::setHouseName( const std::string& name )
{
m_houseName = name;
updateHouseDb();
}

View file

@ -25,6 +25,12 @@ namespace Core
uint16_t getTerritoryTypeId() const;
uint32_t getHouseId() const;
const std::string& getHouseName() const;
void setHouseName( const std::string& name );
const std::string& getHouseGreeting() const;
void setHouseGreeting( const std::string& greeting );
//functions
void setHousePart( Common::HousePartSlot slot, uint32_t id );
void setHousePartColor( Common::HousePartSlot slot, uint32_t id );

View file

@ -9,6 +9,7 @@
#include <Network/CommonActorControl.h>
#include <unordered_map>
#include <cstring>
#include "Actor/Player.h"
@ -19,6 +20,7 @@
#include "Land.h"
#include "Framework.h"
#include "ServerMgr.h"
#include "House.h"
using namespace Core::Common;
using namespace Core::Network;
@ -97,7 +99,15 @@ void Core::HousingMgr::sendLandSignOwned( Entity::Player& player, uint8_t wardId
landInfoSignPacket->data().landIdent.wardNum = land->getWardNum();
landInfoSignPacket->data().landIdent.worldId = 67;
landInfoSignPacket->data().landIdent.territoryTypeId = land->getTerritoryTypeId();
landInfoSignPacket->data().houseIconAdd = land->getSharing();
landInfoSignPacket->data().ownerId = player.getContentId(); // should be real owner contentId, not player.contentId()
if( auto house = land->getHouse() )
{
std::strcpy( landInfoSignPacket->data().estateName, house->getHouseName().c_str() );
std::strcpy( landInfoSignPacket->data().estateGreeting, house->getHouseGreeting().c_str() );
}
memcpy( &landInfoSignPacket->data().ownerName, playerName.c_str(), playerName.size() );
player.queuePacket( landInfoSignPacket );
@ -157,11 +167,10 @@ Core::LandPurchaseResult Core::HousingMgr::purchaseLand( Entity::Player& player,
pLand->setState( HouseState::sold );
pLand->setLandType( Common::LandType::Private );
player.setLandPermissions( LandPermissionSlot::Private, 0x00, plot,
player.setLandFlags( LandFlagsSlot::Private, 0x00, plot,
pHousing->getWardNum(), pHousing->getTerritoryTypeId() );
player.sendLandPermissionSlot( static_cast< uint8_t >( LandType::Private ), plot, pHousing->getWardNum(),
pHousing->getTerritoryTypeId() );
player.sendLandFlagsSlot( LandFlagsSlot::Private );
//pLand->setLandName( "Private Estate" + std::to_string( pHousing->getWardNum() ) + "-" + std::to_string( plot ) );
pLand->updateLandDb();
@ -210,9 +219,9 @@ bool Core::HousingMgr::relinquishLand( Entity::Player& player, uint8_t plot )
pLand->setLandType( Common::LandType::none );
pLand->updateLandDb();
player.setLandPermissions( LandPermissionSlot::Private, 0x00, 0xFF, 0xFF, 0xFF );
player.setLandFlags( LandFlagsSlot::Private, 0x00, 0xFF, 0xFF, 0xFF );
player.sendLandPermissionSlot( static_cast< uint8_t >( LandType::Private ), 0xFF, 0xFF, 0xFF );
player.sendLandFlagsSlot( LandFlagsSlot::Private );
auto screenMsgPkt2 = makeActorControl143( player.getId(), ActorControl::LogMsg, 3351, 0x1AA,
pLand->getWardNum() + 1, plot + 1 );
@ -251,14 +260,14 @@ void Core::HousingMgr::sendWardLandInfo( Entity::Player& player, uint8_t wardId,
switch( land->getLandType() )
{
case LandType::FreeCompany:
entry.infoFlags = Common::WardEstateFlags::IsEstateOwned | Common::WardEstateFlags::IsFreeCompanyEstate;
entry.infoFlags = Common::WardlandFlags::IsEstateOwned | Common::WardlandFlags::IsFreeCompanyEstate;
// todo: send FC name
break;
case LandType::Private:
entry.infoFlags = Common::WardEstateFlags::IsEstateOwned;
entry.infoFlags = Common::WardlandFlags::IsEstateOwned;
auto owner = land->getPlayerOwner();
std::string playerName = g_fw.get< Core::ServerMgr >()->getPlayerNameFromDb( owner );
@ -310,5 +319,110 @@ void Core::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNu
// todo: wtf are these flags
player.playScene( 0x000B0095, 0, 4164955899, 0, 1, plotNum, nullptr );
// todo: send perms/flags for house
player.setLandFlags( LandFlagsSlot::Private, ESTATE_BUILT, pLand->getLandId(), pLand->getWardNum(), pLand->getTerritoryTypeId() );
player.sendLandFlagsSlot( LandFlagsSlot::Private );
}
void Core::HousingMgr::requestEstateRename( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId )
{
auto landSetId = toLandSetId( territoryTypeId, wardId );
auto hZone = getHousingZoneByLandSetId( landSetId );
if( !hZone )
return;
auto land = hZone->getLand( plotId );
auto house = land->getHouse();
if( !house )
return;
auto landRenamePacket = makeZonePacket< Server::FFXIVIpcLandRename >( player.getId() );
landRenamePacket->data().landIdent.landId = land->getLandId();
landRenamePacket->data().landIdent.wardNum = land->getWardNum();
landRenamePacket->data().landIdent.worldId = 67;
landRenamePacket->data().landIdent.territoryTypeId = land->getTerritoryTypeId();
memcpy( &landRenamePacket->data().houseName, house->getHouseName().c_str(), 20 );
player.queuePacket( landRenamePacket );
}
void Core::HousingMgr::requestEstateEditGreeting( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId )
{
auto landSetId = toLandSetId( territoryTypeId, wardId );
auto hZone = getHousingZoneByLandSetId( landSetId );
if( !hZone )
return;
auto land = hZone->getLand( plotId );
if( !land )
return;
auto house = land->getHouse();
if( !house )
return;
auto estateGreetingPacket = makeZonePacket< Server::FFXIVIpcHousingEstateGreeting >( player.getId() );
estateGreetingPacket->data().landIdent.landId = land->getLandId();
estateGreetingPacket->data().landIdent.wardNum = land->getWardNum();
estateGreetingPacket->data().landIdent.worldId = 67;
estateGreetingPacket->data().landIdent.territoryTypeId = land->getTerritoryTypeId();
memcpy( &estateGreetingPacket->data().message, house->getHouseGreeting().c_str(), sizeof( estateGreetingPacket->data().message ) );
player.queuePacket( estateGreetingPacket );
}
void Core::HousingMgr::updateEstateGreeting( Entity::Player& player, const Common::LandIdent& ident, const std::string& greeting )
{
auto landSetId = toLandSetId( ident.territoryTypeId, ident.wardNum );
auto zone = getHousingZoneByLandSetId( landSetId );
if( !zone )
return;
auto land = zone->getLand( ident.landId );
if( !land )
return;
// todo: implement proper permissions checks
if( land->getPlayerOwner() != player.getId() )
return;
auto house = land->getHouse();
if( !house )
return;
house->setHouseGreeting( greeting );
// Greeting updated.
player.sendLogMessage( 3381 );
}
void Core::HousingMgr::requestEstateEditGuestAccess( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId )
{
auto landSetId = toLandSetId( territoryTypeId, wardId );
auto hZone = getHousingZoneByLandSetId( landSetId );
if( !hZone )
return;
auto land = hZone->getLand( plotId );
if( !land )
return;
// todo: add proper permission check
if( land->getPlayerOwner() != player.getId() )
return;
auto packet = makeZonePacket< FFXIVIpcHousingShowEstateGuestAccess >( player.getId() );
packet->data().ident.landId = plotId;
packet->data().ident.territoryTypeId = territoryTypeId;
packet->data().ident.wardNum = wardId;
packet->data().ident.worldId = worldId;
player.queuePacket( packet );
}

View file

@ -36,6 +36,13 @@ namespace Core
void buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetItem );
void requestEstateRename( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId );
void requestEstateEditGreeting( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId );
void updateEstateGreeting( Entity::Player& player, const Common::LandIdent& ident, const std::string& greeting );
void requestEstateEditGuestAccess( Entity::Player& player, uint16_t territoryTypeId, uint16_t worldId, uint8_t wardId, uint8_t plotId );
private:
};