ModernUO/Distribution/Data/Spawns/shared/trammel/PalaceOfParoxysmus.json
Kamron Batman 2f8a7afa57 chore(spawners): migrate spawn data to $type discriminator
- 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>
2026-06-25 16:17:35 -07:00

736 lines
13 KiB
JSON

[
{
"$type": "Spawner",
"guid": "02cf36b9-6188-4bda-9e7f-66d0aac930b8",
"name": "Spawner (115)",
"location": [
6416,
447,
-40
],
"map": "Trammel",
"count": 15,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6396,
"y1": 427,
"z1": -128,
"x2": 6437,
"y2": 468,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "PlagueBeast",
"maxCount": 8,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 8,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 7,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 7,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "4b986151-c607-40ec-b8b2-3b8a09e1e828",
"name": "Spawner (115)",
"location": [
6292,
462,
-50
],
"map": "Trammel",
"count": 18,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6252,
"y1": 422,
"z1": -128,
"x2": 6333,
"y2": 503,
"z2": 128
},
"walkingRange": 40,
"entries": [
{
"name": "ChaosDaemon",
"maxCount": 7,
"probability": 100
},
{
"name": "Moloch",
"maxCount": 7,
"probability": 100
},
{
"name": "Succubus",
"maxCount": 7,
"probability": 100
},
{
"name": "Daemon",
"maxCount": 7,
"probability": 100
},
{
"name": "Balron",
"maxCount": 4,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "546847b9-bd52-4a7b-be03-bd9b9f26cb17",
"name": "Spawner (115)",
"location": [
6249,
352,
60
],
"map": "Trammel",
"count": 9,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6234,
"y1": 337,
"z1": -128,
"x2": 6265,
"y2": 368,
"z2": 128
},
"walkingRange": 15,
"entries": [
{
"name": "AcidElemental",
"maxCount": 6,
"probability": 100
},
{
"name": "EarthElemental",
"maxCount": 6,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 6,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "EarthElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "676cc139-9378-4935-9667-0cbd86e0b2b1",
"name": "Spawner (115)",
"location": [
6285,
353,
60
],
"map": "Trammel",
"count": 1,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6280,
"y1": 348,
"z1": -128,
"x2": 6291,
"y2": 359,
"z2": 128
},
"walkingRange": 5,
"entries": [
{
"name": "PoisonElemental",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "851856f8-49a9-4dfd-95bc-e969d748bd9c",
"name": "Spawner (115)",
"location": [
6404,
378,
-40
],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6386,
"y1": 360,
"z1": -128,
"x2": 6423,
"y2": 397,
"z2": 128
},
"walkingRange": 18,
"entries": [
{
"name": "AcidElemental",
"maxCount": 2,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 2,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "8bbbe927-ffbd-4f1c-aa89-4982088f1dca",
"name": "Spawner (115)",
"location": [
6298,
395,
60
],
"map": "Trammel",
"count": 2,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6290,
"y1": 387,
"z1": -128,
"x2": 6307,
"y2": 404,
"z2": 128
},
"walkingRange": 8,
"entries": [
{
"name": "EarthElemental",
"maxCount": 2,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 2,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "9599a1e0-f678-49f5-8ec6-c4f01998f96f",
"name": "Spawner (115)",
"location": [
6295,
616,
-50
],
"map": "Trammel",
"count": 27,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6245,
"y1": 566,
"z1": -128,
"x2": 6346,
"y2": 667,
"z2": 128
},
"walkingRange": 50,
"entries": [
{
"name": "Daemon",
"maxCount": 6,
"probability": 100
},
{
"name": "Succubus",
"maxCount": 6,
"probability": 100
},
{
"name": "InterredGrizzle",
"maxCount": 6,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 6,
"probability": 100
},
{
"name": "PlagueBeast",
"maxCount": 6,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 6,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 3,
"probability": 100
},
{
"name": "Putrefier",
"maxCount": 3,
"probability": 100
},
{
"name": "PlagueBeastLord",
"maxCount": 3,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "ad7e7828-7b85-416c-8ca6-6a9e7de99d95",
"name": "Spawner (115)",
"location": [
6319,
348,
60
],
"map": "Trammel",
"count": 9,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6299,
"y1": 328,
"z1": -128,
"x2": 6340,
"y2": 369,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "EarthElemental",
"maxCount": 5,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 5,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 5,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 5,
"probability": 100
},
{
"name": "EarthElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 1,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 1,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 1,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "bae60d5d-cbc7-4fed-ae27-75eb68d79870",
"name": "Spawner (115)",
"location": [
6384,
580,
-50
],
"map": "Trammel",
"count": 31,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6354,
"y1": 550,
"z1": -128,
"x2": 6415,
"y2": 611,
"z2": 128
},
"walkingRange": 30,
"entries": [
{
"name": "InterredGrizzle",
"maxCount": 4,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 4,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 3,
"probability": 100
},
{
"name": "Balron",
"maxCount": 9,
"probability": 100
},
{
"name": "Succubus",
"maxCount": 9,
"probability": 100
},
{
"name": "Daemon",
"maxCount": 9,
"probability": 100
},
{
"name": "PlagueBeastLord",
"maxCount": 11,
"probability": 100
},
{
"name": "PlagueBeast",
"maxCount": 11,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 11,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "c32b93fc-8549-4d80-8d8a-de99e885a477",
"name": "Spawner (115)",
"location": [
6353,
400,
60
],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6343,
"y1": 390,
"z1": -128,
"x2": 6364,
"y2": 411,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "EarthElemental",
"maxCount": 4,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 4,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "c3c0fc01-0e9e-420e-a994-ce64bc57a96e",
"name": "Spawner (115)",
"location": [
6354,
455,
-40
],
"map": "Trammel",
"count": 10,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6334,
"y1": 435,
"z1": -128,
"x2": 6375,
"y2": 476,
"z2": 128
},
"walkingRange": 20,
"entries": [
{
"name": "PlagueBeast",
"maxCount": 5,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 5,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 5,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "c68cc7ec-9447-455e-ac60-ab1d1f319bc5",
"name": "Spawner (115)",
"location": [
6466,
543,
-50
],
"map": "Trammel",
"count": 22,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6436,
"y1": 513,
"z1": -128,
"x2": 6497,
"y2": 574,
"z2": 128
},
"walkingRange": 30,
"entries": [
{
"name": "Balron",
"maxCount": 6,
"probability": 100
},
{
"name": "Succubus",
"maxCount": 6,
"probability": 100
},
{
"name": "Daemon",
"maxCount": 6,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 3,
"probability": 100
},
{
"name": "PlagueBeastLord",
"maxCount": 8,
"probability": 100
},
{
"name": "PlagueBeast",
"maxCount": 8,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 8,
"probability": 100
},
{
"name": "InterredGrizzle",
"maxCount": 5,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 5,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "cb00720f-c41e-413f-8cec-b90e2fe72b4a",
"name": "Spawner (115)",
"location": [
6328,
517,
-50
],
"map": "Trammel",
"count": 4,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6318,
"y1": 507,
"z1": -128,
"x2": 6339,
"y2": 528,
"z2": 128
},
"walkingRange": 10,
"entries": [
{
"name": "PoisonElemental",
"maxCount": 4,
"probability": 100
}
]
},
{
"$type": "Spawner",
"guid": "dcc7984a-1911-4368-81df-344fa7b0a2b5",
"name": "Spawner (115)",
"location": [
6418,
358,
-40
],
"map": "Trammel",
"count": 22,
"minDelay": "00:05:00",
"maxDelay": "00:10:00",
"team": 0,
"spawnBounds": {
"x1": 6393,
"y1": 333,
"z1": -128,
"x2": 6444,
"y2": 384,
"z2": 128
},
"walkingRange": 25,
"entries": [
{
"name": "PlagueSpawn",
"maxCount": 12,
"probability": 100
},
{
"name": "PlagueBeast",
"maxCount": 12,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 12,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 12,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 12,
"probability": 100
},
{
"name": "PlagueSpawn",
"maxCount": 2,
"probability": 100
},
{
"name": "PlagueBeast",
"maxCount": 2,
"probability": 100
},
{
"name": "AcidElemental",
"maxCount": 2,
"probability": 100
},
{
"name": "CorrosiveSlime",
"maxCount": 2,
"probability": 100
},
{
"name": "PoisonElemental",
"maxCount": 2,
"probability": 100
}
]
}
]