diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 9ef1ee51..c413d73b 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -1,6 +1,6 @@ if(UNIX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -fPIC") # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32") else() add_definitions(-D_WIN32_WINNT=0x601) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index a8eac01c..39ba1963 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -73,8 +73,6 @@ namespace Core::Network::Packets SocialRequestResponse = 0x00BB, // updated 4.1 CancelAllianceForming = 0x00C6, // updated 4.2 - - Chat = 0x00F4, // updated 4.4 SocialList = 0x00FB, // updated 4.4 @@ -84,8 +82,7 @@ namespace Core::Network::Packets ServerNotice = 0x0104, // updated 4.4 SetOnlineStatus = 0x0105, // updated 4.4 - - + CountdownInitiate = 0x010C, // updated 4.4 CountdownCancel = 0x010D, // updated 4.4 @@ -184,7 +181,8 @@ namespace Core::Network::Packets EquipDisplayFlags = 0x020C, // updated 4.4 - // housing + /// Housing ////////////////////////////////////// + LandSetInitialize = 0x0220, // updated 4.4 LandUpdate = 0x0221, // updated 4.4 YardObjectSpawn = 0x0222, // updated 4.4 @@ -192,13 +190,21 @@ namespace Core::Network::Packets LandPriceUpdate = 0x0224, // updated 4.4 LandInfoSign = 0x0225, // updated 4.4 RenameLand = 0x0226, // updated 4.4 + + LandPermissionSlot = 0x0228, // updated 4.4 + LandPermission = 0x0229, // updated 4.4 + LandSetYardInitialize = 0x022C, // updated 4.4 + YardObjectMove = 0x0230, // updated 4.4 - LandSetMap = 0x0251, // updated 4.4 SharedEstateSettingsResponse = 0x023C, // updated 4.4 + LandSetMap = 0x0251, // updated 4.4 + + ////////////////////////////////////////////////// + DuelChallenge = 0x0277, // 4.2; this is responsible for opening the ui PerformNote = 0x0286, // updated 4.3 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 6a87c9a9..b0f29327 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1575,8 +1575,14 @@ struct FFXIVIpcPerformNote : FFXIVIpcBasePacket< PerformNote > uint8_t data[32]; }; -//IPCs -struct FFXIVIpcLandPermission : FFXIVIpcBasePacket +struct FFXIVIpcLandPermissionSlot : FFXIVIpcBasePacket< LandPermissionSlot > +{ + uint32_t type; + uint32_t unknown; + Common::LandPermissionSet permissionSet; +}; + +struct FFXIVIpcLandPermission : FFXIVIpcBasePacket< LandPermission > { Common::LandPermissionSet freeCompanyHouse; // 00 uint64_t unkown1; diff --git a/src/servers/Scripts/common/CmnDefHousingSignboard.cpp b/src/servers/Scripts/common/CmnDefHousingSignboard.cpp index 083ad183..43e01820 100644 --- a/src/servers/Scripts/common/CmnDefHousingSignboard.cpp +++ b/src/servers/Scripts/common/CmnDefHousingSignboard.cpp @@ -31,30 +31,49 @@ public: auto pTerritory = player.getCurrentZone(); auto pHousing = std::dynamic_pointer_cast< HousingZone >( pTerritory ); - PurchaseResult res = pHousing->purchseLand( player, activeLand.plot, - static_cast< uint8_t >( result.param2 ) ); + LandPurchaseResult res = pHousing->purchseLand( player, activeLand.plot, + static_cast< uint8_t >( result.param2 ) ); switch( res ) { - case PurchaseResult::SUCCESS: + case LandPurchaseResult::SUCCESS: { auto screenMsgPkt = makeActorControl143( player.getId(), ActorControl::DutyQuestScreenMsg, m_id, 0x98 ); player.queuePacket( screenMsgPkt ); + auto screenMsgPkt2 = makeActorControl143( player.getId(), ActorControl::LogMsg, 0x0D16, 0x1AA, + activeLand.ward + 1, activeLand.plot + 1 ); + player.queuePacket( screenMsgPkt2 ); break; } - case PurchaseResult::ERR_NOT_ENOUGH_GIL: + case LandPurchaseResult::ERR_NOT_ENOUGH_GIL: { - auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 4027 ); + auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3314 ); player.queuePacket( errorMsg ); break; } - case PurchaseResult::ERR_NOT_AVAILABLE: + case LandPurchaseResult::ERR_NOT_AVAILABLE: + { + auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3312 ); + player.queuePacket( errorMsg ); break; + } - case PurchaseResult::ERR_INTERNAL: + case LandPurchaseResult::ERR_NO_MORE_LANDS_FOR_CHAR: + { + auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3313 ); + player.queuePacket( errorMsg ); break; + } + + + case LandPurchaseResult::ERR_INTERNAL: + { + auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 1995 ); + player.queuePacket( errorMsg ); + break; + } } } diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 0e4b793d..6029cd17 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -1580,7 +1580,7 @@ void Core::Entity::Player::sendZonePackets() auto pHousingMgr = g_fw.get< HousingMgr >(); if( Core::LandPtr pLand = pHousingMgr->getLandByOwnerId( getId() ) ) { - setLandPermissions( LandPermissionSlot::Private, 0x0B, pLand->getLandId(), pLand->getWardNum(), pLand->getZoneId() ); + setLandPermissions( LandPermissionSlot::Private, 0x00, pLand->getLandId(), pLand->getWardNum(), pLand->getZoneId() ); } sendLandPermissions(); @@ -1761,14 +1761,15 @@ bool Core::Entity::Player::isOnEnterEventDone() const return m_onEnterEventDone; } -void Core::Entity::Player::setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, int16_t landId, int16_t wardNum, int16_t zoneId ) +void Core::Entity::Player::setLandPermissions( uint8_t permissionSet, uint32_t permissionMask, + int16_t landId, int16_t wardNum, int16_t zoneId ) { - m_landPermission[permissionSet].landId = landId; - m_landPermission[permissionSet].permissionMask = permissionMask; - m_landPermission[permissionSet].wardNum = wardNum; - m_landPermission[permissionSet].zoneId = zoneId; - m_landPermission[permissionSet].worldId = 67; - m_landPermission[permissionSet].unkown1 = 0; + m_landPermission[ permissionSet ].landId = landId; + m_landPermission[ permissionSet ].permissionMask = permissionMask; + m_landPermission[ permissionSet ].wardNum = wardNum; + m_landPermission[ permissionSet ].zoneId = zoneId; + m_landPermission[ permissionSet ].worldId = 67; + m_landPermission[ permissionSet ].unkown1 = 0; } void Core::Entity::Player::sendLandPermissions() diff --git a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp index e324a36e..9328e074 100644 --- a/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/sapphire_zone/DebugCommand/DebugCommandHandler.cpp @@ -1018,7 +1018,7 @@ void Core::DebugCommandHandler::housing( char* data, Entity::Player& player, std auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone ); if( pHousing ) { - player.setLandPermissions( permissionSet, 8, pHousing->getLandSetId(), pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); + player.setLandPermissions( permissionSet, 0, pHousing->getLandSetId(), pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); player.sendLandPermissions(); } else diff --git a/src/servers/sapphire_zone/Zone/HousingZone.cpp b/src/servers/sapphire_zone/Zone/HousingZone.cpp index 685cf8c9..eea9a46d 100644 --- a/src/servers/sapphire_zone/Zone/HousingZone.cpp +++ b/src/servers/sapphire_zone/Zone/HousingZone.cpp @@ -111,7 +111,7 @@ void Core::HousingZone::onPlayerZoneIn( Entity::Player& player ) //memcpy( , &getLand( i )->getLand(), sizeof( Common::LandStruct ) ); } - player.queuePacket( landSetMap ); + //player.queuePacket( landSetMap ); } @@ -154,7 +154,7 @@ bool Core::HousingZone::isPlayerSubInstance( Entity::Player& player ) return player.getPos().x < -15000.0f; //ToDo: get correct pos } -Core::PurchaseResult Core::HousingZone::purchseLand( Entity::Player& player, uint8_t plot, uint8_t state ) +Core::LandPurchaseResult Core::HousingZone::purchseLand( Entity::Player& player, uint8_t plot, uint8_t state ) { auto plotPrice = getLand( plot )->getCurrentPrice(); @@ -162,35 +162,44 @@ Core::PurchaseResult Core::HousingZone::purchseLand( Entity::Player& player, uin auto pLand = getLand( plot ); if( !pLand ) - return PurchaseResult::ERR_INTERNAL; + return LandPurchaseResult::ERR_INTERNAL; if( pLand->getState() != HouseState::forSale ) - return PurchaseResult::ERR_NOT_AVAILABLE; + return LandPurchaseResult::ERR_NOT_AVAILABLE; if( gilAvailable < plotPrice ) - return PurchaseResult::ERR_NOT_ENOUGH_GIL; + return LandPurchaseResult::ERR_NOT_ENOUGH_GIL; auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); - switch( state ) + switch( static_cast< LandPurchaseMode >( state ) ) { - case 1: + case LandPurchaseMode::FC: player.sendDebug( "Free company house purchase aren't supported at this time." ); - return PurchaseResult::ERR_INTERNAL; + return LandPurchaseResult::ERR_INTERNAL; + + case LandPurchaseMode::PRIVATE: + { + + auto pHousingMgr = g_fw.get< HousingMgr >(); + auto pOldLand = pHousingMgr->getLandByOwnerId( player.getId() ); + + if( pOldLand ) + return LandPurchaseResult::ERR_NO_MORE_LANDS_FOR_CHAR; - case 2: player.removeCurrency( CurrencyType::Gil, plotPrice ); pLand->setPlayerOwner( player.getId() ); pLand->setState( HouseState::sold ); - player.setLandPermissions( LandPermissionSlot::Private, 0x0B, plot, + player.setLandPermissions( LandPermissionSlot::Private, 0x00, plot, pHousing->getWardNum(), pHousing->getTerritoryTypeId() ); player.sendLandPermissions(); pLand->UpdateLandDb(); sendLandUpdate( plot ); - return PurchaseResult::SUCCESS; + return LandPurchaseResult::SUCCESS; + } default: - return PurchaseResult::ERR_INTERNAL; + return LandPurchaseResult::ERR_INTERNAL; } } diff --git a/src/servers/sapphire_zone/Zone/HousingZone.h b/src/servers/sapphire_zone/Zone/HousingZone.h index a93be9d2..ef321b98 100644 --- a/src/servers/sapphire_zone/Zone/HousingZone.h +++ b/src/servers/sapphire_zone/Zone/HousingZone.h @@ -6,14 +6,22 @@ namespace Core { - enum class PurchaseResult + enum class LandPurchaseResult { SUCCESS, ERR_NOT_ENOUGH_GIL, ERR_NOT_AVAILABLE, + ERR_NO_MORE_LANDS_FOR_CHAR, ERR_INTERNAL, }; + enum class LandPurchaseMode + { + FC = 1, + PRIVATE = 2, + RELOCATE = 4, + }; + class HousingZone : public Zone { public: @@ -34,7 +42,7 @@ namespace Core void sendLandUpdate( uint8_t landId ); bool isPlayerSubInstance( Entity::Player& player ); - PurchaseResult purchseLand( Entity::Player& player, uint8_t plot, uint8_t state ); + LandPurchaseResult purchseLand( Entity::Player& player, uint8_t plot, uint8_t state ); /* returns current ward number for this zone */ uint8_t getWardNum() const;