From 4615365e4fe5788342b702623527cf8d0ed2385b Mon Sep 17 00:00:00 2001 From: AriAvery <41122212+AriAvery@users.noreply.github.com> Date: Sat, 1 Dec 2018 21:40:30 +0100 Subject: [PATCH 01/13] housing instance --- sql/update_land.sql | 3 +- src/common/Common.h | 14 ++++ src/common/Database/ZoneDbConnection.cpp | 2 +- src/common/Network/PacketDef/Ipcs.h | 4 +- .../Network/PacketDef/Zone/ServerZoneDef.h | 20 ++++-- .../common/eobj/HousingEstateEntrance.cpp | 8 ++- .../sapphire_zone/Manager/TerritoryMgr.cpp | 2 +- src/servers/sapphire_zone/Territory/House.cpp | 33 ++++++++- src/servers/sapphire_zone/Territory/House.h | 3 + .../Housing/HousingInteriorTerritory.cpp | 71 ++++++++++++++++++- .../Housing/HousingInteriorTerritory.h | 4 +- .../sapphire_zone/Territory/HousingZone.cpp | 13 ++-- src/servers/sapphire_zone/Territory/Land.cpp | 12 ++++ 13 files changed, 164 insertions(+), 25 deletions(-) diff --git a/sql/update_land.sql b/sql/update_land.sql index 87f14e23..7dc864f6 100644 --- a/sql/update_land.sql +++ b/sql/update_land.sql @@ -1,4 +1,5 @@ ALTER TABLE `land` ADD `Type` SMALLINT(6) NOT NULL DEFAULT '0' AFTER `LandId`; ALTER TABLE `house` ADD `HouseName` binary(23) DEFAULT "" AFTER `Comment`; ALTER TABLE `house` ADD `HousePartModels` BINARY(32) DEFAULT "" AFTER `Endorsements`; -ALTER TABLE `house` ADD `HousePartColours` BINARY(8) DEFAULT "" AFTER `HousePartModels`; \ No newline at end of file +ALTER TABLE `house` ADD `HousePartColours` BINARY(8) DEFAULT "" AFTER `HousePartModels`; +ALTER TABLE `house` ADD `HouseInteriorModels` BINARY(40) DEFAULT "" AFTER `HousePartColours`; \ No newline at end of file diff --git a/src/common/Common.h b/src/common/Common.h index 0eaa4b4f..2ed618a3 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -751,6 +751,20 @@ namespace Sapphire::Common YardSign }; + enum HousingInteriorSlot + { + InteriorWall, + InteriorFloor, + InteriorLight, + InteriorWall_Attic, + InteriorFloor_Attic, + InteriorLight_Attic, + InteriorWall_Basement, + InteriorFloor_Basement, + InteriorLight_Basement, + InteriorLight_Mansion + }; + enum HouseTagSlot { MainTag, diff --git a/src/common/Database/ZoneDbConnection.cpp b/src/common/Database/ZoneDbConnection.cpp index 0cc56879..28eba502 100644 --- a/src/common/Database/ZoneDbConnection.cpp +++ b/src/common/Database/ZoneDbConnection.cpp @@ -197,7 +197,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements() CONNECTION_BOTH ); prepareStatement( HOUSING_HOUSE_UP, - "UPDATE house SET BuildTime = ?, Aetheryte = ?, Comment = ?, HouseName = ?, Endorsements = ?, HousePartModels = ?, HousePartColours = ? WHERE HouseId = ?;", + "UPDATE house SET BuildTime = ?, Aetheryte = ?, Comment = ?, HouseName = ?, Endorsements = ?, HousePartModels = ?, HousePartColours = ?, HouseInteriorModels = ? WHERE HouseId = ?;", CONNECTION_BOTH ); /*prepareStatement( LAND_INS, diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 089744ce..ccf2d3c5 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -186,7 +186,7 @@ namespace Sapphire::Network::Packets LandSetInitialize = 0x0220, // updated 4.4 LandUpdate = 0x0221, // updated 4.4 YardObjectSpawn = 0x0222, // updated 4.4 - + HousingIndoorInitialize = 0x0223, LandPriceUpdate = 0x0224, // updated 4.4 LandInfoSign = 0x0225, // updated 4.4 LandRename = 0x0226, // updated 4.4 @@ -197,7 +197,7 @@ namespace Sapphire::Network::Packets HousingLandFlags = 0x0229, // updated 4.4 HousingShowEstateGuestAccess = 0x022A, // updated 4.4 - LandSetYardInitialize = 0x022C, // updated 4.4 + HousingObjectInitialize = 0x022C, // updated 4.4 HousingWardInfo = 0x022F, // updated 4.4 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 1e8efb03..64bc9a03 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1704,17 +1704,27 @@ struct FFXIVIpcYardObjectMove : FFXIVIpcBasePacket uint16_t unknown3; }; -struct FFXIVIpcLandSetYardInitialize : FFXIVIpcBasePacket< LandSetYardInitialize > +struct FFXIVIpcHousingObjectInitialize : FFXIVIpcBasePacket< HousingObjectInitialize > { - uint32_t unknown1; //always 0xFFFFFFFF - uint32_t unknown2; //always 0xFFFFFFFF - uint8_t unknown3; //always 0xFF + Common::LandIdent landIdent; + int8_t u1; //Outdoor -1 / Indoor 0 - probably indicator uint8_t packetNum; - uint16_t packetTotal; + uint8_t packetTotal; + uint8_t u2; //Outdoor 0 / Indoor 100(?) Common::YardObject object[100]; uint32_t unknown4; //unused }; +struct FFXIVIpcHousingIndoorInitialize : FFXIVIpcBasePacket< HousingIndoorInitialize > +{ + uint16_t u1; + uint16_t u2; + uint16_t u3; + uint16_t u4; + uint32_t indoorItems[10]; +}; + + struct FFXIVIpcHousingWardInfo : FFXIVIpcBasePacket< HousingWardInfo > { Common::LandIdent landIdent; diff --git a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp index 6980d2f6..e534d42e 100644 --- a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp @@ -45,7 +45,13 @@ public: if( result.param2 != 1 ) return; - // param2 == 1, zone into instance + if( result.param2 == 1 ) + { + //player.eventFinish( 131148, 0 ); + //player.eventFinish( this->getId(), 1 ); + player.setPos( {0, 0, 0} ); + player.setInstance( internalZone ); + } } ); } }; \ No newline at end of file diff --git a/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp b/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp index 4db1441c..ecf98d26 100644 --- a/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp +++ b/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp @@ -341,7 +341,7 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInt if( !terriInfo ) return nullptr; - auto zone = World::Territory::Housing::make_HousingInteriorTerritory( ident, territoryTypeId, getNextInstanceId(), + auto zone = World::Territory::Housing::make_HousingInteriorTerritory( landIdent, territoryTypeId, getNextInstanceId(), terriInfo->name, house->getHouseName() ); zone->init(); diff --git a/src/servers/sapphire_zone/Territory/House.cpp b/src/servers/sapphire_zone/Territory/House.cpp index 5698635c..c63f7a2c 100644 --- a/src/servers/sapphire_zone/Territory/House.cpp +++ b/src/servers/sapphire_zone/Territory/House.cpp @@ -48,11 +48,18 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, ui auto housePartColours = res->getBlobVector( "HousePartColours" ); auto models = reinterpret_cast< uint32_t* >( &housePartModels[ 0 ] ); - for( auto i = 0; i < 8; i++ ) { m_houseParts[ i ] = { models[ i ], housePartColours[ i ] }; } + + auto houseInteriorModels = res->getBlobVector( "HouseInteriorModels" ); + + models = reinterpret_cast( &houseInteriorModels[0] ); + for( auto i = 0; i < 10; i++ ) + { + m_houseInteriorParts[ i ] = houseInteriorModels[ i ]; + } } } @@ -67,7 +74,7 @@ void Sapphire::House::updateHouseDb() // BuildTime = 1, Aetheryte = 2, Comment = 3, HouseName = 4, Endorsements = 5, // HousePartModels = 6, HousePartColours = 7, HouseId = 8 auto stmt = pDB->getPreparedStatement( Db::HOUSING_HOUSE_UP ); - stmt->setUInt( 8, m_houseId ); + stmt->setUInt( 9, m_houseId ); stmt->setInt64( 1, m_buildTime ); stmt->setInt( 2, 0 ); @@ -94,6 +101,18 @@ void Sapphire::House::updateHouseDb() stmt->setBinary( 6, tmpModels ); stmt->setBinary( 7, colours ); + models.clear(); + + for( auto i = 0; i < 10; i++ ) + { + models.push_back( m_houseInteriorParts[ i ] ); + } + + std::vector< uint8_t > tmp2Models( models.size() * 4 ); + memcpy( tmp2Models.data(), models.data(), tmp2Models.size() ); + + stmt->setBinary( 8, tmp2Models ); + pDB->execute( stmt ); } @@ -127,6 +146,11 @@ uint8_t Sapphire::House::getHousePartColor( Common::HousePartSlot slot ) const return m_houseParts[ slot ].second; } +uint32_t Sapphire::House::getHouseInteriorPart( Common::HousingInteriorSlot slot ) const +{ + return m_houseInteriorParts[ slot ]; +} + void Sapphire::House::setHousePart( Common::HousePartSlot slot, uint32_t id ) { m_houseParts[ slot ].first = id; @@ -137,6 +161,11 @@ void Sapphire::House::setHousePartColor( Common::HousePartSlot slot, uint32_t id m_houseParts[ slot ].second = id; } +void Sapphire::House::setHouseInteriorPart( Common::HousingInteriorSlot slot, uint32_t id ) +{ + m_houseInteriorParts[ slot ] = id; +} + uint32_t Sapphire::House::getHousePart( Common::HousePartSlot slot ) const { return m_houseParts[ slot ].first; diff --git a/src/servers/sapphire_zone/Territory/House.h b/src/servers/sapphire_zone/Territory/House.h index 6a9196d4..183afd1f 100644 --- a/src/servers/sapphire_zone/Territory/House.h +++ b/src/servers/sapphire_zone/Territory/House.h @@ -34,8 +34,10 @@ namespace Sapphire //functions void setHousePart( Common::HousePartSlot slot, uint32_t id ); void setHousePartColor( Common::HousePartSlot slot, uint32_t id ); + void setHouseInteriorPart( Common::HousingInteriorSlot slot, uint32_t id ); uint32_t getHousePart( Common::HousePartSlot slot ) const; uint8_t getHousePartColor( Common::HousePartSlot slot ) const; + uint32_t getHouseInteriorPart( Common::HousingInteriorSlot slot ) const; HousePartsArray const& getHouseParts() const; @@ -51,6 +53,7 @@ namespace Sapphire uint64_t m_buildTime; HousePartsArray m_houseParts; + uint32_t m_houseInteriorParts[10]; std::string m_estateMessage; std::string m_houseName; diff --git a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp index c89a1a1b..758274ff 100644 --- a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp @@ -1,10 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Actor/Player.h" +#include "Actor/Actor.h" +#include "Actor/EventObject.h" +#include "Manager/HousingMgr.h" +#include "Territory/Land.h" +#include "Territory/House.h" + +#include "Forwards.h" #include "HousingInteriorTerritory.h" -#include "Common.h" +#include "Framework.h" + +extern Sapphire::Framework g_fw; + +using namespace Sapphire::Common; +using namespace Sapphire::Network::Packets; +using namespace Sapphire::Network::Packets::Server; +using namespace Sapphire::World::Manager; using namespace Sapphire; using namespace Sapphire::World::Territory; -Housing::HousingInteriorTerritory::HousingInteriorTerritory( uint64_t ident, uint16_t territoryTypeId, +Housing::HousingInteriorTerritory::HousingInteriorTerritory( Common::LandIdent ident, uint16_t territoryTypeId, uint32_t guId, const std::string& internalName, const std::string& contentName ) : @@ -21,11 +45,52 @@ Housing::HousingInteriorTerritory::~HousingInteriorTerritory() bool Housing::HousingInteriorTerritory::init() { - + return false; } void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player ) { + auto pHousingMgr = g_fw.get< HousingMgr >(); + auto pLog = g_fw.get< Logger >(); + pLog->debug( + "HousingInteriorTerritory::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryTypeId() ) + + ", Entity#" + std::to_string( player.getId() ) ); + + auto housingIndoorInitializPacket = makeZonePacket< FFXIVIpcHousingIndoorInitialize >( player.getId() ); + housingIndoorInitializPacket->data().u1 = 2578; + housingIndoorInitializPacket->data().u2 = 10; + housingIndoorInitializPacket->data().u3 = 530; + housingIndoorInitializPacket->data().u4 = 266; + + auto landSetId = pHousingMgr->toLandSetId( m_landIdent.territoryTypeId, m_landIdent.wardNum ); + auto pLand = pHousingMgr->getHousingZoneByLandSetId( landSetId )->getLand( m_landIdent.landId ); + auto pHouse = pLand->getHouse(); + + + uint32_t yardPacketNum; + uint32_t yardPacketTotal = 2 + pLand->getSize(); + + for( auto i = 0; i < 10; i++ ) + { + housingIndoorInitializPacket->data().indoorItems[ i ] = pHouse->getHouseInteriorPart( (Common::HousingInteriorSlot)i ); + } + + player.queuePacket( housingIndoorInitializPacket ); + + for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) + { + auto housingObjectInitializPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); + memcpy( &housingObjectInitializPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) ); + housingObjectInitializPacket->data().landIdent.worldId = 67; + housingObjectInitializPacket->data().u1 = 0; + housingObjectInitializPacket->data().u2 = 100; + housingObjectInitializPacket->data().packetNum = yardPacketNum; + housingObjectInitializPacket->data().packetTotal = yardPacketTotal; + + //TODO: Add Objects here + + player.queuePacket( housingObjectInitializPacket ); + } } diff --git a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h index 539ebba9..281d4bc4 100644 --- a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h +++ b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h @@ -6,7 +6,7 @@ namespace Sapphire::World::Territory::Housing class HousingInteriorTerritory : public Zone { public: - HousingInteriorTerritory( uint64_t ident, uint16_t territoryTypeId, + HousingInteriorTerritory( Common::LandIdent ident, uint16_t territoryTypeId, uint32_t guId, const std::string& internalName, const std::string& contentName ); @@ -19,6 +19,6 @@ namespace Sapphire::World::Territory::Housing void onUpdate( uint32_t currTime ) override; private: - uint64_t m_landIdent; + Common::LandIdent m_landIdent; }; } \ No newline at end of file diff --git a/src/servers/sapphire_zone/Territory/HousingZone.cpp b/src/servers/sapphire_zone/Territory/HousingZone.cpp index a4f6e49c..57390006 100644 --- a/src/servers/sapphire_zone/Territory/HousingZone.cpp +++ b/src/servers/sapphire_zone/Territory/HousingZone.cpp @@ -96,16 +96,15 @@ void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player ) for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) { - auto landsetYardInitializePacket = makeZonePacket< FFXIVIpcLandSetYardInitialize >( player.getId() ); - landsetYardInitializePacket->data().unknown1 = 0xFFFFFFFF; - landsetYardInitializePacket->data().unknown2 = 0xFFFFFFFF; - landsetYardInitializePacket->data().unknown3 = 0xFF; - landsetYardInitializePacket->data().packetNum = yardPacketNum; - landsetYardInitializePacket->data().packetTotal = yardPacketTotal; + auto housingObjectInitializPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); + memset( &housingObjectInitializPacket->data().landIdent, 0xFF, sizeof( Common::LandIdent ) ); + housingObjectInitializPacket->data().u1 = 0xFF; + housingObjectInitializPacket->data().packetNum = yardPacketNum; + housingObjectInitializPacket->data().packetTotal = yardPacketTotal; //TODO: Add Objects here - player.queuePacket( landsetYardInitializePacket ); + player.queuePacket( housingObjectInitializPacket ); } auto landSetMap = makeZonePacket< FFXIVIpcLandSetMap >( player.getId() ); diff --git a/src/servers/sapphire_zone/Territory/Land.cpp b/src/servers/sapphire_zone/Territory/Land.cpp index 4efe3de7..6319679d 100644 --- a/src/servers/sapphire_zone/Territory/Land.cpp +++ b/src/servers/sapphire_zone/Territory/Land.cpp @@ -337,5 +337,17 @@ bool Sapphire::Land::setPreset( uint32_t itemId ) getHouse()->setHousePart( Common::HousePartSlot::ExteriorWindow, convertItemIdToHousingItemId( housingPreset->exteriorWindow ) ); getHouse()->setHousePart( Common::HousePartSlot::ExteriorDoor, convertItemIdToHousingItemId( housingPreset->exteriorDoor ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall, convertItemIdToHousingItemId( housingPreset->interiorWall ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor, convertItemIdToHousingItemId( housingPreset->interiorFlooring ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight, convertItemIdToHousingItemId( housingPreset->interiorLighting ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorWall ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorFlooring ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorLighting ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall_Basement, convertItemIdToHousingItemId( housingPreset->basementWall ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor_Basement, convertItemIdToHousingItemId( housingPreset->basementFlooring ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Basement, convertItemIdToHousingItemId( housingPreset->basementLighting ) ); + getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Mansion, convertItemIdToHousingItemId( housingPreset->mansionLighting ) ); + + return true; } From d0dc247d6461d5001f736fce6d8f01ff58d90aa9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 14:59:24 +1100 Subject: [PATCH 02/13] fix zoning in/out of houses --- src/common/Network/CommonActorControl.h | 1 + .../common/eobj/HousingEstateEntrance.cpp | 12 ++++----- .../CmnDefHousingPersonalRoomEntrance.cpp | 21 ++++++++++++++++ .../{ => housing}/CmnDefHousingSignboard.cpp | 0 .../warptaxi/HousingWarpTaxiExitEstate.cpp | 25 +++++++++++++++++++ src/servers/sapphire_zone/Territory/House.cpp | 4 +-- src/servers/sapphire_zone/Territory/Land.cpp | 21 ++++++++-------- 7 files changed, 65 insertions(+), 19 deletions(-) create mode 100644 src/servers/Scripts/common/housing/CmnDefHousingPersonalRoomEntrance.cpp rename src/servers/Scripts/common/{ => housing}/CmnDefHousingSignboard.cpp (100%) create mode 100644 src/servers/Scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 357bb54b..208aeb97 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -304,6 +304,7 @@ enum ActorControlType : uint16_t RequestHousingItemUI = 0x463, RequestSharedEstateSettings = 0x46F, + UpdateEstateLightingLevel = 0x471, CompanionAction = 0x6A4, CompanionSetBarding = 0x6A5, diff --git a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp index e534d42e..7394ac86 100644 --- a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp @@ -42,16 +42,14 @@ public: player.sendDebug( "created zone with guid: " + std::to_string( internalZone->getGuId() ) + "\nname: " + internalZone->getName() ); } + // param2 == 1 when player wants to enter house if( result.param2 != 1 ) return; - if( result.param2 == 1 ) - { - //player.eventFinish( 131148, 0 ); - //player.eventFinish( this->getId(), 1 ); - player.setPos( {0, 0, 0} ); - player.setInstance( internalZone ); - } + player.eventFinish( result.eventId, 1 ); + + player.setPos( { 0.f, 0.f, 0.f } ); + player.setInstance( internalZone ); } ); } }; \ No newline at end of file diff --git a/src/servers/Scripts/common/housing/CmnDefHousingPersonalRoomEntrance.cpp b/src/servers/Scripts/common/housing/CmnDefHousingPersonalRoomEntrance.cpp new file mode 100644 index 00000000..abb5e740 --- /dev/null +++ b/src/servers/Scripts/common/housing/CmnDefHousingPersonalRoomEntrance.cpp @@ -0,0 +1,21 @@ +#include +#include + +using namespace Sapphire; + +class CmnDefHousingPersonalRoomEntrance : public Sapphire::ScriptAPI::EventScript +{ +public: + CmnDefHousingPersonalRoomEntrance() : + Sapphire::ScriptAPI::EventScript( 0x000b00b2 ) + { + } + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + player.playScene( eventId, 0, 0, []( Entity::Player& player, const Event::SceneResult& result ) + { + + } ); + } +}; \ No newline at end of file diff --git a/src/servers/Scripts/common/CmnDefHousingSignboard.cpp b/src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp similarity index 100% rename from src/servers/Scripts/common/CmnDefHousingSignboard.cpp rename to src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp diff --git a/src/servers/Scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp b/src/servers/Scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp new file mode 100644 index 00000000..5dd34bf3 --- /dev/null +++ b/src/servers/Scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp @@ -0,0 +1,25 @@ +#include +#include + +using namespace Sapphire; + +class HousingWarpTaxiExitEstate : public Sapphire::ScriptAPI::EventScript +{ +public: + HousingWarpTaxiExitEstate() : + Sapphire::ScriptAPI::EventScript( 0x0002004d ) + { + } + + void onTalk( uint32_t eventId, Entity::Player& player, uint64_t actorId ) override + { + player.playScene( eventId, 0, 0, []( Entity::Player& player, const Event::SceneResult& result ) + { + if( result.param2 == 1 ) + { + player.eventFinish( result.eventId, 1 ); + player.exitInstance(); + } + } ); + } +}; \ No newline at end of file diff --git a/src/servers/sapphire_zone/Territory/House.cpp b/src/servers/sapphire_zone/Territory/House.cpp index c63f7a2c..d5b20ef2 100644 --- a/src/servers/sapphire_zone/Territory/House.cpp +++ b/src/servers/sapphire_zone/Territory/House.cpp @@ -55,10 +55,10 @@ Sapphire::House::House( uint32_t houseId, uint32_t landSetId, uint8_t landId, ui auto houseInteriorModels = res->getBlobVector( "HouseInteriorModels" ); - models = reinterpret_cast( &houseInteriorModels[0] ); + auto interiorModels = reinterpret_cast< uint32_t* >( &houseInteriorModels[ 0 ] ); for( auto i = 0; i < 10; i++ ) { - m_houseInteriorParts[ i ] = houseInteriorModels[ i ]; + m_houseInteriorParts[ i ] = interiorModels[ i ]; } } } diff --git a/src/servers/sapphire_zone/Territory/Land.cpp b/src/servers/sapphire_zone/Territory/Land.cpp index 8ba1412c..d61dcaf5 100644 --- a/src/servers/sapphire_zone/Territory/Land.cpp +++ b/src/servers/sapphire_zone/Territory/Land.cpp @@ -332,21 +332,22 @@ bool Sapphire::Land::setPreset( uint32_t itemId ) m_pHouse = make_House( newId, getLandSetId(), getLandId(), getWardNum(), getTerritoryTypeId() ); } + getHouse()->setHousePart( Common::HousePartSlot::ExteriorRoof, convertItemIdToHousingItemId( housingPreset->exteriorRoof ) ); getHouse()->setHousePart( Common::HousePartSlot::ExteriorWall, convertItemIdToHousingItemId( housingPreset->exteriorWall ) ); getHouse()->setHousePart( Common::HousePartSlot::ExteriorWindow, convertItemIdToHousingItemId( housingPreset->exteriorWindow ) ); getHouse()->setHousePart( Common::HousePartSlot::ExteriorDoor, convertItemIdToHousingItemId( housingPreset->exteriorDoor ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall, convertItemIdToHousingItemId( housingPreset->interiorWall ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor, convertItemIdToHousingItemId( housingPreset->interiorFlooring ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight, convertItemIdToHousingItemId( housingPreset->interiorLighting ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorWall ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorFlooring ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorLighting ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorWall_Basement, convertItemIdToHousingItemId( housingPreset->basementWall ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorFloor_Basement, convertItemIdToHousingItemId( housingPreset->basementFlooring ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Basement, convertItemIdToHousingItemId( housingPreset->basementLighting ) ); - getHouse()->setHouseInteriorPart(Common::HousingInteriorSlot::InteriorLight_Mansion, convertItemIdToHousingItemId( housingPreset->mansionLighting ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorWall, convertItemIdToHousingItemId( housingPreset->interiorWall ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorFloor, convertItemIdToHousingItemId( housingPreset->interiorFlooring ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorLight, convertItemIdToHousingItemId( housingPreset->interiorLighting ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorWall_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorWall ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorFloor_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorFlooring ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorLight_Attic, convertItemIdToHousingItemId( housingPreset->otherFloorLighting ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorWall_Basement, convertItemIdToHousingItemId( housingPreset->basementWall ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorFloor_Basement, convertItemIdToHousingItemId( housingPreset->basementFlooring ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorLight_Basement, convertItemIdToHousingItemId( housingPreset->basementLighting ) ); + getHouse()->setHouseInteriorPart( Common::HousingInteriorSlot::InteriorLight_Mansion, convertItemIdToHousingItemId( housingPreset->mansionLighting ) ); return true; From 62194555912976dad23bc230ae177ddfb23f4ad0 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 15:32:22 +1100 Subject: [PATCH 03/13] when exiting an instance, return the player to correct ward --- src/servers/sapphire_api/PlayerMinimal.cpp | 2 +- src/servers/sapphire_api/PlayerMinimal.h | 4 +-- src/servers/sapphire_zone/Actor/Actor.h | 2 +- src/servers/sapphire_zone/Actor/Player.cpp | 36 +++++++++++++------ src/servers/sapphire_zone/Actor/Player.h | 4 +-- src/servers/sapphire_zone/Actor/PlayerSql.cpp | 13 +++---- .../sapphire_zone/Territory/HousingZone.cpp | 10 +++--- .../sapphire_zone/Territory/HousingZone.h | 2 +- src/servers/sapphire_zone/Territory/Zone.h | 2 +- 9 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/servers/sapphire_api/PlayerMinimal.cpp b/src/servers/sapphire_api/PlayerMinimal.cpp index 31e84818..5ca13b9a 100644 --- a/src/servers/sapphire_api/PlayerMinimal.cpp +++ b/src/servers/sapphire_api/PlayerMinimal.cpp @@ -64,7 +64,7 @@ void PlayerMinimal::load( uint32_t charId ) m_guardianDeity = res->getUInt8( "GuardianDeity" ); m_class = res->getUInt8( "Class" ); m_contentId = res->getUInt64( "ContentId" ); - m_zoneId = res->getUInt16( "TerritoryType" ); + m_territoryTypeId = res->getUInt16( "TerritoryType" ); res.reset(); diff --git a/src/servers/sapphire_api/PlayerMinimal.h b/src/servers/sapphire_api/PlayerMinimal.h index 7cbaade8..dda3202e 100644 --- a/src/servers/sapphire_api/PlayerMinimal.h +++ b/src/servers/sapphire_api/PlayerMinimal.h @@ -131,7 +131,7 @@ namespace Sapphire uint32_t getZoneId() const { - return m_zoneId; + return m_territoryTypeId; } uint32_t getTribe() const @@ -185,7 +185,7 @@ namespace Sapphire uint8_t m_tribe; - uint16_t m_zoneId; + uint16_t m_territoryTypeId; uint64_t m_modelMainWeapon; uint64_t m_modelSubWeapon; diff --git a/src/servers/sapphire_zone/Actor/Actor.h b/src/servers/sapphire_zone/Actor/Actor.h index bacb63e0..5f20797d 100644 --- a/src/servers/sapphire_zone/Actor/Actor.h +++ b/src/servers/sapphire_zone/Actor/Actor.h @@ -30,7 +30,7 @@ namespace Sapphire::Entity /*! Type of the actor */ Common::ObjKind m_objKind; /*! Id of the zone the actor currently is in */ - uint32_t m_zoneId; + uint32_t m_territoryTypeId; /*! Ptr to the ZoneObj the actor belongs to */ ZonePtr m_pCurrentZone; diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 038a95b1..ead5d2d4 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -128,7 +128,7 @@ uint32_t Sapphire::Entity::Player::getMaxMp() uint16_t Sapphire::Entity::Player::getZoneId() const { - return m_zoneId; + return m_territoryTypeId; } uint32_t Sapphire::Entity::Player::getTerritoryId() const @@ -414,9 +414,9 @@ void Sapphire::Entity::Player::setZone( uint32_t zoneId ) // todo: this will require proper handling, for now just return the player to their previous area m_pos = m_prevPos; m_rot = m_prevRot; - m_zoneId = m_prevZoneId; + m_territoryTypeId = m_prevTerritoryTypeId; - if( !pTeriMgr->movePlayer( m_zoneId, getAsPlayer() ) ) + if( !pTeriMgr->movePlayer( m_territoryTypeId, getAsPlayer() ) ) return; } @@ -442,12 +442,15 @@ bool Sapphire::Entity::Player::setInstance( ZonePtr instance ) auto pTeriMgr = g_fw.get< TerritoryMgr >(); + auto currentZone = getCurrentZone(); + // zoning within the same zone won't cause the prev data to be overwritten - if( instance->getTerritoryTypeId() != m_zoneId ) + if( instance->getTerritoryTypeId() != m_territoryTypeId ) { m_prevPos = m_pos; m_prevRot = m_rot; - m_prevZoneId = m_zoneId; + m_prevTerritoryTypeId = currentZone->getTerritoryTypeId(); + m_prevTerritoryId = getTerritoryId(); } if( !pTeriMgr->movePlayer( instance, getAsPlayer() ) ) @@ -461,12 +464,23 @@ bool Sapphire::Entity::Player::setInstance( ZonePtr instance ) bool Sapphire::Entity::Player::exitInstance() { auto pTeriMgr = g_fw.get< TerritoryMgr >(); - if( !pTeriMgr->movePlayer( m_prevZoneId, getAsPlayer() ) ) - return false; + + // check if housing zone + if( pTeriMgr->isHousingTerritory( m_prevTerritoryTypeId ) ) + { + if( !pTeriMgr->movePlayer( pTeriMgr->getZoneByLandSetId( m_prevTerritoryId ), getAsPlayer() ) ) + return false; + } + else + { + if( !pTeriMgr->movePlayer( m_prevTerritoryTypeId, getAsPlayer() ) ) + return false; + } m_pos = m_prevPos; m_rot = m_prevRot; - m_zoneId = m_prevZoneId; + m_territoryTypeId = m_prevTerritoryTypeId; + m_territoryId = m_prevTerritoryId; sendZonePackets(); @@ -1232,7 +1246,7 @@ void Sapphire::Entity::Player::setLoadingComplete( bool bComplete ) void Sapphire::Entity::Player::performZoning( uint16_t zoneId, const Common::FFXIVARR_POSITION3& pos, float rotation ) { m_pos = pos; - m_zoneId = zoneId; + m_territoryTypeId = zoneId; m_bMarkedForZoning = true; setRot( rotation ); setZone( zoneId ); @@ -1530,12 +1544,12 @@ void Sapphire::Entity::Player::setEorzeaTimeOffset( uint64_t timestamp ) void Sapphire::Entity::Player::setTerritoryTypeId( uint32_t territoryTypeId ) { - m_zoneId = territoryTypeId; + m_territoryTypeId = territoryTypeId; } uint32_t Sapphire::Entity::Player::getTerritoryTypeId() const { - return m_zoneId; + return m_territoryTypeId; } void Sapphire::Entity::Player::sendZonePackets() diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index a80cdc6f..8532e21a 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -945,8 +945,8 @@ namespace Sapphire::Entity InventoryMap m_storageMap; Common::FFXIVARR_POSITION3 m_prevPos; - uint32_t m_prevZoneType; - uint32_t m_prevZoneId; + uint32_t m_prevTerritoryTypeId; + uint32_t m_prevTerritoryId; float m_prevRot; uint8_t m_voice; diff --git a/src/servers/sapphire_zone/Actor/PlayerSql.cpp b/src/servers/sapphire_zone/Actor/PlayerSql.cpp index b19fc331..136ddd40 100644 --- a/src/servers/sapphire_zone/Actor/PlayerSql.cpp +++ b/src/servers/sapphire_zone/Actor/PlayerSql.cpp @@ -52,7 +52,8 @@ bool Sapphire::Entity::Player::load( uint32_t charId, SessionPtr pSession ) auto zoneId = res->getUInt( "TerritoryType" ); m_territoryId = res->getUInt( "TerritoryId" ); - m_prevZoneId = res->getUInt( "OTerritoryType" ); + m_prevTerritoryTypeId = res->getUInt( "OTerritoryType" ); + m_prevTerritoryId = res->getUInt( "OTerritoryId" ); // Position m_pos.x = res->getFloat( "PosX" ); @@ -75,7 +76,7 @@ bool Sapphire::Entity::Player::load( uint32_t charId, SessionPtr pSession ) // if none found, revert to previous zone and position if( !pCurrZone ) { - zoneId = m_prevZoneId; + zoneId = m_prevTerritoryTypeId; m_pos.x = m_prevPos.x; m_pos.y = m_prevPos.y; m_pos.z = m_prevPos.z; @@ -92,7 +93,7 @@ bool Sapphire::Entity::Player::load( uint32_t charId, SessionPtr pSession ) pCurrZone = pTeriMgr->getZoneByTerritoryTypeId( zoneId ); } - m_zoneId = zoneId; + m_territoryTypeId = zoneId; // TODO: logic for instances needs to be added here // see if a valid zone could be found for the character @@ -370,15 +371,15 @@ void Sapphire::Entity::Player::updateSql() stmt->setInt( 16, static_cast< uint32_t >( m_bNewGame ) ); stmt->setInt( 17, static_cast< uint32_t >( m_bNewAdventurer ) ); - stmt->setInt( 18, m_zoneId ); // TerritoryType + stmt->setInt( 18, m_territoryTypeId ); // TerritoryType stmt->setInt( 19, m_territoryId ); // TerritoryId stmt->setDouble( 20, m_pos.x ); stmt->setDouble( 21, m_pos.y ); stmt->setDouble( 22, m_pos.z ); stmt->setDouble( 23, getRot() ); - stmt->setInt( 24, m_prevZoneId ); // OTerritoryType - stmt->setInt( 25, m_prevZoneType ); // OTerritoryId + stmt->setInt( 24, m_prevTerritoryTypeId ); // OTerritoryType + stmt->setInt( 25, m_prevTerritoryId ); // OTerritoryId stmt->setDouble( 26, m_prevPos.x ); stmt->setDouble( 27, m_prevPos.y ); stmt->setDouble( 28, m_prevPos.z ); diff --git a/src/servers/sapphire_zone/Territory/HousingZone.cpp b/src/servers/sapphire_zone/Territory/HousingZone.cpp index 57390006..b5304093 100644 --- a/src/servers/sapphire_zone/Territory/HousingZone.cpp +++ b/src/servers/sapphire_zone/Territory/HousingZone.cpp @@ -32,7 +32,7 @@ Sapphire::HousingZone::HousingZone( uint8_t wardNum, const std::string& contentName ) : Zone( territoryTypeId, guId, internalName, contentName ), m_wardNum( wardNum ), - m_zoneId( territoryTypeId ), + m_territoryTypeId( territoryTypeId ), m_landSetId( ( static_cast< uint32_t >( territoryTypeId ) << 16 ) | wardNum ) { @@ -49,13 +49,13 @@ bool Sapphire::HousingZone::init() } int housingIndex; - if( m_zoneId == 339 ) + if( m_territoryTypeId == 339 ) housingIndex = 0; - else if( m_zoneId == 340 ) + else if( m_territoryTypeId == 340 ) housingIndex = 1; - else if( m_zoneId == 341 ) + else if( m_territoryTypeId == 341 ) housingIndex = 2; - else if( m_zoneId == 641 ) + else if( m_territoryTypeId == 641 ) housingIndex = 3; auto pExdData = g_fw.get< Data::ExdDataGenerated >(); diff --git a/src/servers/sapphire_zone/Territory/HousingZone.h b/src/servers/sapphire_zone/Territory/HousingZone.h index 9f0ab003..985bbbba 100644 --- a/src/servers/sapphire_zone/Territory/HousingZone.h +++ b/src/servers/sapphire_zone/Territory/HousingZone.h @@ -56,7 +56,7 @@ namespace Sapphire LandPtrMap m_landPtrMap; uint8_t m_wardNum; uint32_t m_landSetId; - uint32_t m_zoneId; + uint32_t m_territoryTypeId; }; } diff --git a/src/servers/sapphire_zone/Territory/Zone.h b/src/servers/sapphire_zone/Territory/Zone.h index 13d27e40..717973a2 100644 --- a/src/servers/sapphire_zone/Territory/Zone.h +++ b/src/servers/sapphire_zone/Territory/Zone.h @@ -16,7 +16,7 @@ #include #include -namespace Sapphire +namespace Sapphire { class Session; From c13a0b14ed998d31696c5bb72601fb4821f7accc Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 16:42:46 +1100 Subject: [PATCH 04/13] cleanup and document storeroom status actrl --- src/common/Network/CommonActorControl.h | 23 +++++++++++++++---- .../Housing/HousingInteriorTerritory.cpp | 22 +++++++++--------- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index 208aeb97..e15c95c3 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -207,23 +207,38 @@ enum ActorControlType : uint16_t Dismount = 0x3A0, // Duty Recorder - BeginReplayAck = 0x3A1, + BeginReplayAck = 0x3A1, EndReplayAck = 0x3A2, // Housing - ShowHousingItemUI = 0x3F7, + ShowHousingItemUI = 0x3F7, ShowBuildPresetUI = 0x3E9, BuildPresetResponse = 0x3ED, + /*! + * param1 = outdoor furnishings + * u8 0 - relocation available, 1 = available + * u8 1 - outoor furnishings placed + * u8 2 - outdoor furnishings in storeroom + * u8 3 - outdoor funishings limit + * param2 = indoor furnishings + * u16 0 - relocation available, 1 = available + * u16 1 - furnishings placed + * param3 = indoor furnishings + * u16 0 - in storeroom + * u16 1 - indoor furnishings limit + */ + HousingStoreroomStatus = 0x419, + // PvP Duel - SetPvPState = 0x5E0, // param3 must be 6 to engage a duel (hardcoded in the client) + SetPvPState = 0x5E0, // param3 must be 6 to engage a duel (hardcoded in the client) EndDuelSession = 0x5E1, // because someone went oob? StartDuelCountdown = 0x5E2, // begins a countdown; also does some duel bgm thing. StartDuel = 0x5E3, // actually all it does is set the challenger actor id; DuelResultScreen = 0x5E4, // win/lose thing, also reset a target id just like what EndDuelSession does. // Duty Action - SetDutyActionId = 0x5E8, // ContentExAction + SetDutyActionId = 0x5E8, // ContentExAction SetDutyActionHud = 0x5E9, // disable/enable SetDutyActionActive = 0x5EA, SetDutyActionRemaining = 0x5EB, diff --git a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp index 758274ff..009c8d35 100644 --- a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp @@ -56,26 +56,26 @@ void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player ) "HousingInteriorTerritory::onPlayerZoneIn: Zone#" + std::to_string( getGuId() ) + "|" + std::to_string( getTerritoryTypeId() ) + ", Entity#" + std::to_string( player.getId() ) ); - auto housingIndoorInitializPacket = makeZonePacket< FFXIVIpcHousingIndoorInitialize >( player.getId() ); - housingIndoorInitializPacket->data().u1 = 2578; - housingIndoorInitializPacket->data().u2 = 10; - housingIndoorInitializPacket->data().u3 = 530; - housingIndoorInitializPacket->data().u4 = 266; + auto indoorInitPacket = makeZonePacket< FFXIVIpcHousingIndoorInitialize >( player.getId() ); + indoorInitPacket->data().u1 = 0; + indoorInitPacket->data().u2 = 0; + indoorInitPacket->data().u3 = 0; + indoorInitPacket->data().u4 = 0; auto landSetId = pHousingMgr->toLandSetId( m_landIdent.territoryTypeId, m_landIdent.wardNum ); auto pLand = pHousingMgr->getHousingZoneByLandSetId( landSetId )->getLand( m_landIdent.landId ); auto pHouse = pLand->getHouse(); + for( auto i = 0; i < 10; i++ ) + { + indoorInitPacket->data().indoorItems[ i ] = pHouse->getHouseInteriorPart( (Common::HousingInteriorSlot)i ); + } + uint32_t yardPacketNum; uint32_t yardPacketTotal = 2 + pLand->getSize(); - for( auto i = 0; i < 10; i++ ) - { - housingIndoorInitializPacket->data().indoorItems[ i ] = pHouse->getHouseInteriorPart( (Common::HousingInteriorSlot)i ); - } - - player.queuePacket( housingIndoorInitializPacket ); + player.queuePacket( indoorInitPacket ); for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) { From 76662f6e2c34cd188d0a624dc3c7493f2123a04f Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 17:27:59 +1100 Subject: [PATCH 05/13] minor cleanup and track house zone player activity --- .../common/eobj/HousingEstateEntrance.cpp | 1 + .../Housing/HousingInteriorTerritory.cpp | 23 +++++++++++-------- .../Housing/HousingInteriorTerritory.h | 3 +++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp index 7394ac86..b92ca7b9 100644 --- a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp @@ -35,6 +35,7 @@ public: ident.landId = eobj.getHousingLink() >> 8; ident.territoryTypeId = zone->getTerritoryTypeId(); ident.wardNum = zone->getWardNum(); + ident.worldId = 67; auto internalZone = terriMgr->findOrCreateHousingInterior( ident ); if( internalZone ) diff --git a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp index 009c8d35..373d725a 100644 --- a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.cpp @@ -35,7 +35,7 @@ Housing::HousingInteriorTerritory::HousingInteriorTerritory( Common::LandIdent i Zone( territoryTypeId, guId, internalName, contentName ), m_landIdent( ident ) { - + m_lastActivityTime = static_cast< uint32_t >( Util::getTimeSeconds() ); } Housing::HousingInteriorTerritory::~HousingInteriorTerritory() @@ -79,22 +79,27 @@ void Housing::HousingInteriorTerritory::onPlayerZoneIn( Entity::Player& player ) for( yardPacketNum = 0; yardPacketNum < yardPacketTotal; yardPacketNum++ ) { - auto housingObjectInitializPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); - memcpy( &housingObjectInitializPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) ); - housingObjectInitializPacket->data().landIdent.worldId = 67; - housingObjectInitializPacket->data().u1 = 0; - housingObjectInitializPacket->data().u2 = 100; - housingObjectInitializPacket->data().packetNum = yardPacketNum; - housingObjectInitializPacket->data().packetTotal = yardPacketTotal; + auto objectInitPacket = makeZonePacket< FFXIVIpcHousingObjectInitialize >( player.getId() ); + memcpy( &objectInitPacket->data().landIdent, &m_landIdent, sizeof( Common::LandIdent ) ); + objectInitPacket->data().u1 = 0; + objectInitPacket->data().u2 = 100; + objectInitPacket->data().packetNum = yardPacketNum; + objectInitPacket->data().packetTotal = yardPacketTotal; //TODO: Add Objects here - player.queuePacket( housingObjectInitializPacket ); + player.queuePacket( objectInitPacket ); } } void Housing::HousingInteriorTerritory::onUpdate( uint32_t currTime ) { + if( m_playerMap.size() > 0 ) + m_lastActivityTime = currTime; +} +uint32_t Housing::HousingInteriorTerritory::getLastActivityTime() const +{ + return m_lastActivityTime; } \ No newline at end of file diff --git a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h index 281d4bc4..e5be57a9 100644 --- a/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h +++ b/src/servers/sapphire_zone/Territory/Housing/HousingInteriorTerritory.h @@ -18,7 +18,10 @@ namespace Sapphire::World::Territory::Housing void onPlayerZoneIn( Entity::Player& player ) override; void onUpdate( uint32_t currTime ) override; + uint32_t getLastActivityTime() const; + private: Common::LandIdent m_landIdent; + uint32_t m_lastActivityTime; }; } \ No newline at end of file From e290febcc4f78757760e3a55bf67e1ec2d16bf2d Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 18:05:50 +1100 Subject: [PATCH 06/13] remove house instances that haven't had a player for 60 seconds --- .../sapphire_zone/Manager/TerritoryMgr.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp b/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp index 5b4de6b8..7859f7cf 100644 --- a/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp +++ b/src/servers/sapphire_zone/Manager/TerritoryMgr.cpp @@ -446,6 +446,29 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint32_t { zone->update( currentTime ); } + + auto pLog = g_fw.get< Logger >(); + + // remove internal house zones with nobody in them + for( auto it = m_landIdentToZonePtrMap.begin(); it != m_landIdentToZonePtrMap.end(); ) + { + auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( it->second ); + assert( zone ); // wtf?? + + auto diff = std::difftime( currentTime, zone->getLastActivityTime() ); + + // todo: make this timeout configurable, though should be pretty relaxed in any case + if( diff > 60 ) + { + pLog->info( "Removing HousingInteriorTerritory#" + std::to_string( zone->getGuId() ) + " - has been inactive for 60 seconds" ); + + // remove zone from maps + m_zoneSet.erase( zone ); + it = m_landIdentToZonePtrMap.erase( it ); + } + else + it++; + } } Sapphire::World::Manager::TerritoryMgr::InstanceIdList Sapphire::World::Manager::TerritoryMgr::getInstanceContentIdList( uint16_t instanceContentId ) const From 394d8e2b2862ef3d65a613a709f263132c936e52 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 18:50:06 +1100 Subject: [PATCH 07/13] only spawn/lookup house instance if player chooses to enter --- src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp index b92ca7b9..a576bc19 100644 --- a/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/servers/Scripts/common/eobj/HousingEstateEntrance.cpp @@ -23,6 +23,10 @@ public: player.playScene( eventId, 0, 0, [this, eobj]( Entity::Player& player, const Event::SceneResult& result ) { + // param2 == 1 when player wants to enter house + if( result.param2 != 1 ) + return; + auto terriMgr = getFramework()->get< Sapphire::World::Manager::TerritoryMgr >(); if( !terriMgr ) return; @@ -43,10 +47,6 @@ public: player.sendDebug( "created zone with guid: " + std::to_string( internalZone->getGuId() ) + "\nname: " + internalZone->getName() ); } - // param2 == 1 when player wants to enter house - if( result.param2 != 1 ) - return; - player.eventFinish( result.eventId, 1 ); player.setPos( { 0.f, 0.f, 0.f } ); From d49eab1c1cc07086f69d22a40e489a226d04fee3 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 19:44:38 +1100 Subject: [PATCH 08/13] fix housing furnishings menu not closing properly --- .../Network/Handlers/ClientTriggerHandler.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp index c1160246..277ac909 100644 --- a/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/ClientTriggerHandler.cpp @@ -411,7 +411,13 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( const Packets::FFX } case ClientTriggerType::RequestHousingItemUI: { - uint8_t ward = ( param12 & 0xFF00 ) >> 8; + // close ui + if( param11 == 1 ) + break; + + // param12 is 0 when inside a house + + uint8_t ward = ( param12 >> 16 ) & 0xFF; uint8_t plot = ( param12 & 0xFF ); auto pShowHousingItemUIPacket = makeActorControl142( player.getId(), ShowHousingItemUI, 0, plot ); From d66d1e8d55c61a2f7157b10ec8f262afaf5024b9 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 21:08:38 +1100 Subject: [PATCH 09/13] fix wrong placename when buying plot and some logmessage cleanup --- .../common/housing/CmnDefHousingSignboard.cpp | 18 +++++++----------- src/servers/sapphire_zone/Territory/Zone.cpp | 5 +++++ src/servers/sapphire_zone/Territory/Zone.h | 2 ++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp b/src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp index 650baee8..8b0ba8e8 100644 --- a/src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp +++ b/src/servers/Scripts/common/housing/CmnDefHousingSignboard.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "Framework.h" @@ -47,37 +48,32 @@ public: { 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 ); + + player.sendLogMessage( 0x0D16, pTerritory->getTerritoryTypeInfo()->placeName, activeLand.ward + 1, activeLand.plot + 1 ); break; } case LandPurchaseResult::ERR_NOT_ENOUGH_GIL: { - auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3314 ); - player.queuePacket( errorMsg ); + player.sendLogMessage( 3314 ); break; } case LandPurchaseResult::ERR_NOT_AVAILABLE: { - auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3312 ); - player.queuePacket( errorMsg ); + player.sendLogMessage( 3312 ); break; } case LandPurchaseResult::ERR_NO_MORE_LANDS_FOR_CHAR: { - auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 3313 ); - player.queuePacket( errorMsg ); + player.sendLogMessage( 3313 ); break; } case LandPurchaseResult::ERR_INTERNAL: { - auto errorMsg = makeActorControl143( player.getId(), ActorControl::LogMsg, 1995 ); - player.queuePacket( errorMsg ); + player.sendLogMessage( 1995 ); break; } } diff --git a/src/servers/sapphire_zone/Territory/Zone.cpp b/src/servers/sapphire_zone/Territory/Zone.cpp index 2c37892a..eedbe037 100644 --- a/src/servers/sapphire_zone/Territory/Zone.cpp +++ b/src/servers/sapphire_zone/Territory/Zone.cpp @@ -756,3 +756,8 @@ Sapphire::Entity::EventObjectPtr Sapphire::Zone::registerEObj( const std::string return eObj; } + +Sapphire::Data::TerritoryTypePtr Sapphire::Zone::getTerritoryTypeInfo() const +{ + return m_territoryTypeInfo; +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Territory/Zone.h b/src/servers/sapphire_zone/Territory/Zone.h index 717973a2..132b797d 100644 --- a/src/servers/sapphire_zone/Territory/Zone.h +++ b/src/servers/sapphire_zone/Territory/Zone.h @@ -76,6 +76,8 @@ namespace Sapphire void setCurrentFestival( uint16_t festivalId, uint16_t additionalFestivalId = 0 ); + std::shared_ptr< Data::TerritoryType > getTerritoryTypeInfo() const; + virtual bool init(); virtual void loadCellCache(); From b89a21120a8254609ad1309c5909a2e45dd82f41 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 23:26:21 +1100 Subject: [PATCH 10/13] some marketboard shit --- src/common/Network/PacketDef/Ipcs.h | 6 +++++- src/common/Network/PacketDef/Zone/ClientZoneDef.h | 7 +++++++ src/common/Network/PacketDef/Zone/ServerZoneDef.h | 15 +++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 3ed9e23c..9b4e072b 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -97,10 +97,12 @@ namespace Sapphire::Network::Packets ReqMoogleMailLetter = 0x011A, // updated 4.4 MailLetterNotification = 0x011B, // updated 4.4 - ExamineFreeCompanyInfo = 0x013A, // updated 4.1 + MarketBoardItemSummaryListResponse = 0x0125, // updated 4.4 + CharaFreeCompanyTag = 0x0127, // updated 4.4 FreeCompanyBoardMsg = 0x0128, // updated 4.4 FreeCompanyInfo = 0x0129, // updated 4.4 + ExamineFreeCompanyInfo = 0x013A, // updated 4.1 StatusEffectList = 0x0149, // updated 4.4 Effect = 0x014C, // updated 4.4 @@ -258,6 +260,8 @@ namespace Sapphire::Network::Packets LinkshellListHandler = 0x00F4, // updated 4.3 + MarketBoardRequestItemListings = 0x00FE, // updated 4.4 + SearchMarketboard = 0x0103, // updated 4.3 ReqExamineFcInfo = 0x010F, // updated 4.1 diff --git a/src/common/Network/PacketDef/Zone/ClientZoneDef.h b/src/common/Network/PacketDef/Zone/ClientZoneDef.h index 07fc7d88..b2b33033 100644 --- a/src/common/Network/PacketDef/Zone/ClientZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ClientZoneDef.h @@ -233,6 +233,13 @@ struct FFXIVIpcSetSharedEstateSettings : /* 0029 */ char padding3[0x7]; }; +struct FFXIVIpcMarketBoardRequestItemListings : + FFXIVIpcBasePacket< MarketBoardRequestItemListings > +{ + /* 0000 */ uint32_t itemCatalogId; + /* 0004 */ uint32_t padding; +}; + } } } diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 64bc9a03..cf60c0bc 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1830,6 +1830,21 @@ struct FFXIVIpcDuelChallenge : char otherName[32]; }; +struct FFXIVIpcMarketBoardItemSummaryListResponse : + FFXIVIpcBasePacket< MarketBoardItemSummaryListResponse > +{ + struct MarketBoardItemSummary + { + uint32_t itemId; + uint32_t quantity; + } items[20]; + + uint32_t itemIndexEnd; + uint32_t padding1; + uint32_t itemIndexStart; + uint32_t padding2; +}; + } /* Server */ } /* Packets */ From f61c6dd5e9e1d1de3d38ace7a3942c96ef061af3 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Sun, 2 Dec 2018 23:40:18 +1100 Subject: [PATCH 11/13] marketboard packets --- src/common/Network/PacketDef/Ipcs.h | 3 ++- .../Network/PacketDef/Zone/ServerZoneDef.h | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 9b4e072b..836a7668 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -97,7 +97,8 @@ namespace Sapphire::Network::Packets ReqMoogleMailLetter = 0x011A, // updated 4.4 MailLetterNotification = 0x011B, // updated 4.4 - MarketBoardItemSummaryListResponse = 0x0125, // updated 4.4 + MarketBoardItemListingCountResponse = 0x011C, // updated 4.4 + MarketBoardSearchResultResponse = 0x0125, // updated 4.4 CharaFreeCompanyTag = 0x0127, // updated 4.4 FreeCompanyBoardMsg = 0x0128, // updated 4.4 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index cf60c0bc..700b372c 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1830,12 +1830,12 @@ struct FFXIVIpcDuelChallenge : char otherName[32]; }; -struct FFXIVIpcMarketBoardItemSummaryListResponse : - FFXIVIpcBasePacket< MarketBoardItemSummaryListResponse > +struct FFXIVIpcMarketBoardSearchResultResponse : + FFXIVIpcBasePacket< MarketBoardSearchResultResponse > { - struct MarketBoardItemSummary + struct MarketBoardItem { - uint32_t itemId; + uint32_t itemCatalogId; uint32_t quantity; } items[20]; @@ -1845,6 +1845,16 @@ struct FFXIVIpcMarketBoardItemSummaryListResponse : uint32_t padding2; }; +struct FFFXIVIpcMarketBoardItemListingCountResponse : + FFXIVIpcBasePacket< MarketBoardItemListingCountResponse > +{ + uint32_t itemCatalogId; + uint32_t unknown1; // does some shit if nonzero + uint16_t unknown2; + uint16_t quantity; // high/low u8s read separately? + uint32_t padding3; +}; + } /* Server */ } /* Packets */ From f6f01a9ab86f0907737954d3a7264d454e1d9bbb Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 3 Dec 2018 00:11:26 +1100 Subject: [PATCH 12/13] market board item history packet --- src/common/Network/PacketDef/Ipcs.h | 7 +++-- .../Network/PacketDef/Zone/ServerZoneDef.h | 29 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 836a7668..72debdad 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -97,8 +97,10 @@ namespace Sapphire::Network::Packets ReqMoogleMailLetter = 0x011A, // updated 4.4 MailLetterNotification = 0x011B, // updated 4.4 - MarketBoardItemListingCountResponse = 0x011C, // updated 4.4 - MarketBoardSearchResultResponse = 0x0125, // updated 4.4 + MarketBoardItemListingCount = 0x011C, // updated 4.4 + MarketBoardItemListing = 0x011D, // updated 4.4 + MarketBoardItemListingHistory = 0x0121, // updated 4.4 + MarketBoardSearchResult = 0x0125, // updated 4.4 CharaFreeCompanyTag = 0x0127, // updated 4.4 FreeCompanyBoardMsg = 0x0128, // updated 4.4 @@ -262,6 +264,7 @@ namespace Sapphire::Network::Packets LinkshellListHandler = 0x00F4, // updated 4.3 MarketBoardRequestItemListings = 0x00FE, // updated 4.4 + MarketBoardRequestScopedItemListings = 0x00FF, // updated 4.4 SearchMarketboard = 0x0103, // updated 4.3 ReqExamineFcInfo = 0x010F, // updated 4.1 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 700b372c..2db26254 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -1830,8 +1830,8 @@ struct FFXIVIpcDuelChallenge : char otherName[32]; }; -struct FFXIVIpcMarketBoardSearchResultResponse : - FFXIVIpcBasePacket< MarketBoardSearchResultResponse > +struct FFXIVIpcMarketBoardSearchResult : + FFXIVIpcBasePacket< MarketBoardSearchResult > { struct MarketBoardItem { @@ -1845,8 +1845,8 @@ struct FFXIVIpcMarketBoardSearchResultResponse : uint32_t padding2; }; -struct FFFXIVIpcMarketBoardItemListingCountResponse : - FFXIVIpcBasePacket< MarketBoardItemListingCountResponse > +struct FFFXIVIpcMarketBoardItemListingCount : + FFXIVIpcBasePacket< MarketBoardItemListingCount > { uint32_t itemCatalogId; uint32_t unknown1; // does some shit if nonzero @@ -1855,6 +1855,27 @@ struct FFFXIVIpcMarketBoardItemListingCountResponse : uint32_t padding3; }; +struct FFXIVIpcMarketBoardItemListingHistory : + FFXIVIpcBasePacket< MarketBoardItemListingHistory > +{ + uint32_t itemCatalogId; + uint32_t itemCatalogId2; + + struct MarketListing + { + uint32_t salePrice; + time_t purchaseTime; + uint32_t quantity; + uint16_t unknown1; + uint8_t unknown2; + + char sellerName[32]; + + uint8_t unknown3; + uint32_t itemCatalogId; + } listing[20]; +}; + } /* Server */ } /* Packets */ From 96c38f09df501d3ecd89f7c8f4f97ec9148a1136 Mon Sep 17 00:00:00 2001 From: NotAdam Date: Mon, 3 Dec 2018 00:23:07 +1100 Subject: [PATCH 13/13] make the client marketboard ipc names clearer --- src/common/Network/PacketDef/Ipcs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 72debdad..51a4c4bf 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -263,8 +263,8 @@ namespace Sapphire::Network::Packets LinkshellListHandler = 0x00F4, // updated 4.3 - MarketBoardRequestItemListings = 0x00FE, // updated 4.4 - MarketBoardRequestScopedItemListings = 0x00FF, // updated 4.4 + MarketBoardRequestItemInformation = 0x00FE, // updated 4.4 + MarketBoardRequestItemListings = 0x00FF, // updated 4.4 SearchMarketboard = 0x0103, // updated 4.3 ReqExamineFcInfo = 0x010F, // updated 4.1