Convert Regions/Spawns to JSON (#138)
This commit is contained in:
parent
b8316e9202
commit
390f30e706
117 changed files with 97306 additions and 4848 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<spawnDefinitions>
|
||||
<spawnGroup name="Escortables">
|
||||
<object type="EscortableMage" />
|
||||
<object type="Noble" />
|
||||
<object type="SeekerOfAdventure" />
|
||||
</spawnGroup>
|
||||
<spawnGroup name="TownAnimals">
|
||||
<object type="Cat" />
|
||||
<object type="Dog" />
|
||||
</spawnGroup>
|
||||
<spawnGroup name="Reagents">
|
||||
<object type="BlackPearl" />
|
||||
<object type="Bloodmoss" />
|
||||
<object type="Garlic" />
|
||||
<object type="Ginseng" />
|
||||
<object type="MandrakeRoot" />
|
||||
<object type="Nightshade" />
|
||||
<object type="SulfurousAsh" />
|
||||
<object type="SpidersSilk" />
|
||||
</spawnGroup>
|
||||
</spawnDefinitions>
|
||||
339
Distribution/Data/Spawns/eodon.json
Normal file
339
Distribution/Data/Spawns/eodon.json
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [117, 1740, 0],
|
||||
"map": "TerMur",
|
||||
"count": 17,
|
||||
"entries": [{ "maxCount": 3, "name": "GiantBlackWidow", "probability": 100 }],
|
||||
"homeRange": 9,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [122, 1805, 0],
|
||||
"map": "TerMur",
|
||||
"count": 15,
|
||||
"entries": [{ "maxCount": 2, "name": "GiantBlackWidow", "probability": 100 }],
|
||||
"homeRange": 18,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [126, 1692, 0],
|
||||
"map": "TerMur",
|
||||
"count": 12,
|
||||
"entries": [{ "maxCount": 2, "name": "GiantBlackWidow", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [175, 1861, 0],
|
||||
"map": "TerMur",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 1, "name": "GiantBlackWidow", "probability": 100 }],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [267, 1433, 40],
|
||||
"map": "TerMur",
|
||||
"count": 6,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Alligator", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "BullFrog", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "GiantToad", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "AcidElemental", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [286, 1804, 80],
|
||||
"map": "TerMur",
|
||||
"count": 7,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "VampireBat", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "TropicalBird", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [319, 1502, 40],
|
||||
"map": "TerMur",
|
||||
"count": 6,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Alligator", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "BullFrog", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "GiantToad", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "AcidElemental", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [341, 1418, 40],
|
||||
"map": "TerMur",
|
||||
"count": 6,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Alligator", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "BullFrog", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "GiantToad", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "AcidElemental", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [347, 1911, 0],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 6, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Panther", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [355, 1676, 40],
|
||||
"map": "TerMur",
|
||||
"count": 4,
|
||||
"entries": [{ "maxCount": 4, "name": "SandVortex", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [398, 1896, 0],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 6, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Panther", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [424, 1404, 40],
|
||||
"map": "TerMur",
|
||||
"count": 19,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Alligator", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "BullFrog", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "GiantToad", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 }
|
||||
],
|
||||
"homeRange": 65,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [454, 1895, 0],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 6, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Panther", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 22,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [506, 1582, 40],
|
||||
"map": "TerMur",
|
||||
"count": 17,
|
||||
"entries": [
|
||||
{ "maxCount": 9, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "VampireBat", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [512, 1915, 0],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 6, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Panther", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 13,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [586, 1712, 40],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "Corpser", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [606, 1574, 40],
|
||||
"map": "TerMur",
|
||||
"count": 20,
|
||||
"entries": [
|
||||
{ "maxCount": 9, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "VampireBat", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [607, 1647, 40],
|
||||
"map": "TerMur",
|
||||
"count": 17,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Gorilla", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "ForestOstard", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "TropicalBird", "probability": 100 }
|
||||
],
|
||||
"homeRange": 50,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [614, 1748, 48],
|
||||
"map": "TerMur",
|
||||
"count": 16,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Gorilla", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "ForestOstard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 50,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [720, 1860, 40],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "Wisp", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [801, 2003, 80],
|
||||
"map": "TerMur",
|
||||
"count": 17,
|
||||
"entries": [
|
||||
{ "maxCount": 12, "name": "TropicalBird", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Corpser", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [856, 2132, 40],
|
||||
"map": "TerMur",
|
||||
"count": 13,
|
||||
"entries": [
|
||||
{ "maxCount": 3, "name": "LavaSerpent", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "LavaSnake", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "FireElemental", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "LavaLizard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [929, 2013, 50],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "AirElemental", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [942, 2076, 55],
|
||||
"map": "TerMur",
|
||||
"count": 4,
|
||||
"entries": [{ "maxCount": 4, "name": "AirElemental", "probability": 100 }],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
}
|
||||
]
|
||||
34690
Distribution/Data/Spawns/felucca.json
Normal file
34690
Distribution/Data/Spawns/felucca.json
Normal file
File diff suppressed because it is too large
Load diff
46
Distribution/Data/Spawns/gravewaterlake.json
Normal file
46
Distribution/Data/Spawns/gravewaterlake.json
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [6278, 1786, 0],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "WaterElemental", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [6292, 1711, 0],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Hydra", "probability": 100 }],
|
||||
"homeRange": -5,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [6303, 1688, 10],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Hydra", "probability": 100 }],
|
||||
"homeRange": -5,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [6313, 1723, 0],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Hydra", "probability": 100 }],
|
||||
"homeRange": -5,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
}
|
||||
]
|
||||
5944
Distribution/Data/Spawns/ilshenar.json
Normal file
5944
Distribution/Data/Spawns/ilshenar.json
Normal file
File diff suppressed because it is too large
Load diff
3626
Distribution/Data/Spawns/malas.json
Normal file
3626
Distribution/Data/Spawns/malas.json
Normal file
File diff suppressed because it is too large
Load diff
482
Distribution/Data/Spawns/region-spawns.json
Normal file
482
Distribution/Data/Spawns/region-spawns.json
Normal file
|
|
@ -0,0 +1,482 @@
|
|||
[
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [375, 1191, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Yew 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [567, 1239, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Yew 1",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [571, 1099, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Farm in Yew",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [675, 939, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Field of Sheep in Yew 1",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [675, 1179, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Field of Sheep in Yew 2",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [813, 2163, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Skara Brae 1",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2254, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Carrot Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2264, 0],
|
||||
"map": "Felucca",
|
||||
"region": "An Onion Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableOnion", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2264, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Cabbage Field in Skara Brae 1",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2274, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Cabbage Field in Skara Brae 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2355, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Cotton Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCotton", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [843, 2352, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Skara Brae 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1120, 1624, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Britain 4",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1135, 1791, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1152, 1576, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Britain 5",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1183, 1683, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Cabbage Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1199, 1683, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Turnip Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableTurnip", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1199, 1823, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Britain 2",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1215, 1723, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Carrot Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1216, 1604, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Turnip Field in Britain 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableTurnip", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1231, 1723, 0],
|
||||
"map": "Felucca",
|
||||
"region": "An Onion Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableOnion", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1231, 1887, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Wheatfield in Britain 3",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1232, 1604, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Carrot Field in Britain 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [4567, 1475, 0],
|
||||
"map": "Felucca",
|
||||
"region": "A Cotton Field in Moonglow",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCotton", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [375, 1191, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Yew 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [567, 1239, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Yew 1",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [571, 1099, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Farm in Yew",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [675, 939, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Field of Sheep in Yew 1",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [675, 1179, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Field of Sheep in Yew 2",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "Sheep", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [813, 2163, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Skara Brae 1",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2254, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Carrot Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2264, 0],
|
||||
"map": "Trammel",
|
||||
"region": "An Onion Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableOnion", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2264, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Cabbage Field in Skara Brae 1",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2274, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Cabbage Field in Skara Brae 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [823, 2355, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Cotton Field in Skara Brae",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCotton", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [843, 2352, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Skara Brae 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1120, 1624, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Britain 4",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1135, 1791, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1152, 1576, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Britain 5",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1183, 1683, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Cabbage Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCabbage", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1199, 1683, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Turnip Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableTurnip", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1199, 1823, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Britain 2",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1215, 1723, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Carrot Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1216, 1604, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Turnip Field in Britain 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableTurnip", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1231, 1723, 0],
|
||||
"map": "Trammel",
|
||||
"region": "An Onion Field in Britain 1",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableOnion", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1231, 1887, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Wheatfield in Britain 3",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableWheat", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [1232, 1604, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Carrot Field in Britain 2",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "FarmableCarrot", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "RegionSpawner",
|
||||
"location": [4567, 1475, 0],
|
||||
"map": "Trammel",
|
||||
"region": "A Cotton Field in Moonglow",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "FarmableCotton", "probability": 100 }],
|
||||
"minDelay": "00:00:10",
|
||||
"maxDelay": "00:00:30"
|
||||
}
|
||||
]
|
||||
818
Distribution/Data/Spawns/solenhives.json
Normal file
818
Distribution/Data/Spawns/solenhives.json
Normal file
|
|
@ -0,0 +1,818 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5657, 1824, 1],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5657, 1989, 1],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5665, 1869, 10],
|
||||
"map": "Felucca",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "BlackSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 16,
|
||||
"walkingRange": 14,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5672, 1844, 2],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5677, 2027, 3],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5684, 1985, 3],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5698, 1894, 1],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5699, 2025, 4],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5707, 1874, 0],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5708, 1800, 2],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5718, 1819, 3],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5721, 1993, 0],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5725, 1915, 5],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5737, 1941, 3],
|
||||
"map": "Felucca",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "BlackSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5770, 1956, 1],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "DreadSpider", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5775, 1897, 22],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenMatriarch", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:00:05",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5783, 2021, -14],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 7,
|
||||
"walkingRange": 9,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5788, 1796, 1],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "BlackSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5790, 1985, 5],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackAmbitiousSolenQueen", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:00:05",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5793, 1855, 2],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5813, 1945, 2],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5819, 1973, 3],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5830, 1862, 3],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5831, 1910, 3],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Beetle", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5832, 1803, 0],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5835, 1936, 0],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5836, 1994, 0],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Beetle", "probability": 100 }],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5847, 2020, 10],
|
||||
"map": "Felucca",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5860, 1959, 2],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5860, 1979, 4],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5874, 1798, 0],
|
||||
"map": "Felucca",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "BlackSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5885, 1920, -17],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5887, 1840, -18],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5914, 1991, 4],
|
||||
"map": "Felucca",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5919, 1833, 1],
|
||||
"map": "Felucca",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5920, 1814, 1],
|
||||
"map": "Felucca",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BlackSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5657, 1824, 1],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5657, 1989, 1],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5665, 1869, 10],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "RedSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 16,
|
||||
"walkingRange": 14,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5672, 1844, 2],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5677, 2027, 3],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5684, 1985, 3],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5698, 1894, 1],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5699, 2025, 4],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5707, 1874, 0],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5708, 1800, 2],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5718, 1819, 3],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5721, 1993, 0],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5725, 1915, 5],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5737, 1941, 3],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "RedSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5770, 1956, 1],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "DreadSpider", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5775, 1897, 22],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenMatriarch", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:00:05",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5783, 2021, -14],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 7,
|
||||
"walkingRange": 9,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5788, 1796, 1],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "RedSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5790, 1985, 5],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedAmbitiousSolenQueen", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:00:05",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5793, 1855, 2],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5813, 1945, 2],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5819, 1973, 3],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5830, 1862, 3],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5831, 1910, 3],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Beetle", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5832, 1803, 0],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5835, 1936, 0],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5836, 1994, 0],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Beetle", "probability": 100 }],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5847, 2020, 10],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5860, 1959, 2],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5860, 1979, 4],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWarrior", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5874, 1798, 0],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "RedSolenQueen", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5885, 1920, -17],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5887, 1840, -18],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "AntLion", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5914, 1991, 4],
|
||||
"map": "Trammel",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5919, 1833, 1],
|
||||
"map": "Trammel",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [5920, 1814, 1],
|
||||
"map": "Trammel",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "RedSolenWorker", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
}
|
||||
]
|
||||
912
Distribution/Data/Spawns/termur.json
Normal file
912
Distribution/Data/Spawns/termur.json
Normal file
|
|
@ -0,0 +1,912 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [35, 99, -5],
|
||||
"map": "TerMur",
|
||||
"count": 12,
|
||||
"entries": [{ "maxCount": 2, "name": "SilverSerpent", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [35, 159, 0],
|
||||
"map": "TerMur",
|
||||
"count": 18,
|
||||
"entries": [{ "maxCount": 5, "name": "SilverSerpent", "probability": 100 }],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [344, 618, 26],
|
||||
"map": "TerMur",
|
||||
"count": 13,
|
||||
"entries": [
|
||||
{ "maxCount": 8, "name": "Pixie", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Wisp", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [365, 2952, 40],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 3, "name": "FireGargoyle", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "FireElemental", "probability": 100 }
|
||||
],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [365, 3138, 36],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "HeadlessOne", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [375, 2999, -2],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "FireGargoyle", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [386, 3062, 29],
|
||||
"map": "TerMur",
|
||||
"count": 9,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "Efreet", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "Phoenix", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "FireGargoyle", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [399, 3128, 37],
|
||||
"map": "TerMur",
|
||||
"count": 7,
|
||||
"entries": [{ "maxCount": 2, "name": "FireGargoyle", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:04:00",
|
||||
"minDelay": "00:03:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [416, 2939, 36],
|
||||
"map": "TerMur",
|
||||
"count": 7,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "FireElemental", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "LavaSnake", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [418, 2982, 26],
|
||||
"map": "TerMur",
|
||||
"count": 7,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "LavaLizard", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "LavaSnake", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [432, 3071, 39],
|
||||
"map": "TerMur",
|
||||
"count": 4,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "FireElemental", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "LavaSnake", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [452, 3133, 38],
|
||||
"map": "TerMur",
|
||||
"count": 16,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "LavaSerpent", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "LavaSnake", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "HeadlessOne", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [465, 2977, 34],
|
||||
"map": "TerMur",
|
||||
"count": 8,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "FireElemental", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "LavaLizard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [465, 3042, 19],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 3, "name": "Efreet", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [475, 3188, 37],
|
||||
"map": "TerMur",
|
||||
"count": 11,
|
||||
"entries": [{ "maxCount": 3, "name": "HeadlessOne", "probability": 100 }],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [487, 3748, -32],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "WanderingHealer", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [511, 3042, 38],
|
||||
"map": "TerMur",
|
||||
"count": 12,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "LavaSnake", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "LavaSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [534, 3421, 37],
|
||||
"map": "TerMur",
|
||||
"count": 48,
|
||||
"entries": [
|
||||
{ "maxCount": 7, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Horse", "probability": 100 },
|
||||
{ "maxCount": 15, "name": "Bird", "probability": 100 }
|
||||
],
|
||||
"homeRange": 35,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [555, 3495, 38],
|
||||
"map": "TerMur",
|
||||
"count": 22,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 6, "name": "Bird", "probability": 100 }
|
||||
],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [581, 898, -73],
|
||||
"map": "TerMur",
|
||||
"count": 71,
|
||||
"entries": [
|
||||
{ "maxCount": 10, "name": "LavaLizard", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "LavaSnake", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "HellHound", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "LavaSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:02:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [586, 3283, 37],
|
||||
"map": "TerMur",
|
||||
"count": 19,
|
||||
"entries": [
|
||||
{ "maxCount": 10, "name": "Bird", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Horse", "probability": 100 }
|
||||
],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [649, 703, 13],
|
||||
"map": "TerMur",
|
||||
"count": 21,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "LavaSnake", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "GiantSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [657, 2906, -3],
|
||||
"map": "TerMur",
|
||||
"count": 9,
|
||||
"entries": [{ "maxCount": 1, "name": "NetherBoltScroll", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [676, 831, -109],
|
||||
"map": "TerMur",
|
||||
"count": 81,
|
||||
"entries": [
|
||||
{ "maxCount": 10, "name": "PatchworkSkeleton", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Skeleton", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "SkeletalKnight", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "BoneKnight", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "SkeletalMage", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "BoneMagi", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:05:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [689, 485, -15],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [{ "maxCount": 10, "name": "HellHound", "probability": 100 }],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [698, 773, 28],
|
||||
"map": "TerMur",
|
||||
"count": 9,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Coil", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "SilverSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [702, 3434, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Tailor", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [713, 3438, -19],
|
||||
"map": "TerMur",
|
||||
"count": 6,
|
||||
"entries": [{ "maxCount": 6, "name": "Barkeeper", "probability": 100 }],
|
||||
"homeRange": 1,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [715, 3423, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Healer", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [716, 3445, -19],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Farmer", "probability": 100 }],
|
||||
"homeRange": 1,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [726, 3427, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Weaponsmith", "probability": 100 }],
|
||||
"homeRange": 1,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [728, 3445, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Carpenter", "probability": 100 }],
|
||||
"homeRange": 1,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [735, 687, -47],
|
||||
"map": "TerMur",
|
||||
"count": 20,
|
||||
"entries": [
|
||||
{ "maxCount": 6, "name": "GiantSerpent", "probability": 100 },
|
||||
{ "maxCount": 8, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "SilverSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [764, 746, 23],
|
||||
"map": "TerMur",
|
||||
"count": 18,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Hydra", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "GiantSerpent", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "LavaSnake", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:02:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [771, 3475, -20],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 1, "name": "Alchemist", "probability": 100 }],
|
||||
"homeRange": 2,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [772, 3486, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Mage", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [775, 770, 23],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 4, "name": "GiantSerpent", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:03:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [778, 732, 23],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 4, "name": "GiantSerpent", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:03:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [778, 3430, -10],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Jeweler", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [784, 3490, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Healer", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [791, 3448, -10],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Farmer", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [793, 3491, -20],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Provisioner", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [795, 759, 23],
|
||||
"map": "TerMur",
|
||||
"count": 4,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Hydra", "probability": 100 },
|
||||
{ "maxCount": 3, "name": "SilverSerpent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 2,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:02:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [795, 771, 22],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 4, "name": "GiantSerpent", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:02:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [805, 3398, 0],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 1, "name": "Tailor", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [806, 734, 22],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 4, "name": "GiantSerpent", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:03:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [806, 3387, 0],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Tanner", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [806, 3491, -20],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Cook", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Baker", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [808, 3228, 40],
|
||||
"map": "TerMur",
|
||||
"count": 35,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Horse", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Bird", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Hind", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Rabbit", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "TimberWolf", "probability": 100 }
|
||||
],
|
||||
"homeRange": 50,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [810, 3800, -42],
|
||||
"map": "TerMur",
|
||||
"count": 85,
|
||||
"entries": [
|
||||
{ "maxCount": 10, "name": "Horse", "probability": 100 },
|
||||
{ "maxCount": 25, "name": "Mongbat", "probability": 100 }
|
||||
],
|
||||
"homeRange": 75,
|
||||
"walkingRange": 75,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [815, 3420, 0],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Blacksmith", "probability": 100 }],
|
||||
"homeRange": 2,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [816, 658, 22],
|
||||
"map": "TerMur",
|
||||
"count": 25,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Snake", "probability": 100 }
|
||||
],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [816, 3438, 0],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Tinker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [817, 3428, 0],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Carpenter", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [851, 3635, -43],
|
||||
"map": "TerMur",
|
||||
"count": 34,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Bird", "probability": 100 },
|
||||
{ "maxCount": 7, "name": "Horse", "probability": 100 },
|
||||
{ "maxCount": 7, "name": "Hind", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Rat", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Rabbit", "probability": 100 }
|
||||
],
|
||||
"homeRange": 50,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [911, 3998, -40],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Butcher", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [974, 3881, -42],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Baker", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [997, 3904, -42],
|
||||
"map": "TerMur",
|
||||
"count": 30,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "Bird", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Rabbit", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Horse", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Rat", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "GreaterMongbat", "probability": 100 }
|
||||
],
|
||||
"homeRange": 70,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1012, 3881, -42],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Blacksmith", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Armorer", "probability": 100 }
|
||||
],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1018, 3907, -42],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Healer", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1030, 2959, 61],
|
||||
"map": "TerMur",
|
||||
"count": 13,
|
||||
"entries": [
|
||||
{ "maxCount": 10, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 10, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1035, 2993, 50],
|
||||
"map": "TerMur",
|
||||
"count": 10,
|
||||
"entries": [
|
||||
{ "maxCount": 7, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 7, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 7, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1040, 3004, 50],
|
||||
"map": "TerMur",
|
||||
"count": 11,
|
||||
"entries": [
|
||||
{ "maxCount": 8, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 8, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 8, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1055, 2987, 62],
|
||||
"map": "TerMur",
|
||||
"count": 15,
|
||||
"entries": [
|
||||
{ "maxCount": 12, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 12, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 12, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1074, 3008, 63],
|
||||
"map": "TerMur",
|
||||
"count": 15,
|
||||
"entries": [
|
||||
{ "maxCount": 12, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 12, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 12, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1089, 2979, 51],
|
||||
"map": "TerMur",
|
||||
"count": 11,
|
||||
"entries": [
|
||||
{ "maxCount": 8, "name": "DesertOstard", "probability": 100 },
|
||||
{ "maxCount": 8, "name": "SandVortex", "probability": 100 },
|
||||
{ "maxCount": 8, "name": "Scorpion", "probability": 100 }
|
||||
],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1111, 3733, -42],
|
||||
"map": "TerMur",
|
||||
"count": 50,
|
||||
"entries": [
|
||||
{ "maxCount": 20, "name": "GiantBlackWidow", "probability": 100 },
|
||||
{ "maxCount": 30, "name": "GiantSpider", "probability": 100 }
|
||||
],
|
||||
"homeRange": 25,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1128, 3479, -42],
|
||||
"map": "TerMur",
|
||||
"count": 24,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "GreaterMongbat", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Snake", "probability": 100 },
|
||||
{ "maxCount": 5, "name": "Horse", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:03:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1152, 3640, -42],
|
||||
"map": "TerMur",
|
||||
"count": 9,
|
||||
"entries": [{ "maxCount": 5, "name": "GreaterMongbat", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:10:00",
|
||||
"minDelay": "00:05:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1165, 3366, -42],
|
||||
"map": "TerMur",
|
||||
"count": 18,
|
||||
"entries": [
|
||||
{ "maxCount": 4, "name": "SilverSerpent", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "GreaterMongbat", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:04:00",
|
||||
"minDelay": "00:03:00"
|
||||
}
|
||||
]
|
||||
6542
Distribution/Data/Spawns/tokuno.json
Normal file
6542
Distribution/Data/Spawns/tokuno.json
Normal file
File diff suppressed because it is too large
Load diff
37790
Distribution/Data/Spawns/trammel.json
Normal file
37790
Distribution/Data/Spawns/trammel.json
Normal file
File diff suppressed because it is too large
Load diff
16
Distribution/Data/Spawns/treasuresofkotl.json
Normal file
16
Distribution/Data/Spawns/treasuresofkotl.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [541, 2406, 10],
|
||||
"map": "TerMur",
|
||||
"count": 14,
|
||||
"entries": [
|
||||
{ "maxCount": 7, "name": "FireElemental", "probability": 100 },
|
||||
{ "maxCount": 7, "name": "LavaLizard", "probability": 100 }
|
||||
],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
}
|
||||
]
|
||||
261
Distribution/Data/Spawns/twistedweald.json
Normal file
261
Distribution/Data/Spawns/twistedweald.json
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2130, 1174, -46],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Gnaw", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:05:00",
|
||||
"minDelay": "00:02:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2131, 1173, -46],
|
||||
"map": "Ilshenar",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "DireWolf", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:01:00",
|
||||
"minDelay": "00:00:10"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2137, 1216, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Corpser", "probability": 100 }],
|
||||
"homeRange": 4,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2137, 1216, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 4,
|
||||
"entries": [{ "maxCount": 4, "name": "GiantBlackWidow", "probability": 100 }],
|
||||
"homeRange": 0,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2141, 1209, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "WhippingVine", "probability": 100 }],
|
||||
"homeRange": 18,
|
||||
"walkingRange": 18,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2150, 1188, -46],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Changeling", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2158, 1217, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Quagmire", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2158, 1224, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Irk", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2160, 1178, -40],
|
||||
"map": "Ilshenar",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "DireWolf", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2166, 1235, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [
|
||||
{ "maxCount": 1, "name": "Corpser", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "WhippingVine", "probability": 100 }
|
||||
],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2167, 1266, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "Malefic", "probability": 100 }],
|
||||
"homeRange": 0,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2170, 1247, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 4,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "Malefic", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "Virulent", "probability": 100 }
|
||||
],
|
||||
"homeRange": 0,
|
||||
"walkingRange": 10,
|
||||
"maxDelay": "00:02:00",
|
||||
"minDelay": "00:01:00"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2173, 1213, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Guile", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2174, 1203, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "LadyLissith", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2174, 1213, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Spite", "probability": 100 }],
|
||||
"homeRange": 10,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2177, 1229, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 4,
|
||||
"entries": [{ "maxCount": 4, "name": "Silk", "probability": 100 }],
|
||||
"homeRange": 0,
|
||||
"walkingRange": 5,
|
||||
"maxDelay": "00:01:30",
|
||||
"minDelay": "00:00:30"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2179, 1214, -60],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "LadySabrix", "probability": 100 }],
|
||||
"homeRange": 7,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2193, 1170, -36],
|
||||
"map": "Ilshenar",
|
||||
"count": 4,
|
||||
"entries": [{ "maxCount": 4, "name": "Changeling", "probability": 100 }],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 25,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2200, 1192, -35],
|
||||
"map": "Ilshenar",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 3, "name": "MLDryad", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2207, 1191, -36],
|
||||
"map": "Ilshenar",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Satyr", "probability": 100 }],
|
||||
"homeRange": 12,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2210, 1192, -35],
|
||||
"map": "Ilshenar",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "CuSidhe", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2211, 1169, -37],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "MLDryad", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [2222, 1222, 9],
|
||||
"map": "Ilshenar",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Swoop", "probability": 100 }],
|
||||
"homeRange": 5,
|
||||
"walkingRange": 8,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
}
|
||||
]
|
||||
121
Distribution/Data/Spawns/underworld.json
Normal file
121
Distribution/Data/Spawns/underworld.json
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
[
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1018, 1116, -42],
|
||||
"map": "TerMur",
|
||||
"count": 14,
|
||||
"entries": [
|
||||
{ "maxCount": 5, "name": "BoneMagi", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Wraith", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Spectre", "probability": 100 },
|
||||
{ "maxCount": 4, "name": "Skeleton", "probability": 100 }
|
||||
],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 20,
|
||||
"maxDelay": "00:01:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1031, 1152, -65],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Kraken", "probability": 100 }],
|
||||
"homeRange": 30,
|
||||
"walkingRange": 30,
|
||||
"maxDelay": "00:00:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1076, 1117, -65],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "Kraken", "probability": 100 }],
|
||||
"homeRange": 20,
|
||||
"walkingRange": 35,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1111, 1022, -48],
|
||||
"map": "TerMur",
|
||||
"count": 1,
|
||||
"entries": [{ "maxCount": 1, "name": "BloodElemental", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 12,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1111, 1173, -29],
|
||||
"map": "TerMur",
|
||||
"count": 8,
|
||||
"entries": [{ "maxCount": 8, "name": "Slime", "probability": 100 }],
|
||||
"homeRange": 2,
|
||||
"walkingRange": 2,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1113, 1164, -18],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "Slime", "probability": 100 }],
|
||||
"homeRange": 1,
|
||||
"walkingRange": 1,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1197, 1186, -78],
|
||||
"map": "TerMur",
|
||||
"count": 3,
|
||||
"entries": [{ "maxCount": 1, "name": "WaterElemental", "probability": 100 }],
|
||||
"homeRange": 8,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1217, 1075, -52],
|
||||
"map": "TerMur",
|
||||
"count": 2,
|
||||
"entries": [{ "maxCount": 2, "name": "RottingCorpse", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1218, 1075, -52],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [
|
||||
{ "maxCount": 2, "name": "Shade", "probability": 100 },
|
||||
{ "maxCount": 2, "name": "Spectre", "probability": 100 },
|
||||
{ "maxCount": 1, "name": "Wraith", "probability": 100 }
|
||||
],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:00:00",
|
||||
"minDelay": "00:00:01"
|
||||
},
|
||||
{
|
||||
"type": "Spawner",
|
||||
"location": [1219, 1075, -52],
|
||||
"map": "TerMur",
|
||||
"count": 5,
|
||||
"entries": [{ "maxCount": 5, "name": "Mummy", "probability": 100 }],
|
||||
"homeRange": 15,
|
||||
"walkingRange": 15,
|
||||
"maxDelay": "00:03:00",
|
||||
"minDelay": "00:00:01"
|
||||
}
|
||||
]
|
||||
3850
Distribution/Data/regions.json
Normal file
3850
Distribution/Data/regions.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Tests
|
||||
|
|
|
|||
|
|
@ -58,7 +58,8 @@ namespace Server
|
|||
|
||||
public static TypeCache GetTypeCache(Assembly asm)
|
||||
{
|
||||
if (asm == null) return m_NullCache ??= new TypeCache(null);
|
||||
if (asm == null)
|
||||
return m_NullCache ??= new TypeCache(null);
|
||||
|
||||
if (m_TypeCaches.TryGetValue(asm, out var c))
|
||||
return c;
|
||||
|
|
@ -68,6 +69,8 @@ namespace Server
|
|||
|
||||
public static Type FindFirstTypeForName(string name, bool ignoreCase = false, Func<Type, bool> predicate = null)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(name)) return null;
|
||||
|
||||
var types = FindTypesByName(name, ignoreCase).ToList();
|
||||
if (types.Count == 0)
|
||||
return null;
|
||||
|
|
@ -87,14 +90,19 @@ namespace Server
|
|||
types[0];
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> FindTypesByName(string name, bool ignoreCase = false)
|
||||
public static List<Type> FindTypesByName(string name, bool ignoreCase = false)
|
||||
{
|
||||
var types = new List<Type>();
|
||||
|
||||
if (ignoreCase)
|
||||
name = name.ToLower();
|
||||
for (var i = 0; i < Assemblies.Length; i++) types.AddRange(GetTypeCache(Assemblies[i])[name]);
|
||||
|
||||
for (var i = 0; i < Assemblies.Length; i++)
|
||||
types.AddRange(GetTypeCache(Assemblies[i])[name]);
|
||||
|
||||
if (types.Count == 0)
|
||||
types.AddRange(GetTypeCache(Core.Assembly)[name]);
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
|
|
@ -122,6 +130,7 @@ namespace Server
|
|||
public TypeCache(Assembly asm)
|
||||
{
|
||||
m_Types = asm?.GetTypes() ?? Type.EmptyTypes;
|
||||
|
||||
var nameMap = new Dictionary<string, HashSet<int>>();
|
||||
HashSet<int> refs;
|
||||
Action<int, string> addToRefs = (index, key) =>
|
||||
|
|
@ -136,6 +145,7 @@ namespace Server
|
|||
nameMap.Add(key, refs);
|
||||
}
|
||||
};
|
||||
|
||||
var aliasType = typeof(TypeAliasAttribute);
|
||||
for (var i = 0; i < m_Types.Length; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
// See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Buffers.Binary;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Collections.Concurrent;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace System.Buffers
|
||||
|
|
|
|||
|
|
@ -71,14 +71,18 @@ namespace Server
|
|||
void OnStatsQuery(Mobile beholder, Mobile beheld);
|
||||
}
|
||||
|
||||
public interface ISpawner
|
||||
// TODO: Add SpawnMap and change Spawner.Map to use it
|
||||
public interface ISpawner : IEntity
|
||||
{
|
||||
bool UnlinkOnTaming { get; }
|
||||
Point3D HomeLocation { get; }
|
||||
int HomeRange { get; }
|
||||
Region Region { get; }
|
||||
bool ReturnOnDeactivate { get; }
|
||||
|
||||
void Remove(ISpawnable spawn);
|
||||
Point3D GetSpawnPosition(ISpawnable spawned, Map map);
|
||||
void Respawn();
|
||||
}
|
||||
|
||||
public interface ISpawnable : IEntity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: MapConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class MapConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Map);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new MapConverter();
|
||||
}
|
||||
}
|
||||
105
Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs
Normal file
105
Projects/Server/JsonConfiguration/Converters/Point2DConverter.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point2DConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point2DConverter : JsonConverter<Point2D>
|
||||
{
|
||||
private Point2D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[2];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndArray)
|
||||
break;
|
||||
|
||||
if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (count < 2)
|
||||
data[count] = reader.GetInt32();
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 2)
|
||||
throw new JsonException("Point2D must be an array of x, y");
|
||||
|
||||
return new Point2D(data[0], data[1]);
|
||||
}
|
||||
|
||||
private Point2D DeserializeObj(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[2];
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Point2D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
_ => throw new JsonException($"Invalid property {key} for Point2D")
|
||||
};
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonTokenType.Number)
|
||||
throw new JsonException($"Value for {key} must be a number");
|
||||
|
||||
data[i] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return new Point2D(data[0], data[1]);
|
||||
}
|
||||
|
||||
public override Point2D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Point2D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
writer.WriteNumberValue(value.X);
|
||||
writer.WriteNumberValue(value.Y);
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point2DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point2DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Point2D) || typeToConvert == typeof(IPoint2D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new Point2DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,8 @@
|
|||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point3dConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||
* File: Point3DConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
|
|
@ -25,14 +25,11 @@ using System.Text.Json.Serialization;
|
|||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point3dConverter : JsonConverter<Point3D>
|
||||
public class Point3DConverter : JsonConverter<Point3D>
|
||||
{
|
||||
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
private Point3D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
if (reader.TokenType != JsonTokenType.StartArray)
|
||||
throw new JsonException("Point3d must be an array of x, y, z");
|
||||
|
||||
var data = new int[3];
|
||||
Span<int> data = stackalloc int[3];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
|
|
@ -50,12 +47,54 @@ namespace Server.Json
|
|||
}
|
||||
}
|
||||
|
||||
if (count < 2 || count > 3)
|
||||
throw new JsonException("Point3d must be an array of x, y, z");
|
||||
if (count > 3)
|
||||
throw new JsonException("Point3D must be an array of x, y, z");
|
||||
|
||||
return new Point3D(data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
private Point3D DeserializeObj(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[3];
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Point3D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
"z" => 2,
|
||||
_ => throw new JsonException($"Invalid property {key} for Point3D")
|
||||
};
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (reader.TokenType != JsonTokenType.Number)
|
||||
throw new JsonException($"Value for {key} must be a number");
|
||||
|
||||
data[i] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return new Point3D(data[0], data[1], data[2]);
|
||||
}
|
||||
|
||||
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Point3D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Point3DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Point3DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Point3D) || typeToConvert == typeof(IPoint3D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new Point3DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Rectangle3DConverter.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Rectangle3DConverter : JsonConverter<Rectangle3D>
|
||||
{
|
||||
private Rectangle3D DeserializeArray(ref Utf8JsonReader reader)
|
||||
{
|
||||
Span<int> data = stackalloc int[6];
|
||||
var count = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndArray)
|
||||
break;
|
||||
|
||||
if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (count < 6)
|
||||
data[count] = reader.GetInt32();
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 6)
|
||||
throw new JsonException("Rectangle3D must be an array of x, y, z, h, w, d");
|
||||
|
||||
return new Rectangle3D(data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
}
|
||||
|
||||
private Rectangle3D DeserializeObj(ref Utf8JsonReader reader, JsonSerializerOptions options)
|
||||
{
|
||||
Span<int> data = stackalloc int[6];
|
||||
|
||||
// 0 - xyzwhd, 1 - x1y1z1x2y2z2, 2 - start/end
|
||||
int objType = -1;
|
||||
|
||||
while (true)
|
||||
{
|
||||
reader.Read();
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
break;
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
throw new JsonException("Invalid Json structure for Rectangle3D object");
|
||||
|
||||
var key = reader.GetString();
|
||||
|
||||
reader.Read();
|
||||
|
||||
if (key == "start" || key == "end")
|
||||
{
|
||||
if (objType > -1 && objType != 2)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 2;
|
||||
|
||||
var point3D = reader.ToObject<Point3D>(options);
|
||||
var offset = key == "end" ? 3 : 0;
|
||||
data[0 + offset] = point3D.X;
|
||||
data[1 + offset] = point3D.Y;
|
||||
data[1 + offset] = point3D.Z;
|
||||
continue;
|
||||
}
|
||||
|
||||
var i = key switch
|
||||
{
|
||||
"x" => 0,
|
||||
"y" => 1,
|
||||
"z" => 2,
|
||||
"w" => 3,
|
||||
"width" => 3,
|
||||
"h" => 4,
|
||||
"height" => 4,
|
||||
"d" => 5,
|
||||
"depth" => 5,
|
||||
"x1" => 10,
|
||||
"y1" => 11,
|
||||
"z1" => 12,
|
||||
"x2" => 13,
|
||||
"y2" => 14,
|
||||
"z2" => 15,
|
||||
_ => throw new JsonException($"Invalid property {key} for Rectangle3D")
|
||||
};
|
||||
|
||||
if (i < 10)
|
||||
{
|
||||
if (objType > -1 && objType != 0)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 0;
|
||||
data[i] = reader.GetInt32();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (objType > -1 && objType != 1)
|
||||
throw new JsonException("Rectangle3D must have a start/end, or x/y/z/w/h/d, but not both.");
|
||||
|
||||
objType = 1;
|
||||
data[i - 10] = reader.GetInt32();
|
||||
}
|
||||
|
||||
return objType == 0
|
||||
? new Rectangle3D(data[0], data[1], data[2], data[3], data[4], data[5])
|
||||
: new Rectangle3D(
|
||||
new Point3D(data[0], data[1], data[2]),
|
||||
new Point3D(data[3], data[4], data[5])
|
||||
);
|
||||
}
|
||||
|
||||
public override Rectangle3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.StartArray => DeserializeArray(ref reader),
|
||||
JsonTokenType.StartObject => DeserializeObj(ref reader, options),
|
||||
_ => throw new JsonException("Invalid Json for Point3D")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, Rectangle3D value, JsonSerializerOptions options)
|
||||
{
|
||||
writer.WriteStartArray();
|
||||
writer.WriteNumberValue(value.Start.X);
|
||||
writer.WriteNumberValue(value.Start.Y);
|
||||
writer.WriteNumberValue(value.Start.Z);
|
||||
writer.WriteNumberValue(value.Width);
|
||||
writer.WriteNumberValue(value.Height);
|
||||
writer.WriteNumberValue(value.Depth);
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: Rectangle3DConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class Rectangle3DConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(Rectangle3D);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
|
||||
new Rectangle3DConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TimeSpanConverter.cs *
|
||||
* Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TimeSpanConverter : JsonConverter<TimeSpan>
|
||||
{
|
||||
public override TimeSpan Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
=> TimeSpan.Parse(reader.GetString());
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, TimeSpan value, JsonSerializerOptions options)
|
||||
=> writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TimeSpanConverterFactory.cs *
|
||||
* Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TimeSpanConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TimeSpan);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) => new TimeSpanConverter();
|
||||
}
|
||||
}
|
||||
57
Projects/Server/JsonConfiguration/DynamicJson.cs
Normal file
57
Projects/Server/JsonConfiguration/DynamicJson.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: DynamicJson.cs - Created: 2020/05/23 - Updated: 2020/05/23 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class DynamicJson
|
||||
{
|
||||
[JsonPropertyName("type")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[JsonExtensionData]
|
||||
public Dictionary<string, JsonElement> data { get; set; }
|
||||
|
||||
public bool GetProperty<T>(string key, JsonSerializerOptions options, out T t)
|
||||
{
|
||||
if (data.TryGetValue(key, out var el))
|
||||
{
|
||||
t = el.ToObject<T>(options);
|
||||
return true;
|
||||
}
|
||||
|
||||
t = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool GetEnumProperty<T>(string key, JsonSerializerOptions options, out T t) where T : struct, Enum
|
||||
{
|
||||
if (data.TryGetValue(key, out var el))
|
||||
return Enum.TryParse(el.ToObject<string>(options), out t);
|
||||
|
||||
t = default;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
|
|
@ -46,5 +48,23 @@ namespace Server.Json
|
|||
|
||||
File.WriteAllText(filePath, JsonSerializer.Serialize(value, options ?? Options));
|
||||
}
|
||||
|
||||
public static T ToObject<T>(this ref Utf8JsonReader reader, JsonSerializerOptions options = null) =>
|
||||
JsonSerializer.Deserialize<T>(ref reader, options);
|
||||
|
||||
public static T ToObject<T>(this JsonElement element, JsonSerializerOptions options = null)
|
||||
{
|
||||
var bufferWriter = new ArrayBufferWriter<byte>();
|
||||
using (var writer = new Utf8JsonWriter(bufferWriter))
|
||||
element.WriteTo(writer);
|
||||
return JsonSerializer.Deserialize<T>(bufferWriter.WrittenSpan, options);
|
||||
}
|
||||
|
||||
public static T ToObject<T>(this JsonDocument document, JsonSerializerOptions options = null)
|
||||
{
|
||||
if (document == null)
|
||||
throw new ArgumentNullException(nameof(document));
|
||||
return document.RootElement.ToObject<T>(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ namespace Server
|
|||
|
||||
AssemblyHandler.Invoke("Configure");
|
||||
|
||||
Region.Load();
|
||||
RegionLoader.LoadRegions();
|
||||
World.Load();
|
||||
|
||||
AssemblyHandler.Invoke("Initialize");
|
||||
|
|
|
|||
|
|
@ -374,15 +374,9 @@ namespace Server
|
|||
|
||||
public int CompareTo(Map other) => other == null ? -1 : MapID.CompareTo(other.MapID);
|
||||
|
||||
public static string[] GetMapNames()
|
||||
{
|
||||
return Maps.Where(m => m != null).Select(m => m.Name).ToArray();
|
||||
}
|
||||
public static string[] GetMapNames() => Maps.Where(m => m != null).Select(m => m.Name).ToArray();
|
||||
|
||||
public static Map[] GetMapValues()
|
||||
{
|
||||
return Maps.Where(m => m != null).ToArray();
|
||||
}
|
||||
public static Map[] GetMapValues() => Maps.Where(m => m != null).ToArray();
|
||||
|
||||
public static Map Parse(string value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
|
|||
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
|
|
@ -146,10 +145,10 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
public Region(XmlElement xml, Map map, Region parent)
|
||||
public Region(DynamicJson json, JsonSerializerOptions options)
|
||||
{
|
||||
Map = map;
|
||||
Parent = parent;
|
||||
Map = json.GetProperty("map", options, out Map map) ? map : null;
|
||||
Parent = json.GetProperty("parent", options, out string parent) ? Find(parent, Map) : null;
|
||||
Dynamic = false;
|
||||
|
||||
if (Parent == null)
|
||||
|
|
@ -163,31 +162,21 @@ namespace Server
|
|||
m_Priority = Parent.Priority;
|
||||
}
|
||||
|
||||
ReadString(xml, "name", ref m_Name, false);
|
||||
m_Name = json.GetProperty("name", options, out string name) ? name : null;
|
||||
|
||||
if (parent == null)
|
||||
ReadInt32(xml, "priority", ref m_Priority, false);
|
||||
m_Priority = json.GetProperty("priority", options, out int priority) ? priority : 0;
|
||||
|
||||
var minZ = MinZ;
|
||||
var maxZ = MaxZ;
|
||||
|
||||
var zrange = xml["zrange"];
|
||||
ReadInt32(zrange, "min", ref minZ, false);
|
||||
ReadInt32(zrange, "max", ref maxZ, false);
|
||||
|
||||
var area = new List<Rectangle3D>();
|
||||
foreach (XmlElement xmlRect in xml.SelectNodes("rect"))
|
||||
{
|
||||
if (ReadRectangle3D(xmlRect, minZ, maxZ, out var rect))
|
||||
area.Add(rect);
|
||||
}
|
||||
|
||||
Area = area.ToArray();
|
||||
Area = json.GetProperty("rects", options, out List<Rectangle3D> rects) ?
|
||||
rects.ToArray() : Array.Empty<Rectangle3D>();
|
||||
|
||||
if (Area.Length == 0)
|
||||
Console.WriteLine("Empty area for region '{0}'", this);
|
||||
|
||||
if (!ReadPoint3D(xml["go"], map, ref m_GoLocation, false) && Area.Length > 0)
|
||||
if (json.GetProperty("go", options, out Point3D go))
|
||||
{
|
||||
m_GoLocation = go;
|
||||
}
|
||||
else if (Area.Length > 0)
|
||||
{
|
||||
var start = Area[0].Start;
|
||||
var end = Area[0].End;
|
||||
|
|
@ -195,14 +184,10 @@ namespace Server
|
|||
var x = start.X + (end.X - start.X) / 2;
|
||||
var y = start.Y + (end.Y - start.Y) / 2;
|
||||
|
||||
m_GoLocation = new Point3D(x, y, Map.GetAverageZ(x, y));
|
||||
m_GoLocation = new Point3D(x, y, Map?.GetAverageZ(x, y) ?? start.Z + (end.Z - start.Z) / 2);
|
||||
}
|
||||
|
||||
var music = DefaultMusic;
|
||||
|
||||
ReadEnum(xml["music"], "name", ref music, false);
|
||||
|
||||
Music = music;
|
||||
Music = json.GetEnumProperty("music", options, out MusicName music) ? music : DefaultMusic;
|
||||
}
|
||||
|
||||
public static List<Region> Regions { get; } = new List<Region>();
|
||||
|
|
@ -267,6 +252,29 @@ namespace Server
|
|||
return reg.ChildLevel - ChildLevel;
|
||||
}
|
||||
|
||||
// This is not optimized. Use sparingly
|
||||
public static Region Find(string name, Map map, bool insensitive = false)
|
||||
{
|
||||
if (insensitive)
|
||||
name = name.ToLower();
|
||||
|
||||
for (int i = 0; i < Regions.Count; i++)
|
||||
{
|
||||
var region = Regions[i];
|
||||
if (region.Map != map)
|
||||
continue;
|
||||
|
||||
string rName = region.Name;
|
||||
if (insensitive)
|
||||
rName = rName.ToLower();
|
||||
|
||||
if (rName == name)
|
||||
return region;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Region Find(Point3D p, Map map)
|
||||
{
|
||||
if (map == null)
|
||||
|
|
@ -727,338 +735,5 @@ namespace Server
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static void Load()
|
||||
{
|
||||
if (!File.Exists("Data/Regions.xml"))
|
||||
{
|
||||
Console.WriteLine("Error: Data/Regions.xml does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.Write("Regions: Loading...");
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(Path.Combine(Core.BaseDirectory, "Data/Regions.xml"));
|
||||
|
||||
var root = doc["ServerRegions"];
|
||||
|
||||
if (root == null)
|
||||
{
|
||||
Console.WriteLine("Could not find root element 'ServerRegions' in Regions.xml");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (XmlElement facet in root.SelectNodes("Facet"))
|
||||
{
|
||||
Map map = null;
|
||||
if (ReadMap(facet, "name", ref map))
|
||||
{
|
||||
if (map == Map.Internal)
|
||||
Console.WriteLine("Invalid internal map in a facet element");
|
||||
else
|
||||
LoadRegions(facet, map, null);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine("done");
|
||||
}
|
||||
|
||||
private static void LoadRegions(XmlElement xml, Map map, Region parent)
|
||||
{
|
||||
foreach (XmlElement xmlReg in xml.SelectNodes("region"))
|
||||
{
|
||||
var type = DefaultRegionType;
|
||||
|
||||
ReadType(xmlReg, "type", ref type, false);
|
||||
|
||||
if (!typeof(Region).IsAssignableFrom(type))
|
||||
{
|
||||
Console.WriteLine("Invalid region type '{0}' in regions.xml", type.FullName);
|
||||
continue;
|
||||
}
|
||||
|
||||
Region region;
|
||||
try
|
||||
{
|
||||
region = (Region)ActivatorUtil.CreateInstance(type, xmlReg, map, parent);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error during the creation of region type '{0}': {1}", type.FullName, ex);
|
||||
continue;
|
||||
}
|
||||
|
||||
region.Register();
|
||||
|
||||
LoadRegions(xmlReg, map, region);
|
||||
}
|
||||
}
|
||||
|
||||
protected static string GetAttribute(XmlElement xml, string attribute, bool mandatory)
|
||||
{
|
||||
if (xml == null)
|
||||
{
|
||||
if (mandatory)
|
||||
Console.WriteLine("Missing element for attribute '{0}'", attribute);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (xml.HasAttribute(attribute)) return xml.GetAttribute(attribute);
|
||||
if (mandatory)
|
||||
Console.WriteLine("Missing attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool ReadString(XmlElement xml, string attribute, ref string value) =>
|
||||
ReadString(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadString(XmlElement xml, string attribute, ref string value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
value = s;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadInt32(XmlElement xml, string attribute, ref int value) =>
|
||||
ReadInt32(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadInt32(XmlElement xml, string attribute, ref int value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToInt32(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse integer attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadBoolean(XmlElement xml, string attribute, ref bool value) =>
|
||||
ReadBoolean(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadBoolean(XmlElement xml, string attribute, ref bool value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToBoolean(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse boolean attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadDateTime(XmlElement xml, string attribute, ref DateTime value) =>
|
||||
ReadDateTime(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadDateTime(XmlElement xml, string attribute, ref DateTime value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToDateTime(s, XmlDateTimeSerializationMode.Utc);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse DateTime attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadTimeSpan(XmlElement xml, string attribute, ref TimeSpan value) =>
|
||||
ReadTimeSpan(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadTimeSpan(XmlElement xml, string attribute, ref TimeSpan value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = XmlConvert.ToTimeSpan(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse TimeSpan attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadEnum<T>(XmlElement xml, string attribute, ref T value) where T : struct =>
|
||||
ReadEnum(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadEnum<T>(XmlElement xml, string attribute, ref T value, bool mandatory)
|
||||
where T : struct // We can't limit the where clause to Enums only
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
var type = typeof(T);
|
||||
|
||||
if (type.IsEnum && Enum.TryParse(s, true, out T tempVal))
|
||||
{
|
||||
value = tempVal;
|
||||
return true;
|
||||
}
|
||||
|
||||
Console.WriteLine("Could not parse {0} enum attribute '{1}' in element '{2}'", type, attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ReadMap(XmlElement xml, string attribute, ref Map value) => ReadMap(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadMap(XmlElement xml, string attribute, ref Map value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
value = Map.Parse(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse Map attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadType(XmlElement xml, string attribute, ref Type value) =>
|
||||
ReadType(xml, attribute, ref value, true);
|
||||
|
||||
public static bool ReadType(XmlElement xml, string attribute, ref Type value, bool mandatory)
|
||||
{
|
||||
var s = GetAttribute(xml, attribute, mandatory);
|
||||
|
||||
if (s == null)
|
||||
return false;
|
||||
|
||||
Type type;
|
||||
try
|
||||
{
|
||||
type = AssemblyHandler.FindFirstTypeForName(s);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine("Could not parse Type attribute '{0}' in element '{1}'", attribute, xml.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
Console.WriteLine("Could not find Type '{0}'", s);
|
||||
return false;
|
||||
}
|
||||
|
||||
value = type;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool ReadPoint3D(XmlElement xml, Map map, ref Point3D value) => ReadPoint3D(xml, map, ref value, true);
|
||||
|
||||
public static bool ReadPoint3D(XmlElement xml, Map map, ref Point3D value, bool mandatory)
|
||||
{
|
||||
int x = 0, y = 0, z = 0;
|
||||
|
||||
var xyOk = ReadInt32(xml, "x", ref x, mandatory) & ReadInt32(xml, "y", ref y, mandatory);
|
||||
var zOk = ReadInt32(xml, "z", ref z, mandatory && map == null);
|
||||
|
||||
if (xyOk && (zOk || map != null))
|
||||
{
|
||||
if (!zOk)
|
||||
z = map.GetAverageZ(x, y);
|
||||
|
||||
value = new Point3D(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool ReadRectangle3D(XmlElement xml, int defaultMinZ, int defaultMaxZ, out Rectangle3D value) =>
|
||||
ReadRectangle3D(xml, defaultMinZ, defaultMaxZ, out value, true);
|
||||
|
||||
public static bool ReadRectangle3D(XmlElement xml, int defaultMinZ, int defaultMaxZ, out Rectangle3D value,
|
||||
bool mandatory)
|
||||
{
|
||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0;
|
||||
var z1 = defaultMinZ;
|
||||
var z2 = defaultMaxZ;
|
||||
|
||||
if (xml.HasAttribute("x"))
|
||||
{
|
||||
if (ReadInt32(xml, "x", ref x1, mandatory)
|
||||
& ReadInt32(xml, "y", ref y1, mandatory)
|
||||
& ReadInt32(xml, "width", ref x2, mandatory)
|
||||
& ReadInt32(xml, "height", ref y2, mandatory))
|
||||
{
|
||||
x2 += x1;
|
||||
y2 += y1;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ReadInt32(xml, "x1", ref x1, mandatory)
|
||||
| !ReadInt32(xml, "y1", ref y1, mandatory)
|
||||
| !ReadInt32(xml, "x2", ref x2, mandatory)
|
||||
| !ReadInt32(xml, "y2", ref y2, mandatory))
|
||||
{
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ReadInt32(xml, "zmin", ref z1, false);
|
||||
ReadInt32(xml, "zmax", ref z2, false);
|
||||
|
||||
value = new Rectangle3D(new Point3D(x1, y1, z1), new Point3D(x2, y2, z2));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Projects/Server/Regions/RegionLoader.cs
Normal file
60
Projects/Server/Regions/RegionLoader.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class RegionLoader
|
||||
{
|
||||
public static void LoadRegions()
|
||||
{
|
||||
var path = Path.Join(Core.BaseDirectory, "Data/regions.json");
|
||||
|
||||
// Json Deserialization options for custom objects
|
||||
JsonSerializerOptions options = new JsonSerializerOptions();
|
||||
options.Converters.Add(new MapConverterFactory());
|
||||
options.Converters.Add(new Point3DConverterFactory());
|
||||
options.Converters.Add(new Rectangle3DConverterFactory());
|
||||
|
||||
List<string> failures = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
Console.Write("Regions: Loading...");
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
List<DynamicJson> regions = JsonConfig.Deserialize<List<DynamicJson>>(path);
|
||||
|
||||
foreach (var json in regions)
|
||||
{
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(json.Type);
|
||||
|
||||
if (type == null || !typeof(Region).IsAssignableFrom(type))
|
||||
{
|
||||
failures.Add($"\tInvalid region type {json.Type}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var region = ActivatorUtil.CreateInstance(type, json, options) as Region;
|
||||
region?.Register();
|
||||
count++;
|
||||
}
|
||||
|
||||
stopwatch.Stop();
|
||||
|
||||
Console.ForegroundColor = failures.Count > 0 ? ConsoleColor.Yellow : ConsoleColor.Green;
|
||||
Console.Write("done{0}. ", failures.Count > 0 ? " with failures" : "");
|
||||
Console.ResetColor();
|
||||
Console.WriteLine("({0} regions, {1} failures) ({2:F2} seconds)", count, failures.Count, stopwatch.Elapsed.TotalSeconds);
|
||||
if (failures.Count > 0)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(string.Join("\n", failures));
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -75,10 +75,10 @@
|
|||
<CodeAnalysisRuleSet>..\..\Rules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.1.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.3" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Connections.Abstractions" Version="3.1.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="3.1.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="3.1.4" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="4.7.2" />
|
||||
<PackageReference Include="ZLib.Bindings" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Configuration)'=='Analyze'">
|
||||
|
|
@ -87,7 +87,7 @@
|
|||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
|
||||
<Version>2.9.8</Version>
|
||||
<Version>3.0.0</Version>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ namespace Server.Utilities
|
|||
// check all given args map to params.
|
||||
for (var i = 0; i < args.Length; i++)
|
||||
// if a null reference is passed, but the type is not nullable
|
||||
if ((args[i] == null && paramList[i].ParameterType.IsValueType)
|
||||
if (args[i] == null && paramList[i].ParameterType.IsValueType
|
||||
// or if an arg is not null and is not assignable to the parameter type, skip.
|
||||
|| !(args[i] == null || paramList[i].ParameterType.IsAssignableFrom(args[i])))
|
||||
return false;
|
||||
|
|
@ -65,7 +65,8 @@ namespace Server.Utilities
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new TypeInitializationException(type.ToString(), e);
|
||||
Console.WriteLine(e);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ namespace Server
|
|||
{
|
||||
public interface IRandomProvider
|
||||
{
|
||||
public uint Next(uint c);
|
||||
public ulong Next(ulong max);
|
||||
public uint Next(uint max);
|
||||
public bool NextBool();
|
||||
public void GetBytes(Span<byte> b);
|
||||
public double NextDouble();
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ namespace Server
|
|||
|
||||
public override void GetBytes(Span<byte> data) => m_Random.GetBytes(data);
|
||||
|
||||
public ulong Next(ulong c) => throw new NotImplementedException();
|
||||
|
||||
public uint Next(uint c) => throw new NotImplementedException();
|
||||
|
||||
public bool NextBool() => throw new NotImplementedException();
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ namespace Server.Misc
|
|||
state.Send(new CharacterListUpdate(acct));
|
||||
}
|
||||
else if (m.AccessLevel == AccessLevel.Player &&
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf<Jail>()) // Don't need to check current location, if netstate is null, they're logged out
|
||||
Region.Find(m.LogoutLocation, m.LogoutMap).IsPartOf<JailRegion>()) // Don't need to check current location, if netstate is null, they're logged out
|
||||
{
|
||||
state.Send(new DeleteResult(DeleteResultType.BadRequest));
|
||||
state.Send(new CharacterListUpdate(acct));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Server.Items;
|
||||
|
|
@ -190,13 +191,9 @@ namespace Server.Commands
|
|||
if (!IsConstructible(ctor, from.AccessLevel))
|
||||
continue;
|
||||
|
||||
int totalParams = 0;
|
||||
|
||||
// Handle optional constructors
|
||||
ParameterInfo[] paramList = ctor.GetParameters();
|
||||
for (int j = 0; j < paramList.Length; j++)
|
||||
if (!paramList[j].HasDefaultValue)
|
||||
totalParams += 1;
|
||||
int totalParams = paramList.Count(t => !t.HasDefaultValue);
|
||||
|
||||
if (args.Length >= totalParams && args.Length <= paramList.Length)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Server.Engines.Quests.Haven;
|
||||
using Server.Engines.Quests.Necro;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server.Commands
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Server.Engines.Quests.Haven;
|
||||
using Server.Engines.Quests.Necro;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server.Commands
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Server.Commands
|
|||
{
|
||||
public struct Location
|
||||
{
|
||||
[JsonPropertyName("point"), JsonConverter(typeof(Point3dConverter))]
|
||||
[JsonPropertyName("point"), JsonConverter(typeof(Point3DConverter))]
|
||||
public Point3D Pos { get; set; }
|
||||
[JsonPropertyName("map"), JsonConverter(typeof(MapConverter))]
|
||||
public Map Map { get; set; }
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ namespace Server.Commands
|
|||
|
||||
int v = -aCount.CompareTo(bCount);
|
||||
|
||||
return v != 0 ? v : x.Key.FullName.CompareTo(y.Key.FullName);
|
||||
return v != 0 ? v : x.Key.FullName?.CompareTo(y.Key.FullName) ?? -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -353,7 +353,7 @@ namespace Server.Commands
|
|||
|
||||
int v = -aCount.CompareTo(bCount);
|
||||
|
||||
return v != 0 ? v : x.Key.FullName.CompareTo(y.Key.FullName);
|
||||
return v != 0 ? v : x.Key.FullName?.CompareTo(y.Key.FullName) ?? 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
using System;
|
||||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
|
|
|||
|
|
@ -1148,7 +1148,7 @@ namespace Server.Engines.ConPVP
|
|||
if (!pm.CheckAlive())
|
||||
{
|
||||
}
|
||||
else if (pm.Region.IsPartOf<Jail>())
|
||||
else if (pm.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
}
|
||||
else if (CheckCombat(pm))
|
||||
|
|
@ -1942,7 +1942,7 @@ namespace Server.Engines.ConPVP
|
|||
if (dp == null)
|
||||
return "a slot is empty";
|
||||
|
||||
if (dp.Mobile.Region.IsPartOf<Jail>())
|
||||
if (dp.Mobile.Region.IsPartOf<JailRegion>())
|
||||
return $"{dp.Mobile.Name} is in jail";
|
||||
|
||||
if (Sigil.ExistsOn(dp.Mobile))
|
||||
|
|
|
|||
|
|
@ -595,7 +595,7 @@ namespace Server.Engines.ConPVP
|
|||
Mobile check = part.Players[j];
|
||||
|
||||
if (check.Deleted || check.Map == null || check.Map == Map.Internal || !check.Alive ||
|
||||
Sigil.ExistsOn(check) || check.Region.IsPartOf<Jail>())
|
||||
Sigil.ExistsOn(check) || check.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
bad = true;
|
||||
break;
|
||||
|
|
@ -776,7 +776,7 @@ namespace Server.Engines.ConPVP
|
|||
Mobile check = part.Players[j];
|
||||
|
||||
if (check.Deleted || check.Map == null || check.Map == Map.Internal || !check.Alive ||
|
||||
Sigil.ExistsOn(check) || check.Region.IsPartOf<Jail>())
|
||||
Sigil.ExistsOn(check) || check.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
bad = true;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ namespace Server.Engines.Help
|
|||
{
|
||||
from.Location = house.BanLocation;
|
||||
}
|
||||
else if (from.Region.IsPartOf<Jail>())
|
||||
else if (from.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
from.SendLocalizedMessage(1114345, "", 0x35); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ namespace Server.Engines.Help
|
|||
{
|
||||
if (IsYoung(from))
|
||||
{
|
||||
if (from.Region.IsPartOf<Jail>())
|
||||
if (from.Region.IsPartOf<JailRegion>())
|
||||
from.SendLocalizedMessage(1114345, "", 0x35); // You'll need a better jailbreak plan than that!
|
||||
else if (from.Region.IsPartOf("Haven Island"))
|
||||
from.SendLocalizedMessage(1041529); // You're already in Haven
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Configurations;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
@ -275,4 +276,4 @@ namespace Server.Engines.MLQuests.Definitions
|
|||
reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
@ -82,4 +83,4 @@ namespace Server.Engines.MLQuests.Definitions
|
|||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using Server.Engines.MLQuests.Items;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Collections.Generic;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
@ -2518,4 +2519,4 @@ namespace Server.Engines.MLQuests.Definitions
|
|||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using Server.Engines.MLQuests.Gumps;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
using Server.Engines.MLQuests.Rewards;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.MLQuests
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ namespace Server.Engines.Quests
|
|||
|
||||
public override void UseGate(Mobile m)
|
||||
{
|
||||
if (m.Region.IsPartOf<Jail>())
|
||||
if (m.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
m.SendLocalizedMessage(1114345); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class CancelQuestRegion : BaseRegion
|
||||
{
|
||||
private readonly Type m_Quest;
|
||||
|
||||
public CancelQuestRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
ReadType(xml["quest"], "type", ref m_Quest);
|
||||
}
|
||||
|
||||
public Type Quest => m_Quest;
|
||||
|
||||
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
|
||||
{
|
||||
if (!base.OnMoveInto(m, d, newLocation, oldLocation))
|
||||
return false;
|
||||
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
if (m_Quest == null)
|
||||
return true;
|
||||
|
||||
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == m_Quest)
|
||||
{
|
||||
if (!player.HasGump<QuestCancelGump>())
|
||||
player.Quest.BeginCancelQuest();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestCompleteObjectiveRegion : BaseRegion
|
||||
{
|
||||
private readonly Type m_Objective;
|
||||
private readonly Type m_Quest;
|
||||
|
||||
public QuestCompleteObjectiveRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
XmlElement questEl = xml["quest"];
|
||||
|
||||
ReadType(questEl, "type", ref m_Quest);
|
||||
ReadType(questEl, "complete", ref m_Objective);
|
||||
}
|
||||
|
||||
public Type Quest => m_Quest;
|
||||
public Type Objective => m_Objective;
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
base.OnEnter(m);
|
||||
|
||||
if (m_Quest != null && m_Objective != null)
|
||||
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == m_Quest)
|
||||
{
|
||||
QuestObjective obj = player.Quest.FindObjective(m_Objective);
|
||||
|
||||
if (obj?.Completed == false)
|
||||
obj.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestNoEntryRegion : BaseRegion
|
||||
{
|
||||
private readonly Type m_MaxObjective;
|
||||
private readonly int m_Message;
|
||||
private readonly Type m_MinObjective;
|
||||
private readonly Type m_Quest;
|
||||
|
||||
public QuestNoEntryRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
XmlElement questEl = xml["quest"];
|
||||
|
||||
ReadType(questEl, "type", ref m_Quest);
|
||||
ReadType(questEl, "min", ref m_MinObjective, false);
|
||||
ReadType(questEl, "max", ref m_MaxObjective, false);
|
||||
ReadInt32(questEl, "message", ref m_Message, false);
|
||||
}
|
||||
|
||||
public Type Quest => m_Quest;
|
||||
public Type MinObjective => m_MinObjective;
|
||||
public Type MaxObjective => m_MaxObjective;
|
||||
public int Message => m_Message;
|
||||
|
||||
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
|
||||
{
|
||||
if (!base.OnMoveInto(m, d, newLocation, oldLocation))
|
||||
return false;
|
||||
|
||||
if (m.AccessLevel > AccessLevel.Player)
|
||||
return true;
|
||||
|
||||
if (m is BaseCreature bc && !bc.Controlled && !bc.Summoned)
|
||||
return true;
|
||||
|
||||
if (m_Quest == null)
|
||||
return true;
|
||||
|
||||
if (m is PlayerMobile player && player.Quest != null && player.Quest.GetType() == m_Quest
|
||||
&& (m_MinObjective == null || player.Quest.FindObjective(m_MinObjective) != null)
|
||||
&& (m_MaxObjective == null || player.Quest.FindObjective(m_MaxObjective) == null))
|
||||
return true;
|
||||
|
||||
if (m_Message != 0)
|
||||
m.SendLocalizedMessage(m_Message);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server.Engines.Quests
|
||||
{
|
||||
public class QuestOfferRegion : BaseRegion
|
||||
{
|
||||
private readonly Type m_Quest;
|
||||
|
||||
public QuestOfferRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
ReadType(xml["quest"], "type", ref m_Quest);
|
||||
}
|
||||
|
||||
public Type Quest => m_Quest;
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
base.OnEnter(m);
|
||||
|
||||
if (m_Quest == null)
|
||||
return;
|
||||
|
||||
if (m is PlayerMobile player && player.Quest == null && QuestSystem.CanOfferQuest(m, m_Quest))
|
||||
try
|
||||
{
|
||||
QuestSystem qs = (QuestSystem)ActivatorUtil.CreateInstance(m_Quest, player);
|
||||
qs.SendOffer();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error creating quest {0}: {1}", m_Quest, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SpawnerType
|
||||
{
|
||||
public static Type GetType(string name) => AssemblyHandler.FindFirstTypeForName(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using Server.Commands;
|
||||
using Server.Items;
|
||||
using Server.Json;
|
||||
using Server.Mobiles;
|
||||
using Server.Utilities;
|
||||
using CPA = Server.CommandPropertyAttribute;
|
||||
|
||||
namespace Server.Mobiles
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class Spawner : Item, ISpawner
|
||||
public abstract class BaseSpawner : Item, ISpawner
|
||||
{
|
||||
private static WarnTimer m_WarnTimer;
|
||||
private int m_Count;
|
||||
private bool m_Group;
|
||||
private int m_HomeRange;
|
||||
private int m_Team;
|
||||
private TimeSpan m_MaxDelay;
|
||||
private TimeSpan m_MinDelay;
|
||||
private bool m_Running;
|
||||
private int m_Team;
|
||||
|
||||
private InternalTimer m_Timer;
|
||||
private int m_WalkingRange = -1;
|
||||
|
||||
// [Constructible]
|
||||
public Spawner(int amount, int minDelay, int maxDelay, int team, int homeRange, string spawnedNames) : base(0x1f13)
|
||||
public BaseSpawner() : this(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4)
|
||||
{
|
||||
InitSpawn(amount, TimeSpan.FromMinutes(minDelay), TimeSpan.FromMinutes(maxDelay), team, homeRange);
|
||||
AddEntry(spawnedNames, 100, amount, false);
|
||||
}
|
||||
|
||||
// [Constructible]
|
||||
public Spawner(string spawnedName) : base(0x1f13)
|
||||
public BaseSpawner(string spawnedName) : this(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4, spawnedName)
|
||||
{
|
||||
InitSpawn(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4);
|
||||
AddEntry(spawnedName, 100, 1, false);
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public Spawner() : base(0x1f13)
|
||||
public BaseSpawner(int amount, int minDelay, int maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : this(amount, TimeSpan.FromMinutes(minDelay), TimeSpan.FromMinutes(maxDelay),
|
||||
team, homeRange, spawnedNames)
|
||||
{
|
||||
InitSpawn(1, TimeSpan.FromMinutes(5), TimeSpan.FromMinutes(10), 0, 4);
|
||||
}
|
||||
|
||||
public Spawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange,
|
||||
public BaseSpawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : base(0x1f13)
|
||||
{
|
||||
InitSpawn(amount, minDelay, maxDelay, team, homeRange);
|
||||
|
|
@ -51,7 +49,25 @@ namespace Server.Mobiles
|
|||
AddEntry(spawnedNames[i], 100, amount, false);
|
||||
}
|
||||
|
||||
public Spawner(Serial serial) : base(serial)
|
||||
public BaseSpawner(DynamicJson json, JsonSerializerOptions options) : base(0x1f13)
|
||||
{
|
||||
json.GetProperty("count", options, out int amount);
|
||||
json.GetProperty("minDelay", options, out TimeSpan minDelay);
|
||||
json.GetProperty("maxDelay", options, out TimeSpan maxDelay);
|
||||
json.GetProperty("team", options, out int team);
|
||||
json.GetProperty("homeRange", options, out int homeRange);
|
||||
json.GetProperty("walkingRange", options, out int walkingRange);
|
||||
m_WalkingRange = walkingRange;
|
||||
|
||||
InitSpawn(amount, minDelay, maxDelay, team, homeRange);
|
||||
|
||||
json.GetProperty("entries", options, out List<SpawnerEntry> entries);
|
||||
|
||||
foreach (var entry in entries)
|
||||
AddEntry(entry.SpawnedName, entry.SpawnedProbability, entry.SpawnedMaxCount, false);
|
||||
}
|
||||
|
||||
public BaseSpawner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +80,9 @@ namespace Server.Mobiles
|
|||
|
||||
public Dictionary<ISpawnable, SpawnerEntry> Spawned { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Developer)]
|
||||
public bool ReturnOnDeactivate { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.Developer)]
|
||||
public int Count
|
||||
{
|
||||
|
|
@ -72,9 +91,8 @@ namespace Server.Mobiles
|
|||
{
|
||||
m_Count = value;
|
||||
|
||||
if (m_Timer != null)
|
||||
if ((!IsFull && !m_Timer.Running) || (IsFull && m_Timer.Running))
|
||||
DoTimer();
|
||||
if (m_Timer != null && (!IsFull && !m_Timer.Running || IsFull && m_Timer.Running))
|
||||
DoTimer();
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
|
|
@ -164,7 +182,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
}
|
||||
|
||||
public Point3D HomeLocation => Location;
|
||||
public virtual Point3D HomeLocation => Location;
|
||||
public bool UnlinkOnTaming => true;
|
||||
|
||||
[CommandProperty(AccessLevel.Developer)]
|
||||
|
|
@ -199,7 +217,7 @@ namespace Server.Mobiles
|
|||
|
||||
public override void OnAfterDuped(Item newItem)
|
||||
{
|
||||
if (newItem is Spawner newSpawner)
|
||||
if (newItem is BaseSpawner newSpawner)
|
||||
for (int i = 0; i < Entries.Count; i++)
|
||||
newSpawner.AddEntry(Entries[i].SpawnedName, Entries[i].SpawnedProbability, Entries[i].SpawnedMaxCount,
|
||||
false);
|
||||
|
|
@ -238,6 +256,10 @@ namespace Server.Mobiles
|
|||
from.SendGump(new SpawnerGump(this));
|
||||
}
|
||||
|
||||
public virtual void GetSpawnerProperties(ObjectPropertyList list)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
|
@ -248,14 +270,16 @@ namespace Server.Mobiles
|
|||
|
||||
list.Add(1060656, m_Count.ToString()); // amount to make: ~1_val~
|
||||
list.Add(1061169, m_HomeRange.ToString()); // range ~1_val~
|
||||
list.Add(1060658, "walking range\t{0}", m_WalkingRange); // ~1_val~: ~2_val~
|
||||
list.Add(1050039, "walking range:\t{0}", m_WalkingRange); // ~1_NUMBER~ ~2_ITEMNAME~
|
||||
|
||||
list.Add(1060658, "group\t{0}", m_Group); // ~1_val~: ~2_val~
|
||||
list.Add(1060659, "team\t{0}", m_Team); // ~1_val~: ~2_val~
|
||||
list.Add(1060660, "speed\t{0} to {1}", m_MinDelay, m_MaxDelay); // ~1_val~: ~2_val~
|
||||
list.Add(1053099, "group:\t{0}", m_Group); // ~1_oretype~: ~2_armortype~
|
||||
list.Add(1060847, "team:\t{0}", m_Team); // ~1_val~ ~2_val~
|
||||
list.Add(1063483, "delay:\t{0} to {1}", m_MinDelay, m_MaxDelay); // ~1_MATERIAL~: ~2_ITEMNAME~
|
||||
|
||||
for (int i = 0; i < 3 && i < Entries.Count; ++i)
|
||||
list.Add(1060661 + i, "{0}\t{1}", Entries[i].SpawnedName, CountSpawns(Entries[i]));
|
||||
GetSpawnerProperties(list);
|
||||
|
||||
for (int i = 0; i < 6 && i < Entries.Count; ++i)
|
||||
list.Add(1060658 + i, "\t{0}\t{1}", Entries[i].SpawnedName, CountSpawns(Entries[i]));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -300,6 +324,22 @@ namespace Server.Mobiles
|
|||
Entries[i].Defrag(this);
|
||||
}
|
||||
|
||||
public virtual bool OnDefragSpawn(ISpawnable spawned, bool remove)
|
||||
{
|
||||
if (!remove) // Override could have set it to true already
|
||||
remove = spawned.Deleted || spawned.Spawner == null || spawned switch
|
||||
{
|
||||
Item item => item.RootParent is Mobile || item.IsLockedDown || item.IsSecure,
|
||||
Mobile m => m is BaseCreature c && (c.Controlled || c.IsStabled),
|
||||
_ => true
|
||||
};
|
||||
|
||||
if (remove)
|
||||
Spawned.Remove(spawned);
|
||||
|
||||
return remove;
|
||||
}
|
||||
|
||||
public void OnTick()
|
||||
{
|
||||
if (m_Group)
|
||||
|
|
@ -336,11 +376,7 @@ namespace Server.Mobiles
|
|||
if (Entries.Count <= 0 || IsFull)
|
||||
return;
|
||||
|
||||
int probsum = 0;
|
||||
|
||||
for (int i = 0; i < Entries.Count; i++)
|
||||
if (!Entries[i].IsFull)
|
||||
probsum += Entries[i].SpawnedProbability;
|
||||
int probsum = Entries.Where(t => !t.IsFull).Sum(t => t.SpawnedProbability);
|
||||
|
||||
if (probsum <= 0)
|
||||
return;
|
||||
|
|
@ -443,7 +479,7 @@ namespace Server.Mobiles
|
|||
// Defrag taken care of in Spawn(), beforehand
|
||||
// Count check taken care of in Spawn(), beforehand
|
||||
|
||||
Type type = SpawnerType.GetType(entry.SpawnedName);
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(entry.SpawnedName);
|
||||
|
||||
if (type != null)
|
||||
{
|
||||
|
|
@ -453,10 +489,8 @@ namespace Server.Mobiles
|
|||
string[] paramargs;
|
||||
string[] propargs;
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Properties))
|
||||
propargs = Array.Empty<string>();
|
||||
else
|
||||
propargs = CommandSystem.Split(entry.Properties.Trim());
|
||||
propargs = string.IsNullOrEmpty(entry.Properties) ?
|
||||
Array.Empty<string>() : CommandSystem.Split(entry.Properties.Trim());
|
||||
|
||||
string[,] props = FormatProperties(propargs);
|
||||
|
||||
|
|
@ -468,10 +502,8 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(entry.Parameters))
|
||||
paramargs = Array.Empty<string>();
|
||||
else
|
||||
paramargs = entry.Parameters.Trim().Split(' ');
|
||||
paramargs = string.IsNullOrEmpty(entry.Parameters) ?
|
||||
Array.Empty<string>() : entry.Parameters.Trim().Split(' ');
|
||||
|
||||
if (paramargs.Length == 0)
|
||||
{
|
||||
|
|
@ -504,7 +536,6 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
for (int i = 0; i < realProps.Length; i++)
|
||||
{
|
||||
if (realProps[i] != null)
|
||||
{
|
||||
object toSet = null;
|
||||
|
|
@ -523,7 +554,6 @@ namespace Server.Mobiles
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (o is Mobile m)
|
||||
{
|
||||
|
|
@ -591,75 +621,7 @@ namespace Server.Mobiles
|
|||
|
||||
public virtual int GetWalkingRange() => m_WalkingRange;
|
||||
|
||||
public virtual Point3D GetSpawnPosition(ISpawnable spawned, Map map)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
return Location;
|
||||
|
||||
bool waterMob, waterOnlyMob;
|
||||
|
||||
if (spawned is Mobile mob)
|
||||
{
|
||||
waterMob = mob.CanSwim;
|
||||
waterOnlyMob = mob.CanSwim && mob.CantWalk;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterMob = false;
|
||||
waterOnlyMob = false;
|
||||
}
|
||||
|
||||
// Try 10 times to find a Spawnable location.
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int x = Location.X + (Utility.Random(m_HomeRange * 2 + 1) - m_HomeRange);
|
||||
int y = Location.Y + (Utility.Random(m_HomeRange * 2 + 1) - m_HomeRange);
|
||||
|
||||
int mapZ = map.GetAverageZ(x, y);
|
||||
|
||||
if (waterMob)
|
||||
{
|
||||
if (IsValidWater(map, x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (IsValidWater(map, x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
|
||||
if (!waterOnlyMob)
|
||||
{
|
||||
if (map.CanSpawnMobile(x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (map.CanSpawnMobile(x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
}
|
||||
|
||||
return Location;
|
||||
}
|
||||
|
||||
public static bool IsValidWater(Map map, int x, int y, int z)
|
||||
{
|
||||
if (!Region.Find(new Point3D(x, y, z), map).AllowSpawn() || !map.CanFit(x, y, z, 16, false, true, false))
|
||||
return false;
|
||||
|
||||
LandTile landTile = map.Tiles.GetLandTile(x, y);
|
||||
|
||||
if (landTile.Z == z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0)
|
||||
return true;
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
|
||||
|
||||
for (int i = 0; i < staticTiles.Length; ++i)
|
||||
{
|
||||
StaticTile staticTile = staticTiles[i];
|
||||
|
||||
if (staticTile.Z == z &&
|
||||
(TileData.ItemTable[staticTile.ID & TileData.MaxItemValue].Flags & TileFlag.Wet) != 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public abstract Point3D GetSpawnPosition(ISpawnable spawned, Map map);
|
||||
|
||||
public virtual Map GetSpawnMap() => Map;
|
||||
|
||||
|
|
@ -783,7 +745,9 @@ namespace Server.Mobiles
|
|||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(7); // version
|
||||
writer.Write(8); // version
|
||||
|
||||
writer.Write(ReturnOnDeactivate);
|
||||
|
||||
writer.Write(Entries.Count);
|
||||
|
||||
|
|
@ -820,6 +784,11 @@ namespace Server.Mobiles
|
|||
|
||||
switch (version)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
ReturnOnDeactivate = reader.ReadBool();
|
||||
goto case 7;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
int size = reader.ReadInt();
|
||||
|
|
@ -909,7 +878,7 @@ namespace Server.Mobiles
|
|||
else
|
||||
Entries[i].SpawnedName = typeName;
|
||||
|
||||
if (SpawnerType.GetType(typeName) == null)
|
||||
if (AssemblyHandler.FindFirstTypeForName(typeName) == null)
|
||||
{
|
||||
m_WarnTimer ??= new WarnTimer();
|
||||
|
||||
|
|
@ -928,7 +897,7 @@ namespace Server.Mobiles
|
|||
e.Spawner = this;
|
||||
|
||||
for (int j = 0; j < Entries.Count; j++)
|
||||
if (SpawnerType.GetType(Entries[j].SpawnedName) == e.GetType())
|
||||
if (AssemblyHandler.FindFirstTypeForName(Entries[j].SpawnedName) == e.GetType())
|
||||
{
|
||||
Entries[j].Spawned.Add(e);
|
||||
Spawned.Add(e, Entries[j]);
|
||||
|
|
@ -947,30 +916,11 @@ namespace Server.Mobiles
|
|||
m_WalkingRange = m_HomeRange;
|
||||
}
|
||||
|
||||
public static string ConvertTypes(string type)
|
||||
{
|
||||
type = type.ToLower();
|
||||
return type switch
|
||||
{
|
||||
"wheat" => "WheatSheaf",
|
||||
"noxxiousmage" => "NoxiousMage",
|
||||
"noxxiousarcher" => "NoxiousArcher",
|
||||
"noxxiouswarrior" => "NoxiousWarrior",
|
||||
"noxxiouswarlord" => "NoxiousWarlord",
|
||||
"obsidian" => "obsidianstatue",
|
||||
"adeepwaterelemental" => "deepwaterelemental",
|
||||
"noxskeleton" => "poisonskeleton",
|
||||
"earthcaller" => "earthsummoner",
|
||||
"bonedemon" => "bonedaemon",
|
||||
_ => type
|
||||
};
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private readonly Spawner m_Spawner;
|
||||
private readonly BaseSpawner m_Spawner;
|
||||
|
||||
public InternalTimer(Spawner spawner, TimeSpan delay) : base(delay)
|
||||
public InternalTimer(BaseSpawner spawner, TimeSpan delay) : base(delay)
|
||||
{
|
||||
if (spawner.IsFull)
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
|
|
@ -1052,142 +1002,4 @@ namespace Server.Mobiles
|
|||
InvalidProps = 0x004,
|
||||
InvalidEntry = 0x008
|
||||
}
|
||||
|
||||
public class SpawnerEntry
|
||||
{
|
||||
public SpawnerEntry(string name, int probability, int maxcount)
|
||||
{
|
||||
SpawnedName = name;
|
||||
SpawnedProbability = probability;
|
||||
SpawnedMaxCount = maxcount;
|
||||
Spawned = new List<ISpawnable>();
|
||||
}
|
||||
|
||||
public SpawnerEntry(Spawner parent, IGenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
SpawnedName = reader.ReadString();
|
||||
SpawnedProbability = reader.ReadInt();
|
||||
SpawnedMaxCount = reader.ReadInt();
|
||||
|
||||
Properties = reader.ReadString();
|
||||
Parameters = reader.ReadString();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
|
||||
Spawned = new List<ISpawnable>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
// IEntity e = World.FindEntity( reader.ReadInt() );
|
||||
|
||||
if (reader.ReadEntity() is ISpawnable e)
|
||||
{
|
||||
e.Spawner = parent;
|
||||
|
||||
if (e is BaseCreature creature)
|
||||
creature.RemoveIfUntamed = true;
|
||||
|
||||
Spawned.Add(e);
|
||||
|
||||
if (!parent.Spawned.ContainsKey(e))
|
||||
parent.Spawned.Add(e, this);
|
||||
}
|
||||
}
|
||||
|
||||
public int SpawnedProbability { get; set; }
|
||||
|
||||
public int SpawnedMaxCount { get; set; }
|
||||
|
||||
public string SpawnedName { get; set; }
|
||||
|
||||
public string Properties { get; set; }
|
||||
|
||||
public string Parameters { get; set; }
|
||||
|
||||
public EntryFlags Valid { get; set; }
|
||||
|
||||
public List<ISpawnable> Spawned { get; }
|
||||
|
||||
public bool IsFull => Spawned.Count >= SpawnedMaxCount;
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(SpawnedName);
|
||||
writer.Write(SpawnedProbability);
|
||||
writer.Write(SpawnedMaxCount);
|
||||
|
||||
writer.Write(Properties);
|
||||
writer.Write(Parameters);
|
||||
|
||||
writer.Write(Spawned.Count);
|
||||
|
||||
for (int i = 0; i < Spawned.Count; ++i)
|
||||
{
|
||||
object o = Spawned[i];
|
||||
|
||||
if (o is Item item)
|
||||
writer.Write(item);
|
||||
else if (o is Mobile mobile)
|
||||
writer.Write(mobile);
|
||||
else
|
||||
writer.Write(Serial.MinusOne);
|
||||
}
|
||||
}
|
||||
|
||||
public void Defrag(Spawner parent)
|
||||
{
|
||||
for (int i = 0; i < Spawned.Count; ++i)
|
||||
{
|
||||
ISpawnable e = Spawned[i];
|
||||
bool remove = false;
|
||||
|
||||
if (e is Item item)
|
||||
{
|
||||
if (item.Deleted || item.RootParent is Mobile || item.IsLockedDown || item.IsSecure ||
|
||||
item.Spawner == null)
|
||||
remove = true;
|
||||
}
|
||||
else if (e is Mobile m)
|
||||
{
|
||||
if (m.Deleted)
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
else if (m is BaseCreature c)
|
||||
{
|
||||
if (c.Controlled || c.IsStabled)
|
||||
remove = true;
|
||||
/*
|
||||
else if (c.Combatant == null && ( c.GetDistanceToSqrt( Location ) > (c.RangeHome * 4) ))
|
||||
{
|
||||
//m_Spawned[i].Delete();
|
||||
m_Spawned.RemoveAt( i );
|
||||
--i;
|
||||
c.Delete();
|
||||
remove = true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (m.Spawner == null)
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
remove = true;
|
||||
}
|
||||
|
||||
if (remove)
|
||||
{
|
||||
Spawned.RemoveAt(i--);
|
||||
if (parent.Spawned.ContainsKey(e))
|
||||
parent.Spawned.Remove(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
116
Projects/UOContent/Engines/Spawners/GenerateSpawners.cs
Normal file
116
Projects/UOContent/Engines/Spawners/GenerateSpawners.cs
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Utilities;
|
||||
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public static class GenerateSpawners
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register("GenerateSpawners", AccessLevel.Developer, GenerateSpawners_OnCommand);
|
||||
}
|
||||
|
||||
private static void GenerateSpawners_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (e.Arguments.Length == 0)
|
||||
{
|
||||
from.SendMessage("Usage: [GenerateSpawners <path|search pattern>");
|
||||
return;
|
||||
}
|
||||
|
||||
var di = new DirectoryInfo(Core.BaseDirectory);
|
||||
|
||||
var files = di.GetFiles(e.Arguments[0], SearchOption.AllDirectories);
|
||||
|
||||
if (files.Length == 0)
|
||||
{
|
||||
from.SendMessage("GenerateSpawners: No files found matching the pattern");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonSerializerOptions options = new JsonSerializerOptions();
|
||||
options.Converters.Add(new MapConverterFactory());
|
||||
options.Converters.Add(new Point3DConverterFactory());
|
||||
options.Converters.Add(new TimeSpanConverterFactory());
|
||||
options.Converters.Add(new TextDefinitionConverterFactory());
|
||||
|
||||
for (int i = 0; i < files.Length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
from.SendMessage("GenerateSpawners: Generating spawners for {0}...", file.Name);
|
||||
List<DynamicJson> spawners = JsonConfig.Deserialize<List<DynamicJson>>(file.FullName);
|
||||
ParseSpawnerList(from, spawners, options);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseSpawnerList(Mobile from, List<DynamicJson> spawners, JsonSerializerOptions options)
|
||||
{
|
||||
Stopwatch watch = Stopwatch.StartNew();
|
||||
List<string> failures = new List<string>();
|
||||
int count = 0;
|
||||
|
||||
for (var i = 0; i < spawners.Count; i++)
|
||||
{
|
||||
var json = spawners[i];
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(json.Type);
|
||||
|
||||
if (type == null || !typeof(BaseSpawner).IsAssignableFrom(type))
|
||||
{
|
||||
string failure = $"GenerateSpawners: Invalid spawner type {json.Type ?? "(-null-)"} ({i})";
|
||||
if (!failures.Contains(failure))
|
||||
{
|
||||
failures.Add(failure);
|
||||
from.SendMessage(failure);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
json.GetProperty("location", options, out Point3D location);
|
||||
json.GetProperty("map", options, out Map map);
|
||||
|
||||
var eable = map.GetItemsInRange<BaseSpawner>(location, 0);
|
||||
|
||||
if (eable.Any(sp => sp.GetType() == type))
|
||||
{
|
||||
eable.Free();
|
||||
continue;
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
try
|
||||
{
|
||||
var spawner = ActivatorUtil.CreateInstance(type, json, options) as ISpawner;
|
||||
|
||||
spawner!.MoveToWorld(location, map);
|
||||
spawner!.Respawn();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
string failure = $"GenerateSpawners: Spawner {type} failed to construct";
|
||||
if (!failures.Contains(failure))
|
||||
{
|
||||
failures.Add(failure);
|
||||
from.SendMessage(failure);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
watch.Stop();
|
||||
from.SendMessage("GenerateSpawners: Generated {0} spawners ({1:F2} seconds, {2} failures)", count, watch.Elapsed.TotalSeconds, failures.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +1,30 @@
|
|||
using System;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Mobiles
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class ProximitySpawner : Spawner
|
||||
{
|
||||
[Constructible]
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner()
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner(string spawnName)
|
||||
: base(spawnName)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner(int amount, int minDelay, int maxDelay, int team, int homeRange, string spawnName)
|
||||
: base(amount, minDelay, maxDelay, team, homeRange, spawnName)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible]
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner(int amount, int minDelay, int maxDelay, int team, int homeRange, int triggerRange,
|
||||
string spawnMessage, bool instantFlag, string spawnName)
|
||||
: base(amount, minDelay, maxDelay, team, homeRange, spawnName)
|
||||
|
|
@ -31,12 +34,14 @@ namespace Server.Mobiles
|
|||
InstantFlag = instantFlag;
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames)
|
||||
: base(amount, minDelay, maxDelay, team, homeRange, spawnedNames)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public ProximitySpawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange, int triggerRange,
|
||||
TextDefinition spawnMessage, bool instantFlag, params string[] spawnedNames)
|
||||
: base(amount, minDelay, maxDelay, team, homeRange, spawnedNames)
|
||||
|
|
@ -46,6 +51,17 @@ namespace Server.Mobiles
|
|||
InstantFlag = instantFlag;
|
||||
}
|
||||
|
||||
public ProximitySpawner(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
json.GetProperty("triggerRange", options, out int triggerRange);
|
||||
json.GetProperty("spawnMessage", options, out TextDefinition spawnMessage);
|
||||
json.GetProperty("instant", options, out bool instant);
|
||||
|
||||
TriggerRange = triggerRange;
|
||||
SpawnMessage = spawnMessage;
|
||||
InstantFlag = instant;
|
||||
}
|
||||
|
||||
public ProximitySpawner(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
|
|
@ -129,4 +145,4 @@ namespace Server.Mobiles
|
|||
InstantFlag = reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
152
Projects/UOContent/Engines/Spawners/RegionSpawner.cs
Normal file
152
Projects/UOContent/Engines/Spawners/RegionSpawner.cs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
using System;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class RegionSpawner : Spawner
|
||||
{
|
||||
private BaseRegion m_SpawnRegion;
|
||||
|
||||
[CommandProperty(AccessLevel.Developer)]
|
||||
public BaseRegion SpawnRegion
|
||||
{
|
||||
get => m_SpawnRegion;
|
||||
set
|
||||
{
|
||||
m_SpawnRegion = value;
|
||||
m_SpawnRegion?.InitRectangles();
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public RegionSpawner()
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public RegionSpawner(string spawnedName) : base(spawnedName)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public RegionSpawner(int amount, int minDelay, int maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : this(amount, TimeSpan.FromMinutes(minDelay), TimeSpan.FromMinutes(maxDelay),
|
||||
team, homeRange, spawnedNames)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public RegionSpawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : base(amount, minDelay, maxDelay, team, homeRange, spawnedNames)
|
||||
{
|
||||
}
|
||||
|
||||
public RegionSpawner(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
json.GetProperty("map", options, out Map map);
|
||||
json.GetProperty("region", options, out string spawnRegion);
|
||||
|
||||
m_SpawnRegion = Region.Find(spawnRegion, map) as BaseRegion;
|
||||
m_SpawnRegion?.InitRectangles();
|
||||
}
|
||||
|
||||
public RegionSpawner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetSpawnerProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetSpawnerProperties(list);
|
||||
|
||||
if (Running && m_SpawnRegion != null) list.Add(1076228, "region:\t{0}", m_SpawnRegion.Name); // ~1_DUMMY~ ~2_DUMMY~
|
||||
}
|
||||
|
||||
public override Point3D GetSpawnPosition(ISpawnable spawned, Map map)
|
||||
{
|
||||
if (m_SpawnRegion == null || map == null || map == Map.Internal || map != m_SpawnRegion.Map || m_SpawnRegion.TotalWeight <= 0)
|
||||
return Location;
|
||||
|
||||
bool waterMob, waterOnlyMob;
|
||||
|
||||
if (spawned is Mobile mob)
|
||||
{
|
||||
waterMob = mob.CanSwim;
|
||||
waterOnlyMob = mob.CanSwim && mob.CantWalk;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterMob = false;
|
||||
waterOnlyMob = false;
|
||||
}
|
||||
|
||||
// Try 10 times to find a valid location.
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int rand = Utility.Random(m_SpawnRegion.TotalWeight);
|
||||
|
||||
int x = int.MinValue;
|
||||
int y = int.MinValue;
|
||||
|
||||
for (int j = 0; j < m_SpawnRegion.RectangleWeights.Length; j++)
|
||||
{
|
||||
int curWeight = m_SpawnRegion.RectangleWeights[j];
|
||||
|
||||
if (rand < curWeight)
|
||||
{
|
||||
Rectangle3D rect = m_SpawnRegion.Rectangles[j];
|
||||
|
||||
x = rect.Start.X + rand % rect.Width;
|
||||
y = rect.Start.Y + rand / rect.Width;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
rand -= curWeight;
|
||||
}
|
||||
|
||||
int mapZ = map.GetAverageZ(x, y);
|
||||
|
||||
if (waterMob)
|
||||
{
|
||||
if (IsValidWater(map, x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (IsValidWater(map, x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
|
||||
if (!waterOnlyMob)
|
||||
{
|
||||
if (map.CanSpawnMobile(x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (map.CanSpawnMobile(x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
}
|
||||
|
||||
return HomeLocation;
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_SpawnRegion = Region.Find(reader.ReadString(), Map) as BaseRegion;
|
||||
m_SpawnRegion?.InitRectangles();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
|
||||
writer.Write(m_SpawnRegion?.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
139
Projects/UOContent/Engines/Spawners/Spawner.cs
Normal file
139
Projects/UOContent/Engines/Spawners/Spawner.cs
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class Spawner : BaseSpawner
|
||||
{
|
||||
public static bool IsValidWater(Map map, int x, int y, int z)
|
||||
{
|
||||
if (!Region.Find(new Point3D(x, y, z), map).AllowSpawn() || !map.CanFit(x, y, z, 16, false, true, false))
|
||||
return false;
|
||||
|
||||
LandTile landTile = map.Tiles.GetLandTile(x, y);
|
||||
|
||||
if (landTile.Z == z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Wet) != 0)
|
||||
return true;
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
|
||||
|
||||
for (int i = 0; i < staticTiles.Length; ++i)
|
||||
{
|
||||
StaticTile staticTile = staticTiles[i];
|
||||
|
||||
if (staticTile.Z == z &&
|
||||
(TileData.ItemTable[staticTile.ID & TileData.MaxItemValue].Flags & TileFlag.Wet) != 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public Spawner()
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public Spawner(string spawnedName) : base(spawnedName)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public Spawner(int amount, int minDelay, int maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : this(amount, TimeSpan.FromMinutes(minDelay), TimeSpan.FromMinutes(maxDelay),
|
||||
team, homeRange, spawnedNames)
|
||||
{
|
||||
}
|
||||
|
||||
[Constructible(AccessLevel.Developer)]
|
||||
public Spawner(int amount, TimeSpan minDelay, TimeSpan maxDelay, int team, int homeRange,
|
||||
params string[] spawnedNames) : base(amount, minDelay, maxDelay, team, homeRange, spawnedNames)
|
||||
{
|
||||
}
|
||||
|
||||
public Spawner(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
}
|
||||
|
||||
public Spawner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
public override bool OnDefragSpawn(ISpawnable spawned, bool remove)
|
||||
{
|
||||
// To despawn a mob that was lured 4x away from its spawner
|
||||
// TODO: Move this to a config
|
||||
if (spawned is BaseCreature c && c.Combatant == null && c.GetDistanceToSqrt( Location ) > c.RangeHome * 4)
|
||||
{
|
||||
c.Delete();
|
||||
remove = true;
|
||||
}
|
||||
|
||||
return base.OnDefragSpawn(entry, spawned, remove);
|
||||
}
|
||||
*/
|
||||
|
||||
public override Point3D GetSpawnPosition(ISpawnable spawned, Map map)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
return Location;
|
||||
|
||||
bool waterMob, waterOnlyMob;
|
||||
|
||||
if (spawned is Mobile mob)
|
||||
{
|
||||
waterMob = mob.CanSwim;
|
||||
waterOnlyMob = mob.CanSwim && mob.CantWalk;
|
||||
}
|
||||
else
|
||||
{
|
||||
waterMob = false;
|
||||
waterOnlyMob = false;
|
||||
}
|
||||
|
||||
// Try 10 times to find a valid location.
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
int x = Location.X + (Utility.Random(HomeRange * 2 + 1) - HomeRange);
|
||||
int y = Location.Y + (Utility.Random(HomeRange * 2 + 1) - HomeRange);
|
||||
|
||||
int mapZ = map.GetAverageZ(x, y);
|
||||
|
||||
if (waterMob)
|
||||
{
|
||||
if (IsValidWater(map, x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (IsValidWater(map, x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
|
||||
if (!waterOnlyMob)
|
||||
{
|
||||
if (map.CanSpawnMobile(x, y, Z))
|
||||
return new Point3D(x, y, Z);
|
||||
if (map.CanSpawnMobile(x, y, mapZ))
|
||||
return new Point3D(x, y, mapZ);
|
||||
}
|
||||
}
|
||||
|
||||
return HomeLocation;
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
}
|
||||
}
|
||||
}
|
||||
113
Projects/UOContent/Engines/Spawners/SpawnerEntry.cs
Normal file
113
Projects/UOContent/Engines/Spawners/SpawnerEntry.cs
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class SpawnerEntry
|
||||
{
|
||||
public SpawnerEntry() => Spawned = new List<ISpawnable>();
|
||||
|
||||
public SpawnerEntry(string name, int probability, int maxcount) : this()
|
||||
{
|
||||
SpawnedName = name;
|
||||
SpawnedProbability = probability;
|
||||
SpawnedMaxCount = maxcount;
|
||||
}
|
||||
|
||||
public SpawnerEntry(BaseSpawner parent, IGenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
SpawnedName = reader.ReadString();
|
||||
SpawnedProbability = reader.ReadInt();
|
||||
SpawnedMaxCount = reader.ReadInt();
|
||||
|
||||
Properties = reader.ReadString();
|
||||
Parameters = reader.ReadString();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
|
||||
Spawned = new List<ISpawnable>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
// IEntity e = World.FindEntity( reader.ReadInt() );
|
||||
|
||||
if (reader.ReadEntity() is ISpawnable e)
|
||||
{
|
||||
e.Spawner = parent;
|
||||
|
||||
if (e is BaseCreature creature)
|
||||
creature.RemoveIfUntamed = true;
|
||||
|
||||
Spawned.Add(e);
|
||||
|
||||
if (!parent.Spawned.ContainsKey(e))
|
||||
parent.Spawned.Add(e, this);
|
||||
}
|
||||
}
|
||||
|
||||
[JsonPropertyName("probability")]
|
||||
public int SpawnedProbability { get; set; }
|
||||
|
||||
[JsonPropertyName("maxCount")]
|
||||
public int SpawnedMaxCount { get; set; }
|
||||
|
||||
[JsonPropertyName("name")]
|
||||
public string SpawnedName { get; set; }
|
||||
|
||||
[JsonPropertyName("properties")]
|
||||
public string Properties { get; set; }
|
||||
|
||||
[JsonPropertyName("parameters")]
|
||||
public string Parameters { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public EntryFlags Valid { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public List<ISpawnable> Spawned { get; }
|
||||
|
||||
public bool IsFull => Spawned.Count >= SpawnedMaxCount;
|
||||
|
||||
public void Serialize(IGenericWriter writer)
|
||||
{
|
||||
writer.Write(0); // version
|
||||
|
||||
writer.Write(SpawnedName);
|
||||
writer.Write(SpawnedProbability);
|
||||
writer.Write(SpawnedMaxCount);
|
||||
|
||||
writer.Write(Properties);
|
||||
writer.Write(Parameters);
|
||||
|
||||
writer.Write(Spawned.Count);
|
||||
|
||||
for (int i = 0; i < Spawned.Count; ++i)
|
||||
{
|
||||
object o = Spawned[i];
|
||||
|
||||
if (o is Item item)
|
||||
writer.Write(item);
|
||||
else if (o is Mobile mobile)
|
||||
writer.Write(mobile);
|
||||
else
|
||||
writer.Write(Serial.MinusOne);
|
||||
}
|
||||
}
|
||||
|
||||
public void Defrag(BaseSpawner parent)
|
||||
{
|
||||
for (int i = 0; i < Spawned.Count; ++i)
|
||||
{
|
||||
ISpawnable spawned = Spawned[i];
|
||||
|
||||
if (parent.OnDefragSpawn(spawned, false))
|
||||
{
|
||||
Spawned.RemoveAt(i--);
|
||||
parent.Spawned.Remove(spawned);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,15 +3,15 @@ using System.Collections.Generic;
|
|||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Mobiles
|
||||
namespace Server.Engines.Spawners
|
||||
{
|
||||
public class SpawnerGump : Gump
|
||||
{
|
||||
private SpawnerEntry m_Entry;
|
||||
private int m_Page;
|
||||
private readonly Spawner m_Spawner;
|
||||
private readonly BaseSpawner m_Spawner;
|
||||
|
||||
public SpawnerGump(Spawner spawner, SpawnerEntry focusentry = null, int page = 0) : base(50, 50)
|
||||
public SpawnerGump(BaseSpawner spawner, SpawnerEntry focusentry = null, int page = 0) : base(50, 50)
|
||||
{
|
||||
m_Spawner = spawner;
|
||||
m_Entry = focusentry;
|
||||
|
|
@ -124,7 +124,7 @@ namespace Server.Mobiles
|
|||
|
||||
public int GetButtonID(int type, int index) => 1 + index * 10 + type;
|
||||
|
||||
public void CreateArray(RelayInfo info, Mobile from, Spawner spawner)
|
||||
public void CreateArray(RelayInfo info, Mobile from, BaseSpawner spawner)
|
||||
{
|
||||
int ocount = spawner.Entries.Count;
|
||||
|
||||
|
|
@ -148,47 +148,46 @@ namespace Server.Mobiles
|
|||
|
||||
if (str.Length > 0)
|
||||
{
|
||||
Type type = SpawnerType.GetType(str);
|
||||
Type type = AssemblyHandler.FindFirstTypeForName(str);
|
||||
|
||||
if (type != null)
|
||||
if (type == null)
|
||||
{
|
||||
SpawnerEntry entry;
|
||||
from.SendMessage("{0} is not a valid type name for entry #{1}.", str, i);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entryindex < ocount)
|
||||
{
|
||||
entry = spawner.Entries[entryindex];
|
||||
entry.SpawnedName = str;
|
||||
SpawnerEntry entry;
|
||||
|
||||
if (mte != null)
|
||||
entry.SpawnedMaxCount = Utility.ToInt32(mte.Text.Trim());
|
||||
if (entryindex < ocount)
|
||||
{
|
||||
entry = spawner.Entries[entryindex];
|
||||
entry.SpawnedName = str;
|
||||
|
||||
if (poste != null)
|
||||
entry.SpawnedProbability = Utility.ToInt32(poste.Text.Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
int maxcount = 1;
|
||||
int probcount = 100;
|
||||
if (mte != null)
|
||||
entry.SpawnedMaxCount = Utility.ToInt32(mte.Text.Trim());
|
||||
|
||||
if (mte != null)
|
||||
maxcount = Utility.ToInt32(mte.Text.Trim());
|
||||
|
||||
if (poste != null)
|
||||
probcount = Utility.ToInt32(poste.Text.Trim());
|
||||
|
||||
entry = spawner.AddEntry(str, probcount, maxcount);
|
||||
}
|
||||
|
||||
if (parmte != null)
|
||||
entry.Parameters = parmte.Text.Trim();
|
||||
|
||||
if (propte != null)
|
||||
entry.Properties = propte.Text.Trim();
|
||||
if (poste != null)
|
||||
entry.SpawnedProbability = Utility.ToInt32(poste.Text.Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage("{0} is not a valid type name for entry #{1}.", str, i);
|
||||
int maxcount = 1;
|
||||
int probcount = 100;
|
||||
|
||||
if (mte != null)
|
||||
maxcount = Utility.ToInt32(mte.Text.Trim());
|
||||
|
||||
if (poste != null)
|
||||
probcount = Utility.ToInt32(poste.Text.Trim());
|
||||
|
||||
entry = spawner.AddEntry(str, probcount, maxcount);
|
||||
}
|
||||
|
||||
if (parmte != null)
|
||||
entry.Parameters = parmte.Text.Trim();
|
||||
|
||||
if (propte != null)
|
||||
entry.Properties = propte.Text.Trim();
|
||||
}
|
||||
else if (entryindex < ocount && spawner.Entries[entryindex] != null)
|
||||
{
|
||||
|
|
@ -120,7 +120,7 @@ namespace Server.Items
|
|||
|
||||
private void InternalCallback(Mobile from, object targeted)
|
||||
{
|
||||
if (Deleted || UsesRemaining <= 0 || !from.InRange(GetWorldLocation(), 3) ||
|
||||
if (Deleted || UsesRemaining <= 0 || !from.InRange(GetWorldLocation(), 3) ||
|
||||
!IsAccessibleTo(from))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ namespace Server.Items
|
|||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (from.Region.IsPartOf<Jail>())
|
||||
if (from.Region.IsPartOf<JailRegion>())
|
||||
from.SendMessage("You may not do that in jail.");
|
||||
else if (!IsChildOf(from.Backpack))
|
||||
MessageHelper.SendLocalizedMessageTo(this, from, 1062334,
|
||||
|
|
@ -218,7 +218,7 @@ namespace Server.Items
|
|||
if (m_Bag.Deleted)
|
||||
return;
|
||||
|
||||
if (from.Region.IsPartOf<Jail>())
|
||||
if (from.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
from.SendMessage("You may not do that in jail.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ namespace Server.Items
|
|||
0x22); // The Crystal Ball fills with a red mist. You appear to have let your bond to your pet deteriorate.
|
||||
}
|
||||
else if (from.Map == Map.Ilshenar || from.Region.IsPartOf<DungeonRegion>() ||
|
||||
from.Region.IsPartOf<Jail>() || from.Region.IsPartOf<SafeZone>())
|
||||
from.Region.IsPartOf<JailRegion>() || from.Region.IsPartOf<SafeZone>())
|
||||
{
|
||||
from.Send(new AsciiMessage(Serial, ItemID, MessageType.Regular, 0x22, 3, "",
|
||||
"You cannot summon your pet to this location."));
|
||||
|
|
|
|||
|
|
@ -255,13 +255,13 @@ namespace Server.Items
|
|||
return false;
|
||||
}
|
||||
|
||||
if (from.Region.IsPartOf<Jail>())
|
||||
if (from.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
from.SendLocalizedMessage(1114345, "", 0x35); // You'll need a better jailbreak plan than that!
|
||||
return false;
|
||||
}
|
||||
|
||||
if (boundRoot.Region.IsPartOf<Jail>())
|
||||
if (boundRoot.Region.IsPartOf<JailRegion>())
|
||||
{
|
||||
from.SendLocalizedMessage(1019004); // You are not allowed to travel there.
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TextDefinitionConverter.cs *
|
||||
* Created: 2020/05/25 - Updated: 2020/05/25 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TextDefinitionConverter : JsonConverter<TextDefinition>
|
||||
{
|
||||
public override TextDefinition Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) =>
|
||||
reader.TokenType switch
|
||||
{
|
||||
JsonTokenType.String => new TextDefinition(reader.GetString()),
|
||||
JsonTokenType.Number => new TextDefinition(reader.GetInt32()),
|
||||
_ => throw new JsonException("TextDefinition value must be an integer or string")
|
||||
};
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, TextDefinition value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value.Number > 0)
|
||||
writer.WriteNumberValue(value.Number);
|
||||
else
|
||||
writer.WriteStringValue(value.String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: TextDefinitionConverterFactory.cs *
|
||||
* Created: 2020/05/25 - Updated: 2020/05/25 *
|
||||
* *
|
||||
* This program is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
*************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json
|
||||
{
|
||||
public class TextDefinitionConverterFactory : JsonConverterFactory
|
||||
{
|
||||
public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(TextDefinition);
|
||||
|
||||
public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) =>
|
||||
new TextDefinitionConverter();
|
||||
}
|
||||
}
|
||||
|
|
@ -206,7 +206,7 @@ namespace Server.Misc
|
|||
|
||||
public static void Gain(Mobile from, Skill skill)
|
||||
{
|
||||
if (from.Region.IsPartOf<Jail>())
|
||||
if (from.Region.IsPartOf<JailRegion>())
|
||||
return;
|
||||
|
||||
if (from is BaseCreature creature && creature.IsDeadPet)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Spawners;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Spawners;
|
||||
|
||||
// Version 0.8
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ using System.IO;
|
|||
using Server.ContextMenus;
|
||||
using Server.Engines.Quests;
|
||||
using Server.Engines.Quests.Necro;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Factions;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Regions;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Spellweaving;
|
||||
using Server.Targets;
|
||||
|
|
@ -1461,10 +1461,12 @@ namespace Server.Mobiles
|
|||
m_Mobile.OwnerAbandonTime = DateTime.MinValue;
|
||||
m_Mobile.IsBonded = false;
|
||||
|
||||
if (m_Mobile.Spawner is SpawnEntry se && se.HomeLocation != Point3D.Zero)
|
||||
var spawner = m_Mobile.Spawner;
|
||||
|
||||
if (spawner != null && spawner.HomeLocation != Point3D.Zero)
|
||||
{
|
||||
m_Mobile.Home = se.HomeLocation;
|
||||
m_Mobile.RangeHome = se.HomeRange;
|
||||
m_Mobile.Home = spawner.HomeLocation;
|
||||
m_Mobile.RangeHome = spawner.HomeRange;
|
||||
}
|
||||
|
||||
if (m_Mobile.DeleteOnRelease || m_Mobile.IsDeadPet)
|
||||
|
|
@ -1923,9 +1925,9 @@ namespace Server.Mobiles
|
|||
|
||||
if (m_Mobile.Home == Point3D.Zero)
|
||||
{
|
||||
if (m_Mobile.Spawner is SpawnEntry entry)
|
||||
if (m_Mobile.Spawner is RegionSpawner rs)
|
||||
{
|
||||
Region region = entry.Region;
|
||||
Region region = rs.SpawnRegion;
|
||||
|
||||
if (m_Mobile.Region.AcceptsSpawnsFrom(region))
|
||||
{
|
||||
|
|
@ -2375,13 +2377,15 @@ namespace Server.Mobiles
|
|||
{
|
||||
m_Timer.Stop();
|
||||
|
||||
if (m_Mobile.Spawner is SpawnEntry se && se.ReturnOnDeactivate && !m_Mobile.Controlled)
|
||||
var spawner = m_Mobile.Spawner;
|
||||
|
||||
if (spawner?.ReturnOnDeactivate == true && !m_Mobile.Controlled)
|
||||
{
|
||||
if (se.HomeLocation == Point3D.Zero)
|
||||
if (spawner.HomeLocation == Point3D.Zero)
|
||||
{
|
||||
if (!m_Mobile.Region.AcceptsSpawnsFrom(se.Region)) Timer.DelayCall(TimeSpan.Zero, ReturnToHome);
|
||||
if (!m_Mobile.Region.AcceptsSpawnsFrom(spawner.Region)) Timer.DelayCall(TimeSpan.Zero, ReturnToHome);
|
||||
}
|
||||
else if (!m_Mobile.InRange(se.HomeLocation, se.HomeRange))
|
||||
else if (!m_Mobile.InRange(spawner.HomeLocation, spawner.HomeRange))
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.Zero, ReturnToHome);
|
||||
}
|
||||
|
|
@ -2391,11 +2395,11 @@ namespace Server.Mobiles
|
|||
|
||||
private void ReturnToHome()
|
||||
{
|
||||
if (m_Mobile.Spawner is SpawnEntry se)
|
||||
if (m_Mobile.Spawner != null)
|
||||
{
|
||||
Point3D loc = se.RandomSpawnLocation(16, !m_Mobile.CantWalk, m_Mobile.CanSwim);
|
||||
Point3D loc = m_Mobile.Spawner.GetSpawnPosition(m_Mobile, m_Mobile.Spawner.Map);
|
||||
|
||||
if (loc != Point3D.Zero) m_Mobile.MoveToWorld(loc, se.Region.Map);
|
||||
if (loc != Point3D.Zero) m_Mobile.MoveToWorld(loc, m_Mobile.Spawner.Map);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Server.Engines.PartySystem;
|
|||
using Server.Engines.Quests;
|
||||
using Server.Engines.Quests.Doom;
|
||||
using Server.Engines.Quests.Haven;
|
||||
using Server.Engines.Spawners;
|
||||
using Server.Ethics;
|
||||
using Server.Factions;
|
||||
using Server.Items;
|
||||
|
|
@ -2688,7 +2689,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
public override bool CanBeRenamedBy(Mobile from) =>
|
||||
(Controlled && from == ControlMaster && !from.Region.IsPartOf<Jail>()) ||
|
||||
(Controlled && from == ControlMaster && !from.Region.IsPartOf<JailRegion>()) ||
|
||||
base.CanBeRenamedBy(from);
|
||||
|
||||
public bool SetControlMaster(Mobile m)
|
||||
|
|
@ -2746,7 +2747,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
base.OnRegionChange(Old, New);
|
||||
|
||||
if (Controlled && Spawner is SpawnEntry se && !se.UnlinkOnTaming && New?.AcceptsSpawnsFrom(se.Region) != true)
|
||||
if (Controlled && Spawner?.UnlinkOnTaming == false && New?.AcceptsSpawnsFrom(Spawner.Region) != true)
|
||||
{
|
||||
Spawner.Remove(this);
|
||||
Spawner = null;
|
||||
|
|
|
|||
|
|
@ -4119,7 +4119,7 @@ namespace Server.Mobiles
|
|||
|
||||
public bool YoungDeathTeleport()
|
||||
{
|
||||
if (Region.IsPartOf<Jail>()
|
||||
if (Region.IsPartOf<JailRegion>()
|
||||
|| Region.IsPartOf("Samurai start location")
|
||||
|| Region.IsPartOf("Ninja start location")
|
||||
|| Region.IsPartOf("Ninja cave"))
|
||||
|
|
|
|||
|
|
@ -1,35 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.Text.Json;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Json;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Regions
|
||||
{
|
||||
public enum SpawnZLevel
|
||||
{
|
||||
Lowest,
|
||||
Highest,
|
||||
Random
|
||||
}
|
||||
|
||||
public class BaseRegion : Region
|
||||
{
|
||||
private static readonly List<Rectangle3D> m_RectBuffer1 = new List<Rectangle3D>();
|
||||
private static readonly List<Rectangle3D> m_RectBuffer2 = new List<Rectangle3D>();
|
||||
|
||||
private static readonly List<int> m_SpawnBuffer1 = new List<int>();
|
||||
private static readonly List<Item> m_SpawnBuffer2 = new List<Item>();
|
||||
private bool m_ExcludeFromParentSpawns;
|
||||
public bool ExcludeFromParentSpawns { get; set; }
|
||||
|
||||
private Rectangle3D[] m_Rectangles;
|
||||
private int[] m_RectangleWeights;
|
||||
public Rectangle3D[] Rectangles { get; private set; }
|
||||
public int[] RectangleWeights { get; private set; }
|
||||
|
||||
private string m_RuneName;
|
||||
|
||||
private SpawnEntry[] m_Spawns;
|
||||
private int m_TotalWeight;
|
||||
public int TotalWeight { get; private set; }
|
||||
|
||||
public BaseRegion(string name, Map map, int priority, params Rectangle2D[] area) : base(name, map, priority, area)
|
||||
{
|
||||
|
|
@ -47,63 +37,12 @@ namespace Server.Regions
|
|||
{
|
||||
}
|
||||
|
||||
public BaseRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
public BaseRegion(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
ReadString(xml["rune"], "name", ref m_RuneName, false);
|
||||
if (json.data.TryGetValue("rune", out var runeName))
|
||||
m_RuneName = runeName.GetString();
|
||||
|
||||
bool logoutDelayActive = true;
|
||||
ReadBoolean(xml["logoutDelay"], "active", ref logoutDelayActive, false);
|
||||
NoLogoutDelay = !logoutDelayActive;
|
||||
|
||||
XmlElement spawning = xml["spawning"];
|
||||
if (spawning != null)
|
||||
{
|
||||
ReadBoolean(spawning, "excludeFromParent", ref m_ExcludeFromParentSpawns, false);
|
||||
|
||||
SpawnZLevel zLevel = SpawnZLevel.Lowest;
|
||||
ReadEnum(spawning, "zLevel", ref zLevel, false);
|
||||
SpawnZLevel = zLevel;
|
||||
|
||||
List<SpawnEntry> list = new List<SpawnEntry>();
|
||||
|
||||
foreach (XmlNode node in spawning.ChildNodes)
|
||||
if (node is XmlElement el)
|
||||
{
|
||||
SpawnDefinition def = SpawnDefinition.GetSpawnDefinition(el);
|
||||
if (def == null)
|
||||
continue;
|
||||
|
||||
int id = 0;
|
||||
if (!ReadInt32(el, "id", ref id, true))
|
||||
continue;
|
||||
|
||||
int amount = 0;
|
||||
if (!ReadInt32(el, "amount", ref amount, true))
|
||||
continue;
|
||||
|
||||
TimeSpan minSpawnTime = SpawnEntry.DefaultMinSpawnTime;
|
||||
ReadTimeSpan(el, "minSpawnTime", ref minSpawnTime, false);
|
||||
|
||||
TimeSpan maxSpawnTime = SpawnEntry.DefaultMaxSpawnTime;
|
||||
ReadTimeSpan(el, "maxSpawnTime", ref maxSpawnTime, false);
|
||||
|
||||
Point3D home = Point3D.Zero;
|
||||
int range = 0;
|
||||
|
||||
XmlElement homeEl = el["home"];
|
||||
if (ReadPoint3D(homeEl, map, ref home, false))
|
||||
ReadInt32(homeEl, "range", ref range, false);
|
||||
|
||||
Direction dir = SpawnEntry.InvalidDirection;
|
||||
ReadEnum(el["direction"], "value", ref dir, false);
|
||||
|
||||
SpawnEntry entry = new SpawnEntry(id, this, home, range, dir, def, amount, minSpawnTime,
|
||||
maxSpawnTime);
|
||||
list.Add(entry);
|
||||
}
|
||||
|
||||
if (list.Count > 0) m_Spawns = list.ToArray();
|
||||
}
|
||||
NoLogoutDelay = json.data.TryGetValue("logoutDelay", out var logoutDelay) && !logoutDelay.GetBoolean();
|
||||
}
|
||||
|
||||
public virtual bool YoungProtected => true;
|
||||
|
|
@ -121,39 +60,11 @@ namespace Server.Regions
|
|||
|
||||
public bool NoLogoutDelay { get; set; }
|
||||
|
||||
public SpawnEntry[] Spawns
|
||||
{
|
||||
get => m_Spawns;
|
||||
set
|
||||
{
|
||||
if (m_Spawns != null)
|
||||
for (int i = 0; i < m_Spawns.Length; i++)
|
||||
m_Spawns[i].Delete();
|
||||
|
||||
m_Spawns = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SpawnZLevel SpawnZLevel { get; set; }
|
||||
|
||||
public bool ExcludeFromParentSpawns
|
||||
{
|
||||
get => m_ExcludeFromParentSpawns;
|
||||
set => m_ExcludeFromParentSpawns = value;
|
||||
}
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
DefaultRegionType = typeof(BaseRegion);
|
||||
}
|
||||
|
||||
public override void OnUnregister()
|
||||
{
|
||||
base.OnUnregister();
|
||||
|
||||
Spawns = null;
|
||||
}
|
||||
|
||||
public static string GetRuneNameFor(Region region)
|
||||
{
|
||||
while (region != null)
|
||||
|
|
@ -169,61 +80,24 @@ namespace Server.Regions
|
|||
return null;
|
||||
}
|
||||
|
||||
public override TimeSpan GetLogoutDelay(Mobile m)
|
||||
{
|
||||
if (NoLogoutDelay)
|
||||
if (m.Aggressors.Count == 0 && m.Aggressed.Count == 0 && !m.Criminal)
|
||||
return TimeSpan.Zero;
|
||||
|
||||
return base.GetLogoutDelay(m);
|
||||
}
|
||||
|
||||
public static bool CanSpawn(Region region, params Type[] types)
|
||||
{
|
||||
while (region != null)
|
||||
{
|
||||
if (!region.AllowSpawn())
|
||||
return false;
|
||||
|
||||
if (region is BaseRegion br)
|
||||
{
|
||||
if (br.Spawns != null)
|
||||
for (int i = 0; i < br.Spawns.Length; i++)
|
||||
{
|
||||
SpawnEntry entry = br.Spawns[i];
|
||||
|
||||
if (entry.Definition.CanSpawn(types))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (br.ExcludeFromParentSpawns)
|
||||
return false;
|
||||
}
|
||||
|
||||
region = region.Parent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
public override TimeSpan GetLogoutDelay(Mobile m) =>
|
||||
NoLogoutDelay && m.Aggressors.Count == 0 && m.Aggressed.Count == 0 && !m.Criminal
|
||||
? TimeSpan.Zero
|
||||
: base.GetLogoutDelay(m);
|
||||
|
||||
public override void OnEnter(Mobile m)
|
||||
{
|
||||
if (m is PlayerMobile mobile && mobile.Young)
|
||||
if (!YoungProtected)
|
||||
mobile.SendGump(new YoungDungeonWarning());
|
||||
if (m is PlayerMobile mobile && mobile.Young && !YoungProtected)
|
||||
mobile.SendGump(new YoungDungeonWarning());
|
||||
}
|
||||
|
||||
public override bool AcceptsSpawnsFrom(Region region)
|
||||
{
|
||||
if (region == this || !m_ExcludeFromParentSpawns)
|
||||
return base.AcceptsSpawnsFrom(region);
|
||||
public override bool AcceptsSpawnsFrom(Region region) =>
|
||||
(region == this || !ExcludeFromParentSpawns) && base.AcceptsSpawnsFrom(region);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void InitRectangles()
|
||||
// TODO: Clean this up
|
||||
public void InitRectangles()
|
||||
{
|
||||
if (m_Rectangles != null)
|
||||
if (Rectangles != null)
|
||||
return;
|
||||
|
||||
// Test if area rectangles are overlapping, and in that case break them into smaller non overlapping rectangles
|
||||
|
|
@ -270,277 +144,22 @@ namespace Server.Regions
|
|||
m_RectBuffer2.Clear();
|
||||
}
|
||||
|
||||
m_Rectangles = m_RectBuffer1.ToArray();
|
||||
Rectangles = m_RectBuffer1.ToArray();
|
||||
m_RectBuffer1.Clear();
|
||||
|
||||
m_RectangleWeights = new int[m_Rectangles.Length];
|
||||
for (int i = 0; i < m_Rectangles.Length; i++)
|
||||
RectangleWeights = new int[Rectangles.Length];
|
||||
for (int i = 0; i < Rectangles.Length; i++)
|
||||
{
|
||||
Rectangle3D rect = m_Rectangles[i];
|
||||
Rectangle3D rect = Rectangles[i];
|
||||
int weight = rect.Width * rect.Height;
|
||||
|
||||
m_RectangleWeights[i] = weight;
|
||||
m_TotalWeight += weight;
|
||||
RectangleWeights[i] = weight;
|
||||
TotalWeight += weight;
|
||||
}
|
||||
}
|
||||
|
||||
public Point3D RandomSpawnLocation(int spawnHeight, bool land, bool water, Point3D home, int range)
|
||||
{
|
||||
Map map = Map;
|
||||
public override string ToString() => Name ?? RuneName ?? GetType().Name;
|
||||
|
||||
if (map == Map.Internal)
|
||||
return Point3D.Zero;
|
||||
|
||||
InitRectangles();
|
||||
|
||||
if (m_TotalWeight <= 0)
|
||||
return Point3D.Zero;
|
||||
|
||||
for (int i = 0; i < 10; i++) // Try 10 times
|
||||
{
|
||||
int x, y, minZ, maxZ;
|
||||
|
||||
if (home == Point3D.Zero)
|
||||
{
|
||||
int rand = Utility.Random(m_TotalWeight);
|
||||
|
||||
x = int.MinValue;
|
||||
y = int.MinValue;
|
||||
minZ = int.MaxValue;
|
||||
maxZ = int.MinValue;
|
||||
for (int j = 0; j < m_RectangleWeights.Length; j++)
|
||||
{
|
||||
int curWeight = m_RectangleWeights[j];
|
||||
|
||||
if (rand < curWeight)
|
||||
{
|
||||
Rectangle3D rect = m_Rectangles[j];
|
||||
|
||||
x = rect.Start.X + rand % rect.Width;
|
||||
y = rect.Start.Y + rand / rect.Width;
|
||||
|
||||
minZ = rect.Start.Z;
|
||||
maxZ = rect.End.Z;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
rand -= curWeight;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
x = Utility.RandomMinMax(home.X - range, home.X + range);
|
||||
y = Utility.RandomMinMax(home.Y - range, home.Y + range);
|
||||
|
||||
minZ = int.MaxValue;
|
||||
maxZ = int.MinValue;
|
||||
for (int j = 0; j < Area.Length; j++)
|
||||
{
|
||||
Rectangle3D rect = Area[j];
|
||||
|
||||
if (x >= rect.Start.X && x < rect.End.X && y >= rect.Start.Y && y < rect.End.Y)
|
||||
{
|
||||
minZ = rect.Start.Z;
|
||||
maxZ = rect.End.Z;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (minZ == int.MaxValue)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (x < 0 || y < 0 || x >= map.Width || y >= map.Height)
|
||||
continue;
|
||||
|
||||
LandTile lt = map.Tiles.GetLandTile(x, y);
|
||||
|
||||
int ltLowZ = 0, ltAvgZ = 0, ltTopZ = 0;
|
||||
map.GetAverageZ(x, y, ref ltLowZ, ref ltAvgZ, ref ltTopZ);
|
||||
|
||||
TileFlag ltFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;
|
||||
bool ltImpassable = (ltFlags & TileFlag.Impassable) != 0;
|
||||
|
||||
if (!lt.Ignored && ltAvgZ >= minZ && ltAvgZ < maxZ)
|
||||
if ((ltFlags & TileFlag.Wet) != 0)
|
||||
{
|
||||
if (water)
|
||||
m_SpawnBuffer1.Add(ltAvgZ);
|
||||
}
|
||||
else if (land && !ltImpassable)
|
||||
{
|
||||
m_SpawnBuffer1.Add(ltAvgZ);
|
||||
}
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
|
||||
|
||||
for (int j = 0; j < staticTiles.Length; j++)
|
||||
{
|
||||
StaticTile tile = staticTiles[j];
|
||||
ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
|
||||
int tileZ = tile.Z + id.CalcHeight;
|
||||
|
||||
if (tileZ >= minZ && tileZ < maxZ)
|
||||
if ((id.Flags & TileFlag.Wet) != 0)
|
||||
{
|
||||
if (water)
|
||||
m_SpawnBuffer1.Add(tileZ);
|
||||
}
|
||||
else if (land && id.Surface && !id.Impassable)
|
||||
{
|
||||
m_SpawnBuffer1.Add(tileZ);
|
||||
}
|
||||
}
|
||||
|
||||
Sector sector = map.GetSector(x, y);
|
||||
|
||||
for (int j = 0; j < sector.Items.Count; j++)
|
||||
{
|
||||
Item item = sector.Items[j];
|
||||
|
||||
if (!(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint(x, y))
|
||||
{
|
||||
m_SpawnBuffer2.Add(item);
|
||||
|
||||
if (!item.Movable)
|
||||
{
|
||||
ItemData id = item.ItemData;
|
||||
int itemZ = item.Z + id.CalcHeight;
|
||||
|
||||
if (itemZ >= minZ && itemZ < maxZ)
|
||||
if ((id.Flags & TileFlag.Wet) != 0)
|
||||
{
|
||||
if (water)
|
||||
m_SpawnBuffer1.Add(itemZ);
|
||||
}
|
||||
else if (land && id.Surface && !id.Impassable)
|
||||
{
|
||||
m_SpawnBuffer1.Add(itemZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_SpawnBuffer1.Count == 0)
|
||||
{
|
||||
m_SpawnBuffer1.Clear();
|
||||
m_SpawnBuffer2.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
int z;
|
||||
switch (SpawnZLevel)
|
||||
{
|
||||
case SpawnZLevel.Lowest:
|
||||
{
|
||||
z = int.MaxValue;
|
||||
|
||||
for (int j = 0; j < m_SpawnBuffer1.Count; j++)
|
||||
{
|
||||
int l = m_SpawnBuffer1[j];
|
||||
|
||||
if (l < z)
|
||||
z = l;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case SpawnZLevel.Highest:
|
||||
{
|
||||
z = int.MinValue;
|
||||
|
||||
for (int j = 0; j < m_SpawnBuffer1.Count; j++)
|
||||
{
|
||||
int l = m_SpawnBuffer1[j];
|
||||
|
||||
if (l > z)
|
||||
z = l;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: // SpawnZLevel.Random
|
||||
{
|
||||
int index = Utility.Random(m_SpawnBuffer1.Count);
|
||||
z = m_SpawnBuffer1[index];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_SpawnBuffer1.Clear();
|
||||
|
||||
if (!Find(new Point3D(x, y, z), map).AcceptsSpawnsFrom(this))
|
||||
{
|
||||
m_SpawnBuffer2.Clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
int top = z + spawnHeight;
|
||||
|
||||
bool ok = true;
|
||||
for (int j = 0; j < m_SpawnBuffer2.Count; j++)
|
||||
{
|
||||
Item item = m_SpawnBuffer2[j];
|
||||
ItemData id = item.ItemData;
|
||||
|
||||
if ((id.Surface || id.Impassable) && item.Z + id.CalcHeight > z && item.Z < top)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_SpawnBuffer2.Clear();
|
||||
|
||||
if (!ok)
|
||||
continue;
|
||||
|
||||
if (ltImpassable && ltAvgZ > z && ltLowZ < top)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < staticTiles.Length; j++)
|
||||
{
|
||||
StaticTile tile = staticTiles[j];
|
||||
ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];
|
||||
|
||||
if ((id.Surface || id.Impassable) && tile.Z + id.CalcHeight > z && tile.Z < top)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
continue;
|
||||
|
||||
for (int j = 0; j < sector.Mobiles.Count; j++)
|
||||
{
|
||||
Mobile m = sector.Mobiles[j];
|
||||
|
||||
if (m.X == x && m.Y == y && (m.AccessLevel == AccessLevel.Player || !m.Hidden))
|
||||
if (m.Z + 16 > z && m.Z < top)
|
||||
{
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok)
|
||||
return new Point3D(x, y, z);
|
||||
}
|
||||
|
||||
return Point3D.Zero;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Name != null)
|
||||
return Name;
|
||||
if (RuneName != null)
|
||||
return RuneName;
|
||||
return GetType().Name;
|
||||
}
|
||||
public virtual bool CheckTravel(Mobile m, Point3D newLocation, TravelCheckType travelType) => true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,29 +1,22 @@
|
|||
using System.Xml;
|
||||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
|
||||
namespace Server.Regions
|
||||
{
|
||||
public class DungeonRegion : BaseRegion
|
||||
{
|
||||
private Point3D m_EntranceLocation;
|
||||
|
||||
public DungeonRegion(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
public DungeonRegion(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
XmlElement entrEl = xml["entrance"];
|
||||
if (json.GetProperty("map", options, out Map map))
|
||||
EntranceMap = map;
|
||||
|
||||
Map entrMap = map;
|
||||
ReadMap(entrEl, "map", ref entrMap, false);
|
||||
|
||||
if (ReadPoint3D(entrEl, entrMap, ref m_EntranceLocation, false))
|
||||
EntranceMap = entrMap;
|
||||
if (json.GetProperty("entrance", options, out Point3D entrance))
|
||||
EntranceLocation = entrance;
|
||||
}
|
||||
|
||||
public override bool YoungProtected => false;
|
||||
|
||||
public Point3D EntranceLocation
|
||||
{
|
||||
get => m_EntranceLocation;
|
||||
set => m_EntranceLocation = value;
|
||||
}
|
||||
public Point3D EntranceLocation { get; set; }
|
||||
|
||||
public Map EntranceMap { get; set; }
|
||||
|
||||
|
|
@ -34,12 +27,6 @@ namespace Server.Regions
|
|||
global = LightCycle.DungeonLevel;
|
||||
}
|
||||
|
||||
public override bool CanUseStuckMenu(Mobile m)
|
||||
{
|
||||
if (Map == Map.Felucca)
|
||||
return false;
|
||||
|
||||
return base.CanUseStuckMenu(m);
|
||||
}
|
||||
public override bool CanUseStuckMenu(Mobile m) => Map != Map.Felucca && base.CanUseStuckMenu(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
using System.Xml;
|
||||
using Server.Spells.Chivalry;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Seventh;
|
||||
using Server.Spells.Sixth;
|
||||
|
||||
namespace Server.Regions
|
||||
{
|
||||
public class GreenAcres : BaseRegion
|
||||
{
|
||||
public GreenAcres(XmlElement xml, Map map, Region parent) : base(xml, map, parent)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool AllowHousing(Mobile from, Point3D p)
|
||||
{
|
||||
if (from.AccessLevel == AccessLevel.Player)
|
||||
return false;
|
||||
return base.AllowHousing(from, p);
|
||||
}
|
||||
|
||||
public override bool OnBeginSpellCast(Mobile m, ISpell s)
|
||||
{
|
||||
if ((s is GateTravelSpell || s is RecallSpell || s is MarkSpell || s is SacredJourneySpell) &&
|
||||
m.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
m.SendMessage("You cannot cast that spell here.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnBeginSpellCast(m, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
31
Projects/UOContent/Regions/GreenAcresRegion.cs
Normal file
31
Projects/UOContent/Regions/GreenAcresRegion.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System.Text.Json;
|
||||
using Server.Json;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Sixth;
|
||||
|
||||
namespace Server.Regions
|
||||
{
|
||||
public class GreenAcresRegion : BaseRegion
|
||||
{
|
||||
public GreenAcresRegion(DynamicJson json, JsonSerializerOptions options) : base(json, options)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool AllowHousing(Mobile from, Point3D p) =>
|
||||
from.AccessLevel != AccessLevel.Player && base.AllowHousing(from, p);
|
||||
|
||||
public override bool CheckTravel(Mobile m, Point3D newLocation, TravelCheckType travelType) =>
|
||||
m.AccessLevel != AccessLevel.Player;
|
||||
|
||||
public override bool OnBeginSpellCast(Mobile m, ISpell s)
|
||||
{
|
||||
if (m.AccessLevel == AccessLevel.Player && s is MarkSpell)
|
||||
{
|
||||
m.SendLocalizedMessage(501802); // Thy spell doth not appear to work...
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.OnBeginSpellCast(m, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue