diff --git a/deps/datReader/DatCategories/bg/lgb.h b/deps/datReader/DatCategories/bg/lgb.h index c5c99f11..d0c3f29b 100644 --- a/deps/datReader/DatCategories/bg/lgb.h +++ b/deps/datReader/DatCategories/bg/lgb.h @@ -227,6 +227,8 @@ struct LGB_GROUP memcpy( (char*)&refs[0], buf + offset + header.LayerSetRef + layerSetReferencedList.LayerSets, layerSetReferencedList.LayerSetCount * sizeof( LayerSetReferenced ) ); } + entries.reserve( header.entryCount ); + const auto entriesOffset = offset + header.entriesOffset; for( auto i = 0; i < header.entryCount; ++i ) { @@ -235,41 +237,53 @@ struct LGB_GROUP try { const auto type = *reinterpret_cast< LgbEntryType* >( buf + entryOffset ); - if( type == LgbEntryType::BgParts ) + switch( type ) { - entries.push_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::Gimmick ) - { - entries.push_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::EventNpc ) - { - entries.push_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::EventObject ) - { - entries.push_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) ); - } - else if( type == LgbEntryType::ExitRange ) - { - 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 ) ); - } - else - { - entries.push_back( std::make_shared< LgbEntry >( buf, entryOffset ) ); + case LgbEntryType::BgParts: + { + entries.emplace_back( std::make_shared< LGB_BGPARTS_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::Gimmick: + { + entries.emplace_back( std::make_shared< LGB_GIMMICK_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventNpc: + { + entries.emplace_back( std::make_shared< LGB_ENPC_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventObject: + { + entries.emplace_back( std::make_shared< LGB_EOBJ_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::ExitRange: + { + entries.emplace_back( std::make_shared< LGB_EXIT_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::EventRange: + { + entries.emplace_back( std::make_shared< LGB_EVENT_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::PopRange: + { + entries.emplace_back( std::make_shared< LGB_POP_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + case LgbEntryType::MapRange: + { + entries.emplace_back( std::make_shared< LGB_MAP_RANGE_ENTRY >( buf, entryOffset ) ); + break; + } + default: + { + entries.emplace_back( std::make_shared< LgbEntry >( buf, entryOffset ) ); + break; + } } } catch( std::exception& e ) diff --git a/deps/datReader/Exd.cpp b/deps/datReader/Exd.cpp index 74aae36e..b1a2a2b5 100644 --- a/deps/datReader/Exd.cpp +++ b/deps/datReader/Exd.cpp @@ -7,50 +7,6 @@ using xiv::utils::bparse::extract; - -namespace xiv::exd -{ - struct ExdHeader - { - char magic[0x4]; - uint16_t unknown; - uint16_t unknown2; - uint32_t index_size; - }; - - struct ExdRecordIndex - { - uint32_t id; - uint32_t offset; - }; -} - -namespace xiv::utils::bparse { -template<> - inline void reorder< xiv::exd::ExdHeader >( xiv::exd::ExdHeader& i_struct ) - { - for( int32_t i = 0; i < 0x4; ++i ) - { - xiv::utils::bparse::reorder( i_struct.magic[ i ] ); - } - i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown ); - xiv::utils::bparse::reorder( i_struct.unknown ); - i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 ); - xiv::utils::bparse::reorder( i_struct.unknown2 ); - i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size ); - xiv::utils::bparse::reorder( i_struct.index_size ); - } - - template<> - inline void reorder< xiv::exd::ExdRecordIndex >( xiv::exd::ExdRecordIndex& i_struct ) - { - i_struct.id = xiv::utils::bparse::byteswap( i_struct.id ); - xiv::utils::bparse::reorder( i_struct.id ); - i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); - xiv::utils::bparse::reorder( i_struct.offset ); - } -}; - namespace xiv::exd { Exd::Exd( std::shared_ptr< Exh > i_exh, const std::vector< std::shared_ptr< dat::File>>& i_files ) @@ -68,16 +24,16 @@ namespace xiv::exd std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); // Extract the header and skip to the record indices - auto exd_header = extract< ExdHeader >( iss ); + auto exd_header = extract< ExdHeaderMinimal >( iss ); iss.seekg( 0x20 ); // Preallocate and extract the record_indices - const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex ); - std::vector< ExdRecordIndex > record_indices; + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; record_indices.reserve( record_count ); for( uint32_t i = 0; i < record_count; ++i ) { - auto recordIndex = extract< ExdRecordIndex >( iss ); + auto recordIndex = extract< ExdRecordIndexData >( iss ); _idCache[ recordIndex.id ] = ExdCacheEntry{ file_ptr, recordIndex.offset }; } } @@ -290,16 +246,16 @@ namespace xiv::exd std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); // Extract the header and skip to the record indices - auto exd_header = extract< ExdHeader >( iss ); + auto exd_header = extract< ExdHeaderMinimal >( iss ); iss.seekg( 0x20 ); // Preallocate and extract the record_indices - const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndex ); - std::vector< ExdRecordIndex > record_indices; + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; record_indices.reserve( record_count ); for( uint32_t i = 0; i < record_count; ++i ) { - record_indices.emplace_back( extract< ExdRecordIndex >( iss ) ); + record_indices.emplace_back( extract< ExdRecordIndexData >( iss ) ); } for( auto& record_index : record_indices ) diff --git a/deps/datReader/Exd.h b/deps/datReader/Exd.h index 8cf40658..e08f6e54 100644 --- a/deps/datReader/Exd.h +++ b/deps/datReader/Exd.h @@ -2,6 +2,7 @@ #include #include +#include #include @@ -12,6 +13,49 @@ #include #include "Exh.h" #include "bparse.h" + +namespace xiv::exd +{ + struct ExdHeaderMinimal { + char magic[ 0x4 ]; + uint16_t unknown; + uint16_t unknown2; + uint32_t index_size; + }; + + struct ExdRecordIndexData { + uint32_t id; + uint32_t offset; + }; +} + +namespace xiv::utils::bparse +{ + template<> + inline void reorder< xiv::exd::ExdHeaderMinimal >( xiv::exd::ExdHeaderMinimal& i_struct ) + { + for( int32_t i = 0; i < 0x4; ++i ) + { + xiv::utils::bparse::reorder( i_struct.magic[ i ] ); + } + i_struct.unknown = xiv::utils::bparse::byteswap( i_struct.unknown ); + xiv::utils::bparse::reorder( i_struct.unknown ); + i_struct.unknown2 = xiv::utils::bparse::byteswap( i_struct.unknown2 ); + xiv::utils::bparse::reorder( i_struct.unknown2 ); + i_struct.index_size = xiv::utils::bparse::byteswap( i_struct.index_size ); + xiv::utils::bparse::reorder( i_struct.index_size ); + } + + template<> + inline void reorder< xiv::exd::ExdRecordIndexData >( xiv::exd::ExdRecordIndexData& i_struct ) + { + i_struct.id = xiv::utils::bparse::byteswap( i_struct.id ); + xiv::utils::bparse::reorder( i_struct.id ); + i_struct.offset = xiv::utils::bparse::byteswap( i_struct.offset ); + xiv::utils::bparse::reorder( i_struct.offset ); + } +};// namespace xiv::utils::bparse + namespace xiv::exd { @@ -184,12 +228,153 @@ namespace xiv::exd const std::vector< Field > get_row( uint32_t id, uint32_t subRow ); // Get all rows - const std::map< uint32_t, std::vector< Field>>& get_rows(); + const std::map< uint32_t, std::vector< Field > >& get_rows(); + + // Get all rows + template< typename T > + const std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > get_sheet_rows() + { + std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > sheets; + + // Iterates over all the files + const uint32_t member_count = static_cast< uint32_t >( _exh->get_members().size() ); + for( auto& file_ptr : _files ) + { + // Get a stream + std::vector< char > dataCpy = file_ptr->get_data_sections().front(); + std::istringstream iss( std::string( dataCpy.begin(), dataCpy.end() ) ); + + // Extract the header and skip to the record indices + auto exd_header = xiv::utils::bparse::extract< ExdHeaderMinimal >( iss ); + iss.seekg( 0x20 ); + + // Preallocate and extract the record_indices + const uint32_t record_count = exd_header.index_size / sizeof( ExdRecordIndexData ); + std::vector< ExdRecordIndexData > record_indices; + record_indices.reserve( record_count ); + for( uint32_t i = 0; i < record_count; ++i ) + { + record_indices.emplace_back( xiv::utils::bparse::extract< ExdRecordIndexData >( iss ) ); + } + + for( auto& record_index : record_indices ) + { + auto cacheEntryIt = _idCache.find( record_index.id ); + if( cacheEntryIt == _idCache.end() ) + throw std::out_of_range( "Id not found: " + std::to_string( record_index.id ) ); + + auto pSheet = std::make_shared< Excel::ExcelStruct< T > >(); + + // Get the vector fields for the given record and preallocate it + auto fields = _data[ record_index.id ]; + fields.reserve( member_count ); + iss.seekg( cacheEntryIt->second.offset + 6 ); + + iss.read( reinterpret_cast( &pSheet.get()->_data ), sizeof( T ) ); + + int stringCount = 0; + for( auto& member_entry : _exh->get_exh_members() ) + { + + // Seek to the position of the member to extract. + // 6 is because we have uint32_t/uint16_t at the start of each record + iss.seekg( cacheEntryIt->second.offset + 6 + member_entry.offset ); + + // Switch depending on the type to extract + switch( member_entry.type ) + { + case DataType::string: + // Extract the offset to the actual string + // Seek to it then extract the actual string + { + auto string_offset = xiv::utils::bparse::extract< uint32_t >( iss, "string_offset", false ); + iss.seekg( cacheEntryIt->second.offset + 6 + _exh->get_header().data_offset + string_offset ); + std::string value = xiv::utils::bparse::extract_cstring( iss, "string" ); + auto it = pSheet->_strings.insert( pSheet->_strings.end(), value ); + *reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = + static_cast< uint32_t >( std::distance( pSheet->_strings.begin(), it ) ); + } + break; + + case DataType::boolean: + xiv::utils::bparse::extract< bool >( iss, "bool" ); + break; + + case DataType::int8: + xiv::utils::bparse::extract< int8_t >( iss, "int8_t" ); + break; + + case DataType::uint8: + xiv::utils::bparse::extract< uint8_t >( iss, "uint8_t" ); + break; + + + case DataType::int16: + { + int16_t value = xiv::utils::bparse::extract< int16_t >( iss, "int16_t", false ); + *reinterpret_cast< int16_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint16: + { + uint16_t value = xiv::utils::bparse::extract< uint16_t >( iss, "uint16_t", false ); + *reinterpret_cast< uint16_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::int32: + { + int32_t value = xiv::utils::bparse::extract< int32_t >( iss, "int32_t", false ); + *reinterpret_cast< int32_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint32: + { + uint32_t value = xiv::utils::bparse::extract< uint32_t >( iss, "uint32_t", false ); + *reinterpret_cast< uint32_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::float32: + { + float value = xiv::utils::bparse::extract< float >( iss, "float", false ); + *reinterpret_cast< float* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + case DataType::uint64: + { + uint64_t value = xiv::utils::bparse::extract< uint64_t >( iss, "uint64_t", false ); + *reinterpret_cast< uint64_t* >( pSheet->ptr() + member_entry.offset ) = value; + } + break; + + default: + auto type = static_cast< uint16_t >( member_entry.type ); + if( type < 0x19 || type > 0x20 ) + throw std::runtime_error( "Unknown DataType: " + std::to_string( type ) ); + uint64_t val = xiv::utils::bparse::extract< uint64_t >( iss, "bool" ); + int32_t shift = type - 0x19; + int32_t i = 1 << shift; + val &= i; + fields.emplace_back( ( val & i ) == i ); + break; + } + } + + sheets[ record_index.id ] = pSheet; + } + } + + return sheets; + } protected: // Data indexed by the ID of the row, the vector is field with the same order as exh.members - std::map< uint32_t, std::vector< Field>> _data; - std::vector< std::shared_ptr< dat::File>> _files; + std::map< uint32_t, std::vector< Field > > _data; + std::vector< std::shared_ptr< dat::File > > _files; std::shared_ptr< Exh > _exh; std::map< uint32_t, ExdCacheEntry > _idCache; }; diff --git a/src/common/Exd/ExdData.h b/src/common/Exd/ExdData.h index 5ba553e5..a4be9156 100644 --- a/src/common/Exd/ExdData.h +++ b/src/common/Exd/ExdData.h @@ -91,6 +91,27 @@ namespace Sapphire::Data return ids; } + template< typename T > + std::unordered_map< uint32_t, std::shared_ptr< Excel::ExcelStruct< T > > > getRows() + { + xiv::exd::Exd sheet; + auto needle = m_sheets.find( typeid( T ) ); + if( needle == m_sheets.end() ) + { + auto sheetName = getSheetName< T >(); + + // load sheet + auto& cat = m_exd_data->get_category( sheetName ); + m_sheets[ typeid( T ) ] = sheet = static_cast< xiv::exd::Exd >( cat.get_data( xiv::exd::Language::en ) ); + } + else + { + sheet = needle->second; + } + + return sheet.get_sheet_rows< T >(); + } + std::shared_ptr< xiv::dat::GameData > getGameData() { return m_data; diff --git a/src/tools/action_parse/main.cpp b/src/tools/action_parse/main.cpp index c542eae7..4abed826 100644 --- a/src/tools/action_parse/main.cpp +++ b/src/tools/action_parse/main.cpp @@ -157,22 +157,20 @@ int main( int argc, char* argv[] ) Logger::fatal( "Error setting up EXD data " ); return 0; } - auto idList = g_exdDataGen.getIdList< Excel::Action >(); + auto actionList = g_exdDataGen.getRows< Excel::Action >(); std::map< uint32_t, ActionEntry > actions; std::map< uint32_t, std::vector< uint32_t > > traversedCombos; - auto total = idList.size(); + auto total = actionList.size(); int cursor = 0; - for( auto id : idList ) + for( const auto& [ id, action ] : actionList ) { auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f; if( cursor % 50 == 0 && cursor > 0 ) Logger::info( "Processing {} actions of {} ({:.2f}%)", cursor, total, done ); - auto action = g_exdDataGen.getRow< Excel::Action >( id ); - //auto actionTransient = g_exdData.get< Sapphire::Data::ActionTransient >( id ); if( action ) { diff --git a/src/tools/wiki_parse/main.cpp b/src/tools/wiki_parse/main.cpp index 914e7983..ca12c46d 100644 --- a/src/tools/wiki_parse/main.cpp +++ b/src/tools/wiki_parse/main.cpp @@ -89,11 +89,11 @@ int main( int argc, char* argv[] ) // CFC list { - auto idList = g_exdDataGen.getIdList< Excel::ContentFinderCondition >(); + auto cfcList = g_exdDataGen.getRows< Excel::ContentFinderCondition >(); std::stringstream cfcOutputStream; - auto total = idList.size(); + auto total = cfcList.size(); int cursor = 0; std::map< uint8_t, std::string > instanceContentTypeMap; @@ -118,7 +118,7 @@ int main( int argc, char* argv[] ) cfcOutputStream << "| ID | Instance | Territory | Name | Type |" << std::endl << "| --- | --- | --- | --- | --- |" << std::endl; - for( auto id : idList ) + for( const auto& [ id, cfc ] : cfcList ) { auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f; if( cursor % 50 == 0 && cursor > 0 ) @@ -127,8 +127,6 @@ int main( int argc, char* argv[] ) if( id == 0 ) continue; - auto cfc = g_exdDataGen.getRow< Excel::ContentFinderCondition >( id ); - if( cfc ) { auto& cfcData = cfc->data(); @@ -234,24 +232,22 @@ int main( int argc, char* argv[] ) teriTypeIntendedUseMap[ TheFeastArea ] = "TheFeastArea"; teriTypeIntendedUseMap[ PrivateEventArea ] = "PrivateEventArea"; - auto idList = g_exdDataGen.getIdList< Excel::TerritoryType >(); + auto teriList = g_exdDataGen.getRows< Excel::TerritoryType >(); std::stringstream teritypeOutputStream; teritypeOutputStream << "| ID | Place Name | Name | Intended Use |" << std::endl << "| --- | --- | --- | --- |" << std::endl; - auto total = idList.size(); + auto total = teriList.size(); int cursor = 0; - for( auto id : idList ) + for( const auto& [ id, teriType ] : teriList ) { auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f; if( cursor % 50 == 0 && cursor > 0 ) Logger::info( "Processing {} teritypes of {} ({:.2f}%)", cursor, total, done ); - auto teriType = g_exdDataGen.getRow< Excel::TerritoryType >( id ); - if( teriType ) { auto& teriTypeData = teriType->data(); @@ -291,24 +287,22 @@ int main( int argc, char* argv[] ) // class/job list { - auto idList = g_exdDataGen.getIdList< Excel::ClassJob >(); + auto classJobList = g_exdDataGen.getRows< Excel::ClassJob >(); std::stringstream classjobOutputStream; classjobOutputStream << "| ID | Name | Short | Main Class |" << std::endl << "| --- | --- | --- | --- |" << std::endl; - auto total = idList.size(); + auto total = classJobList.size(); int cursor = 0; - for( auto id : idList ) + for( const auto& [ id, classJob ] : classJobList ) { auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f; if( cursor % 50 == 0 && cursor > 0 ) Logger::info( "Processing {} classjobs of {} ({:.2f}%)", cursor, total, done ); - auto classJob = g_exdDataGen.getRow< Excel::ClassJob >( id ); - if( classJob ) { auto& classJobData = classJob->data(); @@ -338,7 +332,7 @@ int main( int argc, char* argv[] ) // achievement list { - auto idList = g_exdDataGen.getIdList< Excel::Achievement >(); + auto achvList = g_exdDataGen.getRows< Excel::Achievement >(); enum class Type : uint8_t { @@ -394,17 +388,15 @@ int main( int argc, char* argv[] ) achvOutputStream << "| ID | Name | Type (Subtype) | Description |" << std::endl << "| --- | --- | --- | --- |" << std::endl; - auto total = idList.size(); + auto total = achvList.size(); int cursor = 0; - for( auto id : idList ) + for( const auto& [ id, pAchv ] : achvList ) { auto done = ( cursor++ / static_cast< float >( total ) ) * 100.f; if( cursor % 50 == 0 && cursor > 0 ) Logger::info( "Processing {} achievements of {} ({:.2f}%)", cursor, total, done ); - auto pAchv = g_exdDataGen.getRow< Excel::Achievement >( id ); - if( pAchv ) { auto& achvData = pAchv->data(); diff --git a/src/world/ContentFinder/ContentFinder.cpp b/src/world/ContentFinder/ContentFinder.cpp index 78faebe3..8d53c2ea 100644 --- a/src/world/ContentFinder/ContentFinder.cpp +++ b/src/world/ContentFinder/ContentFinder.cpp @@ -131,12 +131,11 @@ void World::ContentFinder::registerContentRequest( Entity::Player &player, uint3 void World::ContentFinder::registerRandomContentRequest( Entity::Player &player, uint32_t randomContentTypeId ) { auto& exdData = Service< Data::ExdData >::ref(); - auto contentListIds = exdData.getIdList< Excel::ContentFinderCondition >(); + auto contentFinderList = exdData.getRows< Excel::ContentFinderCondition >(); std::vector< uint32_t > idList; - for( auto id : contentListIds ) + for( const auto& [ id, instanceContent ] : contentFinderList ) { - auto instanceContent = exdData.getRow< Excel::ContentFinderCondition >( id ); if( instanceContent->data().RandomContentType == randomContentTypeId ) { if( instanceContent->data().LevelMin <= player.getLevel() ) diff --git a/src/world/Manager/AchievementMgr.cpp b/src/world/Manager/AchievementMgr.cpp index 191c3f8e..2c41e123 100644 --- a/src/world/Manager/AchievementMgr.cpp +++ b/src/world/Manager/AchievementMgr.cpp @@ -14,12 +14,10 @@ using namespace Sapphire::World::Manager; bool AchievementMgr::cacheAchievements() { auto& exdData = Common::Service< Data::ExdData >::ref(); - auto idList = exdData.getIdList< Excel::Achievement >(); + auto achvDat = exdData.getRows< Excel::Achievement >(); - for( auto id : idList ) + for( const auto& [ id, achvExdData ] : achvDat ) { - auto achvExdData = exdData.getRow< Excel::Achievement >( id ); - uint32_t key = achvExdData->data().ConditionType; auto achvType = static_cast< Common::Achievement::Type >( key ); diff --git a/src/world/Manager/MapMgr.cpp b/src/world/Manager/MapMgr.cpp index 2824f4ae..f7a18a40 100644 --- a/src/world/Manager/MapMgr.cpp +++ b/src/world/Manager/MapMgr.cpp @@ -35,12 +35,10 @@ using namespace Sapphire::World::Manager; bool MapMgr::loadQuests() { auto& exdData = Common::Service< Data::ExdData >::ref(); - auto idList = exdData.getIdList< Excel::Quest >(); + auto questList = exdData.getRows< Excel::Quest >(); - for( auto id : idList ) + for( auto& [ id, questExdData ] : questList ) { - auto questExdData = exdData.getRow< Excel::Quest >( id ); - m_quests.emplace( id, std::move( questExdData ) ); } diff --git a/src/world/Manager/ShopMgr.cpp b/src/world/Manager/ShopMgr.cpp index 2edeec1c..7d9c9aa5 100644 --- a/src/world/Manager/ShopMgr.cpp +++ b/src/world/Manager/ShopMgr.cpp @@ -12,13 +12,12 @@ using namespace Sapphire::World::Manager; void ShopMgr::cacheShop( uint32_t shopId ) { auto& exdData = Common::Service< Data::ExdData >::ref(); - auto itemShopList = exdData.getIdList< Excel::Shop >(); + auto itemShopList = exdData.getRows< Excel::Shop >(); uint8_t count = 0; - for( auto itemShop : itemShopList ) + for( const auto& [ itemShop, shop ] : itemShopList ) { if( shopId == itemShop ) { - auto shop = exdData.getRow< Excel::Shop >( itemShop ); for( auto shopItemId : shop->data().Item ) { auto shopItem = exdData.getRow< Excel::ShopItem >( shopItemId ); diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index 540a0617..a7a27a7f 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -35,14 +35,12 @@ TerritoryMgr::TerritoryMgr() : void TerritoryMgr::loadTerritoryTypeDetailCache() { auto& exdData = Common::Service< Data::ExdData >::ref(); - auto idList = exdData.getIdList< Excel::TerritoryType >(); + auto teriList = exdData.getRows< Excel::TerritoryType >(); - for( auto id : idList ) + for( const auto& [ id, teri ] : teriList ) { - auto teri1 = exdData.getRow< Excel::TerritoryType >( id ); - - if( !teri1->getString( teri1->data().Name ).empty() && id > 90 ) - m_territoryTypeDetailCacheMap[ id ] = teri1; + if( !teri->getString( teri->data().Name ).empty() && id > 90 ) + m_territoryTypeDetailCacheMap[ id ] = teri; } } @@ -77,12 +75,11 @@ uint32_t TerritoryMgr::getNextInstanceId() Excel::ExcelStructPtr< Excel::TerritoryType > TerritoryMgr::getTerritoryDetail( uint32_t territoryTypeId ) const { - auto& exdData = Common::Service< Data::ExdData >::ref(); - auto teri1 = exdData.getRow< Excel::TerritoryType >( territoryTypeId ); - if( !teri1 ) + auto it = m_territoryTypeDetailCacheMap.find( territoryTypeId ); + if( it == m_territoryTypeDetailCacheMap.end() ) return nullptr; - return teri1; + return it->second; } bool TerritoryMgr::isInstanceContentTerritory( uint32_t territoryTypeId ) const @@ -159,11 +156,10 @@ bool TerritoryMgr::isHousingTerritory( uint32_t territoryTypeId ) const uint32_t TerritoryMgr::getInstanceContentId( uint32_t territoryTypeId ) const { auto& exdData = Common::Service< Data::ExdData >::ref(); - auto contentListIds = exdData.getIdList< Excel::InstanceContent >(); + auto contentFinderList = exdData.getRows< Excel::InstanceContent >(); - for( auto id : contentListIds ) + for( const auto& [ id, instanceContent ] : contentFinderList ) { - auto instanceContent = exdData.getRow< Excel::InstanceContent >( id ); if( instanceContent->data().TerritoryType == territoryTypeId ) { return id; @@ -198,8 +194,6 @@ bool TerritoryMgr::createDefaultTerritories() pPlaceName->getString( pPlaceName->data().Text.SGL ) ); pZone->init(); - std::string bgPath = territoryInfo->getString( territoryData.LVB ); - bool hasNaviMesh = pZone->getNaviProvider() != nullptr; Logger::info( "{0}\t{1}\t{2}\t{3:<10}\t{4}\t{5}\t{6}", @@ -309,10 +303,10 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId ) if( !pQuestInfo || pQuestInfo->getString( pQuestInfo->data().Text.Name ).empty() ) return nullptr; - for( auto& teriId : exdData.getIdList< Excel::TerritoryType >() ) - { + auto teriList = exdData.getRows< Excel::TerritoryType >(); - auto pTeri = exdData.getRow< Excel::TerritoryType >( teriId ); + for( const auto& [ teriId, pTeri ] : teriList ) + { if( !pTeri || pTeri->data().QuestBattle != questBattleId ) continue; @@ -332,8 +326,6 @@ TerritoryPtr TerritoryMgr::createQuestBattle( uint32_t questBattleId ) m_instanceZoneSet.insert( pZone ); return pZone; - - } return nullptr; diff --git a/src/world/Network/Handlers/CFHandlers.cpp b/src/world/Network/Handlers/CFHandlers.cpp index 6aef66e0..61c0484c 100644 --- a/src/world/Network/Handlers/CFHandlers.cpp +++ b/src/world/Network/Handlers/CFHandlers.cpp @@ -74,12 +74,12 @@ void Sapphire::Network::GameConnection::find5Contents( const Packets::FFXIVARR_P if( territoryType != 0 ) selectedContent.insert( territoryType ); - auto contentListIds = exdData.getIdList< Excel::InstanceContent >(); - std::vector< uint32_t > idList; - for( auto id : contentListIds ) + + auto contentFinderList = exdData.getRows< Excel::InstanceContent >(); + + for( const auto& [ id, instanceContent ] : contentFinderList ) { - auto instanceContent = exdData.getRow< Excel::InstanceContent >( id ); if( selectedContent.count( instanceContent->data().TerritoryType ) ) { idList.push_back( id ); diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index ace19b6d..a0076141 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -506,19 +506,14 @@ void Sapphire::Network::GameConnection::gmCommandHandler( const Packets::FFXIVAR bool doTeleport = false; uint16_t teleport; - auto idList = exdData.getIdList< Excel::Aetheryte >(); + auto aetheryteList = exdData.getRows< Excel::Aetheryte >(); - for( auto i : idList ) + for( const auto& [ id, data ] : aetheryteList ) { - auto data = exdData.getRow< Excel::Aetheryte >( i ); - - if( !data ) - continue; - if( data->data().TerritoryType == param1 && data->data().Telepo ) { doTeleport = true; - teleport = static_cast< uint16_t >( i ); + teleport = static_cast< uint16_t >( id ); break; } diff --git a/src/world/Network/Util/PacketUtil.cpp b/src/world/Network/Util/PacketUtil.cpp index 450bcfd6..584f5ee3 100644 --- a/src/world/Network/Util/PacketUtil.cpp +++ b/src/world/Network/Util/PacketUtil.cpp @@ -52,15 +52,13 @@ void Util::Packet::sendBaseParams( Entity::Player& player ) std::fill( std::begin( statParams ), std::end( statParams ), 0 ); auto& exd = Common::Service< Data::ExdData >::ref(); - auto idList = exd.getIdList< Excel::BaseParam >(); + auto baseParamList = exd.getRows< Excel::BaseParam >(); - for( const auto id : idList ) + for( const auto& [ id, row ] : baseParamList ) { - auto row = exd.getRow< Excel::BaseParam >( id ); - if( !row ) - continue; - if( row->data().PacketIndex < 0 ) + if( !row || row->data().PacketIndex < 0 ) continue; + statParams[ row->data().PacketIndex ] = player.getStatValue( static_cast< Common::BaseParam >( id ) ); } diff --git a/src/world/Territory/InstanceObjectCache.cpp b/src/world/Territory/InstanceObjectCache.cpp index 455975b2..91ff7a4c 100644 --- a/src/world/Territory/InstanceObjectCache.cpp +++ b/src/world/Territory/InstanceObjectCache.cpp @@ -11,27 +11,24 @@ #include #include +#include +#include + #include #include #include Sapphire::InstanceObjectCache::InstanceObjectCache() { - auto& exdData = Common::Service< Sapphire::Data::ExdData >::ref(); - auto idList = exdData.getIdList< Excel::TerritoryType >(); + auto teriList = exdData.getRows< Excel::TerritoryType >(); size_t count = 0; - for( const auto& id : idList ) - { + for( const auto& [ id, territoryType ] : teriList ) { // show some loading indication... if( count++ % 10 == 0 ) std::cout << "."; - auto territoryType = exdData.getRow< Excel::TerritoryType >( id ); - if( !territoryType ) - continue; - auto path = territoryType->getString( territoryType->data().LVB ); if( path.empty() ) @@ -56,7 +53,11 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() try { - bgFile = exdData.getGameData()->getFile( bgLgbPath ); + if( exdData.getGameData()->doesFileExist( bgLgbPath ) ) + bgFile = exdData.getGameData()->getFile( bgLgbPath ); + else + continue; + planmap_file = exdData.getGameData()->getFile( planmapLgbPath ); planevent_file = exdData.getGameData()->getFile( planeventLgbPath ); } @@ -101,49 +102,60 @@ Sapphire::InstanceObjectCache::InstanceObjectCache() { for( const auto& pEntry : group.entries ) { + switch( pEntry->getType() ) + { + case LgbEntryType::MapRange: + { + auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry ); + m_mapRangeCache.insert( id, pMapRange ); - if( pEntry->getType() == LgbEntryType::MapRange ) - { - auto pMapRange = std::reinterpret_pointer_cast< LGB_MAP_RANGE_ENTRY >( pEntry ); - m_mapRangeCache.insert( id, pMapRange ); - } - else if( pEntry->getType() == LgbEntryType::ExitRange ) - { - auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry ); - m_exitRangeCache.insert( id, pExitRange ); - } - else if( pEntry->getType() == LgbEntryType::PopRange ) - { + break; + } + case LgbEntryType::ExitRange: + { + auto pExitRange = std::reinterpret_pointer_cast< LGB_EXIT_RANGE_ENTRY >( pEntry ); + m_exitRangeCache.insert( id, pExitRange ); - auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry ); - m_popRangeCache.insert( id, pPopRange ); - } - else if( pEntry->getType() == LgbEntryType::CollisionBox ) - { - //auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); + break; + } + case LgbEntryType::PopRange: + { + auto pPopRange = std::reinterpret_pointer_cast< LGB_POP_RANGE_ENTRY >( pEntry ); + m_popRangeCache.insert( id, pPopRange ); + break; + } + case LgbEntryType::CollisionBox: + { + //auto pEObj = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); - //Logger::debug( "CollisionBox {}", pEntry->header.nameOffset ); - } - else if( pEntry->getType() == LgbEntryType::EventObject ) - { - auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry ); - m_eobjCache.insert( id, pEObj ); - } - else if( pEntry->getType() == LgbEntryType::EventNpc ) - { - auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); - m_enpcCache.insert( id, pENpc ); - } - else if( pEntry->getType() == LgbEntryType::EventRange ) - { - auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry ); - m_eventRangeCache.insert( 0, pEventRange ); + //Logger::debug( "CollisionBox {}", pEntry->header.nameOffset ); + break; + } + case LgbEntryType::EventObject: + { + auto pEObj = std::reinterpret_pointer_cast< LGB_EOBJ_ENTRY >( pEntry ); + m_eobjCache.insert( id, pEObj ); + break; + } + case LgbEntryType::EventNpc: + { + auto pENpc = std::reinterpret_pointer_cast< LGB_ENPC_ENTRY >( pEntry ); + m_enpcCache.insert( id, pENpc ); + break; + } + case LgbEntryType::EventRange: + { + auto pEventRange = std::reinterpret_pointer_cast< LGB_EVENT_RANGE_ENTRY >( pEntry ); + m_eventRangeCache.insert( 0, pEventRange ); + break; + } } } } } } - std::cout << "\n"; + + std::cout << std::endl; Logger::debug( "InstanceObjectCache Cached: MapRange: {} ExitRange: {} PopRange: {} EventObj: {} EventNpc: {} EventRange: {}",