From a84d0f4154fce4651d9c51a733448c36257c9cde Mon Sep 17 00:00:00 2001 From: Mordred Date: Sat, 26 Feb 2022 19:45:19 +0900 Subject: [PATCH 01/11] Map previously unmapped eobj and enpc # Conflicts: # src/world/Manager/EventMgr.cpp --- deps/datReader/DatCategories/bg/lgb.h | 30 ++++++++-------- src/tools/nav_export/lgb.h | 2 +- src/tools/pcb_reader/lgb.h | 18 +++++----- src/world/Manager/EventMgr.cpp | 13 +++++++ src/world/Territory/InstanceObjectCache.cpp | 40 +++++++++++---------- src/world/Territory/InstanceObjectCache.h | 20 +++++------ 6 files changed, 69 insertions(+), 54 deletions(-) diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index 25bd5b6b..085325b7 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -34,10 +34,10 @@ public: memset( &header, 0, sizeof( header ) ); }; - LgbEntry( char* buf, uint32_t offset ) + LgbEntry( char* buf, size_t offset ) { m_buf = buf; - m_offset = offset; + m_offset = static_cast< uint32_t >( offset ); header = *reinterpret_cast< InstanceObject* >( buf + offset ); }; @@ -60,11 +60,9 @@ public: std::string modelFileName; std::string collisionFileName; - LGB_BGPARTS_ENTRY() - { - }; + LGB_BGPARTS_ENTRY() = default; - LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_BGPARTS_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< BgPartsData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -80,7 +78,7 @@ public: std::string name; std::string gimmickFileName; - LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_GIMMICK_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< GimmickData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -88,13 +86,13 @@ public: }; }; -class LGB_ENPC_ENTRY : public LgbEntry +struct LGB_ENPC_ENTRY : public LgbEntry { public: ENpcData data; std::string name; - LGB_ENPC_ENTRY( char* buf, uint32_t offset ) : + LGB_ENPC_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< ENpcData* >( buf + offset ); @@ -102,13 +100,13 @@ public: }; }; -class LGB_EOBJ_ENTRY : public LgbEntry +struct LGB_EOBJ_ENTRY : public LgbEntry { public: EObjData data; std::string name; - LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_EOBJ_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< EObjData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -121,7 +119,7 @@ public: MapRangeData data; std::string name; - LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_MAP_RANGE_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< MapRangeData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -134,7 +132,7 @@ public: ExitRangeData data; std::string name; - LGB_EXIT_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_EXIT_RANGE_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< ExitRangeData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -146,7 +144,7 @@ struct LGB_POP_RANGE_ENTRY : public LgbEntry public: PopRangeData data; - LGB_POP_RANGE_ENTRY( char* buf, uint32_t offset ) : LgbEntry( buf, offset ) + LGB_POP_RANGE_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) { data = *reinterpret_cast< PopRangeData* >( buf + offset ); }; @@ -176,7 +174,7 @@ struct LGB_GROUP std::string name; std::vector< std::shared_ptr< LgbEntry > > entries; - LGB_GROUP( char* buf, LGB_FILE* parentStruct, uint32_t offset ) + LGB_GROUP( char* buf, LGB_FILE* parentStruct, size_t offset ) { parent = parentStruct; header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset ); @@ -257,7 +255,7 @@ struct LGB_FILE throw std::runtime_error( "Invalid LGB file!" ); constexpr auto baseOffset = sizeof( header ); - for( auto i = 0; i < header.groupCount; ++i ) + for( size_t i = 0; i < header.groupCount; ++i ) { const auto groupOffset = baseOffset + *reinterpret_cast< int32_t* >( buf + ( baseOffset + i * 4 ) ); const auto group = LGB_GROUP( buf, this, groupOffset ); diff --git a/src/tools/nav_export/lgb.h b/src/tools/nav_export/lgb.h index 937f2f77..ab4df7f3 100644 --- a/src/tools/nav_export/lgb.h +++ b/src/tools/nav_export/lgb.h @@ -202,7 +202,7 @@ struct EObjData : uint8_t unknown1[0xC]; }; -class LGB_EOBJ_ENTRY : +struct LGB_EOBJ_ENTRY : public LgbEntry { public: diff --git a/src/tools/pcb_reader/lgb.h b/src/tools/pcb_reader/lgb.h index d87a2809..bd3be81c 100644 --- a/src/tools/pcb_reader/lgb.h +++ b/src/tools/pcb_reader/lgb.h @@ -137,7 +137,7 @@ public: }; LGB_BGPARTS_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -162,7 +162,7 @@ public: std::string gimmickFileName; LGB_GIMMICK_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -178,7 +178,7 @@ struct ENpcData : uint8_t unknown1[0x24]; }; -class LGB_ENPC_ENTRY : +struct LGB_ENPC_ENTRY : public LgbEntry { public: @@ -186,7 +186,7 @@ public: std::string name; LGB_ENPC_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast< ENpcData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -202,7 +202,7 @@ struct EObjData : uint8_t unknown1[0xC]; }; -class LGB_EOBJ_ENTRY : +struct LGB_EOBJ_ENTRY : public LgbEntry { public: @@ -210,7 +210,7 @@ public: std::string name; LGB_EOBJ_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast< EObjData* >( buf + offset ); //std::cout << "\t " << header.eobjId << " " << name << " unknown: " << header.unknown << "\n"; @@ -234,7 +234,7 @@ public: std::string name; LGB_MAP_RANGE_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast< MapRangeData* >( buf + offset ); name = std::string( buf + offset + header.nameOffset ); @@ -254,7 +254,7 @@ struct LGB_COLLISION_BOX_ENTRY : std::string name; LGB_COLLISION_BOX_ENTRY( char* buf, uint32_t offset ) : - LgbEntry( buf, offset ) + LgbEntry( buf, offset ) { header = *reinterpret_cast< LGB_COLLISION_BOX_HEADER* >( buf + offset ); header.type = LgbEntryType::CollisionBox; @@ -366,7 +366,7 @@ struct LGB_FILE { LGB_FILE_HEADER header; std::vector< LGB_GROUP > groups; - + LGB_FILE( char* buf ) { header = *reinterpret_cast< LGB_FILE_HEADER* >( buf ); diff --git a/src/world/Manager/EventMgr.cpp b/src/world/Manager/EventMgr.cpp index bc417c11..cd242f3a 100644 --- a/src/world/Manager/EventMgr.cpp +++ b/src/world/Manager/EventMgr.cpp @@ -3,9 +3,17 @@ #include #include +#include +#include +#include + #include "EventMgr.h" #include "Event/EventHandler.h" +#include "Territory/InstanceObjectCache.h" + +#include "Actor/Player.h" + using namespace Sapphire::Common; std::string Sapphire::World::Manager::EventMgr::getEventName( uint32_t eventId ) @@ -113,10 +121,15 @@ std::string Sapphire::World::Manager::EventMgr::getEventName( uint32_t eventId ) uint32_t Sapphire::World::Manager::EventMgr::mapEventActorToRealActor( uint32_t eventActorId ) { + auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref(); auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); auto levelInfo = exdData.get< Sapphire::Data::Level >( eventActorId ); if( levelInfo ) return levelInfo->object; + else if( auto pObj = instanceObjectCache.getEObj( eventActorId ) ) + return pObj->data.eobjId; + else if( auto pNpc = instanceObjectCache.getENpc( eventActorId ) ) + return pNpc->data.enpcId; return 0; } diff --git a/src/world/Territory/InstanceObjectCache.cpp b/src/world/Territory/InstanceObjectCache.cpp index d117df96..66539258 100644 --- a/src/world/Territory/InstanceObjectCache.cpp +++ b/src/world/Territory/InstanceObjectCache.cpp @@ -115,15 +115,19 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry ); m_popRangeCache.insert( id, pPopRange ); } - else if( pEntry->getType() == LgbEntryType::EventNpc ) + else if( pEntry->getType() == LgbEntryType::SharedGroup6 ) { - auto pEventNpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); - m_eventNpcCache.insert( id, pEventNpc ); + } else if( pEntry->getType() == LgbEntryType::EventObject ) { - auto pEventObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry ); - m_eventObjCache.insert( id, pEventObj ); + auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry ); + m_eobjCache.insert( 0, pEObj ); + } + else if( pEntry->getType() == LgbEntryType::EventNpc ) + { + auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); + m_enpcCache.insert( 0, pENpc ); } } } @@ -132,50 +136,50 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() std::cout << "\n"; Logger::debug( - "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} ENpc: {} Eobj: {}", - m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size(), m_eventNpcCache.size(), m_eventObjCache.size() + "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {}", + m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size() ); } Sapphire::InstanceObjectCache::MapRangePtr - Sapphire::InstanceObjectCache::getMapRange( uint16_t zoneId, uint32_t mapRangeId ) +Sapphire::InstanceObjectCache::getMapRange( uint16_t zoneId, uint32_t mapRangeId ) { return m_mapRangeCache.get( zoneId, mapRangeId ); } Sapphire::InstanceObjectCache::ExitRangePtr - Sapphire::InstanceObjectCache::getExitRange( uint16_t zoneId, uint32_t exitRangeId ) +Sapphire::InstanceObjectCache::getExitRange( uint16_t zoneId, uint32_t exitRangeId ) { return m_exitRangeCache.get( zoneId, exitRangeId ); } Sapphire::InstanceObjectCache::PopRangePtr - Sapphire::InstanceObjectCache::getPopRange( uint16_t zoneId, uint32_t popRangeId ) +Sapphire::InstanceObjectCache::getPopRange( uint16_t zoneId, uint32_t popRangeId ) { return m_popRangeCache.get( zoneId, popRangeId ); } -Sapphire::InstanceObjectCache::EventNpcPtr - Sapphire::InstanceObjectCache::getEventNpc( uint16_t zoneId, uint32_t eventNpcId ) +Sapphire::InstanceObjectCache::EObjPtr +Sapphire::InstanceObjectCache::getEObj( uint32_t eObjId ) { - return m_eventNpcCache.get( zoneId, eventNpcId ); + return m_eobjCache.get( 0, eObjId ); } -Sapphire::InstanceObjectCache::EventObjPtr - Sapphire::InstanceObjectCache::getEventObj( uint16_t zoneId, uint32_t eventObjId ) +Sapphire::InstanceObjectCache::ENpcPtr +Sapphire::InstanceObjectCache::getENpc( uint32_t eNpcId ) { - return m_eventObjCache.get( zoneId, eventObjId ); + return m_enpcCache.get( 0, eNpcId ); } Sapphire::InstanceObjectCache::EventNpcMapPtr Sapphire::InstanceObjectCache::getAllEventNpc( uint16_t zoneId ) { - return m_eventNpcCache.getAll( zoneId ); + return m_enpcCache.getAll( zoneId ); } Sapphire::InstanceObjectCache::EventObjMapPtr Sapphire::InstanceObjectCache::getAllEventObj( uint16_t zoneId ) { - return m_eventObjCache.getAll( zoneId ); + return m_eobjCache.getAll( zoneId ); } \ No newline at end of file diff --git a/src/world/Territory/InstanceObjectCache.h b/src/world/Territory/InstanceObjectCache.h index 7f8bd17c..7df41b79 100644 --- a/src/world/Territory/InstanceObjectCache.h +++ b/src/world/Territory/InstanceObjectCache.h @@ -7,8 +7,8 @@ struct LGB_MAP_RANGE_ENTRY; struct LGB_EXIT_RANGE_ENTRY; struct LGB_POP_RANGE_ENTRY; -struct LGB_ENPC_ENTRY; struct LGB_EOBJ_ENTRY; +struct LGB_ENPC_ENTRY; namespace Sapphire @@ -65,7 +65,7 @@ namespace Sapphire } } - uint32_t size() const + size_t size() const { return m_objectCache.size(); } @@ -77,11 +77,11 @@ namespace Sapphire using MapRangePtr = std::shared_ptr< LGB_MAP_RANGE_ENTRY >; using ExitRangePtr = std::shared_ptr< LGB_EXIT_RANGE_ENTRY >; using PopRangePtr = std::shared_ptr< LGB_POP_RANGE_ENTRY >; - using EventNpcPtr = std::shared_ptr< LGB_ENPC_ENTRY >; - using EventObjPtr = std::shared_ptr< LGB_EOBJ_ENTRY >; + using EObjPtr = std::shared_ptr< LGB_EOBJ_ENTRY >; + using ENpcPtr = std::shared_ptr< LGB_ENPC_ENTRY >; - using EventNpcMapPtr = std::unordered_map< uint32_t, EventNpcPtr >*; - using EventObjMapPtr = std::unordered_map< uint32_t, EventObjPtr >*; + using EventNpcMapPtr = std::unordered_map< uint32_t, ENpcPtr >*; + using EventObjMapPtr = std::unordered_map< uint32_t, EObjPtr >*; InstanceObjectCache(); ~InstanceObjectCache() = default; @@ -89,8 +89,8 @@ namespace Sapphire MapRangePtr getMapRange( uint16_t zoneId, uint32_t mapRangeId ); ExitRangePtr getExitRange( uint16_t zoneId, uint32_t exitRangeId ); PopRangePtr getPopRange( uint16_t zoneId, uint32_t popRangeId ); - EventNpcPtr getEventNpc( uint16_t zoneId, uint32_t eventNpcId ); - EventObjPtr getEventObj( uint16_t zoneId, uint32_t eventObjId ); + EObjPtr getEObj( uint32_t eObjId ); + ENpcPtr getENpc( uint32_t eNpcId ); EventNpcMapPtr getAllEventNpc( uint16_t zoneId ); EventObjMapPtr getAllEventObj( uint16_t zoneId ); @@ -99,8 +99,8 @@ namespace Sapphire ObjectCache< LGB_MAP_RANGE_ENTRY > m_mapRangeCache; ObjectCache< LGB_EXIT_RANGE_ENTRY > m_exitRangeCache; ObjectCache< LGB_POP_RANGE_ENTRY > m_popRangeCache; - ObjectCache< LGB_ENPC_ENTRY > m_eventNpcCache; - ObjectCache< LGB_EOBJ_ENTRY > m_eventObjCache; + ObjectCache< LGB_EOBJ_ENTRY > m_eobjCache; + ObjectCache< LGB_ENPC_ENTRY > m_enpcCache; std::shared_ptr< Framework > m_pFramework; }; From a56eec5d328bfde29193f34e9e282a2a597ffd25 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 30 Jan 2022 22:32:03 +0100 Subject: [PATCH 02/11] Fallback to entranceRect if no entrance circle is found in instance --- deps/datReader/DatCategories/bg/LgbTypes.h | 7 ++- deps/datReader/DatCategories/bg/lgb.h | 11 ++++ src/world/Territory/InstanceContent.cpp | 20 ++++++- src/world/Territory/InstanceContent.h | 59 +++++++++++++++++++++ src/world/Territory/InstanceObjectCache.cpp | 15 +++++- src/world/Territory/InstanceObjectCache.h | 10 +++- 6 files changed, 117 insertions(+), 5 deletions(-) diff --git a/deps/datReader/DatCategories/bg/LgbTypes.h b/deps/datReader/DatCategories/bg/LgbTypes.h index 8b9d5ad5..31cbe8b4 100644 --- a/deps/datReader/DatCategories/bg/LgbTypes.h +++ b/deps/datReader/DatCategories/bg/LgbTypes.h @@ -137,7 +137,7 @@ struct EObjData : public InstanceObject uint8_t unknown1[0xC]; }; -enum TriggerBoxShape : uint32_t +enum TriggerBoxShape : int32_t { TriggerBoxShapeBox = 0x1, TriggerBoxShapeSphere = 0x2, @@ -156,6 +156,11 @@ struct TriggerBoxInstanceObject uint32_t reserved; }; +struct EventRangeData : public InstanceObject +{ + TriggerBoxInstanceObject triggerBox; +}; + struct ExitRangeData : public InstanceObject { TriggerBoxInstanceObject triggerBoxType; diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index 085325b7..93688c8e 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -150,6 +150,17 @@ public: }; }; +struct LGB_EVENT_RANGE_ENTRY : public LgbEntry +{ +public: + EventRangeData data; + + LGB_EVENT_RANGE_ENTRY( char* buf, size_t offset ) : LgbEntry( buf, offset ) + { + data = *reinterpret_cast< EventRangeData* >( buf + offset ); + }; +}; + struct LGB_GROUP_HEADER { uint32_t id; diff --git a/src/world/Territory/InstanceContent.cpp b/src/world/Territory/InstanceContent.cpp index bd50e9bf..207a8302 100644 --- a/src/world/Territory/InstanceContent.cpp +++ b/src/world/Territory/InstanceContent.cpp @@ -6,10 +6,15 @@ #include #include #include - +#include +#include +#include #include "Event/Director.h" #include "Event/EventDefs.h" #include "Script/ScriptMgr.h" +#include "Manager/PlayerMgr.h" +#include "Manager/TerritoryMgr.h" +#include "Manager/EventMgr.h" #include "Actor/Player.h" #include "Actor/EventObject.h" @@ -21,6 +26,8 @@ #include "Event/EventHandler.h" #include "InstanceContent.h" +#include "InstanceObjectCache.h" + using namespace Sapphire::Common; using namespace Sapphire::Network::Packets; @@ -339,11 +346,22 @@ void Sapphire::InstanceContent::onBeforePlayerZoneIn( Sapphire::Entity::Player& // if a player has already spawned once inside this instance, don't move them if they happen to zone in again if( !hasPlayerPreviouslySpawned( player ) ) { + auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); + auto& instanceObjectCache = Common::Service< InstanceObjectCache >::ref(); + auto contentInfo = exdData.get< Data::InstanceContent >( m_instanceContentId ); + + auto rect = instanceObjectCache.getEventRange( contentInfo->lGBEventRange ); + if( m_pEntranceEObj != nullptr ) { player.setRot( PI ); player.setPos( m_pEntranceEObj->getPos() ); } + else if( rect ) + { + player.setRot( PI ); + player.setPos( { rect->header.transform.translation.x, rect->header.transform.translation.y, rect->header.transform.translation.z } ); + } else { player.setRot( PI ); diff --git a/src/world/Territory/InstanceContent.h b/src/world/Territory/InstanceContent.h index cc8600a4..f7a38196 100644 --- a/src/world/Territory/InstanceContent.h +++ b/src/world/Territory/InstanceContent.h @@ -23,6 +23,65 @@ namespace Sapphire DutyFinished }; + /*0x40000001 - INSTANCE_CONTENT_ORDER_SYSTEM_START + 0x40000002 - INSTANCE_CONTENT_ORDER_SYSTEM_CLEAR_NORMAL + 0x40000003 - INSTANCE_CONTENT_ORDER_SYSTEM_RESET_???? ( not really sure about that, seems like reset, arg1 must be 1 ) + 0x40000004 - INSTANCE_CONTENT_ORDER_PVP_READY ( unsure ) + 0x40000005 - INSTANCE_CONTENT_ORDER_SYSTEM_RESET + 0x40000006 - INSTANCE_CONTENT_ORDER_SYSTEM_RESTART + 0x40000007 - INSTANCE_CONTENT_ORDER_SYSTEM_VOTE_ENABLE + 0x40000008 - INSTANCE_CONTENT_ORDER_SYSTEM_VOTE_START + 0x40000009 - INSTANCE_CONTENT_ORDER_SYSTEM_VOTE_RESULT + 0x4000000A - INSTANCE_CONTENT_ORDER_SYSTEM_VOTE_CANCEL + 0x4000000B - INSTANCE_CONTENT_ORDER_SYSTEM_UPDATE_CLEAR_MEMBER + 0x4000000C - INSTANCE_CONTENT_ORDER_SYSTEM_PLAY_SHARED_GROUP + 0x4000000D - INSTANCE_CONTENT_ORDER_SYSTEM_SyncTime? + 0x4000000E - INSTANCE_CONTENT_ORDER_SYSTEM_Unknown - no args - some timer set */ + enum DirectorEventId : uint32_t + { + DEBUG_TimeSync = 0xC0000001, + DutyCommence = 0x40000001, + BattleGroundMusic = 0x40000002, + SetStringendoMode = 0x40000003, + DutyComplete = 0x40000004, + InvalidateTodoList = 0x40000005, + LoadingScreen = 0x40000007, + Forward = 0x40000008, + VoteState = 0x40000009, + VoteStart = 0x4000000A, + VoteResult = 0x4000000B, + VoteFinish = 0x4000000C, + TreasureVoteRefresh = 0x4000000D, + SetSharedGroupId = 0x4000000E, + FirstTimeNotify = 0x4000000F + }; + + enum EventHandlerOrderId : uint32_t + { + SheetDataReady = 0x80000000, + AbortContent = 0x40000001, //forceFlag + LuaOnStartCutscene = 0x40000002, //returnCode + VoteRequest = 0x40000003, //voteType + VoteReplay = 0x40000004 //voteType, accept + }; + + enum DirectorSceneId + { + None = 0, + SetupEventArgsOnStart = 1, + SetupEventArgsInProgress = 2, + + DutyFailed = 5 + }; + + enum TerminateReason : uint8_t + { + TimeExpired, + TimeLimitReached, + Abandoned, + Ended + }; + InstanceContent( std::shared_ptr< Sapphire::Data::InstanceContent > pInstanceConfiguration, uint16_t territoryType, uint32_t guId, diff --git a/src/world/Territory/InstanceObjectCache.cpp b/src/world/Territory/InstanceObjectCache.cpp index 66539258..84fad5f6 100644 --- a/src/world/Territory/InstanceObjectCache.cpp +++ b/src/world/Territory/InstanceObjectCache.cpp @@ -100,6 +100,7 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() { for( const auto& pEntry : group.entries ) { + if( pEntry->getType() == LgbEntryType::MapRange ) { auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry ); @@ -129,6 +130,11 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); m_enpcCache.insert( 0, pENpc ); } + else if( pEntry->getType() == LgbEntryType::EventRange ) + { + auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry ); + m_eventRangeCache.insert( 0, pEventRange ); + } } } } @@ -136,8 +142,8 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() std::cout << "\n"; Logger::debug( - "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {}", - m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size() + "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventNpc: {} EventRange: {}", + m_mapRangeCache.size(), m_exitRangeCache.size(), m_popRangeCache.size(), m_enpcCache.size(), m_eventRangeCache.size() ); } @@ -172,6 +178,11 @@ Sapphire::InstanceObjectCache::getENpc( uint32_t eNpcId ) return m_enpcCache.get( 0, eNpcId ); } +Sapphire::InstanceObjectCache::EventRangePtr Sapphire::InstanceObjectCache::getEventRange( uint32_t eventRangeId ) +{ + return m_eventRangeCache.get( 0, eventRangeId ); +} + Sapphire::InstanceObjectCache::EventNpcMapPtr Sapphire::InstanceObjectCache::getAllEventNpc( uint16_t zoneId ) { diff --git a/src/world/Territory/InstanceObjectCache.h b/src/world/Territory/InstanceObjectCache.h index 7df41b79..0dd23bf7 100644 --- a/src/world/Territory/InstanceObjectCache.h +++ b/src/world/Territory/InstanceObjectCache.h @@ -9,6 +9,7 @@ struct LGB_EXIT_RANGE_ENTRY; struct LGB_POP_RANGE_ENTRY; struct LGB_EOBJ_ENTRY; struct LGB_ENPC_ENTRY; +struct LGB_EVENT_RANGE_ENTRY; namespace Sapphire @@ -67,7 +68,11 @@ namespace Sapphire size_t size() const { - return m_objectCache.size(); + size_t size = 0; + for( auto& it = m_objectCache.begin(); it != m_objectCache.end(); ++it ) + size += it->second.size(); + + return size; } }; @@ -79,6 +84,7 @@ namespace Sapphire using PopRangePtr = std::shared_ptr< LGB_POP_RANGE_ENTRY >; using EObjPtr = std::shared_ptr< LGB_EOBJ_ENTRY >; using ENpcPtr = std::shared_ptr< LGB_ENPC_ENTRY >; + using EventRangePtr = std::shared_ptr< LGB_EVENT_RANGE_ENTRY >; using EventNpcMapPtr = std::unordered_map< uint32_t, ENpcPtr >*; using EventObjMapPtr = std::unordered_map< uint32_t, EObjPtr >*; @@ -91,6 +97,7 @@ namespace Sapphire PopRangePtr getPopRange( uint16_t zoneId, uint32_t popRangeId ); EObjPtr getEObj( uint32_t eObjId ); ENpcPtr getENpc( uint32_t eNpcId ); + EventRangePtr getEventRange( uint32_t eventRangeId ); EventNpcMapPtr getAllEventNpc( uint16_t zoneId ); EventObjMapPtr getAllEventObj( uint16_t zoneId ); @@ -101,6 +108,7 @@ namespace Sapphire ObjectCache< LGB_POP_RANGE_ENTRY > m_popRangeCache; ObjectCache< LGB_EOBJ_ENTRY > m_eobjCache; ObjectCache< LGB_ENPC_ENTRY > m_enpcCache; + ObjectCache< LGB_EVENT_RANGE_ENTRY > m_eventRangeCache; std::shared_ptr< Framework > m_pFramework; }; From ba1b8aadfb597ec8af5fafa919a977009f787f7c Mon Sep 17 00:00:00 2001 From: Mordred Date: Fri, 11 Feb 2022 10:32:13 +0100 Subject: [PATCH 03/11] Added layerset parsing --- deps/datReader/DatCategories/bg/lgb.h | 55 ++++++++++++++++--- .../Network/PacketDef/Zone/ServerZoneDef.h | 6 +- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index 93688c8e..2a10251a 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -161,35 +161,72 @@ public: }; }; +enum LayerSetReferencedType +{ + All = 0x0, + Include = 0x1, + Exclude = 0x2, + Undetermined = 0x3, +}; + +struct LayerSetReferenced +{ + uint32_t LayerSetID; +}; + +struct LayerSetReferencedList +{ + LayerSetReferencedType ReferencedType; + int LayerSets; + int LayerSetCount; +}; + struct LGB_GROUP_HEADER { uint32_t id; int32_t groupNameOffset; int32_t entriesOffset; int32_t entryCount; - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; - uint32_t unknown10; + int8_t ToolModeVisible; + int8_t ToolModeReadOnly; + int8_t IsBushLayer; + int8_t PS3Visible; + int32_t LayerSetRef; + uint16_t FestivalID; + uint16_t FestivalPhaseID; + int8_t IsTemporary; + int8_t IsHousing; + uint16_t VersionMask; + uint32_t Reserved; + int32_t OBSetReferencedList; + int32_t OBSetReferencedList_Count; + int32_t OBSetEnableReferencedList; + int32_t OBSetEnableReferencedList_Count; }; struct LGB_GROUP { LGB_FILE* parent; LGB_GROUP_HEADER header; + LayerSetReferencedList layerSetReferencedList; std::string name; std::vector< std::shared_ptr< LgbEntry > > entries; + std::vector< LayerSetReferenced > refs; LGB_GROUP( char* buf, LGB_FILE* parentStruct, size_t offset ) { parent = parentStruct; header = *reinterpret_cast< LGB_GROUP_HEADER* >( buf + offset ); name = std::string( buf + offset + header.groupNameOffset ); + + layerSetReferencedList = *reinterpret_cast< LayerSetReferencedList* >( buf + offset + header.LayerSetRef ); + + if( layerSetReferencedList.LayerSetCount > 0 ) + { + refs.resize( layerSetReferencedList.LayerSetCount ); + memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) ); + } + const auto entriesOffset = offset + header.entriesOffset; for( auto i = 0; i < header.entryCount; ++i ) { diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 87ab1c3d..74b980a1 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -907,10 +907,10 @@ namespace Sapphire::Network::Packets::Server { uint16_t serverId; uint16_t zoneId; - uint16_t unknown1; + uint16_t zoneIndex; uint16_t contentfinderConditionId; - uint32_t unknown3; - uint32_t unknown4; + uint32_t layerSetId; + uint32_t layoutId; uint8_t weatherId; uint8_t bitmask; uint8_t bitmask1; From a9a628fe474341ce873903e9175ddbbad9e560a4 Mon Sep 17 00:00:00 2001 From: Mordred Date: Fri, 18 Feb 2022 00:03:04 +0100 Subject: [PATCH 04/11] Updated EventHandlerTypes --- src/world/Event/EventHandler.h | 8 +++++--- src/world/Manager/EventMgr.cpp | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/world/Event/EventHandler.h b/src/world/Event/EventHandler.h index 0990ec87..1a337d2d 100644 --- a/src/world/Event/EventHandler.h +++ b/src/world/Event/EventHandler.h @@ -54,7 +54,7 @@ namespace Sapphire::Event Aetheryte = 0x0005, GuildLeveAssignment = 0x0006, DefaultTalk = 0x0009, - Craft = 0x000A, + Crafting = 0x000A, CustomTalk = 0x000B, CompanyLeveOfficer = 0x000C, Array = 0x000D, @@ -65,7 +65,7 @@ namespace Sapphire::Event ChocoboTaxiStand = 0x0012, Opening = 0x0013, ExitRange = 0x0014, - Fishing = 0x0015, + Fish = 0x0015, GCShop = 0x0016, GuildOrderGuide = 0x0017, GuildOrderOfficer = 0x0018, @@ -75,7 +75,9 @@ namespace Sapphire::Event BahamutGuide = 0x001C, InstanceContentGuide = 0x001D, HousingAethernet = 0x001E, - FcTalk = 0x001F, + SwitchTalk = 0x001F, + Adventure = 0x0020, + DailyQuestSupply = 0x0021, Adventure = 0x0021, DailyQuestSupply = 0x0022, TripleTriad = 0x0023, diff --git a/src/world/Manager/EventMgr.cpp b/src/world/Manager/EventMgr.cpp index cd242f3a..60f3a3e4 100644 --- a/src/world/Manager/EventMgr.cpp +++ b/src/world/Manager/EventMgr.cpp @@ -112,6 +112,11 @@ std::string Sapphire::World::Manager::EventMgr::getEventName( uint32_t eventId ) }*/ //return unknown + "GilShop"; } + + case Event::EventHandler::EventHandlerType::SwitchTalk: + { + return "FcTalk"; + } default: { return unknown; From ec7195639e1f2c2f8551908c5af276957b4815a1 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 22 Feb 2022 23:47:11 +0100 Subject: [PATCH 05/11] Removed unused cell logic --- src/world/Territory/Cell.cpp | 33 ++---------------------------- src/world/Territory/Cell.h | 34 +------------------------------ src/world/Territory/Territory.cpp | 13 +++--------- 3 files changed, 6 insertions(+), 74 deletions(-) diff --git a/src/world/Territory/Cell.cpp b/src/world/Territory/Cell.cpp index bbcfdd79..7f0e39cb 100644 --- a/src/world/Territory/Cell.cpp +++ b/src/world/Territory/Cell.cpp @@ -10,9 +10,7 @@ Sapphire::Cell::Cell() : m_bActive( false ), - m_bLoaded( false ), - m_playerCount( 0 ), - m_bUnloadPending( false ) + m_playerCount( 0 ) { m_bForcedActive = false; } @@ -22,9 +20,8 @@ Sapphire::Cell::~Cell() removeActors(); } -void Sapphire::Cell::init( uint32_t x, uint32_t y, TerritoryPtr pZone ) +void Sapphire::Cell::init( uint32_t x, uint32_t y ) { - m_pZone = pZone; m_posX = static_cast< uint16_t >( x ); m_posY = static_cast< uint16_t >( y ); @@ -57,9 +54,6 @@ void Sapphire::Cell::setActivity( bool state ) //} - if( m_bUnloadPending ) - cancelPendingUnload(); - } else if( m_bActive && !state ) { @@ -94,40 +88,17 @@ void Sapphire::Cell::removeActors() continue; } - if( m_bUnloadPending ) - { - - } - } m_playerCount = 0; - m_bLoaded = false; -} - -void Sapphire::Cell::queueUnloadPending() -{ - if( m_bUnloadPending ) - return; - - m_bUnloadPending = true; - -} - -void Sapphire::Cell::cancelPendingUnload() -{ - if( !m_bUnloadPending ) - return; } void Sapphire::Cell::unload() { - assert( m_bUnloadPending ); if( m_bActive ) return; removeActors(); - m_bUnloadPending = false; } diff --git a/src/world/Territory/Cell.h b/src/world/Territory/Cell.h index 23351b34..4a7dbbd6 100644 --- a/src/world/Territory/Cell.h +++ b/src/world/Territory/Cell.h @@ -21,18 +21,15 @@ private: uint16_t m_posY; ActorSet m_actors; bool m_bActive; - bool m_bLoaded; - bool m_bUnloadPending; uint16_t m_playerCount; - TerritoryPtr m_pZone; public: Cell(); ~Cell(); - void init( uint32_t x, uint32_t y, TerritoryPtr pZone ); + void init( uint32_t x, uint32_t y ); void addActor( Entity::ActorPtr pAct ); @@ -72,37 +69,8 @@ public: return m_bActive; } - bool isLoaded() const - { - return m_bLoaded; - } - - uint32_t getPlayerCount() const - { - return m_playerCount; - } - - bool isUnloadPending() const - { - return m_bUnloadPending; - } - - void setUnloadPending( bool up ) - { - m_bUnloadPending = up; - } - - void queueUnloadPending(); - - void cancelPendingUnload(); - void unload(); - void setPermanentActivity( bool val ) - { - m_bForcedActive = val; - } - bool isForcedActive() const { return m_bForcedActive; diff --git a/src/world/Territory/Territory.cpp b/src/world/Territory/Territory.cpp index d3d78dcb..c7fdb724 100644 --- a/src/world/Territory/Territory.cpp +++ b/src/world/Territory/Territory.cpp @@ -214,7 +214,7 @@ void Sapphire::Territory::pushActor( Entity::ActorPtr pActor ) if( !pCell ) { pCell = create( cx, cy ); - pCell->init( cx, cy, shared_from_this() ); + pCell->init( cx, cy ); } pCell->addActor( pActor ); @@ -576,12 +576,10 @@ void Sapphire::Territory::updateCellActivity( uint32_t x, uint32_t y, int32_t ra if( isCellActive( posX, posY ) ) { pCell = create( posX, posY ); - pCell->init( posX, posY, shared_from_this() ); + pCell->init( posX, posY ); pCell->setActivity( true ); - assert( !pCell->isLoaded() ); - } } else @@ -590,11 +588,6 @@ void Sapphire::Territory::updateCellActivity( uint32_t x, uint32_t y, int32_t ra if( isCellActive( posX, posY ) && !pCell->isActive() ) { pCell->setActivity( true ); - - if( !pCell->isLoaded() ) - { - - } } else if( !isCellActive( posX, posY ) && pCell->isActive() ) pCell->setActivity( false ); @@ -623,7 +616,7 @@ void Sapphire::Territory::updateActorPosition( Entity::Actor& actor ) if( !pCell ) { pCell = create( cellX, cellY ); - pCell->init( cellX, cellY, shared_from_this() ); + pCell->init( cellX, cellY ); } // If object moved cell From 459fa4865ba2dcd7ae4d168943b4bc4de0fdaae3 Mon Sep 17 00:00:00 2001 From: collett Date: Sat, 26 Feb 2022 20:22:30 +0900 Subject: [PATCH 06/11] fix merge error --- src/world/Event/EventHandler.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/world/Event/EventHandler.h b/src/world/Event/EventHandler.h index 1a337d2d..d5dbc82d 100644 --- a/src/world/Event/EventHandler.h +++ b/src/world/Event/EventHandler.h @@ -78,8 +78,6 @@ namespace Sapphire::Event SwitchTalk = 0x001F, Adventure = 0x0020, DailyQuestSupply = 0x0021, - Adventure = 0x0021, - DailyQuestSupply = 0x0022, TripleTriad = 0x0023, PreHandler = 0x0036, ICDirector = 0x8003, From 3b139571ebe1da51fd77bfe7ba0a1fb95ed93018 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sat, 26 Feb 2022 10:36:03 +0100 Subject: [PATCH 07/11] Fixed types in lgb.h and lgbtypes.h --- deps/datReader/DatCategories/bg/LgbTypes.h | 2 +- deps/datReader/DatCategories/bg/lgb.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deps/datReader/DatCategories/bg/LgbTypes.h b/deps/datReader/DatCategories/bg/LgbTypes.h index 31cbe8b4..b883858c 100644 --- a/deps/datReader/DatCategories/bg/LgbTypes.h +++ b/deps/datReader/DatCategories/bg/LgbTypes.h @@ -167,7 +167,7 @@ struct ExitRangeData : public InstanceObject uint32_t exitType; uint16_t zoneId; uint16_t destTerritoryType; - int index; + int32_t index; uint32_t destInstanceObjectId; uint32_t returnInstanceObjectId; float direction; diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index 2a10251a..a7a8fc38 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -177,8 +177,8 @@ struct LayerSetReferenced struct LayerSetReferencedList { LayerSetReferencedType ReferencedType; - int LayerSets; - int LayerSetCount; + int32_t LayerSets; + int32_t LayerSetCount; }; struct LGB_GROUP_HEADER From abb295d4fe06dce875c398bb8359320899922dd1 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sat, 26 Feb 2022 10:50:10 +0100 Subject: [PATCH 08/11] parse Event and PopRange into entries too --- deps/datReader/DatCategories/bg/lgb.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index a7a8fc38..c5c99f11 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -255,6 +255,14 @@ struct LGB_GROUP { entries.push_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) ); } + else if( type == LgbEntryType::EventRange ) + { + entries.push_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) ); + } + else if( type == LgbEntryType::PopRange ) + { + entries.push_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) ); + } else if( type == LgbEntryType::MapRange ) { entries.push_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) ); From 616b12c695d2a64fda107ba89a0eb459c2c0fe90 Mon Sep 17 00:00:00 2001 From: collett Date: Thu, 17 Feb 2022 04:53:19 +0900 Subject: [PATCH 09/11] Fix OutsideRange event. --- src/world/Network/Handlers/EventHandlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/Network/Handlers/EventHandlers.cpp b/src/world/Network/Handlers/EventHandlers.cpp index d869c62a..70d28f95 100644 --- a/src/world/Network/Handlers/EventHandlers.cpp +++ b/src/world/Network/Handlers/EventHandlers.cpp @@ -154,7 +154,7 @@ void Sapphire::Network::GameConnection::eventHandlerOutsideRange( const Packets: std::string objName = eventMgr.getEventName( eventId ); player.sendDebug( "Calling: {0}.{1} - {2} p1: {3}", objName, eventName, eventId, param1 ); - player.eventStart( player.getId(), eventId, Event::EventHandler::WithinRange, 1, param1 ); + player.eventStart( player.getId(), eventId, Event::EventHandler::OutsideRange, 1, param1 ); scriptMgr.onOutsideRange( player, eventId, param1, pos.x, pos.y, pos.z ); From 0d6a0719de275691ab49ab5dc5203ecceae4cd7c Mon Sep 17 00:00:00 2001 From: collett Date: Sat, 21 Jan 2023 07:09:00 +0900 Subject: [PATCH 10/11] fix quest battles which are using InstanceContent instead of QuestBattle. --- src/world/Manager/TerritoryMgr.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index 0b46881b..9df18782 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -788,7 +788,14 @@ void Sapphire::World::Manager::TerritoryMgr::createAndJoinQuestBattle( Entity::P { auto qb = createQuestBattle( questBattleId ); if( !qb ) - return; + { + auto& exdData = Common::Service< Data::ExdDataGenerated >::ref(); + auto instanceInfo = exdData.get< Sapphire::Data::InstanceContent >( questBattleId ); + if( !instanceInfo ) + return; + qb = createInstanceContent( instanceInfo->order ); + qb->getAsInstanceContent()->bindPlayer( player.getId() ); + } player.setInstance( qb ); From 5d6aa369dc44e348ab15afbaccda979accacc016 Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Feb 2023 07:24:25 +0900 Subject: [PATCH 11/11] Fix item count in container. --- src/world/Manager/InventoryMgr.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/world/Manager/InventoryMgr.cpp b/src/world/Manager/InventoryMgr.cpp index 7a17defa..0b61c37e 100644 --- a/src/world/Manager/InventoryMgr.cpp +++ b/src/world/Manager/InventoryMgr.cpp @@ -19,11 +19,14 @@ void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::E { auto sequence = player.getNextInventorySequence(); auto pMap = container->getItemMap(); + uint32_t itemCount = 0; for( auto itM = pMap.begin(); itM != pMap.end(); ++itM ) { if( !itM->second ) - return; + continue; + + itemCount++; if( container->getId() == Common::InventoryType::Currency || container->getId() == Common::InventoryType::Crystal ) { @@ -57,7 +60,7 @@ void Sapphire::World::Manager::InventoryMgr::sendInventoryContainer( Sapphire::E auto containerInfoPacket = makeZonePacket< Server::FFXIVIpcContainerInfo >( player.getId() ); containerInfoPacket->data().containerSequence = sequence; - containerInfoPacket->data().numItems = container->getEntryCount(); + containerInfoPacket->data().numItems = itemCount; containerInfoPacket->data().containerId = container->getId(); player.queuePacket( containerInfoPacket );