aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tools/vmap4_extractor/adtfile.cpp33
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp36
-rw-r--r--src/tools/vmap4_extractor/model.cpp28
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp208
-rw-r--r--src/tools/vmap4_extractor/vmapexport.h42
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp31
-rw-r--r--src/tools/vmap4_extractor/wdtfile.h2
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp17
8 files changed, 230 insertions, 167 deletions
diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp
index 01c1f3f5b53..d34c2a3cfdf 100644
--- a/src/tools/vmap4_extractor/adtfile.cpp
+++ b/src/tools/vmap4_extractor/adtfile.cpp
@@ -15,12 +15,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "vmapexport.h"
#include "adtfile.h"
+#include "Memory.h"
#include "StringFormat.h"
+#include "vmapexport.h"
#include <cstdio>
-#include "Errors.h"
-#include "Memory.h"
char const* GetPlainName(char const* FileName)
{
@@ -183,16 +182,15 @@ bool ADTFile::init(uint32 map_num, uint32 originalMapId)
{
ADT::MDDF doodadDef;
_file.read(&doodadDef, sizeof(ADT::MDDF));
- if (!(doodadDef.Flags & 0x40))
- {
- Doodad::Extract(doodadDef, ModelInstanceNames[doodadDef.Id].c_str(), map_num, originalMapId, dirfile.get(), dirfileCache);
- }
+
+ std::string fileName;
+ if (doodadDef.Flags & 0x40)
+ fileName = Trinity::StringFormat("FILE{:08X}.xxx", doodadDef.Id);
else
- {
- std::string fileName = Trinity::StringFormat("FILE{:08X}.xxx", doodadDef.Id);
- ExtractSingleModel(fileName);
+ fileName = ModelInstanceNames[doodadDef.Id];
+
+ if (ExtractSingleModel(fileName))
Doodad::Extract(doodadDef, fileName.c_str(), map_num, originalMapId, dirfile.get(), dirfileCache);
- }
}
ModelInstanceNames.clear();
@@ -210,15 +208,18 @@ bool ADTFile::init(uint32 map_num, uint32 originalMapId)
std::string fileName;
if (mapObjDef.Flags & 0x8)
- {
fileName = Trinity::StringFormat("FILE{:08X}.xxx", mapObjDef.Id);
- ExtractSingleWmo(fileName);
- }
else
fileName = WmoInstanceNames[mapObjDef.Id];
- MapObject::Extract(mapObjDef, fileName.c_str(), false, map_num, originalMapId, dirfile.get(), dirfileCache);
- Doodad::ExtractSet(WmoDoodads[fileName], mapObjDef, false, map_num, originalMapId, dirfile.get(), dirfileCache);
+ if (ExtractedModelData const* extracted = ExtractSingleWmo(fileName))
+ {
+ if (extracted->HasCollision())
+ MapObject::Extract(mapObjDef, fileName.c_str(), false, map_num, originalMapId, dirfile.get(), dirfileCache);
+
+ if (extracted->Doodads)
+ Doodad::ExtractSet(*extracted->Doodads, mapObjDef, false, map_num, originalMapId, dirfile.get(), dirfileCache);
+ }
}
WmoInstanceNames.clear();
diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp
index 9b6188304d7..df9fcb95f16 100644
--- a/src/tools/vmap4_extractor/gameobject_extract.cpp
+++ b/src/tools/vmap4_extractor/gameobject_extract.cpp
@@ -19,6 +19,7 @@
#include "DB2CascFileSource.h"
#include "Errors.h"
#include "ExtractorDB2LoadInfo.h"
+#include "Memory.h"
#include "model.h"
#include "StringFormat.h"
#include "vmapexport.h"
@@ -28,10 +29,10 @@
#include <cstdio>
#include "advstd.h"
-bool ExtractSingleModel(std::string& fname)
+ExtractedModelData const* ExtractSingleModel(std::string& fname)
{
if (fname.length() < 4)
- return false;
+ return nullptr;
std::string extension = fname.substr(fname.length() - 4, 4);
if (extension == ".mdx" || extension == ".MDX" || extension == ".mdl" || extension == ".MDL")
@@ -45,18 +46,28 @@ bool ExtractSingleModel(std::string& fname)
char* name = GetPlainName((char*)fname.c_str());
NormalizeFileName(name, strlen(name));
- std::string output(szWorkDirWmo);
- output += "/";
- output += name;
+ auto [model, shouldExtract] = BeginModelExtraction(name);
+ if (!shouldExtract)
+ {
+ model->Wait();
+ return model->State.load(std::memory_order::relaxed) == ExtractedModelData::Ok ? model : nullptr;
+ }
- if (FileExists(output.c_str()))
- return true;
+ auto stateGuard = Trinity::make_unique_ptr_with_deleter<&ExtractedModelData::Fail>(model);
Model mdl(originalName);
if (!mdl.open())
- return false;
+ return nullptr;
- return mdl.ConvertToVMAPModel(output.c_str());
+ std::string output(szWorkDirWmo);
+ output += "/";
+ output += name;
+
+ if (!mdl.ConvertToVMAPModel(output.c_str()))
+ return nullptr;
+
+ stateGuard->Complete();
+ return stateGuard.release();
}
extern std::shared_ptr<CASC::Storage> CascStorage;
@@ -123,9 +134,12 @@ void ExtractGameobjectModels()
std::string_view header(headerRaw.data(), headerRaw.size());
if (header == "REVM")
- result = ExtractSingleWmo(fileName);
+ {
+ ExtractedModelData const* wmo = ExtractSingleWmo(fileName);
+ result = wmo && wmo->HasCollision();
+ }
else if (header == "MD20" || header == "MD21")
- result = ExtractSingleModel(fileName);
+ result = ExtractSingleModel(fileName) != nullptr;
else if (header == "BLP2")
continue; // broken db2 data
else
diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp
index 9b4b629265c..fc4aff04902 100644
--- a/src/tools/vmap4_extractor/model.cpp
+++ b/src/tools/vmap4_extractor/model.cpp
@@ -159,21 +159,7 @@ Vec3D fixCoordSystem(Vec3D const& v)
void Doodad::Extract(ADT::MDDF const& doodadDef, char const* ModelInstName, uint32 mapID, uint32 originalMapId, FILE* pDirfile, std::vector<ADTOutputCache>* dirfileCache)
{
- std::string tempname = Trinity::StringFormat("{}/{}", szWorkDirWmo, ModelInstName);
- FILE* input = fopen(tempname.c_str(), "r+b");
-
- if (!input)
- return;
-
- fseek(input, 8, SEEK_SET); // get the correct no of vertices
- int nVertices;
- int count = fread(&nVertices, sizeof(int), 1, input);
- fclose(input);
-
- if (count != 1 || nVertices == 0)
- return;
-
- // scale factor - divide by 1024. blizzard devs must be on crack, why not just use a float?
+ // scale factor - divide by 1024
float sc = doodadDef.Scale / 1024.0f;
Vec3D position = fixCoords(doodadDef.Position);
@@ -261,17 +247,7 @@ void Doodad::ExtractSet(WMODoodadData const& doodadData, ADT::MODF const& wmo, b
nlen = ModelInstName.length();
}
- std::string tempname = Trinity::StringFormat("{}/{}", szWorkDirWmo, ModelInstName);
- FILE* input = fopen(tempname.c_str(), "r+b");
- if (!input)
- continue;
-
- fseek(input, 8, SEEK_SET); // get the correct no of vertices
- int nVertices;
- int count = fread(&nVertices, sizeof(int), 1, input);
- fclose(input);
-
- if (count != 1 || nVertices == 0)
+ if (!ExtractSingleModel(ModelInstName))
continue;
ASSERT(doodadId < std::numeric_limits<uint16>::max());
diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp
index 3f3e29685f0..92bb2b087a2 100644
--- a/src/tools/vmap4_extractor/vmapexport.cpp
+++ b/src/tools/vmap4_extractor/vmapexport.cpp
@@ -24,7 +24,10 @@
#include "Locales.h"
#include "MapDefines.h"
#include "MapUtils.h"
+#include "Memory.h"
+#include "StringConvert.h"
#include "StringFormat.h"
+#include "ThreadPool.h"
#include "Util.h"
#include "VMapDefinitions.h"
#include "wdtfile.h"
@@ -33,7 +36,6 @@
#include <boost/filesystem/directory.hpp>
#include <boost/filesystem/operations.hpp>
#include <algorithm>
-#include <fstream>
#include <list>
#include <map>
#include <unordered_map>
@@ -62,19 +64,21 @@ struct MapEntry
int16 ParentMapID = 0;
std::string Name;
std::string Directory;
+
+ uint32 ChildDepth = 0;
+ bool IsParent = false;
};
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;
+std::vector<MapEntry> map_ids;
boost::filesystem::path input_path;
bool preciseVectorData = false;
char const* CascProduct = "wow";
char const* CascRegion = "eu";
bool UseRemoteCasc = false;
uint32 DbcLocale = 0;
-std::unordered_map<std::string, WMODoodadData> WmoDoodads;
+uint32 Threads = std::thread::hardware_concurrency();
// Constants
@@ -171,38 +175,51 @@ uint32 GetInstalledLocalesMask()
return 0;
}
-uint32 uniqueObjectIdGenerator = std::numeric_limits<uint32>::max() - 1;
-std::map<std::pair<uint32, uint16>, uint32> uniqueObjectIds;
+static std::atomic<uint32> UniqueObjectIdGenerator = std::numeric_limits<uint32>::max() - 1;
+static std::mutex UniqueObjectIdsMutex;
+static std::map<std::pair<uint32, uint16>, uint32> UniqueObjectIds;
uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId, bool isWmo)
{
// WMO client ids must be preserved, they are used in DB2 files
- uint32 newId = isWmo ? clientId : uniqueObjectIdGenerator--;
- return uniqueObjectIds.emplace(std::make_pair(clientId, clientDoodadId), newId).first->second;
+ uint32 newId = isWmo ? clientId : UniqueObjectIdGenerator--;
+ std::lock_guard lock(UniqueObjectIdsMutex);
+ return UniqueObjectIds.emplace(std::make_pair(clientId, clientDoodadId), newId).first->second;
}
-// Local testing functions
-bool FileExists(char const* file)
+static std::mutex ExtractedModelsMutex;
+std::unordered_map<std::string, ExtractedModelData> ExtractedModels;
+
+std::pair<ExtractedModelData*, bool> BeginModelExtraction(std::string const& outputName)
{
- if (FILE* n = fopen(file, "rb"))
- {
- fclose(n);
- return true;
- }
- return false;
+ std::lock_guard lock(ExtractedModelsMutex);
+ auto [itr, isNew] = ExtractedModels.try_emplace(outputName);
+ return { &itr->second, isNew };
}
-bool ExtractSingleWmo(std::string& fname)
+ExtractedModelData const* ExtractSingleWmo(std::string& fname)
{
// Copy files from archive
std::string originalName = fname;
char* plain_name = GetPlainName(&fname[0]);
NormalizeFileName(plain_name, strlen(plain_name));
- std::string szLocalFile = Trinity::StringFormat("{}/{}", szWorkDirWmo, plain_name);
- if (FileExists(szLocalFile.c_str()))
- return true;
+ auto [model, shouldExtract] = BeginModelExtraction(plain_name);
+ if (!shouldExtract)
+ {
+ model->Wait();
+ switch (model->State.load(std::memory_order::relaxed))
+ {
+ case ExtractedModelData::Ok:
+ case ExtractedModelData::OkNoCollision:
+ return model;
+ default:
+ return nullptr;
+ }
+ }
+
+ auto stateGuard = Trinity::make_unique_ptr_with_deleter<&ExtractedModelData::Fail>(model);
int p = 0;
// Select root wmo files
@@ -213,23 +230,24 @@ bool ExtractSingleWmo(std::string& fname)
p++;
if (p == 3)
- return true;
+ return nullptr;
bool file_ok = true;
WMORoot froot(originalName);
if (!froot.open())
{
printf("Couldn't open RootWmo!!!\n");
- return true;
+ return nullptr;
}
- FILE *output = fopen(szLocalFile.c_str(),"wb");
+ std::string szLocalFile = Trinity::StringFormat("{}/{}", szWorkDirWmo, plain_name);
+ FILE* output = fopen(szLocalFile.c_str(), "wb");
if(!output)
{
printf("couldn't open %s for writing!\n", szLocalFile.c_str());
- return false;
+ return nullptr;
}
froot.ConvertToVMAPRootWmo(output);
- WMODoodadData& doodads = WmoDoodads[plain_name];
+ WMODoodadData& doodads = *(model->Doodads = std::make_unique<WMODoodadData>());
std::swap(doodads, froot.DoodadData);
int Wmo_nVertices = 0;
uint32 groupCount = 0;
@@ -266,7 +284,7 @@ bool ExtractSingleWmo(std::string& fname)
continue;
uint32 doodadNameIndex = doodads.Spawns[groupReference].NameIndex;
- if (froot.ValidDoodadNames.find(doodadNameIndex) == froot.ValidDoodadNames.end())
+ if (!froot.ValidDoodadNames.contains(doodadNameIndex))
continue;
doodads.References.insert(groupReference);
@@ -279,10 +297,18 @@ bool ExtractSingleWmo(std::string& fname)
fwrite(&groupCount, sizeof(uint32), 1, output);
fclose(output);
- // Delete the extracted file in the case of an error
- if (!file_ok)
+ if (!Wmo_nVertices && (doodads.Sets.empty() || doodads.References.empty()))
+ file_ok = false;
+
+ // Delete the extracted file in the case of an error or no collision
+ if (!file_ok || !Wmo_nVertices)
remove(szLocalFile.c_str());
- return true;
+
+ if (!file_ok)
+ return nullptr;
+
+ stateGuard->Complete(Wmo_nVertices ? ExtractedModelData::Ok : ExtractedModelData::OkNoCollision);
+ return stateGuard.release();
}
bool IsLiquidIgnored(uint32 liquidTypeId)
@@ -298,62 +324,75 @@ bool IsLiquidIgnored(uint32 liquidTypeId)
void ParsMapFiles()
{
std::unordered_map<uint32, WDTFile> wdts;
- auto getWDT = [&wdts](uint32 mapId) -> WDTFile*
+ std::map<uint32, std::vector<MapEntry const*>> steps;
+ for (MapEntry const& mapEntry : map_ids)
{
- auto itr = wdts.find(mapId);
- if (itr == wdts.end())
- {
- auto mapEntryItr = std::ranges::find(map_ids, mapId, &MapEntry::Id);
- if (mapEntryItr == map_ids.end())
- return nullptr;
-
- uint32 fileDataId = mapEntryItr->WdtFileDataId;
- if (!fileDataId)
- return nullptr;
+ steps[mapEntry.ChildDepth].push_back(&mapEntry);
- std::string description = Trinity::StringFormat("WDT for map {} - {} (FileDataID {})", mapId, mapEntryItr->Name, fileDataId);
- std::string directory = mapEntryItr->Directory;
- itr = wdts.emplace(std::piecewise_construct, std::forward_as_tuple(mapId), std::forward_as_tuple(fileDataId, description, std::move(directory), maps_that_are_parents.count(mapId) > 0)).first;
- if (!itr->second.init(mapId))
- {
- wdts.erase(itr);
- return nullptr;
- }
- }
-
- return &itr->second;
- };
+ // preload WDTs
+ std::string description = Trinity::StringFormat("WDT for map {} - {} (FileDataID {})", mapEntry.Id, mapEntry.Name, mapEntry.WdtFileDataId);
+ auto itr = wdts.try_emplace(mapEntry.Id, mapEntry.WdtFileDataId, description, mapEntry.Directory, mapEntry.IsParent).first;
+ if (!itr->second.init(mapEntry.Id))
+ wdts.erase(itr);
+ }
- for (MapEntry const& mapEntry : map_ids)
+ for (auto const& [_, maps] : steps)
{
- if (WDTFile* WDT = getWDT(mapEntry.Id))
+ Trinity::ThreadPool threadPool(Threads);
+
+ for (MapEntry const* mapEntry : maps)
{
- WDTFile* parentWDT = mapEntry.ParentMapID >= 0 ? getWDT(mapEntry.ParentMapID) : nullptr;
- printf("Processing Map %u\n[", mapEntry.Id);
- for (int32 x = 0; x < 64; ++x)
+ threadPool.PostWork([mapEntry, &wdts]
{
- for (int32 y = 0; y < 64; ++y)
+ if (WDTFile* WDT = Trinity::Containers::MapGetValuePtr(wdts, mapEntry->Id))
{
- bool success = false;
- if (ADTFile* ADT = WDT->GetMap(x, y))
+ int16 parentMapId = mapEntry->ParentMapID;
+ std::vector<WDTFile*> parentWDTs;
+ while (parentMapId >= 0)
{
- success = ADT->init(mapEntry.Id, mapEntry.Id);
- WDT->FreeADT(ADT);
+ parentWDTs.push_back(Trinity::Containers::MapGetValuePtr(wdts, mapEntry->ParentMapID));
+
+ auto parentMapItr = std::ranges::find(map_ids, uint32(parentMapId), &MapEntry::Id);
+ if (parentMapItr == map_ids.end())
+ break;
+
+ parentMapId = parentMapItr->ParentMapID;
}
- if (!success && parentWDT)
+
+ printf("Processing Map %u\n", mapEntry->Id);
+ for (int32 x = 0; x < 64; ++x)
{
- if (ADTFile* ADT = parentWDT->GetMap(x, y))
+ for (int32 y = 0; y < 64; ++y)
{
- ADT->init(mapEntry.Id, mapEntry.ParentMapID);
- parentWDT->FreeADT(ADT);
+ bool success = false;
+ if (ADTFile* ADT = WDT->GetMap(x, y, true))
+ {
+ success = ADT->init(mapEntry->Id, mapEntry->Id);
+ WDT->FreeADT(ADT);
+ }
+
+ if (!success)
+ {
+ for (WDTFile* parentWDT : parentWDTs)
+ {
+ if (ADTFile* ADT = parentWDT->GetMap(x, y, false))
+ {
+ success = ADT->init(mapEntry->Id, mapEntry->ParentMapID);
+ parentWDT->FreeADT(ADT);
+ }
+
+ if (success)
+ break;
+ }
+ }
}
}
+ printf("Processing Map %u Done\n", mapEntry->Id);
}
- printf("#");
- fflush(stdout);
- }
- printf("]\n");
+ });
}
+
+ threadPool.Join();
}
}
@@ -396,9 +435,6 @@ void ReadMapTable()
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;
}
@@ -413,10 +449,22 @@ void ReadMapTable()
}
}
- 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); });
+ for (MapEntry& map : map_ids)
+ {
+ int16 parentMapId = map.ParentMapID;
+ while (parentMapId >= 0)
+ {
+ ++map.ChildDepth;
+
+ MapEntry& parent = map_ids[idToIndex[parentMapId]];
+ parent.IsParent = true;
+
+ parentMapId = parent.ParentMapID;
+ }
+ }
+
+ std::erase_if(map_ids, [](MapEntry const& map) { return !map.WdtFileDataId; });
printf("Done! (" SZFMTD " maps loaded)\n", map_ids.size());
}
@@ -530,6 +578,13 @@ bool processArgv(int argc, char ** argv, const char *versionString)
else
result = false;
}
+ else if (strcmp("--threads", argv[i]) == 0)
+ {
+ if (i + 1 < argc && strlen(argv[i + 1]))
+ Threads = Trinity::StringTo<uint32>(argv[++i]).value_or(std::thread::hardware_concurrency());
+ else
+ result = false;
+ }
else
{
result = false;
@@ -548,6 +603,7 @@ bool processArgv(int argc, char ** argv, const char *versionString)
printf(" -c use remote casc\n");
printf(" -r set remote casc region - standard: eu\n");
printf(" -dl dbc locale\n");
+ printf(" --threads <N> number of threads to use, default: all cpu cores\n");
printf(" -? : This message.\n");
}
diff --git a/src/tools/vmap4_extractor/vmapexport.h b/src/tools/vmap4_extractor/vmapexport.h
index c6a88518083..99e13814e81 100644
--- a/src/tools/vmap4_extractor/vmapexport.h
+++ b/src/tools/vmap4_extractor/vmapexport.h
@@ -19,6 +19,8 @@
#define VMAPEXPORT_H
#include "Define.h"
+#include <atomic>
+#include <memory>
#include <string>
#include <unordered_map>
@@ -40,14 +42,46 @@ enum class ModelFlags : uint32
struct WMODoodadData;
extern const char * szWorkDirWmo;
-extern std::unordered_map<std::string, WMODoodadData> WmoDoodads;
uint32 GenerateUniqueObjectId(uint32 clientId, uint16 clientDoodadId, bool isWmo);
-bool FileExists(const char * file);
+struct ExtractedModelData
+{
+ enum ExtractionState : uint8
+ {
+ InProgress,
+ Ok,
+ OkNoCollision, // has no data by itself but its WMO doodads do
+ Failed
+ };
+
+ std::atomic<ExtractionState> State;
+ std::unique_ptr<WMODoodadData> Doodads;
+
+ void Wait()
+ {
+ State.wait(InProgress);
+ }
+
+ void Fail()
+ {
+ State.store(Failed);
+ State.notify_all();
+ }
+
+ void Complete(ExtractionState state = Ok)
+ {
+ State.store(state);
+ State.notify_all();
+ }
+
+ bool HasCollision() const { return State.load(std::memory_order::relaxed) == Ok; }
+};
+
+std::pair<ExtractedModelData*, bool> BeginModelExtraction(std::string const& outputName);
-bool ExtractSingleWmo(std::string& fname);
-bool ExtractSingleModel(std::string& fname);
+ExtractedModelData const* ExtractSingleWmo(std::string& fname);
+ExtractedModelData const* ExtractSingleModel(std::string& fname);
void ExtractGameobjectModels();
diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp
index f507d14b1a7..58f26bb7b65 100644
--- a/src/tools/vmap4_extractor/wdtfile.cpp
+++ b/src/tools/vmap4_extractor/wdtfile.cpp
@@ -27,17 +27,9 @@
extern std::shared_ptr<CASC::Storage> CascStorage;
WDTFile::WDTFile(uint32 fileDataId, std::string const& description, std::string mapName, bool cache)
- : _file(CascStorage, fileDataId, description), _mapName(std::move(mapName))
+ : _file(CascStorage, fileDataId, description), _header(), _adtInfo(), _mapName(std::move(mapName)),
+ _adtCache(cache ? std::make_unique<ADTCache>() : nullptr)
{
- memset(&_header, 0, sizeof(WDT::MPHD));
- memset(&_adtInfo, 0, sizeof(WDT::MAIN));
- if (cache)
- {
- _adtCache = std::make_unique<ADTCache>();
- memset(_adtCache->file, 0, sizeof(_adtCache->file));
- }
- else
- _adtCache = nullptr;
}
WDTFile::~WDTFile() = default;
@@ -116,17 +108,21 @@ bool WDTFile::init(uint32 mapId)
{
ADT::MODF mapObjDef;
_file.read(&mapObjDef, sizeof(ADT::MODF));
+
std::string fileName;
if (mapObjDef.Flags & 0x8)
- {
fileName = Trinity::StringFormat("FILE{:08X}.xxx", mapObjDef.Id);
- ExtractSingleWmo(fileName);
- }
else
fileName = _wmoNames[mapObjDef.Id];
- MapObject::Extract(mapObjDef, fileName.c_str(), true, mapId, mapId, dirfile.get(), nullptr);
- Doodad::ExtractSet(WmoDoodads[fileName], mapObjDef, true, mapId, mapId, dirfile.get(), nullptr);
+ if (ExtractedModelData const* extracted = ExtractSingleWmo(fileName))
+ {
+ if (extracted->HasCollision())
+ MapObject::Extract(mapObjDef, fileName.c_str(), true, mapId, mapId, dirfile.get(), nullptr);
+
+ if (extracted->Doodads)
+ Doodad::ExtractSet(*extracted->Doodads, mapObjDef, true, mapId, mapId, dirfile.get(), nullptr);
+ }
}
}
}
@@ -137,7 +133,7 @@ bool WDTFile::init(uint32 mapId)
return true;
}
-ADTFile* WDTFile::GetMap(int32 x, int32 y)
+ADTFile* WDTFile::GetMap(int32 x, int32 y, bool createIfMissing)
{
if (!(x >= 0 && y >= 0 && x < 64 && y < 64))
return nullptr;
@@ -148,6 +144,9 @@ ADTFile* WDTFile::GetMap(int32 x, int32 y)
if (!(_adtInfo.Data[y][x].Flag & 1))
return nullptr;
+ if (!createIfMissing)
+ return nullptr;
+
ADTFile* adt;
std::string name = Trinity::StringFormat(R"(World\Maps\{}\{}_{}_{}_obj0.adt)", _mapName, _mapName, x, y);
if (_header.Flags & 0x200)
diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h
index 47b111fd13e..e8fe5ea193b 100644
--- a/src/tools/vmap4_extractor/wdtfile.h
+++ b/src/tools/vmap4_extractor/wdtfile.h
@@ -74,7 +74,7 @@ public:
~WDTFile();
bool init(uint32 mapId);
- ADTFile* GetMap(int32 x, int32 y);
+ ADTFile* GetMap(int32 x, int32 y, bool createIfMissing);
void FreeADT(ADTFile* adt);
private:
CASCFile _file;
diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp
index 77985aefacf..1f1ecb467d2 100644
--- a/src/tools/vmap4_extractor/wmo.cpp
+++ b/src/tools/vmap4_extractor/wmo.cpp
@@ -589,23 +589,6 @@ void MapObject::Extract(ADT::MODF const& mapObjDef, char const* WmoInstName, boo
{
//-----------add_in _dir_file----------------
- std::string tempname = Trinity::StringFormat("{}/{}", szWorkDirWmo, WmoInstName);
- FILE* input = fopen(tempname.c_str(), "r+b");
-
- if (!input)
- {
- printf("WMOInstance::WMOInstance: couldn't open %s\n", tempname.c_str());
- return;
- }
-
- fseek(input, 8, SEEK_SET); // get the correct no of vertices
- int nVertices;
- int count = fread(&nVertices, sizeof(int), 1, input);
- fclose(input);
-
- if (count != 1 || nVertices == 0)
- return;
-
Vec3D position = fixCoords(mapObjDef.Position);
AaBox3D bounds;
bounds.min = fixCoords(mapObjDef.Bounds.min);