diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-06-07 12:49:34 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2025-06-07 12:49:34 +0200 |
commit | f22321ede4968c9e7e09a91ffe66a785d6734082 (patch) | |
tree | b264d0a5d4ca87295524075ab34c83f6ce6b336d /src | |
parent | 46ddf90661405f220068afaf51588ef465cf2f41 (diff) |
Tools/Extractors: Skip extracting visual only liquids (determined by LiquidMaterial flags)
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Collision/Maps/MapDefines.h | 8 | ||||
-rw-r--r-- | src/tools/map_extractor/System.cpp | 13 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vmapexport.cpp | 212 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/vmapexport.h | 2 | ||||
-rw-r--r-- | src/tools/vmap4_extractor/wmo.cpp | 7 |
5 files changed, 170 insertions, 72 deletions
diff --git a/src/common/Collision/Maps/MapDefines.h b/src/common/Collision/Maps/MapDefines.h index 468d9cee9a6..9afe2e93f61 100644 --- a/src/common/Collision/Maps/MapDefines.h +++ b/src/common/Collision/Maps/MapDefines.h @@ -108,6 +108,14 @@ enum class map_liquidHeaderTypeFlags : uint8 DEFINE_ENUM_FLAG(map_liquidHeaderTypeFlags); +enum class LiquidMaterialFlags : int32 +{ + Transparent = 0x1, + VisualOnly = 0x2, +}; + +DEFINE_ENUM_FLAG(LiquidMaterialFlags); + struct map_liquidHeader { u_map_magic liquidMagic; diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp index b8b71f5f2e5..b0fbed1960d 100644 --- a/src/tools/map_extractor/System.cpp +++ b/src/tools/map_extractor/System.cpp @@ -25,6 +25,7 @@ #include "IteratorPair.h" #include "Locales.h" #include "MapDefines.h" +#include "MapUtils.h" #include "StringFormat.h" #include "Util.h" #include "adt.h" @@ -59,6 +60,7 @@ struct MapEntry struct LiquidMaterialEntry { + EnumFlag<LiquidMaterialFlags> Flags = { { } }; int8 LVF = 0; }; @@ -330,6 +332,7 @@ void ReadLiquidMaterialTable() continue; LiquidMaterialEntry& liquidType = LiquidMaterials[record.GetId()]; + liquidType.Flags = static_cast<LiquidMaterialFlags>(record.GetUInt32("Flags")); liquidType.LVF = record.GetUInt8("LVF"); } @@ -653,6 +656,13 @@ bool ConvertADT(ChunkedFile& adt, std::string const& mapName, std::string const& if (!h) continue; + liquid_entry[i][j] = h2o->GetLiquidType(h); + LiquidTypeEntry const& liquidTypeEntry = LiquidTypes.at(liquid_entry[i][j]); + + if (LiquidMaterialEntry const* liquidMaterial = Trinity::Containers::MapGetValuePtr(LiquidMaterials, liquidTypeEntry.MaterialID)) + if (liquidMaterial->Flags.HasFlag(LiquidMaterialFlags::VisualOnly)) + continue; + adt_liquid_attributes attrs = h2o->GetLiquidAttributes(i, j); int32 count = 0; @@ -672,8 +682,7 @@ bool ConvertADT(ChunkedFile& adt, std::string const& mapName, std::string const& } } - liquid_entry[i][j] = h2o->GetLiquidType(h); - switch (LiquidTypes.at(liquid_entry[i][j]).SoundBank) + switch (liquidTypeEntry.SoundBank) { case LIQUID_TYPE_WATER: liquid_flags[i][j] |= map_liquidHeaderTypeFlags::Water; break; case LIQUID_TYPE_OCEAN: liquid_flags[i][j] |= map_liquidHeaderTypeFlags::Ocean; if (!ignoreDeepWater && attrs.Deep) liquid_flags[i][j] |= map_liquidHeaderTypeFlags::DarkWater; break; diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index cc518cfab50..3f3e29685f0 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -15,23 +15,24 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "vmapexport.h" #include "adtfile.h" #include "Banner.h" #include "Common.h" -#include "cascfile.h" #include "DB2CascFileSource.h" #include "ExtractorDB2LoadInfo.h" -#include "StringFormat.h" -#include "VMapDefinitions.h" -#include "vmapexport.h" #include "Locales.h" +#include "MapDefines.h" +#include "MapUtils.h" +#include "StringFormat.h" #include "Util.h" +#include "VMapDefinitions.h" #include "wdtfile.h" #include "wmo.h" -#include <algorithm> #include <CascLib.h> #include <boost/filesystem/directory.hpp> #include <boost/filesystem/operations.hpp> +#include <algorithm> #include <fstream> #include <list> #include <map> @@ -39,12 +40,21 @@ #include <unordered_set> #include <vector> #include <cstdio> -#include <cerrno> //----------------------------------------------------------------------------- std::shared_ptr<CASC::Storage> CascStorage; +struct LiquidMaterialEntry +{ + EnumFlag<LiquidMaterialFlags> Flags = { { } }; +}; + +struct LiquidTypeEntry +{ + uint8 MaterialID = 0; +}; + struct MapEntry { uint32 Id = 0; @@ -54,6 +64,8 @@ struct MapEntry std::string Directory; }; +std::unordered_map<uint32, LiquidMaterialEntry> LiquidMaterials; +std::unordered_map<uint32, LiquidTypeEntry> LiquidTypes; std::vector<MapEntry> map_ids; // partitioned by parent maps first std::unordered_set<uint32> maps_that_are_parents; boost::filesystem::path input_path; @@ -273,6 +285,16 @@ bool ExtractSingleWmo(std::string& fname) return true; } +bool IsLiquidIgnored(uint32 liquidTypeId) +{ + if (LiquidTypeEntry const* liquidType = Trinity::Containers::MapGetValuePtr(LiquidTypes, liquidTypeId)) + if (LiquidMaterialEntry const* liquidMaterial = Trinity::Containers::MapGetValuePtr(LiquidMaterials, liquidType->MaterialID)) + if (liquidMaterial->Flags.HasFlag(LiquidMaterialFlags::VisualOnly)) + return true; + + return false; +} + void ParsMapFiles() { std::unordered_map<uint32, WDTFile> wdts; @@ -281,7 +303,7 @@ void ParsMapFiles() auto itr = wdts.find(mapId); if (itr == wdts.end()) { - auto mapEntryItr = std::find_if(map_ids.begin(), map_ids.end(), [mapId](MapEntry const& mapEntry) { return mapEntry.Id == mapId; }); + auto mapEntryItr = std::ranges::find(map_ids, mapId, &MapEntry::Id); if (mapEntryItr == map_ids.end()) return nullptr; @@ -335,6 +357,118 @@ void ParsMapFiles() } } +void TryLoadDB2(char const* name, DB2CascFileSource* source, DB2FileLoader* db2, DB2FileLoadInfo const* loadInfo) +{ + try + { + db2->Load(source, loadInfo); + } + catch (std::exception const& e) + { + printf("Fatal error: Invalid %s file format! %s\n%s\n", name, CASC::HumanReadableCASCError(GetCascError()), e.what()); + exit(1); + } +} + +void ReadMapTable() +{ + printf("Read Map.dbc file... "); + + DB2CascFileSource source(CascStorage, MapLoadInfo::Instance.Meta->FileDataId); + DB2FileLoader db2; + TryLoadDB2("Map.db2", &source, &db2, &MapLoadInfo::Instance); + + map_ids.reserve(db2.GetRecordCount() + db2.GetRecordCopyCount()); + std::unordered_map<uint32, std::size_t> idToIndex; + for (uint32 x = 0; x < db2.GetRecordCount(); ++x) + { + DB2Record record = db2.GetRecord(x); + if (!record) + continue; + + MapEntry& map = map_ids.emplace_back(); + map.Id = record.GetId(); + map.WdtFileDataId = record.GetInt32("WdtFileDataID"); + map.ParentMapID = int16(record.GetUInt16("ParentMapID")); + map.Name = record.GetString("MapName"); + map.Directory = record.GetString("Directory"); + + if (map.ParentMapID < 0) + map.ParentMapID = int16(record.GetUInt16("CosmeticParentMapID")); + + if (map.ParentMapID >= 0) + maps_that_are_parents.insert(map.ParentMapID); + + idToIndex[map.Id] = map_ids.size() - 1; + } + + for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) + { + DB2RecordCopy copy = db2.GetRecordCopy(x); + auto itr = idToIndex.find(copy.SourceRowId); + if (itr != idToIndex.end()) + { + MapEntry& map = map_ids.emplace_back(map_ids[itr->second]); + map.Id = copy.NewRowId; + } + } + + std::erase_if(map_ids, [](MapEntry const& map) { return !map.WdtFileDataId; }); + + // force parent maps to be extracted first + std::stable_partition(map_ids.begin(), map_ids.end(), [](MapEntry const& map) { return maps_that_are_parents.contains(map.Id); }); + + printf("Done! (" SZFMTD " maps loaded)\n", map_ids.size()); +} + +void ReadLiquidMaterialTable() +{ + printf("Read LiquidMaterial.db2 file...\n"); + + DB2CascFileSource source(CascStorage, LiquidMaterialLoadInfo::Instance.Meta->FileDataId); + DB2FileLoader db2; + TryLoadDB2("LiquidMaterial.db2", &source, &db2, &LiquidMaterialLoadInfo::Instance); + + for (uint32 x = 0; x < db2.GetRecordCount(); ++x) + { + DB2Record record = db2.GetRecord(x); + if (!record) + continue; + + LiquidMaterialEntry& liquidType = LiquidMaterials[record.GetId()]; + liquidType.Flags = static_cast<LiquidMaterialFlags>(record.GetUInt32("Flags")); + } + + for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) + LiquidMaterials[db2.GetRecordCopy(x).NewRowId] = LiquidMaterials[db2.GetRecordCopy(x).SourceRowId]; + + printf("Done! (" SZFMTD " LiquidMaterials loaded)\n", LiquidMaterials.size()); +} + +void ReadLiquidTypeTable() +{ + printf("Read LiquidType.db2 file...\n"); + + DB2CascFileSource source(CascStorage, LiquidTypeLoadInfo::Instance.Meta->FileDataId); + DB2FileLoader db2; + TryLoadDB2("LiquidType.db2", &source, &db2, &LiquidTypeLoadInfo::Instance); + + for (uint32 x = 0; x < db2.GetRecordCount(); ++x) + { + DB2Record record = db2.GetRecord(x); + if (!record) + continue; + + LiquidTypeEntry& liquidType = LiquidTypes[record.GetId()]; + liquidType.MaterialID = record.GetUInt8("MaterialID"); + } + + for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) + LiquidTypes[db2.GetRecordCopy(x).NewRowId] = LiquidTypes[db2.GetRecordCopy(x).SourceRowId]; + + printf("Done! (" SZFMTD " LiquidTypes loaded)\n", LiquidTypes.size()); +} + bool processArgv(int argc, char ** argv, const char *versionString) { bool result = true; @@ -528,67 +662,9 @@ int main(int argc, char ** argv) //map.dbc if (success) { - printf("Read Map.dbc file... "); - - DB2CascFileSource source(CascStorage, MapLoadInfo::Instance.Meta->FileDataId); - DB2FileLoader db2; - try - { - db2.Load(&source, &MapLoadInfo::Instance); - } - catch (std::exception const& e) - { - printf("Fatal error: Invalid Map.db2 file format! %s\n%s\n", CASC::HumanReadableCASCError(GetCascError()), e.what()); - exit(1); - } - - map_ids.reserve(db2.GetRecordCount()); - std::unordered_map<uint32, std::size_t> idToIndex; - for (uint32 x = 0; x < db2.GetRecordCount(); ++x) - { - DB2Record record = db2.GetRecord(x); - if (!record) - continue; - - MapEntry map; - map.Id = record.GetId(); - map.WdtFileDataId = record.GetInt32("WdtFileDataID"); - map.ParentMapID = int16(record.GetUInt16("ParentMapID")); - map.Name = record.GetString("MapName"); - map.Directory = record.GetString("Directory"); - - if (map.ParentMapID < 0) - map.ParentMapID = int16(record.GetUInt16("CosmeticParentMapID")); - - if (map.ParentMapID >= 0) - maps_that_are_parents.insert(map.ParentMapID); - - idToIndex[map.Id] = map_ids.size(); - map_ids.push_back(map); - } - - for (uint32 x = 0; x < db2.GetRecordCopyCount(); ++x) - { - DB2RecordCopy copy = db2.GetRecordCopy(x); - auto itr = idToIndex.find(copy.SourceRowId); - if (itr != idToIndex.end()) - { - MapEntry map; - map.Id = copy.NewRowId; - map.WdtFileDataId = map_ids[itr->second].WdtFileDataId; - map.ParentMapID = map_ids[itr->second].ParentMapID; - map.Name = map_ids[itr->second].Name; - map.Directory = map_ids[itr->second].Directory; - map_ids.push_back(map); - } - } - - map_ids.erase(std::remove_if(map_ids.begin(), map_ids.end(), [](MapEntry const& map) { return !map.WdtFileDataId; }), map_ids.end()); - - // force parent maps to be extracted first - std::stable_partition(map_ids.begin(), map_ids.end(), [](MapEntry const& map) { return maps_that_are_parents.count(map.Id) > 0; }); - - printf("Done! (" SZFMTD " maps loaded)\n", map_ids.size()); + ReadMapTable(); + ReadLiquidMaterialTable(); + ReadLiquidTypeTable(); ParsMapFiles(); } diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h index 49129ded1ac..1aba56a44c1 100644 --- a/src/tools/vmap4_extractor/vmapexport.h +++ b/src/tools/vmap4_extractor/vmapexport.h @@ -50,4 +50,6 @@ bool ExtractSingleModel(std::string& fname); void ExtractGameobjectModels(); +bool IsLiquidIgnored(uint32 liquidTypeId); + #endif diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp index ddf669b0141..001abad4907 100644 --- a/src/tools/vmap4_extractor/wmo.cpp +++ b/src/tools/vmap4_extractor/wmo.cpp @@ -262,7 +262,7 @@ bool WMOGroup::open(WMORoot* rootWMO) else groupLiquid = GetLiquidTypeId(groupLiquid + 1); - if (groupLiquid) + if (groupLiquid && !IsLiquidIgnored(groupLiquid)) liquflags |= 2; } else if (!strcmp(fourcc,"MOPY")) @@ -329,7 +329,7 @@ bool WMOGroup::open(WMORoot* rootWMO) // Determine legacy liquid type if (!groupLiquid) { - for (int i = 0; i < hlq->xtiles * hlq->ytiles; ++i) + for (int i = 0; i < nLiquBytes; ++i) { if ((LiquBytes[i] & 0xF) != 15) { @@ -339,6 +339,9 @@ bool WMOGroup::open(WMORoot* rootWMO) } } + if (IsLiquidIgnored(groupLiquid)) + liquflags = 0; + /* std::ofstream llog("Buildings/liquid.log", ios_base::out | ios_base::app); llog << filename; llog << "\nbbox: " << bbcorn1[0] << ", " << bbcorn1[1] << ", " << bbcorn1[2] << " | " << bbcorn2[0] << ", " << bbcorn2[1] << ", " << bbcorn2[2]; |