- 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>
511 lines
9 KiB
JSON
511 lines
9 KiB
JSON
[
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "418a0be2-0604-4ff8-b39d-1fb570fa7b7e",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2177,
|
|
1210,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2167,
|
|
"y1": 1200,
|
|
"z1": -128,
|
|
"x2": 2188,
|
|
"y2": 1221,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "LadyLissith",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "LadySabrix",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "46dc7fc7-d062-4be9-8134-f960352fbca3",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2171,
|
|
1181,
|
|
-44
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 10,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2151,
|
|
"y1": 1161,
|
|
"z1": -128,
|
|
"x2": 2192,
|
|
"y2": 1202,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "CuSidhe",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "DryadA",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Changeling",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Satyr",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "DireWolf",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "5a47595b-b894-4d45-b35d-5714de0c8c51",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2206,
|
|
1220,
|
|
-8
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2186,
|
|
"y1": 1200,
|
|
"z1": -128,
|
|
"x2": 2227,
|
|
"y2": 1241,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "CuSidhe",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "5cb54b29-10c4-448f-a036-5ba23dcb350a",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2224,
|
|
1218,
|
|
13
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 1,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2216,
|
|
"y1": 1210,
|
|
"z1": -128,
|
|
"x2": 2233,
|
|
"y2": 1227,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 8,
|
|
"entries": [
|
|
{
|
|
"name": "Swoop",
|
|
"maxCount": 1,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "68b1853c-f9bd-4bd1-852f-dcc9977a3049",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2167,
|
|
1266,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2162,
|
|
"y1": 1261,
|
|
"z1": -128,
|
|
"x2": 2173,
|
|
"y2": 1272,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "Malefic",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "6eee069d-8662-415f-bdcc-78975f1a54ae",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2207,
|
|
1180,
|
|
-36
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 15,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2182,
|
|
"y1": 1155,
|
|
"z1": -128,
|
|
"x2": 2233,
|
|
"y2": 1206,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 25,
|
|
"entries": [
|
|
{
|
|
"name": "CuSidhe",
|
|
"maxCount": 12,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Dryada",
|
|
"maxCount": 12,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Changeling",
|
|
"maxCount": 12,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Satyr",
|
|
"maxCount": 12,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "DireWolf",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "76ef21c0-5e48-410e-84f5-57023fa7efb4",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2137,
|
|
1216,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2132,
|
|
"y1": 1211,
|
|
"z1": -128,
|
|
"x2": 2143,
|
|
"y2": 1222,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "Silk",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "7e991368-4fad-4e2b-af3b-88d360b88627",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2157,
|
|
1206,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 3,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2152,
|
|
"y1": 1201,
|
|
"z1": -128,
|
|
"x2": 2163,
|
|
"y2": 1212,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "Virulent",
|
|
"maxCount": 3,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "852fa8b9-931f-493c-9ee0-200a3f229110",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2163,
|
|
1189,
|
|
-48
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 2,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2155,
|
|
"y1": 1181,
|
|
"z1": -128,
|
|
"x2": 2172,
|
|
"y2": 1198,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 8,
|
|
"entries": [
|
|
{
|
|
"name": "Changeling",
|
|
"maxCount": 2,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "aa8d4c55-b124-40ae-a0db-31b873c7a549",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2134,
|
|
1174,
|
|
-46
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 5,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2129,
|
|
"y1": 1169,
|
|
"z1": -128,
|
|
"x2": 2140,
|
|
"y2": 1180,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "Gnaw",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "DireWolf",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "b5b1118b-161e-43fb-80dd-f890dec2be53",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2177,
|
|
1229,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2172,
|
|
"y1": 1224,
|
|
"z1": -128,
|
|
"x2": 2183,
|
|
"y2": 1235,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 5,
|
|
"entries": [
|
|
{
|
|
"name": "GiantBlackWidow",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "cd6dab60-126f-4877-b9dd-f786cbfad49b",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2138,
|
|
1212,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 8,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2118,
|
|
"y1": 1192,
|
|
"z1": -128,
|
|
"x2": 2159,
|
|
"y2": 1233,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 20,
|
|
"entries": [
|
|
{
|
|
"name": "Quagmire",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "WhippingVine",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Irk",
|
|
"maxCount": 8,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "eea8e238-78e9-4d84-a91b-95360f6f2fd6",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2170,
|
|
1247,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 4,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2160,
|
|
"y1": 1237,
|
|
"z1": -128,
|
|
"x2": 2181,
|
|
"y2": 1258,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Malefic",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Virulent",
|
|
"maxCount": 4,
|
|
"probability": 100
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"$type": "Spawner",
|
|
"guid": "fe2db064-ee88-4f04-8c49-b3d7a56fd9a2",
|
|
"name": "Spawner (314)",
|
|
"location": [
|
|
2159,
|
|
1223,
|
|
-60
|
|
],
|
|
"map": "Ilshenar",
|
|
"count": 5,
|
|
"minDelay": "00:05:00",
|
|
"maxDelay": "00:10:00",
|
|
"team": 0,
|
|
"spawnBounds": {
|
|
"x1": 2149,
|
|
"y1": 1213,
|
|
"z1": -128,
|
|
"x2": 2170,
|
|
"y2": 1234,
|
|
"z2": 128
|
|
},
|
|
"walkingRange": 10,
|
|
"entries": [
|
|
{
|
|
"name": "Corpser",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Spite",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
},
|
|
{
|
|
"name": "Guile",
|
|
"maxCount": 5,
|
|
"probability": 100
|
|
}
|
|
]
|
|
}
|
|
]
|