- Rename "type" -> "$type" (first key, required for STJ polymorphism) in all 109 spawn JSON files (5,612 records). - Convert "homeRange" + "location" -> "spawnBounds" object, dropping homeRange. Runtime keeps reading homeRange so un-migrated/external files still load. - Add BoundsEquivalenceTests (hr=0/1/3/7) validating that the script's toBounds formula produces the same Rectangle3D as the runtime homeRange path. - Add MigratedDataLoadTests loading a real migrated file as List<SpawnerDto> and round-tripping each DTO through ToSpawner(). - Add tools/spawner-json-migrate/migrate.mjs (offline Node script). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
783 lines
14 KiB
JSON
783 lines
14 KiB
JSON
[
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "005c0fd4-1893-489e-9a09-14c53b246567",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
96,
|
|
540,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 81,
|
|
"y1": 525,
|
|
"z1": -128,
|
|
"x2": 112,
|
|
"y2": 556,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Ronin",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "016a082b-0696-40c3-815b-c3dbef373d50",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
173,
|
|
615,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 8,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 153,
|
|
"y1": 595,
|
|
"z1": -128,
|
|
"x2": 194,
|
|
"y2": 636,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Oni",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "06d87817-7b93-45c4-9696-35c26ca4218d",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
120,
|
|
415,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 110,
|
|
"y1": 405,
|
|
"z1": -128,
|
|
"x2": 131,
|
|
"y2": 426,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "12d3edf5-87f3-4fb4-9ca5-8462b94a81d8",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
134,
|
|
651,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 129,
|
|
"y1": 646,
|
|
"z1": -128,
|
|
"x2": 140,
|
|
"y2": 657,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellHound",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellCat",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "183ea3fc-7ed8-4f54-bd05-513be50f48d6",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
79,
|
|
521,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 74,
|
|
"y1": 516,
|
|
"z1": -128,
|
|
"x2": 85,
|
|
"y2": 527,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "1a384aa9-3d4c-4df7-82df-58e658f4bf5f",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
147,
|
|
646,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 142,
|
|
"y1": 641,
|
|
"z1": -128,
|
|
"x2": 153,
|
|
"y2": 652,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "24b2ba02-2289-4cb3-a957-e3ec7629c0b1",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
64,
|
|
488,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 6,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 44,
|
|
"y1": 468,
|
|
"z1": -128,
|
|
"x2": 85,
|
|
"y2": 509,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "42b06210-4cd3-49d6-a5d1-74e5ab0cc77a",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
977,
|
|
218,
|
|
23
|
|
],
|
|
"map": "Tokuno",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 962,
|
|
"y1": 203,
|
|
"z1": -128,
|
|
"x2": 993,
|
|
"y2": 234,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "47256f4f-b709-4c19-866b-2d7bdd896fd6",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
78,
|
|
546,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 63,
|
|
"y1": 531,
|
|
"z1": -128,
|
|
"x2": 94,
|
|
"y2": 562,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellHound",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Succubus",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "477ff85e-e7ac-4a85-a99f-75d1b3e9eb74",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
110,
|
|
649,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 100,
|
|
"y1": 639,
|
|
"z1": -128,
|
|
"x2": 121,
|
|
"y2": 660,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellCat",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Balron",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "4849d20d-77fc-4f0d-a513-a352a5849467",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
123,
|
|
387,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 113,
|
|
"y1": 377,
|
|
"z1": -128,
|
|
"x2": 134,
|
|
"y2": 398,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "624d9055-be69-4b42-9aa8-f8876a6c3cbf",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
88,
|
|
332,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 68,
|
|
"y1": 312,
|
|
"z1": -128,
|
|
"x2": 109,
|
|
"y2": 353,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "66d98c69-5788-471a-b93c-d82e252471b2",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
110,
|
|
540,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 95,
|
|
"y1": 525,
|
|
"z1": -128,
|
|
"x2": 126,
|
|
"y2": 556,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellHound",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Succubus",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "752b7dfa-4f8c-4bb6-875e-2f18385881b5",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
111,
|
|
352,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 101,
|
|
"y1": 342,
|
|
"z1": -128,
|
|
"x2": 122,
|
|
"y2": 363,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "9a661087-c1ec-4503-9451-8873a8c24bd9",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
175,
|
|
660,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 6,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 155,
|
|
"y1": 640,
|
|
"z1": -128,
|
|
"x2": 196,
|
|
"y2": 681,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HellCat",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Balron",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "a4392a5c-8729-40c2-bd31-4b145cba2f1a",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
106,
|
|
685,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 86,
|
|
"y1": 665,
|
|
"z1": -128,
|
|
"x2": 127,
|
|
"y2": 706,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "HellHound",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Succubus",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "bd077bc0-b36c-41b4-9e4c-e3f067d6846e",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
99,
|
|
387,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 89,
|
|
"y1": 377,
|
|
"z1": -128,
|
|
"x2": 110,
|
|
"y2": 398,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "cdd374da-1e88-4389-ac42-a6c63ba30d0b",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
97,
|
|
467,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 77,
|
|
"y1": 447,
|
|
"z1": -128,
|
|
"x2": 118,
|
|
"y2": 488,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Succubus",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "e3fd2f65-4f1e-4af5-8cab-26493d9c5350",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
142,
|
|
692,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 122,
|
|
"y1": 672,
|
|
"z1": -128,
|
|
"x2": 163,
|
|
"y2": 713,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "f093fd90-d7b6-48a7-b5f3-c2524f4ca2ca",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
100,
|
|
499,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 80,
|
|
"y1": 479,
|
|
"z1": -128,
|
|
"x2": 121,
|
|
"y2": 520,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "f3743807-ec35-485a-82b5-f3cd3ba27bc0",
|
|
"name": "Spawner (501)",
|
|
"location": [
|
|
70,
|
|
376,
|
|
-1
|
|
],
|
|
"map": "Malas",
|
|
"count": 10,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 45,
|
|
"y1": 351,
|
|
"z1": -128,
|
|
"x2": 96,
|
|
"y2": 402,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 30,
|
|
"entries": [
|
|
{
|
|
"name": "FanDancer",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HeadlessOne",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "HordeMinion",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Daemon",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
}
|
|
]
|