diff --git a/CMakeLists.txt b/CMakeLists.txt index 7195ee02..60fe8ac8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1300,6 +1300,7 @@ add_executable(wowee_editor tools/editor/wowee_terrain.cpp tools/editor/editor_project.cpp tools/editor/texture_exporter.cpp + tools/editor/dbc_exporter.cpp tools/editor/asset_browser.cpp tools/editor/editor_water.cpp tools/editor/editor_markers.cpp diff --git a/tools/editor/dbc_exporter.cpp b/tools/editor/dbc_exporter.cpp new file mode 100644 index 00000000..795e311f --- /dev/null +++ b/tools/editor/dbc_exporter.cpp @@ -0,0 +1,99 @@ +#include "dbc_exporter.hpp" +#include "pipeline/asset_manager.hpp" +#include "core/logger.hpp" +#include +#include + +namespace wowee { +namespace editor { + +bool DBCExporter::exportAsJson(pipeline::AssetManager* am, + const std::string& dbcName, + const std::string& outputPath) { + auto dbc = am->loadDBC(dbcName); + if (!dbc || !dbc->isLoaded()) return false; + + namespace fs = std::filesystem; + fs::create_directories(fs::path(outputPath).parent_path()); + + std::ofstream f(outputPath); + if (!f) return false; + + f << "{\n"; + f << " \"format\": \"wowee-dbc-json-1.0\",\n"; + f << " \"source\": \"" << dbcName << "\",\n"; + f << " \"recordCount\": " << dbc->getRecordCount() << ",\n"; + f << " \"fieldCount\": " << dbc->getFieldCount() << ",\n"; + f << " \"records\": [\n"; + + for (uint32_t i = 0; i < dbc->getRecordCount(); i++) { + f << " ["; + for (uint32_t j = 0; j < dbc->getFieldCount(); j++) { + // Try to detect string fields vs numeric + uint32_t val = dbc->getUInt32(i, j); + // Check if it looks like a string offset (points into string block) + std::string strVal = dbc->getString(i, j); + if (!strVal.empty() && strVal[0] != '\0' && strVal.size() < 200) { + // Escape quotes in string + std::string escaped; + for (char c : strVal) { + if (c == '"') escaped += "\\\""; + else if (c == '\\') escaped += "\\\\"; + else if (c == '\n') escaped += "\\n"; + else escaped += c; + } + f << "\"" << escaped << "\""; + } else { + // Check if it's a float + float fval = dbc->getFloat(i, j); + if (val != 0 && fval != 0.0f && fval > -1e10f && fval < 1e10f && + static_cast(fval) != val) { + f << fval; + } else { + f << val; + } + } + if (j + 1 < dbc->getFieldCount()) f << ", "; + } + f << "]" << (i + 1 < dbc->getRecordCount() ? "," : "") << "\n"; + } + + f << " ]\n}\n"; + + LOG_INFO("DBC exported as JSON: ", dbcName, " → ", outputPath, + " (", dbc->getRecordCount(), " records)"); + return true; +} + +int DBCExporter::exportZoneDBCs(pipeline::AssetManager* am, + const std::string& outputDir) { + // Zone-relevant DBCs for custom content + const char* zoneDBCs[] = { + "AreaTable.dbc", + "Map.dbc", + "Light.dbc", + "LightParams.dbc", + "ZoneMusic.dbc", + "SoundAmbience.dbc", + "GroundEffectTexture.dbc", + "GroundEffectDoodad.dbc", + "LiquidType.dbc" + }; + + int exported = 0; + for (const char* name : zoneDBCs) { + std::string baseName(name); + auto dot = baseName.rfind('.'); + if (dot != std::string::npos) baseName = baseName.substr(0, dot); + + std::string outPath = outputDir + "/" + baseName + ".json"; + if (exportAsJson(am, name, outPath)) + exported++; + } + + LOG_INFO("Exported ", exported, " zone-relevant DBCs as JSON to ", outputDir); + return exported; +} + +} // namespace editor +} // namespace wowee diff --git a/tools/editor/dbc_exporter.hpp b/tools/editor/dbc_exporter.hpp new file mode 100644 index 00000000..d917b83c --- /dev/null +++ b/tools/editor/dbc_exporter.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "pipeline/dbc_loader.hpp" +#include +#include + +namespace wowee { +namespace pipeline { class AssetManager; } + +namespace editor { + +class DBCExporter { +public: + // Export a DBC file as JSON with field names from layout + static bool exportAsJson(pipeline::AssetManager* am, + const std::string& dbcName, + const std::string& outputPath); + + // Export all zone-relevant DBCs to JSON + static int exportZoneDBCs(pipeline::AssetManager* am, + const std::string& outputDir); +}; + +} // namespace editor +} // namespace wowee diff --git a/tools/editor/editor_app.cpp b/tools/editor/editor_app.cpp index d8e70df4..38575d8d 100644 --- a/tools/editor/editor_app.cpp +++ b/tools/editor/editor_app.cpp @@ -4,6 +4,7 @@ #include "content_pack.hpp" #include "wowee_terrain.hpp" #include "texture_exporter.hpp" +#include "dbc_exporter.hpp" #include "core/coordinates.hpp" #include "rendering/vk_context.hpp" #include "pipeline/adt_loader.hpp" @@ -740,6 +741,9 @@ void EditorApp::exportZone(const std::string& outputDir) { LOG_INFO("Exported ", exported, " textures as PNG"); } + // Export zone-relevant DBCs as JSON (open format replacement for DBC) + DBCExporter::exportZoneDBCs(assetManager_.get(), base + "/data"); + // Export open terrain format alongside ADT std::string openBase = base + "/" + loadedMap_ + "_" + std::to_string(loadedTileX_) + "_" + std::to_string(loadedTileY_);