From 5cefbb75395e88b5021143c32116aeffbe663817 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:17:41 -0700 Subject: [PATCH] chore(spawners): remove one-time spawn migration tool tools/spawner-json-migrate/migrate.mjs was a one-time offline script to rename "type"->"$type" and convert homeRange->spawnBounds in spawn data. Migration is complete; the tool is no longer needed. Co-Authored-By: Claude Sonnet 4.6 --- tools/spawner-json-migrate/migrate.mjs | 81 -------------------------- 1 file changed, 81 deletions(-) delete mode 100644 tools/spawner-json-migrate/migrate.mjs diff --git a/tools/spawner-json-migrate/migrate.mjs b/tools/spawner-json-migrate/migrate.mjs deleted file mode 100644 index 90627f2c2..000000000 --- a/tools/spawner-json-migrate/migrate.mjs +++ /dev/null @@ -1,81 +0,0 @@ -// One-time migration: rename "type" -> "$type" (kept first), and convert legacy -// homeRange (+location) -> spawnBounds, dropping homeRange. Run once, then delete this tool. -// -// Usage: node tools/spawner-json-migrate/migrate.mjs Distribution/Data/Spawns -import { readdirSync, readFileSync, writeFileSync, statSync } from "node:fs"; -import { join } from "node:path"; - -function* walk(dir) { - for (const name of readdirSync(dir)) { - const p = join(dir, name); - if (statSync(p).isDirectory()) { - yield* walk(p); - } else if (name.endsWith(".json")) { - yield p; - } - } -} - -// Produce a spawnBounds object that deserializes to the SAME Rectangle3D as the -// runtime homeRange path in BaseSpawner.ApplyDto. -// -// Runtime formula: -// homeRange == 0 -> Rectangle3D(x, y, z, 1, 1, 0) -// -> _start=(x,y,z), _end=(x+1,y+1,z) -// homeRange > 0 -> Rectangle3D(x-hr, y-hr, -128, hr*2+1, hr*2+1, 256) -// -> _start=(x-hr,y-hr,-128), _end=(x+hr+1,y+hr+1,128) -// -// Rectangle3DConverter x1/y1/z1/x2/y2/z2 form creates: -// Rectangle3D(Point3D(x1,y1,z1), Point3D(x2,y2,z2)) -// where _start=(x1,y1,z1) and _end=(x2,y2,z2). -// Rectangle3D.End is EXCLUSIVE (contains: x >= start.X && x < end.X). -function toBounds(loc, hr) { - const [x, y, z] = loc; - if (hr === 0) { - // Single-tile bounds: _start=(x,y,z), _end=(x+1,y+1,z) - return { x1: x, y1: y, z1: z, x2: x + 1, y2: y + 1, z2: z }; - } - // hr*2+1 wide/tall: _start=(x-hr,y-hr,-128), _end=(x+hr+1,y+hr+1,128) - return { x1: x - hr, y1: y - hr, z1: -128, x2: x + hr + 1, y2: y + hr + 1, z2: 128 }; -} - -function migrateOne(obj) { - const out = {}; - // $type must be the first key (STJ polymorphism requires discriminator first). - if ("type" in obj) { - out["$type"] = obj["type"]; - } else if ("$type" in obj) { - out["$type"] = obj["$type"]; - } - for (const [k, v] of Object.entries(obj)) { - if (k === "type" || k === "$type") { - continue; - } - if (k === "homeRange") { - // Convert homeRange -> spawnBounds (skip if spawnBounds already present). - if (obj.spawnBounds === undefined && Array.isArray(obj.location)) { - out.spawnBounds = toBounds(obj.location, v); - } - continue; // drop homeRange from output - } - out[k] = v; - } - return out; -} - -let files = 0; -let records = 0; -for (const file of walk(process.argv[2])) { - // Strip UTF-8 BOM if present (some editors write it, JSON.parse chokes on it). - const raw = readFileSync(file, "utf8").replace(/^/, ""); - const data = JSON.parse(raw); - const arr = Array.isArray(data) ? data : [data]; - const migrated = arr.map((o) => { - records++; - return migrateOne(o); - }); - const result = Array.isArray(data) ? migrated : migrated[0]; - writeFileSync(file, JSON.stringify(result, null, 2) + "\n", "utf8"); - files++; -} -console.log(`Migrated ${records} record(s) across ${files} file(s).`);