mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-08 10:03:51 +00:00
feat(editor): add --info-spawn single-spawn detail view
Detailed view of one creature or object by index. Where --list-zone-spawns shows headline fields in a table, --info-spawn dumps every field for a single record: Creatures: id, name, modelPath, displayId, position, orientation, level, health/mana, faction, scale, behavior mode, wander/aggro/ leash radii, respawn time, flag set (hostile/questgiver/vendor/ trainer), patrol-path waypoint count. Objects: uniqueId, path, type (m2/wmo), position, rotation, scale. Both kinds support --json for downstream scripts. Useful for spot-checking individual records discovered via list-zone-spawns or audit-zone-spawns. Verified: random-populated zone → info-spawn creature 0 shows Spider with all behavior fields populated; object 0 shows mushroom WMO with rotation/scale.
This commit is contained in:
parent
d64d188b13
commit
3810dfc510
1 changed files with 145 additions and 1 deletions
|
|
@ -595,6 +595,8 @@ static void printUsage(const char* argv0) {
|
|||
std::printf(" List spawns whose Z is more than <threshold> yards off from the terrain (default 5)\n");
|
||||
std::printf(" --list-zone-spawns <zoneDir> [--json]\n");
|
||||
std::printf(" Combined creature+object listing for a zone (kind, name, position, key fields)\n");
|
||||
std::printf(" --info-spawn <zoneDir> <creature|object> <index> [--json]\n");
|
||||
std::printf(" Detailed view of a single creature/object spawn by index\n");
|
||||
std::printf(" --list-project-spawns <projectDir> [--json]\n");
|
||||
std::printf(" Combined creature+object listing across every zone (zone column added)\n");
|
||||
std::printf(" --audit-project-spawns <projectDir> [--threshold yards]\n");
|
||||
|
|
@ -1053,7 +1055,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", "--list-project-spawns",
|
||||
"--gen-random-zone", "--gen-random-project",
|
||||
"--gen-random-zone", "--gen-random-project", "--info-spawn",
|
||||
"--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",
|
||||
|
|
@ -14037,6 +14039,148 @@ int main(int argc, char* argv[]) {
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
} else if (std::strcmp(argv[i], "--info-spawn") == 0 && i + 3 < argc) {
|
||||
// Detailed view of one creature or object by index. The
|
||||
// list-zone-spawns table only shows headline fields; this
|
||||
// dumps every field including AI behavior, faction,
|
||||
// patrol path waypoints, etc.
|
||||
std::string zoneDir = argv[++i];
|
||||
std::string kind = argv[++i];
|
||||
int idx = -1;
|
||||
try { idx = std::stoi(argv[++i]); }
|
||||
catch (...) {
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: <index> must be an integer\n");
|
||||
return 1;
|
||||
}
|
||||
bool jsonOut = (i + 1 < argc &&
|
||||
std::strcmp(argv[i + 1], "--json") == 0);
|
||||
if (jsonOut) i++;
|
||||
namespace fs = std::filesystem;
|
||||
std::transform(kind.begin(), kind.end(), kind.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
if (kind == "creature") {
|
||||
wowee::editor::NpcSpawner spawner;
|
||||
if (!spawner.loadFromFile(zoneDir + "/creatures.json")) {
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: %s has no creatures.json\n",
|
||||
zoneDir.c_str());
|
||||
return 1;
|
||||
}
|
||||
const auto& spawns = spawner.getSpawns();
|
||||
if (idx < 0 || static_cast<size_t>(idx) >= spawns.size()) {
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: index %d out of range (have %zu)\n",
|
||||
idx, spawns.size());
|
||||
return 1;
|
||||
}
|
||||
const auto& s = spawns[idx];
|
||||
static const char* behaviors[] = {
|
||||
"Stationary", "Patrol", "Wander", "Scripted"
|
||||
};
|
||||
int bIdx = static_cast<int>(s.behavior);
|
||||
if (bIdx < 0 || bIdx > 3) bIdx = 0;
|
||||
if (jsonOut) {
|
||||
nlohmann::json j;
|
||||
j["zone"] = zoneDir;
|
||||
j["kind"] = "creature";
|
||||
j["index"] = idx;
|
||||
j["id"] = s.id;
|
||||
j["name"] = s.name;
|
||||
j["modelPath"] = s.modelPath;
|
||||
j["displayId"] = s.displayId;
|
||||
j["position"] = {s.position.x, s.position.y, s.position.z};
|
||||
j["orientation"] = s.orientation;
|
||||
j["level"] = s.level;
|
||||
j["health"] = s.health;
|
||||
j["mana"] = s.mana;
|
||||
j["faction"] = s.faction;
|
||||
j["scale"] = s.scale;
|
||||
j["behavior"] = behaviors[bIdx];
|
||||
j["wanderRadius"] = s.wanderRadius;
|
||||
j["aggroRadius"] = s.aggroRadius;
|
||||
j["leashRadius"] = s.leashRadius;
|
||||
j["respawnTimeMs"] = s.respawnTimeMs;
|
||||
j["hostile"] = s.hostile;
|
||||
j["questgiver"] = s.questgiver;
|
||||
j["vendor"] = s.vendor;
|
||||
j["trainer"] = s.trainer;
|
||||
j["patrolPathSize"] = s.patrolPath.size();
|
||||
std::printf("%s\n", j.dump(2).c_str());
|
||||
return 0;
|
||||
}
|
||||
std::printf("Creature spawn %d in %s\n", idx, zoneDir.c_str());
|
||||
std::printf(" id : %u\n", s.id);
|
||||
std::printf(" name : %s\n", s.name.c_str());
|
||||
std::printf(" modelPath : %s\n",
|
||||
s.modelPath.empty() ? "(template)" : s.modelPath.c_str());
|
||||
std::printf(" displayId : %u\n", s.displayId);
|
||||
std::printf(" position : (%.2f, %.2f, %.2f)\n",
|
||||
s.position.x, s.position.y, s.position.z);
|
||||
std::printf(" orientation : %.1f°\n", s.orientation);
|
||||
std::printf(" level : %u\n", s.level);
|
||||
std::printf(" health/mana : %u / %u\n", s.health, s.mana);
|
||||
std::printf(" faction : %u\n", s.faction);
|
||||
std::printf(" scale : %.2f\n", s.scale);
|
||||
std::printf(" behavior : %s\n", behaviors[bIdx]);
|
||||
std::printf(" wander/aggro : %.1f / %.1f y\n",
|
||||
s.wanderRadius, s.aggroRadius);
|
||||
std::printf(" leash : %.1f y\n", s.leashRadius);
|
||||
std::printf(" respawn : %.0f s\n", s.respawnTimeMs / 1000.0f);
|
||||
std::printf(" flags : %s%s%s%s\n",
|
||||
s.hostile ? "hostile " : "",
|
||||
s.questgiver ? "questgiver " : "",
|
||||
s.vendor ? "vendor " : "",
|
||||
s.trainer ? "trainer " : "");
|
||||
std::printf(" patrol path : %zu waypoint(s)\n",
|
||||
s.patrolPath.size());
|
||||
return 0;
|
||||
} else if (kind == "object") {
|
||||
wowee::editor::ObjectPlacer placer;
|
||||
if (!placer.loadFromFile(zoneDir + "/objects.json")) {
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: %s has no objects.json\n",
|
||||
zoneDir.c_str());
|
||||
return 1;
|
||||
}
|
||||
const auto& objs = placer.getObjects();
|
||||
if (idx < 0 || static_cast<size_t>(idx) >= objs.size()) {
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: index %d out of range (have %zu)\n",
|
||||
idx, objs.size());
|
||||
return 1;
|
||||
}
|
||||
const auto& o = objs[idx];
|
||||
if (jsonOut) {
|
||||
nlohmann::json j;
|
||||
j["zone"] = zoneDir;
|
||||
j["kind"] = "object";
|
||||
j["index"] = idx;
|
||||
j["uniqueId"] = o.uniqueId;
|
||||
j["path"] = o.path;
|
||||
j["type"] = o.type == wowee::editor::PlaceableType::M2 ? "m2" : "wmo";
|
||||
j["position"] = {o.position.x, o.position.y, o.position.z};
|
||||
j["rotation"] = {o.rotation.x, o.rotation.y, o.rotation.z};
|
||||
j["scale"] = o.scale;
|
||||
std::printf("%s\n", j.dump(2).c_str());
|
||||
return 0;
|
||||
}
|
||||
std::printf("Object spawn %d in %s\n", idx, zoneDir.c_str());
|
||||
std::printf(" uniqueId : %u\n", o.uniqueId);
|
||||
std::printf(" path : %s\n", o.path.c_str());
|
||||
std::printf(" type : %s\n",
|
||||
o.type == wowee::editor::PlaceableType::M2 ? "m2" : "wmo");
|
||||
std::printf(" position : (%.2f, %.2f, %.2f)\n",
|
||||
o.position.x, o.position.y, o.position.z);
|
||||
std::printf(" rotation : (%.2f, %.2f, %.2f) rad\n",
|
||||
o.rotation.x, o.rotation.y, o.rotation.z);
|
||||
std::printf(" scale : %.2f\n", o.scale);
|
||||
return 0;
|
||||
}
|
||||
std::fprintf(stderr,
|
||||
"info-spawn: kind must be 'creature' or 'object' (got '%s')\n",
|
||||
kind.c_str());
|
||||
return 1;
|
||||
} else if (std::strcmp(argv[i], "--list-project-spawns") == 0 && i + 1 < argc) {
|
||||
// Project-wide companion to --list-zone-spawns. Combines
|
||||
// creatures + objects across every zone into one big
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue