mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-08 10:03:51 +00:00
feat(editor): add --gen-random-zone end-to-end one-shot generator
Composes scaffold-zone + random-populate-zone + random-populate-
items into a single invocation. Useful for "I just want a complete
test zone, don't make me chain three commands" — common case for
playtest fixtures and CI scenario setup.
Args:
<name> required (becomes the slug)
[tx ty] optional (default 32 32)
--seed N default 42 (items use seed+1 so they don't
correlate with creature/object placements)
--creatures N default 20
--objects N default 10
--items N default 25
Each sub-step's output streams through. If any step fails the
generator stops and reports which one. Slug-cleans the name to
match scaffold-zone's expectations.
Verified: TestZone with 5/3/8 counts produces a complete zone dir
containing creatures.json, items.json, objects.json, the .whm/.wot
tile pair, and zone.json.
This commit is contained in:
parent
998ee7ce04
commit
fba11943e3
1 changed files with 106 additions and 0 deletions
|
|
@ -573,6 +573,8 @@ static void printUsage(const char* argv0) {
|
|||
std::printf(" Add random creatures/objects to a zone (seeded for reproducibility)\n");
|
||||
std::printf(" --random-populate-items <zoneDir> [--seed N] [--count N] [--max-quality Q]\n");
|
||||
std::printf(" Generate random items.json entries (seeded; quality cap defaults to epic=4)\n");
|
||||
std::printf(" --gen-random-zone <name> [tx ty] [--seed N] [--creatures N] [--objects N] [--items N]\n");
|
||||
std::printf(" End-to-end: scaffold-zone + random-populate-zone + random-populate-items\n");
|
||||
std::printf(" --info-zone-audio <zoneDir> [--json]\n");
|
||||
std::printf(" Print zone audio config (music + ambience tracks, volumes)\n");
|
||||
std::printf(" --info-project-audio <projectDir> [--json]\n");
|
||||
|
|
@ -1037,6 +1039,7 @@ int main(int argc, char* argv[]) {
|
|||
"--info-zone-audio", "--snap-zone-to-ground", "--audit-zone-spawns",
|
||||
"--info-project-audio", "--snap-project-to-ground",
|
||||
"--audit-project-spawns", "--list-zone-spawns",
|
||||
"--gen-random-zone",
|
||||
"--list-items", "--info-item", "--set-item", "--export-zone-items-md",
|
||||
"--export-project-items-md", "--export-project-items-csv",
|
||||
"--add-quest-objective", "--add-quest-reward-item", "--set-quest-reward",
|
||||
|
|
@ -13426,6 +13429,109 @@ int main(int argc, char* argv[]) {
|
|||
std::printf(" total items : %zu\n", doc["items"].size());
|
||||
std::printf(" max quality : %d\n", maxQuality);
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--gen-random-zone") == 0 && i + 1 < argc) {
|
||||
// End-to-end random zone generator. Composes scaffold-zone
|
||||
// + random-populate-zone + random-populate-items in one
|
||||
// invocation. Useful for "I just want a complete test
|
||||
// zone, don't make me chain three commands."
|
||||
//
|
||||
// Args:
|
||||
// <name> required (becomes the slug)
|
||||
// [tx ty] optional (default 32 32)
|
||||
// --seed N default 42
|
||||
// --creatures N default 20
|
||||
// --objects N default 10
|
||||
// --items N default 25
|
||||
//
|
||||
// Honors --random-populate-zone's hard caps + the existing
|
||||
// scaffold-zone validation. Sub-commands' output streams
|
||||
// through.
|
||||
std::string name = argv[++i];
|
||||
int tx = 32, ty = 32;
|
||||
uint32_t seed = 42;
|
||||
int creatures = 20, objects = 10, items = 25;
|
||||
// Optional positional tx/ty (must be before any --flags).
|
||||
if (i + 2 < argc && argv[i + 1][0] != '-' && argv[i + 2][0] != '-') {
|
||||
try { tx = std::stoi(argv[++i]); ty = std::stoi(argv[++i]); }
|
||||
catch (...) {}
|
||||
}
|
||||
while (i + 2 < argc && argv[i + 1][0] == '-') {
|
||||
std::string flag = argv[++i];
|
||||
if (flag == "--seed")
|
||||
try { seed = static_cast<uint32_t>(std::stoul(argv[++i])); } catch (...) {}
|
||||
else if (flag == "--creatures")
|
||||
try { creatures = std::stoi(argv[++i]); } catch (...) {}
|
||||
else if (flag == "--objects")
|
||||
try { objects = std::stoi(argv[++i]); } catch (...) {}
|
||||
else if (flag == "--items")
|
||||
try { items = std::stoi(argv[++i]); } catch (...) {}
|
||||
else {
|
||||
std::fprintf(stderr,
|
||||
"gen-random-zone: unknown flag '%s'\n", flag.c_str());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
// Slug-clean the name to match scaffold-zone's expectations.
|
||||
std::string slug;
|
||||
for (char c : name) {
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
||||
(c >= '0' && c <= '9') || c == '_' || c == '-') {
|
||||
slug += c;
|
||||
} else if (c == ' ') {
|
||||
slug += '_';
|
||||
}
|
||||
}
|
||||
if (slug.empty()) {
|
||||
std::fprintf(stderr,
|
||||
"gen-random-zone: name '%s' has no valid characters\n",
|
||||
name.c_str());
|
||||
return 1;
|
||||
}
|
||||
std::string self = argv[0];
|
||||
namespace fs = std::filesystem;
|
||||
std::string zoneDir = "custom_zones/" + slug;
|
||||
std::printf("gen-random-zone: %s (tile %d, %d)\n",
|
||||
slug.c_str(), tx, ty);
|
||||
std::fflush(stdout);
|
||||
// 1. Scaffold.
|
||||
std::string scaffoldCmd = "\"" + self + "\" --scaffold-zone \"" +
|
||||
slug + "\" " + std::to_string(tx) + " " +
|
||||
std::to_string(ty);
|
||||
int rc = std::system(scaffoldCmd.c_str());
|
||||
if (rc != 0) {
|
||||
std::fprintf(stderr,
|
||||
"gen-random-zone: scaffold step failed (rc=%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
// 2. Random populate.
|
||||
std::fflush(stdout);
|
||||
std::string popCmd = "\"" + self + "\" --random-populate-zone \"" +
|
||||
zoneDir + "\" --seed " + std::to_string(seed) +
|
||||
" --creatures " + std::to_string(creatures) +
|
||||
" --objects " + std::to_string(objects);
|
||||
rc = std::system(popCmd.c_str());
|
||||
if (rc != 0) {
|
||||
std::fprintf(stderr,
|
||||
"gen-random-zone: populate step failed (rc=%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
// 3. Random items.
|
||||
std::fflush(stdout);
|
||||
std::string itemsCmd = "\"" + self + "\" --random-populate-items \"" +
|
||||
zoneDir + "\" --seed " + std::to_string(seed + 1) +
|
||||
" --count " + std::to_string(items);
|
||||
rc = std::system(itemsCmd.c_str());
|
||||
if (rc != 0) {
|
||||
std::fprintf(stderr,
|
||||
"gen-random-zone: items step failed (rc=%d)\n", rc);
|
||||
return 1;
|
||||
}
|
||||
std::printf("\ngen-random-zone: complete\n");
|
||||
std::printf(" zone dir : %s\n", zoneDir.c_str());
|
||||
std::printf(" creatures : %d\n", creatures);
|
||||
std::printf(" objects : %d\n", objects);
|
||||
std::printf(" items : %d\n", items);
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--info-zone-audio") == 0 && i + 1 < argc) {
|
||||
// Print the audio configuration stored in zone.json:
|
||||
// music track, day/night ambience, volume sliders.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue