aboutsummaryrefslogtreecommitdiff
path: root/src/tools
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-06-07 12:49:34 +0200
committerShauren <shauren.trinity@gmail.com>2025-06-07 12:49:34 +0200
commitf22321ede4968c9e7e09a91ffe66a785d6734082 (patch)
treeb264d0a5d4ca87295524075ab34c83f6ce6b336d /src/tools
parent46ddf90661405f220068afaf51588ef465cf2f41 (diff)
Tools/Extractors: Skip extracting visual only liquids (determined by LiquidMaterial flags)
Diffstat (limited to 'src/tools')
-rw-r--r--src/tools/map_extractor/System.cpp13
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp212
-rw-r--r--src/tools/vmap4_extractor/vmapexport.h2
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp7
4 files changed, 162 insertions, 72 deletions
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];