- 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>
723 lines
13 KiB
JSON
723 lines
13 KiB
JSON
[
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "0d68da82-d86a-4c40-8085-174a01c65f55",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
775,
|
|
1479,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 760,
|
|
"y1": 1464,
|
|
"z1": -128,
|
|
"x2": 791,
|
|
"y2": 1495,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Balron",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "0fe99fe0-a203-4563-994b-5e02d70f1b3f",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
888,
|
|
1568,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 878,
|
|
"y1": 1558,
|
|
"z1": -128,
|
|
"x2": 899,
|
|
"y2": 1579,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "EvilMage",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "EvilMageLord",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "14b1989d-ec45-42db-af1b-92f49023b981",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
891,
|
|
1537,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 885,
|
|
"y1": 1531,
|
|
"z1": -128,
|
|
"x2": 898,
|
|
"y2": 1544,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "RottingCorpse",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "2ef49b9b-97d6-431a-946d-ffd2f1615697",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
855,
|
|
1566,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 849,
|
|
"y1": 1560,
|
|
"z1": -128,
|
|
"x2": 862,
|
|
"y2": 1573,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Shade",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "33185d9f-afa2-43d7-a7aa-7d221c1a309a",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
964,
|
|
1554,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 957,
|
|
"y1": 1547,
|
|
"z1": -128,
|
|
"x2": 972,
|
|
"y2": 1562,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "LichLord",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "4b9e3103-e83e-48a4-88b3-c72acbe5e173",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
936,
|
|
1559,
|
|
-22
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 926,
|
|
"y1": 1549,
|
|
"z1": -128,
|
|
"x2": 947,
|
|
"y2": 1570,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 25,
|
|
"entries": [
|
|
{
|
|
"name": "Balron",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "516473d8-b5d1-4924-ad74-556649f98470",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
939,
|
|
1492,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 934,
|
|
"y1": 1487,
|
|
"z1": -128,
|
|
"x2": 945,
|
|
"y2": 1498,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Imp",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "530dcd87-a132-4cdb-a9c9-0f78758e4ad0",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
962,
|
|
1480,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 952,
|
|
"y1": 1470,
|
|
"z1": -128,
|
|
"x2": 973,
|
|
"y2": 1491,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Wraith",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Spectre",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Shade",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "5ce9d857-549d-4bf0-8e70-2dd6902c4ccf",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
775,
|
|
1480,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 5,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 735,
|
|
"y1": 1440,
|
|
"z1": -128,
|
|
"x2": 816,
|
|
"y2": 1521,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 40,
|
|
"entries": [
|
|
{
|
|
"name": "Imp",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "649b7645-25f8-4c0c-ac2d-896e558b2767",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
776,
|
|
1480,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 15,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 773,
|
|
"y1": 1477,
|
|
"z1": -128,
|
|
"x2": 780,
|
|
"y2": 1484,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 3,
|
|
"entries": [
|
|
{
|
|
"name": "TreasureChestLevel1",
|
|
"maxCount": 9,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "TreasureChestLevel2",
|
|
"maxCount": 9,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "TreasureChestLevel3",
|
|
"maxCount": 6,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "TreasureChestLevel4",
|
|
"maxCount": 6,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "67d46705-d56a-4098-bafb-ede2658118a8",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
855,
|
|
1567,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 849,
|
|
"y1": 1561,
|
|
"z1": -128,
|
|
"x2": 862,
|
|
"y2": 1574,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 6,
|
|
"entries": [
|
|
{
|
|
"name": "SkeletalMage",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "6cf2cd79-9f0f-4f25-af2b-333a9317171f",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
827,
|
|
1479,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 6,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 817,
|
|
"y1": 1469,
|
|
"z1": -128,
|
|
"x2": 838,
|
|
"y2": 1490,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Shade",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "BoneKnight",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "BoneMagi",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "74498688-9c91-4ea3-8abd-adcd2beb3b8d",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
959,
|
|
1530,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 952,
|
|
"y1": 1523,
|
|
"z1": -128,
|
|
"x2": 967,
|
|
"y2": 1538,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Lich",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Wraith",
|
|
"maxCount": 0,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Spectre",
|
|
"maxCount": 0,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Shade",
|
|
"maxCount": 0,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "79272788-c6c6-4216-84e0-985b942af71b",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
871,
|
|
1531,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 865,
|
|
"y1": 1525,
|
|
"z1": -128,
|
|
"x2": 878,
|
|
"y2": 1538,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "EvilMage",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "a90852cd-b672-4c4f-83bb-99dcc861ead0",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
851,
|
|
1498,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 846,
|
|
"y1": 1493,
|
|
"z1": -128,
|
|
"x2": 857,
|
|
"y2": 1504,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "RottingCorpse",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "add779de-8361-4edb-b214-900500ca81f0",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
888,
|
|
1471,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 8,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 876,
|
|
"y1": 1459,
|
|
"z1": -128,
|
|
"x2": 901,
|
|
"y2": 1484,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "Shade",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "BoneKnight",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "BoneMagi",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "ae956108-5118-4793-94d7-ac885617030f",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
681,
|
|
1535,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 20,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 641,
|
|
"y1": 1495,
|
|
"z1": -128,
|
|
"x2": 722,
|
|
"y2": 1576,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 60,
|
|
"entries": [
|
|
{
|
|
"name": "Wisp",
|
|
"maxCount": 20,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "b19163ea-9376-48e7-9bf7-b0a6a2e75d38",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
1000,
|
|
1512,
|
|
0
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 5,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 985,
|
|
"y1": 1497,
|
|
"z1": -128,
|
|
"x2": 1016,
|
|
"y2": 1528,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 15,
|
|
"entries": [
|
|
{
|
|
"name": "Titan",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Cyclops",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "be42e727-e04f-47a2-b07c-49046fdafcb9",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
939,
|
|
1531,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 934,
|
|
"y1": 1526,
|
|
"z1": -128,
|
|
"x2": 945,
|
|
"y2": 1537,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Imp",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "f4f8aa84-982a-4bd5-a708-9724d8598dd7",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
901,
|
|
1507,
|
|
2
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 891,
|
|
"y1": 1497,
|
|
"z1": -128,
|
|
"x2": 912,
|
|
"y2": 1518,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "EvilMageLord",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "fc4fedc9-9489-4385-bf85-9ec569081f4a",
|
|
"name": "Spawner (313)",
|
|
"location": [
|
|
961,
|
|
1502,
|
|
-28
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 955,
|
|
"y1": 1496,
|
|
"z1": -128,
|
|
"x2": 968,
|
|
"y2": 1509,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Ettin",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
}
|
|
]
|