diff --git a/src/scripts/common/eobj/HousingEstateEntrance.cpp b/src/scripts/common/eobj/HousingEstateEntrance.cpp index 8f1b8298..0267323e 100644 --- a/src/scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/scripts/common/eobj/HousingEstateEntrance.cpp @@ -56,7 +56,7 @@ public: Common::FFXIVARR_POSITION3 pos; - auto land = zone->getLand( eobj.getHousingLink() >> 8 ); + auto land = zone->getLand( eobj.getHousingLink() ); if( !land ) return; diff --git a/src/scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp b/src/scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp index d35fdcd3..d0149236 100644 --- a/src/scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp +++ b/src/scripts/common/warptaxi/HousingWarpTaxiExitEstate.cpp @@ -1,6 +1,15 @@ #include #include +#include +#include +#include +#include + +#include "Territory/InstanceObjectCache.h" +#include "Territory/Territory.h" +#include "Territory/Housing/HousingInteriorTerritory.h" + using namespace Sapphire; class HousingWarpTaxiExitEstate : public Sapphire::ScriptAPI::EventScript @@ -17,8 +26,35 @@ public: { if( result.getResult( 0 ) == 1 ) { - eventMgr().eventFinish( player, result.eventId, 1 ); - player.exitInstance(); + auto& terriMgr = Common::Service< Sapphire::World::Manager::TerritoryMgr >::ref(); + auto pHZone = terriMgr.getTerritoryByGuId( player.getTerritoryId() ); + if( !pHZone ) + return; + auto zone = std::dynamic_pointer_cast< World::Territory::Housing::HousingInteriorTerritory >( pHZone ); + if( !zone ) + return; + + auto landIdent = zone->getLandIdent(); + + int housingIndex; + if( landIdent.territoryTypeId == 339 ) + housingIndex = 0; + else if( landIdent.territoryTypeId == 340 ) + housingIndex = 1; + else if( landIdent.territoryTypeId == 341 ) + housingIndex = 2; + + auto& exdData = Common::Service< Data::ExdData >::ref(); + auto info = exdData.getRow< Excel::HousingLandSet >( housingIndex ); + + auto landInfo = info->_data.Lands[ landIdent.landId ]; + auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref(); + auto exitRange = instanceObjectCache.getPopRange( landInfo.ExitPopRange ); + + Common::FFXIVARR_POSITION3 pos{ exitRange->data.transform.translation.x, exitRange->data.transform.translation.y, exitRange->data.transform.translation.z }; + float rot = Common::Util::eulerToDirection( { exitRange->data.transform.rotation.x, exitRange->data.transform.rotation.y, exitRange->data.transform.rotation.z } ); + + warpMgr().requestMoveTerritory( player, Common::WarpType::WARP_TYPE_NORMAL, landIdent.territoryTypeId << 16 | landIdent.wardNum, pos, rot ); } } ); } diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index f8e2d538..1fbcbb4e 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -1676,7 +1676,7 @@ void Player::setLandFlags( uint8_t flagSlot, uint32_t landFlags, Common::LandIde auto& server = Common::Service< World::WorldServer >::ref(); m_charaLandData[ flagSlot ].landId = ident; - m_charaLandData[ flagSlot ].landId.worldId = server.getWorldId(); + m_charaLandData[ flagSlot ].landId.worldId = static_cast< int16_t >( server.getWorldId() ); m_charaLandData[ flagSlot ].landFlags = landFlags; } diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index eff4b737..bbccff83 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -1759,7 +1759,8 @@ void HousingMgr::removeHouse( Entity::Player& player, uint16_t plot ) land->updateLandDb(); terri->sendLandUpdate( plot ); - player.setLandFlags( Common::LandFlagsSlot::Private, 0, land->getLandIdent() ); + player.setLandFlags( Common::LandFlagsSlot::Private, Common::HOUSING_LAND_STATUS::HOUSING_LAND_STATUS_NOINIT, land->getLandIdent() ); + sendLandFlagsSlot( player, Common::LandFlagsSlot::Private ); terri->removeEstateEntranceEObj( plot ); return; diff --git a/src/world/Manager/WarpMgr.cpp b/src/world/Manager/WarpMgr.cpp index 92defc4c..f8baf892 100644 --- a/src/world/Manager/WarpMgr.cpp +++ b/src/world/Manager/WarpMgr.cpp @@ -5,6 +5,7 @@ #include "TerritoryMgr.h" #include +#include #include "Task/MoveTerritoryTask.h" #include "Task/WarpTask.h" @@ -30,7 +31,10 @@ void WarpMgr::requestMoveTerritory( Entity::Player& player, Common::WarpType war auto pTeri = teriMgr.getTerritoryByGuId( targetTerritoryId ); if( !pTeri ) + { + Logger::error( "Unable to find target territory instance {}", targetTerritoryId ); return; + } m_entityIdToWarpInfoMap[ player.getId() ] = { targetTerritoryId, warpType, targetPos, targetRot }; diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.cpp b/src/world/Territory/Housing/HousingInteriorTerritory.cpp index 5f7477b3..9296f73b 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/world/Territory/Housing/HousingInteriorTerritory.cpp @@ -101,9 +101,10 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone } case HouseSize::HOUSE_SIZE_L: { - auto objectInitPacket = makeZonePacket< FFXIVIpcFurnitureListL >( player.getId() ); + auto objectInitPacket = makeZonePacket< FFXIVIpcFurnitureListL >( player.getId() ); memcpy( &objectInitPacket->data().LandId, &m_landIdent, sizeof( Common::LandIdent ) ); memcpy( &objectInitPacket->data().Furnitures, m_housingObjects.data(), sizeof( Common::Furniture ) * 200 ); + server.queueForPlayer( player.getCharacterId(), objectInitPacket ); break; } } diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index 3f60b6ff..3c5f72e0 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -19,9 +19,13 @@ #include "Inventory/ItemContainer.h" #include "WorldServer.h" +#include +#include + #include "Forwards.h" #include "HousingZone.h" #include "Manager/HousingMgr.h" +#include "InstanceObjectCache.h" using namespace Sapphire::Common; using namespace Sapphire::Network::Packets; @@ -34,7 +38,6 @@ Sapphire::HousingZone::HousingZone( uint8_t wardNum, uint16_t territoryTypeId, m_wardNum( wardNum ), m_landSetId( ( static_cast< uint32_t >( territoryTypeId ) << 16 ) | wardNum ) { - m_inRangeDistance = 3000; } bool Sapphire::HousingZone::init() @@ -57,8 +60,6 @@ bool Sapphire::HousingZone::init() housingIndex = 1; else if( m_territoryTypeId == 341 ) housingIndex = 2; - else if( m_territoryTypeId == 641 ) - housingIndex = 3; auto& exdData = Common::Service< Data::ExdData >::ref(); auto info = exdData.getRow< Excel::HousingLandSet >( housingIndex ); @@ -298,7 +299,34 @@ Sapphire::Entity::EventObjectPtr Sapphire::HousingZone::registerEstateEntranceEO auto land = getLand( landId ); assert( land ); - auto eObj = Entity::make_EventObject( getNextEObjId(), 2002737, 0, 0, 0, FFXIVARR_POSITION3{ 0, 10, 0 }, 0.f, "entrance", 0 ); + int housingIndex; + if( m_territoryTypeId == 339 ) + housingIndex = 0; + else if( m_territoryTypeId == 340 ) + housingIndex = 1; + else if( m_territoryTypeId == 341 ) + housingIndex = 2; + + auto& exdData = Common::Service< Data::ExdData >::ref(); + auto info = exdData.getRow< Excel::HousingLandSet >( housingIndex ); + + auto landInfo = info->_data.Lands[ landId ]; + auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref(); + + FFXIVARR_POSITION3 pos{ 0, 10, 0 }; + auto eObjInfo = instanceObjectCache.getEObj( landInfo.SignboardEObj ); + if( eObjInfo ) + { + pos.x = eObjInfo->data.transform.translation.x; + pos.y = eObjInfo->data.transform.translation.y; + pos.z = eObjInfo->data.transform.translation.z; + } + else + { + Logger::error( "No position could be determined for housing entrance!" ); + } + + auto eObj = Entity::make_EventObject( getNextEObjId(), 2002737, 0, 0, 0, pos, 0.f, "entrance", 0 ); eObj->setHousingLink( static_cast< uint32_t >( landId ) ); eObj->setScale( 1.f ); diff --git a/src/world/Territory/InstanceObjectCache.cpp b/src/world/Territory/InstanceObjectCache.cpp index a61f9da4..71d418bc 100644 --- a/src/world/Territory/InstanceObjectCache.cpp +++ b/src/world/Territory/InstanceObjectCache.cpp @@ -97,6 +97,7 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() } else if( pEntry->getType() == LgbEntryType::PopRange ) { + auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry ); m_popRangeCache.insert( id, pPopRange ); }