mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-06 09:03:52 +00:00
feat(editor): project system for multi-zone custom expansions
- EditorProject: manages multiple zones in a single project file (wowee-project-1.0 JSON format) - Project stores: name, author, description, version, zone list - Each zone has: mapName, tileX/Y, biome, description - Save/load project files (.json) with full round-trip - Foundation for creating custom expansions with multiple maps, quest chains spanning zones, and campaign progression - getZoneOutputDir() resolves per-zone output paths
This commit is contained in:
parent
c28d3f8a99
commit
1d2f25f169
3 changed files with 142 additions and 0 deletions
|
|
@ -1296,6 +1296,7 @@ add_executable(wowee_editor
|
||||||
tools/editor/zone_manifest.cpp
|
tools/editor/zone_manifest.cpp
|
||||||
tools/editor/content_pack.cpp
|
tools/editor/content_pack.cpp
|
||||||
tools/editor/wowee_terrain.cpp
|
tools/editor/wowee_terrain.cpp
|
||||||
|
tools/editor/editor_project.cpp
|
||||||
tools/editor/asset_browser.cpp
|
tools/editor/asset_browser.cpp
|
||||||
tools/editor/editor_water.cpp
|
tools/editor/editor_water.cpp
|
||||||
tools/editor/editor_markers.cpp
|
tools/editor/editor_markers.cpp
|
||||||
|
|
|
||||||
109
tools/editor/editor_project.cpp
Normal file
109
tools/editor/editor_project.cpp
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
#include "editor_project.hpp"
|
||||||
|
#include "core/logger.hpp"
|
||||||
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace wowee {
|
||||||
|
namespace editor {
|
||||||
|
|
||||||
|
bool EditorProject::save(const std::string& path) const {
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
fs::create_directories(fs::path(path).parent_path());
|
||||||
|
|
||||||
|
std::ofstream f(path);
|
||||||
|
if (!f) return false;
|
||||||
|
|
||||||
|
f << "{\n";
|
||||||
|
f << " \"format\": \"wowee-project-1.0\",\n";
|
||||||
|
f << " \"name\": \"" << name << "\",\n";
|
||||||
|
f << " \"author\": \"" << author << "\",\n";
|
||||||
|
f << " \"description\": \"" << description << "\",\n";
|
||||||
|
f << " \"version\": \"" << version << "\",\n";
|
||||||
|
f << " \"startMapId\": " << startMapId << ",\n";
|
||||||
|
f << " \"zones\": [\n";
|
||||||
|
for (size_t i = 0; i < zones.size(); i++) {
|
||||||
|
const auto& z = zones[i];
|
||||||
|
f << " {\"mapName\": \"" << z.mapName << "\""
|
||||||
|
<< ", \"tileX\": " << z.tileX
|
||||||
|
<< ", \"tileY\": " << z.tileY
|
||||||
|
<< ", \"biome\": \"" << z.biome << "\""
|
||||||
|
<< ", \"description\": \"" << z.description << "\""
|
||||||
|
<< "}" << (i + 1 < zones.size() ? "," : "") << "\n";
|
||||||
|
}
|
||||||
|
f << " ]\n";
|
||||||
|
f << "}\n";
|
||||||
|
|
||||||
|
LOG_INFO("Project saved: ", path, " (", zones.size(), " zones)");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EditorProject::load(const std::string& path) {
|
||||||
|
std::ifstream f(path);
|
||||||
|
if (!f) return false;
|
||||||
|
std::string content((std::istreambuf_iterator<char>(f)),
|
||||||
|
std::istreambuf_iterator<char>());
|
||||||
|
|
||||||
|
auto findStr = [&](const std::string& key) -> std::string {
|
||||||
|
auto pos = content.find("\"" + key + "\"");
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
pos = content.find('"', content.find(':', pos) + 1);
|
||||||
|
if (pos == std::string::npos) return "";
|
||||||
|
auto end = content.find('"', pos + 1);
|
||||||
|
return content.substr(pos + 1, end - pos - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
name = findStr("name");
|
||||||
|
author = findStr("author");
|
||||||
|
description = findStr("description");
|
||||||
|
version = findStr("version");
|
||||||
|
projectDir = std::filesystem::path(path).parent_path().string();
|
||||||
|
|
||||||
|
// Parse zones from JSON array
|
||||||
|
zones.clear();
|
||||||
|
size_t zonesPos = content.find("\"zones\"");
|
||||||
|
if (zonesPos != std::string::npos) {
|
||||||
|
size_t start = zonesPos;
|
||||||
|
while ((start = content.find('{', start + 1)) != std::string::npos) {
|
||||||
|
auto end = content.find('}', start);
|
||||||
|
if (end == std::string::npos) break;
|
||||||
|
// Check we're still inside the zones array
|
||||||
|
auto closeBracket = content.find(']', zonesPos);
|
||||||
|
if (start > closeBracket) break;
|
||||||
|
|
||||||
|
std::string block = content.substr(start, end - start + 1);
|
||||||
|
ProjectZone z;
|
||||||
|
|
||||||
|
auto blockFindStr = [&](const std::string& key) -> std::string {
|
||||||
|
auto p = block.find("\"" + key + "\"");
|
||||||
|
if (p == std::string::npos) return "";
|
||||||
|
p = block.find('"', block.find(':', p) + 1);
|
||||||
|
if (p == std::string::npos) return "";
|
||||||
|
auto e = block.find('"', p + 1);
|
||||||
|
return block.substr(p + 1, e - p - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
z.mapName = blockFindStr("mapName");
|
||||||
|
z.biome = blockFindStr("biome");
|
||||||
|
z.description = blockFindStr("description");
|
||||||
|
|
||||||
|
auto txPos = block.find("\"tileX\":");
|
||||||
|
if (txPos != std::string::npos) z.tileX = std::stoi(block.substr(txPos + 8));
|
||||||
|
auto tyPos = block.find("\"tileY\":");
|
||||||
|
if (tyPos != std::string::npos) z.tileY = std::stoi(block.substr(tyPos + 8));
|
||||||
|
|
||||||
|
if (!z.mapName.empty()) zones.push_back(z);
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO("Project loaded: ", path, " (", name, ", ", zones.size(), " zones)");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EditorProject::getZoneOutputDir(int zoneIdx) const {
|
||||||
|
if (zoneIdx < 0 || zoneIdx >= static_cast<int>(zones.size())) return "";
|
||||||
|
return projectDir + "/" + zones[zoneIdx].mapName;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace editor
|
||||||
|
} // namespace wowee
|
||||||
32
tools/editor/editor_project.hpp
Normal file
32
tools/editor/editor_project.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace wowee {
|
||||||
|
namespace editor {
|
||||||
|
|
||||||
|
struct ProjectZone {
|
||||||
|
std::string mapName;
|
||||||
|
int tileX = 32, tileY = 32;
|
||||||
|
std::string biome;
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EditorProject {
|
||||||
|
std::string name = "Untitled";
|
||||||
|
std::string author;
|
||||||
|
std::string description;
|
||||||
|
std::string version = "1.0";
|
||||||
|
std::string projectDir;
|
||||||
|
uint32_t startMapId = 9000;
|
||||||
|
std::vector<ProjectZone> zones;
|
||||||
|
|
||||||
|
bool save(const std::string& path) const;
|
||||||
|
bool load(const std::string& path);
|
||||||
|
std::string getZoneOutputDir(int zoneIdx) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace editor
|
||||||
|
} // namespace wowee
|
||||||
Loading…
Add table
Add a link
Reference in a new issue