mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-09 02:23:52 +00:00
feat(editor): zone metadata panel with mapId, displayName, gameplay flags
- Map ID: configurable integer input (0-65535) for private server integration. Custom zones default to 9000+ to avoid Blizzard conflicts - Display Name: editable text field for in-game world map/loading screen - Description: multi-line text field for zone documentation - Zone Flags: Allow Flying, PvP Enabled, Indoor, Sanctuary checkboxes - All fields serialized to zone.json under "flags" key - Info panel shows quest count alongside objects/NPCs
This commit is contained in:
parent
2136727c68
commit
9db5cced2c
3 changed files with 57 additions and 2 deletions
|
|
@ -2402,9 +2402,41 @@ void EditorUI::renderPropertiesPanel(EditorApp& app) {
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::Text("[%d, %d]", app.getLoadedTileX(), app.getLoadedTileY());
|
ImGui::Text("[%d, %d]", app.getLoadedTileX(), app.getLoadedTileY());
|
||||||
ImGui::Text("Chunks: %d Tris: %d", tr->getChunkCount(), tr->getTriangleCount());
|
ImGui::Text("Chunks: %d Tris: %d", tr->getChunkCount(), tr->getTriangleCount());
|
||||||
ImGui::Text("Objects: %zu NPCs: %zu",
|
ImGui::Text("Objects: %zu NPCs: %zu Q: %zu",
|
||||||
app.getObjectPlacer().objectCount(),
|
app.getObjectPlacer().objectCount(),
|
||||||
app.getNpcSpawner().spawnCount());
|
app.getNpcSpawner().spawnCount(),
|
||||||
|
app.getQuestEditor().questCount());
|
||||||
|
|
||||||
|
// Zone metadata (mapId, displayName, flags)
|
||||||
|
if (ImGui::CollapsingHeader("Zone Metadata")) {
|
||||||
|
auto& m = app.getZoneManifest();
|
||||||
|
int mid = static_cast<int>(m.mapId);
|
||||||
|
if (ImGui::InputInt("Map ID", &mid))
|
||||||
|
m.mapId = static_cast<uint32_t>(std::clamp(mid, 0, 65535));
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip("Custom zones: 9000-12000. Must be unique per server.");
|
||||||
|
|
||||||
|
char dispBuf[128] = {};
|
||||||
|
std::strncpy(dispBuf, m.displayName.c_str(), sizeof(dispBuf) - 1);
|
||||||
|
if (ImGui::InputText("Display Name", dispBuf, sizeof(dispBuf)))
|
||||||
|
m.displayName = dispBuf;
|
||||||
|
if (ImGui::IsItemHovered())
|
||||||
|
ImGui::SetTooltip("Name shown in-game on the world map and loading screen");
|
||||||
|
|
||||||
|
char descBuf[256] = {};
|
||||||
|
std::strncpy(descBuf, m.description.c_str(), sizeof(descBuf) - 1);
|
||||||
|
if (ImGui::InputTextMultiline("Description##zone", descBuf, sizeof(descBuf), ImVec2(-1, 40)))
|
||||||
|
m.description = descBuf;
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Zone Flags:");
|
||||||
|
ImGui::Checkbox("Allow Flying", &m.allowFlying);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("PvP", &m.pvpEnabled);
|
||||||
|
ImGui::Checkbox("Indoor", &m.isIndoor);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Sanctuary", &m.isSanctuary);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), "No terrain loaded");
|
ImGui::TextColored(ImVec4(0.6f, 0.6f, 0.6f, 1.0f), "No terrain loaded");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,14 @@ bool ZoneManifest::save(const std::string& path) const {
|
||||||
if (hasCreatures) files["creatures"] = "creatures.json";
|
if (hasCreatures) files["creatures"] = "creatures.json";
|
||||||
j["files"] = files;
|
j["files"] = files;
|
||||||
|
|
||||||
|
// Zone gameplay flags
|
||||||
|
nlohmann::json flags;
|
||||||
|
flags["allowFlying"] = allowFlying;
|
||||||
|
flags["pvpEnabled"] = pvpEnabled;
|
||||||
|
flags["isIndoor"] = isIndoor;
|
||||||
|
flags["isSanctuary"] = isSanctuary;
|
||||||
|
j["flags"] = flags;
|
||||||
|
|
||||||
// Audio configuration
|
// Audio configuration
|
||||||
if (!musicTrack.empty() || !ambienceDay.empty()) {
|
if (!musicTrack.empty() || !ambienceDay.empty()) {
|
||||||
nlohmann::json audio;
|
nlohmann::json audio;
|
||||||
|
|
@ -87,6 +95,15 @@ bool ZoneManifest::load(const std::string& path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zone gameplay flags
|
||||||
|
if (j.contains("flags")) {
|
||||||
|
const auto& fl = j["flags"];
|
||||||
|
allowFlying = fl.value("allowFlying", false);
|
||||||
|
pvpEnabled = fl.value("pvpEnabled", false);
|
||||||
|
isIndoor = fl.value("isIndoor", false);
|
||||||
|
isSanctuary = fl.value("isSanctuary", false);
|
||||||
|
}
|
||||||
|
|
||||||
// Audio configuration
|
// Audio configuration
|
||||||
if (j.contains("audio")) {
|
if (j.contains("audio")) {
|
||||||
const auto& a = j["audio"];
|
const auto& a = j["audio"];
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@ struct ZoneManifest {
|
||||||
bool hasCreatures = false;
|
bool hasCreatures = false;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
|
||||||
|
// Zone gameplay flags
|
||||||
|
bool allowFlying = false;
|
||||||
|
bool pvpEnabled = false;
|
||||||
|
bool isIndoor = false;
|
||||||
|
bool isSanctuary = false;
|
||||||
|
|
||||||
// Audio configuration
|
// Audio configuration
|
||||||
std::string musicTrack; // Background music file path
|
std::string musicTrack; // Background music file path
|
||||||
std::string ambienceDay; // Daytime ambient sound
|
std::string ambienceDay; // Daytime ambient sound
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue