mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-07 09:33:51 +00:00
feat(editor): add --add-tile to extend a zone with another ADT tile
--scaffold-zone creates a zone with one tile; some zones (continent fragments, large dungeons) span multiple ADT tiles. This extends an existing zone: wowee_editor --add-tile custom_zones/MyZone 29 30 # default baseHeight=100 wowee_editor --add-tile custom_zones/MyZone 28 31 250.5 # custom baseHeight What it does: - Generates a fresh blank-flat WHM/WOT pair via the same factory --scaffold-zone uses, so output is consistent. - Appends (tx, ty) to ZoneManifest::tiles. Save() rebuilds the files-block from tiles, so the new adt_TX_TY entry appears automatically in zone.json. Safety: - Tile coord must be in WoW grid [0, 64) per axis; rejects 99,99. - Refuses if the tile is already in the manifest (catches typos). - Refuses if the .whm/.wot files exist on disk but aren't in the manifest (catches manifest-out-of-sync drift from hand edits). - Optional baseHeight allows seeding flat terrain at a non-default elevation. Verified end-to-end: scaffolded 1-tile zone, added 2 more tiles (one with custom height). Result: 3 tiles in manifest, 6 files on disk, files-block has all 3 adt_TX_TY entries. Duplicate and out-of-range cases both rejected with exit 1.
This commit is contained in:
parent
b04a3ede99
commit
9c46d3aeeb
1 changed files with 86 additions and 1 deletions
|
|
@ -409,6 +409,8 @@ static void printUsage(const char* argv0) {
|
|||
std::printf(" Convert a wowee JSON DBC back to binary DBC for private-server compat\n");
|
||||
std::printf(" --list-zones [--json] List discovered custom zones and exit\n");
|
||||
std::printf(" --scaffold-zone <name> [tx ty] Create a blank zone in custom_zones/<name>/ and exit\n");
|
||||
std::printf(" --add-tile <zoneDir> <tx> <ty> [baseHeight]\n");
|
||||
std::printf(" Add a new ADT tile to an existing zone (extends the manifest's tiles list)\n");
|
||||
std::printf(" --add-creature <zoneDir> <name> <x> <y> <z> [displayId] [level]\n");
|
||||
std::printf(" Append one creature spawn to <zoneDir>/creatures.json and exit\n");
|
||||
std::printf(" --add-object <zoneDir> <m2|wmo> <gamePath> <x> <y> <z> [scale]\n");
|
||||
|
|
@ -522,7 +524,8 @@ int main(int argc, char* argv[]) {
|
|||
"--unpack-wcp", "--pack-wcp",
|
||||
"--validate", "--validate-wom", "--validate-wob", "--validate-woc",
|
||||
"--validate-whm", "--validate-all", "--zone-summary",
|
||||
"--scaffold-zone", "--add-creature", "--add-object", "--add-quest",
|
||||
"--scaffold-zone", "--add-tile",
|
||||
"--add-creature", "--add-object", "--add-quest",
|
||||
"--add-quest-objective", "--add-quest-reward-item", "--set-quest-reward",
|
||||
"--remove-creature", "--remove-object", "--remove-quest",
|
||||
"--copy-zone", "--rename-zone",
|
||||
|
|
@ -583,6 +586,11 @@ int main(int argc, char* argv[]) {
|
|||
"--set-quest-reward requires <zoneDir> <questIdx> [--xp N] [--gold N] [--silver N] [--copper N]\n");
|
||||
return 1;
|
||||
}
|
||||
if (std::strcmp(argv[i], "--add-tile") == 0 && i + 3 >= argc) {
|
||||
std::fprintf(stderr,
|
||||
"--add-tile requires <zoneDir> <tx> <ty>\n");
|
||||
return 1;
|
||||
}
|
||||
if (std::strcmp(argv[i], "--copy-zone") == 0 && i + 2 >= argc) {
|
||||
std::fprintf(stderr,
|
||||
"--copy-zone requires <srcDir> <newName>\n");
|
||||
|
|
@ -3622,6 +3630,83 @@ int main(int argc, char* argv[]) {
|
|||
slug.c_str(), slug.c_str());
|
||||
std::printf(" next step: run editor without args, then File → Open Zone\n");
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--add-tile") == 0 && i + 3 < argc) {
|
||||
// Extend an existing zone with another ADT tile. Zones can
|
||||
// span multiple tiles (e.g. a continent fragment), but
|
||||
// --scaffold-zone only creates one. This adds another:
|
||||
// wowee_editor --add-tile custom_zones/MyZone 29 30
|
||||
// Generates a fresh blank-flat WHM/WOT pair at the new tile
|
||||
// and appends to the zone manifest's tiles list.
|
||||
std::string zoneDir = argv[++i];
|
||||
int tx, ty;
|
||||
try {
|
||||
tx = std::stoi(argv[++i]);
|
||||
ty = std::stoi(argv[++i]);
|
||||
} catch (...) {
|
||||
std::fprintf(stderr, "add-tile: bad coordinates\n");
|
||||
return 1;
|
||||
}
|
||||
float baseHeight = 100.0f;
|
||||
if (i + 1 < argc && argv[i + 1][0] != '-') {
|
||||
try { baseHeight = std::stof(argv[++i]); }
|
||||
catch (...) {}
|
||||
}
|
||||
if (tx < 0 || tx >= 64 || ty < 0 || ty >= 64) {
|
||||
std::fprintf(stderr, "add-tile: tile coord (%d, %d) out of WoW grid [0, 64)\n",
|
||||
tx, ty);
|
||||
return 1;
|
||||
}
|
||||
namespace fs = std::filesystem;
|
||||
std::string manifestPath = zoneDir + "/zone.json";
|
||||
if (!fs::exists(manifestPath)) {
|
||||
std::fprintf(stderr, "add-tile: %s has no zone.json — not a zone dir\n",
|
||||
zoneDir.c_str());
|
||||
return 1;
|
||||
}
|
||||
wowee::editor::ZoneManifest zm;
|
||||
if (!zm.load(manifestPath)) {
|
||||
std::fprintf(stderr, "add-tile: failed to parse %s\n", manifestPath.c_str());
|
||||
return 1;
|
||||
}
|
||||
// Reject duplicates so we don't silently overwrite an existing
|
||||
// tile's heightmap when the user makes a typo.
|
||||
for (const auto& [ex, ey] : zm.tiles) {
|
||||
if (ex == tx && ey == ty) {
|
||||
std::fprintf(stderr,
|
||||
"add-tile: tile (%d, %d) already in manifest\n", tx, ty);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Also bail if the file would clobber an existing one outside
|
||||
// the manifest (e.g. user hand-created tiles without updating
|
||||
// zone.json). Catches drift between disk and manifest.
|
||||
std::string base = zoneDir + "/" + zm.mapName + "_" +
|
||||
std::to_string(tx) + "_" + std::to_string(ty);
|
||||
if (fs::exists(base + ".whm") || fs::exists(base + ".wot")) {
|
||||
std::fprintf(stderr,
|
||||
"add-tile: %s.{whm,wot} already exists on disk (manifest out of sync?)\n",
|
||||
base.c_str());
|
||||
return 1;
|
||||
}
|
||||
// Generate the new heightmap. Reuses the same factory that
|
||||
// --scaffold-zone uses, so the output is consistent.
|
||||
auto terrain = wowee::editor::TerrainEditor::createBlankTerrain(
|
||||
tx, ty, baseHeight, wowee::editor::Biome::Grassland);
|
||||
wowee::editor::WoweeTerrain::exportOpen(terrain, base, tx, ty);
|
||||
// Append + save manifest. ZoneManifest::save rebuilds the
|
||||
// files block from the tiles list, so the new adt_tx_ty entry
|
||||
// appears automatically in zone.json.
|
||||
zm.tiles.push_back({tx, ty});
|
||||
if (!zm.save(manifestPath)) {
|
||||
std::fprintf(stderr, "add-tile: failed to save %s\n", manifestPath.c_str());
|
||||
return 1;
|
||||
}
|
||||
std::printf("Added tile (%d, %d) to %s\n", tx, ty, zoneDir.c_str());
|
||||
std::printf(" files : %s.whm, %s.wot\n",
|
||||
(zm.mapName + "_" + std::to_string(tx) + "_" + std::to_string(ty)).c_str(),
|
||||
(zm.mapName + "_" + std::to_string(tx) + "_" + std::to_string(ty)).c_str());
|
||||
std::printf(" tiles now : %zu total\n", zm.tiles.size());
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--copy-zone") == 0 && i + 2 < argc) {
|
||||
// Duplicate a zone — copy every file then rename slug-prefixed
|
||||
// ones (heightmap/terrain/collision sidecars carry the slug in
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue