mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-06 09:03:52 +00:00
feat(editor): WMO-only instance loading (Dire Maul, dungeons, raids)
Many WoW instances (Dire Maul, Blackrock Depths, etc.) are WMO-only maps with no ADT terrain tiles. The editor now handles these: - loadWMOInstance(): reads WDT, detects WDTF_GLOBAL_WMO flag, loads the root WMO path from MWMO chunk, places it as an object with correct position/rotation from MODF chunk - Automatic fallback: when loadADT fails to find tiles, tries WMO-only loading before showing error - Load dialog: "Find Tile" detects WMO-only instances and shows "WMO-only instance — click Load to open" instead of "not found" - Camera positioned near the WMO for immediate editing - Blank terrain floor generated as ground reference
This commit is contained in:
parent
072d0f78c2
commit
d773109b50
3 changed files with 71 additions and 1 deletions
|
|
@ -15,6 +15,7 @@
|
|||
#include <nlohmann/json.hpp>
|
||||
#include "rendering/vk_context.hpp"
|
||||
#include "pipeline/adt_loader.hpp"
|
||||
#include "pipeline/wdt_loader.hpp"
|
||||
#include "pipeline/terrain_mesh.hpp"
|
||||
#include "core/logger.hpp"
|
||||
#include <imgui.h>
|
||||
|
|
@ -663,6 +664,65 @@ void EditorApp::refreshDirtyChunks() {
|
|||
viewport_.loadTerrain(mesh, terrain_.textures, loadedTileX_, loadedTileY_);
|
||||
}
|
||||
|
||||
bool EditorApp::loadWMOInstance(const std::string& mapName) {
|
||||
std::string mapLower = mapName;
|
||||
std::transform(mapLower.begin(), mapLower.end(), mapLower.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
|
||||
std::string wdtPath = "world\\maps\\" + mapLower + "\\" + mapLower + ".wdt";
|
||||
auto wdtData = assetManager_->readFile(wdtPath);
|
||||
if (wdtData.empty()) return false;
|
||||
|
||||
auto wdtInfo = pipeline::parseWDT(wdtData);
|
||||
if (!wdtInfo.isWMOOnly() || wdtInfo.rootWMOPath.empty()) return false;
|
||||
|
||||
LOG_INFO("WMO-only instance: ", mapName, " root=", wdtInfo.rootWMOPath);
|
||||
|
||||
clearAllObjects();
|
||||
questEditor_.clear();
|
||||
ui_.clearPath();
|
||||
viewport_.clearTerrain();
|
||||
|
||||
// Create blank terrain as a floor reference
|
||||
terrain_ = TerrainEditor::createBlankTerrain(32, 32, 0.0f, Biome::Rocky);
|
||||
terrain_.coord = {32, 32};
|
||||
terrainEditor_.setTerrain(&terrain_);
|
||||
texturePainter_.setTerrain(&terrain_);
|
||||
objectPlacer_.setTerrain(&terrain_);
|
||||
|
||||
auto mesh = pipeline::TerrainMeshGenerator::generate(terrain_);
|
||||
viewport_.loadTerrain(mesh, terrain_.textures, 32, 32);
|
||||
|
||||
// Place the root WMO as an object
|
||||
glm::vec3 wmoPos = core::coords::adtToWorld(
|
||||
wdtInfo.position[0], wdtInfo.position[1], wdtInfo.position[2]);
|
||||
glm::vec3 wmoRot(-wdtInfo.rotation[2], -wdtInfo.rotation[0],
|
||||
wdtInfo.rotation[1] + 180.0f);
|
||||
|
||||
PlacedObject wmo;
|
||||
wmo.type = PlaceableType::WMO;
|
||||
wmo.path = wdtInfo.rootWMOPath;
|
||||
wmo.position = wmoPos;
|
||||
wmo.rotation = wmoRot;
|
||||
wmo.scale = 1.0f;
|
||||
wmo.uniqueId = 1;
|
||||
objectPlacer_.getObjects().push_back(wmo);
|
||||
objectsDirty_ = true;
|
||||
|
||||
loadedMap_ = mapName;
|
||||
loadedTileX_ = 32;
|
||||
loadedTileY_ = 32;
|
||||
|
||||
// Position camera near the WMO
|
||||
camera_.setPosition(wmoPos + glm::vec3(0, 0, 50));
|
||||
camera_.setYawPitch(0.0f, -30.0f);
|
||||
|
||||
showToast("WMO instance loaded: " + mapName);
|
||||
LOG_INFO("WMO instance loaded: ", mapName, " at (",
|
||||
wmoPos.x, ",", wmoPos.y, ",", wmoPos.z, ")");
|
||||
return true;
|
||||
}
|
||||
|
||||
void EditorApp::loadADT(const std::string& mapName, int tileX, int tileY) {
|
||||
// Clear previous state before loading new tile
|
||||
clearAllObjects();
|
||||
|
|
@ -690,6 +750,8 @@ void EditorApp::loadADT(const std::string& mapName, int tileX, int tileY) {
|
|||
|
||||
auto adtData = assetManager_->readFile(path.str());
|
||||
if (adtData.empty()) {
|
||||
// Try WMO-only instance (dungeons like Dire Maul have no ADT tiles)
|
||||
if (loadWMOInstance(mapName)) return;
|
||||
LOG_ERROR("ADT file not found: ", path.str());
|
||||
showToast("Zone not found: " + mapName + " [" + std::to_string(tileX) + "," + std::to_string(tileY) + "]");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ public:
|
|||
void shutdown();
|
||||
|
||||
void loadADT(const std::string& mapName, int tileX, int tileY);
|
||||
bool loadWMOInstance(const std::string& mapName);
|
||||
void createNewTerrain(const std::string& mapName, int tileX, int tileY, float baseHeight, Biome biome);
|
||||
void saveADT(const std::string& path);
|
||||
void saveWDT(const std::string& path);
|
||||
|
|
|
|||
|
|
@ -799,7 +799,14 @@ void EditorUI::renderLoadDialog(EditorApp& app) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!found) app.showToast("No ADT tiles found for this map");
|
||||
if (!found) {
|
||||
// Check if it's a WMO-only instance
|
||||
std::string wdtPath = "world\\maps\\" + mapLower + "\\" + mapLower + ".wdt";
|
||||
if (app.getAssetManager()->getManifest().hasEntry(wdtPath))
|
||||
app.showToast("WMO-only instance — click Load to open");
|
||||
else
|
||||
app.showToast("No ADT tiles found for this map");
|
||||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered()) ImGui::SetTooltip("Auto-find first available tile");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue