rename file

This commit is contained in:
2024-06-09 14:50:21 +08:00
parent 138a16c289
commit 0e22d8dbce
376 changed files with 3 additions and 3 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Kevin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+14
View File
@@ -0,0 +1,14 @@
# IMPORTANT
# PLEASE READ THE MOD PAGE FOR THE MOST UP TO DATE INFORMATION!
# tbh I hardly update this so please check the mod page for info/faq/questions!
#
#
# SWAG + Donuts
![Version: 3.3.0](https://img.shields.io/badge/Version-3.3.0-informational?style=flat-square)
**All credit goes to Props, creator of SWAG and DONUTS**
---
All mod info can be found on the mod page: https://hub.sp-tarkov.com/files/file/878-swag-donuts-dynamic-spawn-waves-and-custom-spawn-points/
+194
View File
@@ -0,0 +1,194 @@
{
"TotalBossesPerMap": {
"factory": 1,
"factory_night": 1,
"customs": 1,
"woods": 1,
"shoreline": 1,
"lighthouse": 1,
"reserve": 1,
"interchange": 1,
"laboratory": 1,
"streets": 1
},
"Bosses": {
"useGlobalBossSpawnChance": true,
"gluhar": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 35,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"goons": {
"customs": 35,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 30,
"reserve": 0,
"shoreline": 35,
"streets": 0,
"woods": 35
},
"kaban": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 35,
"woods": 0
},
"killa": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 35,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"kolontay": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 35,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 35,
"woods": 0
},
"reshala": {
"customs": 35,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"sanitar": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 25,
"streets": 0,
"woods": 0
},
"shturman": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 15
},
"tagilla": {
"customs": 0,
"factory": 35,
"factory_night": 35,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"zryachiy": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 100,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
}
},
"CustomBosses": {
"santa": {
"enabled": true,
"forceSpawnOutsideEvent": false,
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"punisher": {
"enabled": false,
"useProgressSpawnChance": true,
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"legion": {
"enabled": false,
"useProgressSpawnChance": true,
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
}
}
}
+273
View File
@@ -0,0 +1,273 @@
{
"customs": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"factory": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"factory_night": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"groundzero": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"interchange": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"laboratory": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"reserve": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": [
"ZoneRailStrorage",
"ZonePTOR2",
"ZoneBarrack"
],
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"shoreline": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"streets": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
],
"woods": [
{
"BossChance": 35,
"BossEscortAmount": "0",
"BossEscortType": "followergluharassault",
"BossName": "bossgluhar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharsecurity"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followergluharscout"
}
],
"Time": 1
}
]
}
+233
View File
@@ -0,0 +1,233 @@
{
"customs": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": [
"ZoneScavBase"
]
}
],
"factory": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"factory_night": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"groundzero": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"interchange": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"laboratory": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"lighthouse": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": [
"Zone_Chalet",
"Zone_TreatmentContainers"
]
}
],
"reserve": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"shoreline": [
{
"BossName": "bossknight",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": [
"ZoneMeteoStation",
"ZoneSanatorium1",
"ZoneSanatorium2"
]
}
],
"streets": [
{
"BossName": "bossknight",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": null
}
],
"woods": [
{
"BossName": "bossknight",
"BossChance": 20,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "exusec",
"Supports": [
{
"BossEscortAmount": "1",
"BossEscortType": "followerbigpipe"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerbirdeye"
}
],
"BossZone": [
"ZoneScavBase2"
]
}
]
}
+283
View File
@@ -0,0 +1,283 @@
{
"customs": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"factory": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"factory_night": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"groundzero": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"interchange": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"laboratory": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"reserve": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"shoreline": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
],
"streets": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": [
"ZoneCarShowroom"
],
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
},
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "bossboarsniper",
"BossName": "bossboarsniper",
"BossZone": [
"ZoneSnipeCarShowroom"
],
"Time": 99999,
"TriggerId": "BossBoarBorn",
"TriggerName": "botEvent"
}
],
"woods": [
{
"BossChance": 11,
"BossEscortAmount": "6",
"BossEscortType": "followerboar",
"BossName": "bossboar",
"BossZone": null,
"Supports": [
{
"BossEscortAmount": "4",
"BossEscortType": "followerboar"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose1"
},
{
"BossEscortAmount": "1",
"BossEscortType": "followerboarclose2"
}
],
"Time": 1
}
]
}
+121
View File
@@ -0,0 +1,121 @@
{
"customs": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": [
"ZoneCenterBot",
"ZoneCenter",
"ZoneOLI",
"ZoneIDEA",
"ZoneGoshan"
],
"Time": 1
}
],
"laboratory": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Time": 1
}
],
"streets": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followertagilla",
"BossName": "bosskilla",
"BossZone": null,
"Time": 1
}
]
}
+272
View File
@@ -0,0 +1,272 @@
{
"customs": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"factory": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"factory_night": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"groundzero": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"interchange": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"laboratory": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"lighthouse": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"reserve": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
],
"shoreline": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
]
}
],
"streets": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": [
"ZoneClimova",
"ZoneMvd"
]
}
],
"woods": [
{
"BossName": "bosskolontay",
"BossChance": 35,
"Time": 1,
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity",
"Supports": [
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontayassault"
},
{
"BossEscortAmount": "2",
"BossEscortType": "followerkolontaysecurity"
},
{
"BossEscortAmount": "0",
"BossEscortType": "followergluharscout"
}
],
"BossZone": null
}
]
}
+118
View File
@@ -0,0 +1,118 @@
{
"customs": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": [
"ZoneDormitory",
"ZoneGasStation"
],
"Time": 1
}
],
"factory": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Time": 1
}
],
"streets": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 35,
"BossEscortAmount": "4",
"BossEscortType": "followerbully",
"BossName": "bossbully",
"BossZone": null,
"Time": 1
}
]
}
+116
View File
@@ -0,0 +1,116 @@
{
"customs": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2",
"ZonePort"
],
"Time": 1
}
],
"streets": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 5,
"BossEscortAmount": "2,3",
"BossEscortType": "followersanitar",
"BossName": "bosssanitar",
"BossZone": null,
"Time": 1
}
]
}
+117
View File
@@ -0,0 +1,117 @@
{
"customs": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Time": 1
}
],
"streets": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 35,
"BossEscortAmount": "2",
"BossEscortType": "followerkojaniy",
"BossName": "bosskojaniy",
"BossZone": [
"ZoneWoodCutter"
],
"Time": 1
}
]
}
+119
View File
@@ -0,0 +1,119 @@
{
"customs": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": [
"BotZone"
],
"Time": 1
}
],
"factory_night": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": [
"BotZone"
],
"Time": 1
}
],
"groundzero": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": [
"ZoneSanatorium1",
"ZoneSanatorium2"
],
"Time": 1
}
],
"streets": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 30,
"BossEscortAmount": "0",
"BossEscortType": "followerbully",
"BossName": "bosstagilla",
"BossZone": null,
"Time": 1
}
]
}
+114
View File
@@ -0,0 +1,114 @@
{
"customs": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 100,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": [
"Zone_Island"
],
"Time": 1
}
],
"reserve": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 0,
"BossEscortAmount": "2",
"BossEscortType": "followerzryachiy",
"BossName": "bosszryachiy",
"BossZone": null,
"Time": 1
}
]
}
+110
View File
@@ -0,0 +1,110 @@
{
"BossDifficulty": "normal",
"BossEscortDifficulty": "normal",
"disableAllSpawns": {
"bosses": false,
"rogues": false,
"raiders": false,
"cultists": false,
"scav_snipers": false,
"bloodhounds": false
},
"Spawns": {
"useGlobalSpawnChance": true,
"bloodhounds": {
"customs": 5,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 5,
"streets": 0,
"woods": 5
},
"cultists": {
"customs": 10,
"factory": 0,
"factory_night": 2,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 0,
"reserve": 0,
"shoreline": 10,
"streets": 0,
"woods": 12
},
"raiders": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 65,
"lighthouse": 0,
"reserve": 65,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"rogues": {
"customs": 0,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 75,
"reserve": 0,
"shoreline": 0,
"streets": 0,
"woods": 0
},
"scav_snipers": {
"customs": 65,
"factory": 0,
"factory_night": 0,
"groundzero": 0,
"interchange": 0,
"laboratory": 0,
"lighthouse": 65,
"reserve": 0,
"shoreline": 65,
"streets": 65,
"woods": 65
}
},
"MaxBotCap": {
"factory": 16,
"customs": 24,
"woods": 26,
"shoreline": 24,
"lighthouse": 26,
"reserve": 24,
"interchange": 24,
"laboratory": 18,
"streets": 26,
"groundzero": 22
},
"NightMaxBotCap": {
"factory_night": 16,
"customs": 24,
"woods": 26,
"shoreline": 24,
"lighthouse": 26,
"reserve": 24,
"interchange": 24,
"laboratory": 18,
"streets": 26,
"groundzero": 22
},
"UseDefaultSpawns": {
"Waves": false,
"Bosses": false,
"TriggeredWaves": false
},
"DebugOutput": false
}
+112
View File
@@ -0,0 +1,112 @@
{
"customs": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossName": "bosslegion",
"BossZone": null,
"Time": 1
}
]
}
+134
View File
@@ -0,0 +1,134 @@
{
"customs": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 15,
"BossEscortAmount": "4",
"BossEscortType": "exusec",
"BossDifficult": "impossible",
"BossEscortDifficult": "impossible",
"BossName": "bosspunisher",
"BossZone": null,
"Time": 1
}
]
}
+112
View File
@@ -0,0 +1,112 @@
{
"customs": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 35,
"BossName": "gifter",
"BossEscortType": "gifter",
"BossEscortAmount": "0",
"BossZone": null,
"Time": 1
}
]
}
@@ -0,0 +1,124 @@
{
"customs": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": [
"ZoneBrige",
"ZoneBlockPost"
]
}
],
"factory": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"factory_night": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"groundzero": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"interchange": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"laboratory": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"lighthouse": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"reserve": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"shoreline": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"BossEscortType": "arenafighterevent",
"BossEscortAmount": "3,4",
"Time": 1,
"BossZone": [
"ZoneStartVillage",
"ZoneGasStation",
"ZonePowerStation"
]
}
],
"streets": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"Time": 1,
"BossEscortAmount": "3,4",
"BossEscortType": "arenafighterevent",
"BossZone": null
}
],
"woods": [
{
"BossName": "arenafighterevent",
"BossChance": 5,
"BossEscortType": "arenafighterevent",
"BossEscortAmount": "3,4",
"Time": 1,
"BossZone": [
"ZoneClearVill",
"ZoneRoad",
"ZoneHouse",
"ZoneBigRocks"
]
}
]
}
+164
View File
@@ -0,0 +1,164 @@
{
"customs": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": [
"ZoneCustoms",
"ZoneWade",
"ZoneCrossRoad",
"ZoneOldAZS"
]
}
],
"factory": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"factory_night": [
{
"BossName": "sectantpriest",
"BossChance": 55,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "2",
"Time": 1,
"BossZone": [
"BotZone"
]
},
{
"BossName": "sectantpriest",
"BossChance": 55,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "2",
"Time": 300,
"BossZone": [
"BotZone"
]
},
{
"BossName": "sectantpriest",
"BossChance": 55,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "2",
"Time": 600,
"BossZone": [
"BotZone"
]
},
{
"BossName": "sectantpriest",
"BossChance": 55,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "2",
"Time": 900,
"BossZone": [
"BotZone"
]
}
],
"groundzero": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"interchange": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"laboratory": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"lighthouse": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"reserve": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"shoreline": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "3",
"Time": 1,
"BossZone": [
"ZoneForestGasStation"
]
},
{
"BossName": "sectantpriest",
"BossChance": 15,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "3",
"Time": 1,
"BossZone": [
"ZoneForestSpawn"
]
}
],
"streets": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"Time": 1,
"BossEscortAmount": "4",
"BossEscortType": "sectantwarrior",
"BossZone": null
}
],
"woods": [
{
"BossName": "sectantpriest",
"BossChance": 15,
"BossEscortType": "sectantwarrior",
"BossEscortAmount": "4",
"Time": 1,
"BossZone": [
"ZoneMiniHouse",
"ZoneBrokenVill"
]
}
]
}
+330
View File
@@ -0,0 +1,330 @@
{
"customs": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 55,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor1"
],
"Time": 900
},
{
"BossChance": 55,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": 300
},
{
"BossChance": 45,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneBasement"
],
"Time": 450,
"TriggerId": "autoId_00008_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 45,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneBasement"
],
"Time": 800,
"TriggerId": "autoId_00010_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 40,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneBasement"
],
"Time": -1,
"TriggerId": "autoId_00007_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 45,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": -1,
"TriggerId": "autoId_00007_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor1"
],
"Time": 600,
"TriggerId": "autoId_00632_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": 600,
"TriggerId": "autoId_00632_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor1"
],
"Time": -1,
"TriggerId": "autoId_00012_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": -1,
"TriggerId": "autoId_00012_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor1"
],
"Time": 1200,
"TriggerId": "autoId_00014_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,2,2,1,1,2,2,2,2,1,1,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": 1200,
"TriggerId": "autoId_00014_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,2,2,1,1,2,2,2,2,1,1,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor1"
],
"Time": -1,
"TriggerId": "autoId_00009_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 35,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneFloor2"
],
"Time": -1,
"TriggerId": "autoId_00009_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 40,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneGate2"
],
"Time": -1,
"TriggerId": "autoId_00014_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 45,
"BossEscortAmount": "1,1,1,1,2,2,2,1,1,1,1,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"BotZoneGate1"
],
"Time": -1,
"TriggerId": "autoId_00632_EXFIL",
"TriggerName": "interactObject"
}
],
"lighthouse": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"reserve": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"ZoneRailStrorage"
],
"Time": 1470
},
{
"BossChance": 40,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"ZoneRailStrorage"
],
"Time": -1,
"TriggerId": "autoId_00632_EXFIL",
"TriggerName": "interactObject"
},
{
"BossChance": 40,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"ZoneSubCommand"
],
"Time": -1,
"TriggerId": "autoId_00000_D2_LEVER",
"TriggerName": "interactObject"
},
{
"BossChance": 40,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": [
"ZoneSubCommand"
],
"Time": 3,
"TriggerId": "raider_simple_patroling",
"TriggerName": "interactObject"
}
],
"shoreline": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 35,
"BossEscortAmount": "2,2,2,2,3",
"BossEscortType": "pmcbot",
"BossName": "pmcbot",
"BossZone": null,
"Time": 1
}
]
}
+174
View File
@@ -0,0 +1,174 @@
{
"customs": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"factory": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"factory_night": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"groundzero": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"interchange": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"laboratory": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"lighthouse": [
{
"BossChance": 100,
"BossEscortAmount": "1",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_Blockpost"
],
"Time": 1
},
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_RoofContainers"
],
"Time": 1
},
{
"BossChance": 40,
"BossEscortAmount": "1,1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_TreatmentRocks"
],
"Time": 1
},
{
"BossChance": 40,
"BossEscortAmount": "1,1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_TreatmentBeach"
],
"Time": 1
},
{
"BossChance": 80,
"BossEscortAmount": "0",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_RoofRocks"
],
"Time": 1
},
{
"BossChance": 80,
"BossEscortAmount": "1",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_RoofBeach"
],
"Time": 1
},
{
"BossChance": 10,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": [
"Zone_Hellicopter"
],
"Time": 1
}
],
"reserve": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"shoreline": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"streets": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
],
"woods": [
{
"BossChance": 100,
"BossEscortAmount": "1,2",
"BossEscortType": "exusec",
"BossName": "exusec",
"BossZone": null,
"Time": 1
}
]
}
@@ -0,0 +1,194 @@
{
"customs": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeTower"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeFactory"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneBlockPostSniper"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeBrige"
]
}
],
"factory": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": null
}
],
"factory_night": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": null
}
],
"groundzero": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSandSnipeCenter"
]
}
],
"interchange": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": null
}
],
"laboratory": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": null
}
],
"lighthouse": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"Zone_SniperPeak"
]
}
],
"reserve": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": null
}
],
"shoreline": [
{
"BossName": "marksman",
"BossChance": 65,
"BossEscortType": "marksman",
"BossEscortAmount": "0",
"Time": 1,
"BossZone": [
"ZonePowerStationSniper"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"BossEscortType": "marksman",
"BossEscortAmount": "0",
"Time": 1,
"BossZone": [
"ZoneBunkeSniper"
]
}
],
"streets": [
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeCinema"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeCarShowroom"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeBuilding"
]
},
{
"BossName": "marksman",
"BossChance": 65,
"Time": 1,
"BossEscortAmount": "0",
"BossEscortType": "marksman",
"BossZone": [
"ZoneSnipeSW01"
]
}
],
"woods": [
{
"BossName": "marksman",
"BossChance": 65,
"BossEscortType": "marksman",
"BossEscortAmount": "0",
"Time": 1,
"BossZone": [
"ZoneHighRocks"
]
}
]
}
+23
View File
@@ -0,0 +1,23 @@
{
"name": "SWAG + DONUTS",
"version": "3.3.6",
"main": "src/SWAG.js",
"license": "MIT",
"author": "nooky and props",
"akiVersion": "~3.8.0",
"scripts": {
"setup": "npm i",
"build": "node ./packageBuild.ts"
},
"devDependencies": {
"@types/node": "16.18.10",
"@typescript-eslint/eslint-plugin": "5.46.1",
"@typescript-eslint/parser": "5.46.1",
"bestzip": "2.2.1",
"eslint": "8.30.0",
"fs-extra": "11.1.0",
"glob": "8.0.3",
"tsyringe": "4.7.0",
"typescript": "4.9.4"
}
}
+170
View File
@@ -0,0 +1,170 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.aiAmountProper = exports.validMaps = exports.pmcType = exports.diffProper = exports.reverseMapNames = exports.reverseBossNames = exports.roleCase = exports.Props = exports.Center = exports.ColliderParams = exports.Position = exports.SpawnPointParam = exports.MapWrapper = exports.GroupPattern = exports.Bot = void 0;
class Bot {
BotType;
MaxBotCount;
}
exports.Bot = Bot;
class GroupPattern {
Name;
Bots;
Time_min;
Time_max;
BotZone;
RandomTimeSpawn;
OnlySpawnOnce;
}
exports.GroupPattern = GroupPattern;
class MapWrapper {
MapName;
MapGroups;
MapBosses;
}
exports.MapWrapper = MapWrapper;
class SpawnPointParam {
Id;
Position;
Rotation;
Sides;
Categories;
Infiltration;
DelayToCanSpawnSec;
ColliderParams;
BotZoneName;
}
exports.SpawnPointParam = SpawnPointParam;
class Position {
x;
y;
z;
}
exports.Position = Position;
class ColliderParams {
_parent;
_props;
}
exports.ColliderParams = ColliderParams;
class Center {
x;
y;
z;
}
exports.Center = Center;
class Props {
Center;
Radius;
}
exports.Props = Props;
exports.roleCase = {
assault: "assault",
exusec: "exUsec",
marksman: "marksman",
pmcbot: "pmcBot",
sectantpriest: "sectantPriest",
sectantwarrior: "sectantWarrior",
assaultgroup: "assaultGroup",
bossbully: "bossBully",
bosstagilla: "bossTagilla",
bossgluhar: "bossGluhar",
bosskilla: "bossKilla",
bosskojaniy: "bossKojaniy",
bosssanitar: "bossSanitar",
bossboar: "bossBoar",
bossboarsniper: "bossBoarSniper",
bosskolontay: "bossKolontay",
bosspunisher: "bosspunisher",
bosslegion: "bosslegion",
followerboar: "followerBoar",
followerboarclose1: "followerBoarClose1",
followerboarclose2: "followerBoarClose2",
followerbully: "followerBully",
followergluharassault: "followerGluharAssault",
followergluharscout: "followerGluharScout",
followergluharsecurity: "followerGluharSecurity",
followergluharsnipe: "followerGluharSnipe",
followerkojaniy: "followerKojaniy",
followersanitar: "followerSanitar",
followertagilla: "followerTagilla",
followerkolontayassault: "followerKolontayAssault",
followerkolontaysecurity: "followerKolontaySecurity",
cursedassault: "cursedAssault",
pmc: "pmc",
usec: "usec",
bear: "bear",
sptbear: "sptBear",
sptusec: "sptUsec",
bosstest: "bossTest",
followertest: "followerTest",
gifter: "gifter",
bossknight: "bossKnight",
followerbigpipe: "followerBigPipe",
followerbirdeye: "followerBirdEye",
bosszryachiy: "bossZryachiy",
followerzryachiy: "followerZryachiy",
arenafighterevent: "arenaFighterEvent",
crazyassaultevent: "crazyAssaultEvent"
};
exports.reverseBossNames = {
bossboar: "kaban",
bossbully: "reshala",
bosstagilla: "tagilla",
bossgluhar: "gluhar",
bosskilla: "killa",
bosskojaniy: "shturman",
bosssanitar: "sanitar",
bossknight: "goons",
bosszryachiy: "zryachiy",
bosskolontay: "kolontay",
marksman: "scav_snipers",
sectantpriest: "cultists",
exusec: "rogues",
pmcbot: "raiders",
crazyassaultevent: "crazyscavs",
arenafighterevent: "bloodhounds",
bosspunisher: "punisher",
bosslegion: "legion",
gifter: "santa"
};
exports.reverseMapNames = {
factory4_day: "factory",
factory4_night: "factory_night",
bigmap: "customs",
woods: "woods",
shoreline: "shoreline",
lighthouse: "lighthouse",
rezervbase: "reserve",
interchange: "interchange",
laboratory: "laboratory",
tarkovstreets: "streets",
sandbox: "groundzero"
};
exports.diffProper = {
easy: "easy",
asonline: "random",
normal: "normal",
hard: "hard",
impossible: "impossible"
};
exports.pmcType = ["sptbear", "sptusec"];
exports.validMaps = [
"bigmap",
"factory4_day",
"factory4_night",
"interchange",
"laboratory",
"lighthouse",
"rezervbase",
"shoreline",
"tarkovstreets",
"woods",
"sandbox"
];
exports.aiAmountProper = {
low: 0.5,
asonline: 1,
medium: 1,
high: 2,
horde: 4,
};
//# sourceMappingURL=ClassDef.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"ClassDef.js","sourceRoot":"","sources":["ClassDef.ts"],"names":[],"mappings":";;;AAQA,MAAa,GAAG;IACd,OAAO,CAAS;IAChB,WAAW,CAAS;CACrB;AAHD,kBAGC;AAED,MAAa,YAAY;IACvB,IAAI,CAAS;IACb,IAAI,CAAQ;IACZ,QAAQ,CAAS;IACjB,QAAQ,CAAS;IACjB,OAAO,CAAS;IAChB,eAAe,CAAW;IAC1B,aAAa,CAAW;CACzB;AARD,oCAQC;AAED,MAAa,UAAU;IACrB,OAAO,CAAS;IAChB,SAAS,CAAiB;IAC1B,SAAS,CAAgB;CAC1B;AAJD,gCAIC;AAED,MAAa,eAAe;IAC1B,EAAE,CAAS;IACX,QAAQ,CAAW;IACnB,QAAQ,CAAS;IACjB,KAAK,CAAW;IAChB,UAAU,CAAW;IACrB,YAAY,CAAS;IACrB,kBAAkB,CAAS;IAC3B,cAAc,CAAiB;IAC/B,WAAW,CAAS;CACrB;AAVD,0CAUC;AAED,MAAa,QAAQ;IACnB,CAAC,CAAS;IACV,CAAC,CAAS;IACV,CAAC,CAAS;CACX;AAJD,4BAIC;AAED,MAAa,cAAc;IACzB,OAAO,CAAS;IAChB,MAAM,CAAQ;CACf;AAHD,wCAGC;AAED,MAAa,MAAM;IACjB,CAAC,CAAS;IACV,CAAC,CAAS;IACV,CAAC,CAAS;CACX;AAJD,wBAIC;AAED,MAAa,KAAK;IAChB,MAAM,CAAS;IACf,MAAM,CAAS;CAChB;AAHD,sBAGC;AAEY,QAAA,QAAQ,GAAW;IAC9B,OAAO,EAAE,SAAS;IAClB,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,MAAM,EAAE,QAAQ;IAChB,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,gBAAgB;IAChC,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,cAAc;IAC5B,kBAAkB,EAAE,oBAAoB;IACxC,kBAAkB,EAAE,oBAAoB;IACxC,aAAa,EAAE,eAAe;IAC9B,qBAAqB,EAAE,uBAAuB;IAC9C,mBAAmB,EAAE,qBAAqB;IAC1C,sBAAsB,EAAE,wBAAwB;IAChD,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,eAAe,EAAE,iBAAiB;IAClC,eAAe,EAAE,iBAAiB;IAClC,uBAAuB,EAAE,yBAAyB;IAClD,wBAAwB,EAAE,0BAA0B;IACpD,aAAa,EAAE,eAAe;IAC9B,GAAG,EAAE,KAAK;IACV,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM;IACZ,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,YAAY,EAAE,cAAc;IAC5B,MAAM,EAAE,QAAQ;IAChB,UAAU,EAAE,YAAY;IACxB,eAAe,EAAE,iBAAiB;IAClC,eAAe,EAAE,iBAAiB;IAClC,YAAY,EAAE,cAAc;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,iBAAiB,EAAE,mBAAmB;IACtC,iBAAiB,EAAE,mBAAmB;CACvC,CAAC;AAEW,QAAA,gBAAgB,GAAW;IACtC,QAAQ,EAAE,OAAO;IACjB,SAAS,EAAE,SAAS;IACpB,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE,QAAQ;IACpB,SAAS,EAAE,OAAO;IAClB,WAAW,EAAE,UAAU;IACvB,WAAW,EAAE,SAAS;IACtB,UAAU,EAAE,OAAO;IACnB,YAAY,EAAE,UAAU;IACxB,YAAY,EAAE,UAAU;IACxB,QAAQ,EAAE,cAAc;IACxB,aAAa,EAAE,UAAU;IACzB,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,SAAS;IACjB,iBAAiB,EAAE,YAAY;IAC/B,iBAAiB,EAAE,aAAa;IAChC,YAAY,EAAE,UAAU;IACxB,UAAU,EAAE,QAAQ;IACpB,MAAM,EAAE,OAAO;CAChB,CAAC;AAEW,QAAA,eAAe,GAAW;IACrC,YAAY,EAAE,SAAS;IACvB,cAAc,EAAE,eAAe;IAC/B,MAAM,EAAE,SAAS;IACjB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,aAAa;IAC1B,UAAU,EAAE,YAAY;IACxB,aAAa,EAAE,SAAS;IACxB,OAAO,EAAE,YAAY;CACtB,CAAC;AAEW,QAAA,UAAU,GAAG;IACxB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,QAAQ;IAClB,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,UAAU,EAAE,YAAY;CACzB,CAAC;AAEW,QAAA,OAAO,GAAa,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAE3C,QAAA,SAAS,GAAa;IACjC,QAAQ;IACR,cAAc;IACd,gBAAgB;IAChB,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,eAAe;IACf,OAAO;IACP,SAAS;CACV,CAAC;AAEW,QAAA,cAAc,GAAG;IAC5B,GAAG,EAAE,GAAG;IACR,QAAQ,EAAE,CAAC;IACX,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC"}
+180
View File
@@ -0,0 +1,180 @@
import {
BossLocationSpawn,
} from "@spt-aki/models/eft/common/ILocationBase";
export interface BossPattern extends BossLocationSpawn {
OnlySpawnOnce?: boolean;
}
export class Bot {
BotType: string;
MaxBotCount: number;
}
export class GroupPattern {
Name: string;
Bots: Bot[];
Time_min: number;
Time_max: number;
BotZone: string;
RandomTimeSpawn?: boolean;
OnlySpawnOnce?: boolean;
}
export class MapWrapper {
MapName: string;
MapGroups: GroupPattern[];
MapBosses: BossPattern[];
}
export class SpawnPointParam {
Id: string;
Position: Position;
Rotation: number;
Sides: string[];
Categories: string[];
Infiltration: string;
DelayToCanSpawnSec: number;
ColliderParams: ColliderParams;
BotZoneName: string;
}
export class Position {
x: number;
y: number;
z: number;
}
export class ColliderParams {
_parent: string;
_props: Props;
}
export class Center {
x: number;
y: number;
z: number;
}
export class Props {
Center: Center;
Radius: number;
}
export const roleCase: object = {
assault: "assault",
exusec: "exUsec",
marksman: "marksman",
pmcbot: "pmcBot",
sectantpriest: "sectantPriest",
sectantwarrior: "sectantWarrior",
assaultgroup: "assaultGroup",
bossbully: "bossBully",
bosstagilla: "bossTagilla",
bossgluhar: "bossGluhar",
bosskilla: "bossKilla",
bosskojaniy: "bossKojaniy",
bosssanitar: "bossSanitar",
bossboar: "bossBoar",
bossboarsniper: "bossBoarSniper",
bosskolontay: "bossKolontay",
bosspunisher: "bosspunisher",
bosslegion: "bosslegion",
followerboar: "followerBoar",
followerboarclose1: "followerBoarClose1",
followerboarclose2: "followerBoarClose2",
followerbully: "followerBully",
followergluharassault: "followerGluharAssault",
followergluharscout: "followerGluharScout",
followergluharsecurity: "followerGluharSecurity",
followergluharsnipe: "followerGluharSnipe",
followerkojaniy: "followerKojaniy",
followersanitar: "followerSanitar",
followertagilla: "followerTagilla",
followerkolontayassault: "followerKolontayAssault",
followerkolontaysecurity: "followerKolontaySecurity",
cursedassault: "cursedAssault",
pmc: "pmc",
usec: "usec",
bear: "bear",
sptbear: "sptBear",
sptusec: "sptUsec",
bosstest: "bossTest",
followertest: "followerTest",
gifter: "gifter",
bossknight: "bossKnight",
followerbigpipe: "followerBigPipe",
followerbirdeye: "followerBirdEye",
bosszryachiy: "bossZryachiy",
followerzryachiy: "followerZryachiy",
arenafighterevent: "arenaFighterEvent",
crazyassaultevent: "crazyAssaultEvent"
};
export const reverseBossNames: object = {
bossboar: "kaban",
bossbully: "reshala",
bosstagilla: "tagilla",
bossgluhar: "gluhar",
bosskilla: "killa",
bosskojaniy: "shturman",
bosssanitar: "sanitar",
bossknight: "goons",
bosszryachiy: "zryachiy",
bosskolontay: "kolontay",
marksman: "scav_snipers",
sectantpriest: "cultists",
exusec: "rogues",
pmcbot: "raiders",
crazyassaultevent: "crazyscavs",
arenafighterevent: "bloodhounds",
bosspunisher: "punisher",
bosslegion: "legion",
gifter: "santa"
};
export const reverseMapNames: object = {
factory4_day: "factory",
factory4_night: "factory_night",
bigmap: "customs",
woods: "woods",
shoreline: "shoreline",
lighthouse: "lighthouse",
rezervbase: "reserve",
interchange: "interchange",
laboratory: "laboratory",
tarkovstreets: "streets",
sandbox: "groundzero"
};
export const diffProper = {
easy: "easy",
asonline: "random",
normal: "normal",
hard: "hard",
impossible: "impossible"
};
export const pmcType: string[] = ["sptbear", "sptusec"];
export const validMaps: string[] = [
"bigmap",
"factory4_day",
"factory4_night",
"interchange",
"laboratory",
"lighthouse",
"rezervbase",
"shoreline",
"tarkovstreets",
"woods",
"sandbox"
];
export const aiAmountProper = {
low: 0.5,
asonline: 1,
medium: 1,
high: 2,
horde: 4,
};
+599
View File
@@ -0,0 +1,599 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ConfigTypes_1 = require("/snapshot/project/obj/models/enums/ConfigTypes");
const ContextVariableType_1 = require("/snapshot/project/obj/context/ContextVariableType");
const JsonUtil_1 = require("/snapshot/project/obj/utils/JsonUtil");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ClassDef = __importStar(require("./ClassDef"));
const ClassDef_1 = require("./ClassDef");
// General SWAG Config
const config_json_1 = __importDefault(require("../config/config.json"));
const bossConfig_json_1 = __importDefault(require("../config/bossConfig.json"));
// Bosses
const gluhar_json_1 = __importDefault(require("../config/bosses/gluhar.json"));
const goons_json_1 = __importDefault(require("../config/bosses/goons.json"));
const kaban_json_1 = __importDefault(require("../config/bosses/kaban.json"));
const killa_json_1 = __importDefault(require("../config/bosses/killa.json"));
const kolontay_json_1 = __importDefault(require("../config/bosses/kolontay.json"));
const reshala_json_1 = __importDefault(require("../config/bosses/reshala.json"));
const sanitar_json_1 = __importDefault(require("../config/bosses/sanitar.json"));
const shturman_json_1 = __importDefault(require("../config/bosses/shturman.json"));
const tagilla_json_1 = __importDefault(require("../config/bosses/tagilla.json"));
const zryachiy_json_1 = __importDefault(require("../config/bosses/zryachiy.json"));
// Spawn Configs
const bloodhounds_json_1 = __importDefault(require("../config/other/bloodhounds.json"));
const cultists_json_1 = __importDefault(require("../config/other/cultists.json"));
const raiders_json_1 = __importDefault(require("../config/other/raiders.json"));
const rogues_json_1 = __importDefault(require("../config/other/rogues.json"));
const scav_snipers_json_1 = __importDefault(require("../config/other/scav_snipers.json"));
// Custom
const punisher_json_1 = __importDefault(require("../config/custom/punisher.json"));
const legion_json_1 = __importDefault(require("../config/custom/legion.json"));
const otherSpawnConfigs = [
bloodhounds_json_1.default,
cultists_json_1.default,
scav_snipers_json_1.default,
raiders_json_1.default,
rogues_json_1.default
];
const bossSpawnConfigs = [
gluhar_json_1.default,
goons_json_1.default,
kaban_json_1.default,
killa_json_1.default,
kolontay_json_1.default,
reshala_json_1.default,
sanitar_json_1.default,
shturman_json_1.default,
tagilla_json_1.default,
zryachiy_json_1.default
];
const customSpawnConfigs = [
punisher_json_1.default,
legion_json_1.default
];
const modName = "SWAG";
let logger;
let LocationCallbacks;
LocationCallbacks;
let jsonUtil;
JsonUtil_1.JsonUtil;
let botConfig;
let pmcConfig;
let iGlobals;
let configServer;
let databaseServer;
let locations;
let seasonalEvents;
let randomUtil;
let profileHelper;
let sessionId;
let BossWaveSpawnedOnceAlready;
const customPatterns = {};
class SWAG {
static savedLocationData = {
factory4_day: undefined,
factory4_night: undefined,
bigmap: undefined,
interchange: undefined,
laboratory: undefined,
lighthouse: undefined,
rezervbase: undefined,
shoreline: undefined,
tarkovstreets: undefined,
woods: undefined,
sandbox: undefined,
// unused
develop: undefined,
hideout: undefined,
privatearea: undefined,
suburbs: undefined,
terminal: undefined,
town: undefined,
};
static pmcType = ["sptbear", "sptusec"];
static randomWaveTimer = {
time_min: 0,
time_max: 0,
};
static actual_timers = {
time_min: 0,
time_max: 0,
};
static waveCounter = {
count: 1,
};
static raid_time = {
time_of_day: "day",
};
static bossCount = {
count: 0,
};
preAkiLoad(container) {
const HttpResponse = container.resolve("HttpResponseUtil");
const staticRouterModService = container.resolve("StaticRouterModService");
staticRouterModService.registerStaticRouter(`${modName}/client/match/offline/end`, [
{
url: "/client/match/offline/end",
action: (url, info, sessionID, output) => {
sessionId = sessionID;
SWAG.ClearDefaultSpawns();
SWAG.ConfigureMaps();
return LocationCallbacks.getLocationData(url, info, sessionID);
},
},
], "SWAG");
staticRouterModService.registerStaticRouter(`${modName}/client/locations`, [
{
url: "/client/locations",
action: (url, info, sessionID, output) => {
sessionId = sessionID;
SWAG.ClearDefaultSpawns();
SWAG.ConfigureMaps();
return LocationCallbacks.getLocationData(url, info, sessionID);
},
},
], "SWAG");
staticRouterModService.registerStaticRouter(`${modName}/client/items`, [
{
url: "/client/items",
action: (url, info, sessionID, output) => {
sessionId = sessionID;
const locationConfig = container.resolve("ConfigServer").getConfig(ConfigTypes_1.ConfigTypes.LOCATION);
// as of SPT 3.6.0 we need to disable the new spawn system so that SWAG can clear spawns properly
if (!config_json_1.default?.UseDefaultSpawns?.Waves ||
!config_json_1.default?.UseDefaultSpawns?.Bosses ||
!config_json_1.default?.UseDefaultSpawns?.TriggeredWaves) {
SWAG.disableSpawnSystems();
}
// disable more vanilla spawn stuff
locationConfig.splitWaveIntoSingleSpawnsSettings.enabled = false;
locationConfig.rogueLighthouseSpawnTimeSettings.enabled = false;
locationConfig.fixEmptyBotWavesSettings.enabled = false;
locationConfig.addOpenZonesToAllMaps = false;
locationConfig.addCustomBotWavesToMaps = false;
locationConfig.enableBotTypeLimits = false;
logger.info("SWAG: Vanilla spawn systems disabled");
return output;
},
},
], "SWAG");
staticRouterModService.registerStaticRouter(`${modName}/client/raid/configuration`, [{
url: "/client/raid/configuration",
action: (url, info, sessionID, output) => {
try {
// Retrieve configurations
const botConfig = container.resolve("ConfigServer").getConfig(ConfigTypes_1.ConfigTypes.BOT);
const pmcConfig = container.resolve("ConfigServer").getConfig(ConfigTypes_1.ConfigTypes.PMC);
// Disable PMC conversion
const conversionTypes = ["assault", "cursedassault", "pmcbot", "exusec", "arenafighter", "arenafighterevent", "crazyassaultevent"];
conversionTypes.forEach(type => {
pmcConfig.convertIntoPmcChance[type] = { min: 0, max: 0 };
});
logger.info("SWAG: PMC conversion is OFF (this is good - be sure this loads AFTER Realism/SVM)");
// Adjust time and map caps
const appContext = container.resolve("ApplicationContext");
const weatherController = container.resolve("WeatherController");
const matchInfoStartOff = appContext.getLatestValue(ContextVariableType_1.ContextVariableType.RAID_CONFIGURATION).getValue();
const time = weatherController.generate().time;
let realTime = time;
if (matchInfoStartOff.timeVariant === "PAST") {
let [hours, minutes] = time.split(":").map(Number);
hours = (hours - 12 + 24) % 24; // Adjust time backwards by 12 hours and ensure it wraps correctly
realTime = `${hours}:${minutes}`;
}
// Determine Time of Day
let TOD = "day";
let [hours] = realTime.split(":").map(Number);
if ((matchInfoStartOff.location !== "factory4_night" && hours >= 5 && hours < 22) ||
matchInfoStartOff.location === "factory4_day" ||
matchInfoStartOff.location.toLowerCase() === "laboratory") {
TOD = "day";
}
else {
TOD = "night";
}
// Set map caps based on Time of Day
if (TOD === "day") {
Object.keys(config_json_1.default.MaxBotCap).forEach(key => {
botConfig.maxBotCap[key] = config_json_1.default.MaxBotCap[key];
});
}
else { // "night"
Object.keys(config_json_1.default.NightMaxBotCap).forEach(key => {
botConfig.maxBotCap[key] = config_json_1.default.NightMaxBotCap[key];
});
}
logger.info(`SWAG: ${TOD} Raid Max Bot Caps set`);
return HttpResponse.nullResponse();
}
catch (e) {
logger.error(`SWAG: Failed To modify PMC conversion, you may have more PMCs than you're supposed to. Error: ${e}`);
return HttpResponse.nullResponse();
}
},
}], "SWAG");
}
postDBLoad(container) {
logger = container.resolve("WinstonLogger");
LocationCallbacks =
container.resolve("LocationCallbacks");
jsonUtil = container.resolve("JsonUtil");
configServer = container.resolve("ConfigServer");
botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
databaseServer = container.resolve("DatabaseServer");
locations = databaseServer.getTables().locations;
randomUtil = container.resolve("RandomUtil");
seasonalEvents = container.resolve("SeasonalEventService");
profileHelper = container.resolve("ProfileHelper");
}
/**
* Returns all available OpenZones specified in location.base.OpenZones as well as any OpenZone found in the SpawnPointParams.
* Filters out all sniper zones
* @param map
* @returns
*/
static GetOpenZones(map) {
const baseobj = locations[map]?.base;
// Get all OpenZones defined in the base obj that do not include sniper zones. Need to filter for empty strings as well.
const foundOpenZones = baseobj?.OpenZones?.split(",")
.filter((name) => !name.includes("Snipe"))
.filter((name) => name.trim() !== "") ?? [];
// Sometimes there are zones in the SpawnPointParams that arent listed in the OpenZones, parse these and add them to the list of zones
baseobj?.SpawnPointParams?.forEach((spawn) => {
//check spawn for open zones and if it doesn't exist add to end of array
if (spawn?.BotZoneName &&
!foundOpenZones.includes(spawn.BotZoneName) &&
!spawn.BotZoneName.includes("Snipe")) {
foundOpenZones.push(spawn.BotZoneName);
}
});
//logger.info(`SWAG: Open Zones(${map}): ${JSON.stringify(foundOpenZones)}`);
return foundOpenZones;
}
static shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
static ConfigureMaps() {
const bossConfigs = {};
const otherConfigs = {};
const customConfigs = {};
bossSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (bossConfig_json_1.default.TotalBossesPerMap[mapKey] === 0 || config_json_1.default.disableAllSpawns.bosses) {
return;
}
if (!bossConfigs[mapKey]) {
bossConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
// ignore boarsniper
if (boss.BossName == "bossboarsniper") {
return false;
}
const shouldSkip = boss.BossChance === 0 ||
(bossConfig_json_1.default.Bosses.useGlobalBossSpawnChance &&
bossConfig_json_1.default.Bosses[ClassDef_1.reverseBossNames[boss.BossName]][mapKey] === 0);
return !shouldSkip;
});
bossConfigs[mapKey].push(...filteredBosses);
});
});
otherSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (!otherConfigs[mapKey]) {
otherConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
const bossType = ClassDef_1.reverseBossNames[boss.BossName];
if (config_json_1.default.disableAllSpawns[bossType]) {
return false;
}
const shouldSkip = boss.BossChance === 0 ||
(config_json_1.default.Spawns.useGlobalSpawnChance && config_json_1.default.Spawns[bossType][mapKey] === 0);
return !shouldSkip;
});
otherConfigs[mapKey].push(...filteredBosses);
});
});
customSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (!customConfigs[mapKey]) {
customConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
if (boss.BossName == "gifter") {
if (!bossConfig_json_1.default.CustomBosses.santa.enabled ||
(!seasonalEvents.christmasEventEnabled() && !bossConfig_json_1.default.CustomBosses.santa.forceSpawnOutsideEvent)) {
return false;
}
}
const shouldSkip = boss.BossChance === 0 ||
!bossConfig_json_1.default.CustomBosses[ClassDef_1.reverseBossNames[boss.BossName]].enabled ||
(bossConfig_json_1.default.CustomBosses[ClassDef_1.reverseBossNames[boss.BossName]].enabled &&
bossConfig_json_1.default.CustomBosses[ClassDef_1.reverseBossNames[boss.BossName]][mapKey] === 0);
return !shouldSkip;
});
customConfigs[mapKey].push(...filteredBosses);
});
});
// Shuffle each array within the configuration objects
Object.values(bossConfigs).forEach(array => this.shuffleArray(array));
Object.values(otherConfigs).forEach(array => this.shuffleArray(array));
Object.values(customConfigs).forEach(array => this.shuffleArray(array));
ClassDef.validMaps.forEach((globalmap) => {
if (bossConfigs[ClassDef_1.reverseMapNames[globalmap]]) {
bossConfigs[ClassDef_1.reverseMapNames[globalmap]].forEach(boss => {
SWAG.SpawnBosses(boss, globalmap);
SWAG.bossCount.count += 1;
});
}
// reset boss count for the next map
SWAG.bossCount.count = 0;
if (otherConfigs[ClassDef_1.reverseMapNames[globalmap]]) {
otherConfigs[ClassDef_1.reverseMapNames[globalmap]].forEach(spawn => {
SWAG.SpawnBots(spawn, globalmap);
});
}
if (customConfigs[ClassDef_1.reverseMapNames[globalmap]]) {
customConfigs[ClassDef_1.reverseMapNames[globalmap]].forEach(custom => {
SWAG.SpawnCustom(custom, globalmap);
});
}
logger.warning(`SWAG: Configured boss spawns for map ${globalmap}`);
});
}
static SpawnBosses(boss, globalmap) {
if (bossConfig_json_1.default.TotalBossesPerMap[ClassDef_1.reverseMapNames[globalmap]] == 0) {
config_json_1.default.DebugOutput &&
logger.info("SWAG: TotalBosses set to 0 for this map, skipping boss spawn");
return;
}
else if (bossConfig_json_1.default.TotalBossesPerMap[ClassDef_1.reverseMapNames[globalmap]] != -1 && (SWAG.bossCount.count >= bossConfig_json_1.default.TotalBossesPerMap[ClassDef_1.reverseMapNames[globalmap]])) {
config_json_1.default.DebugOutput &&
logger.info("SWAG: Skipping boss spawn as total boss count has been met already");
return;
}
else {
let wave = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
}
static SpawnBots(boss, globalmap) {
let wave = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
static SpawnCustom(boss, globalmap) {
let wave = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
static ConfigureBossWave(boss, globalmap) {
let spawnChance = 0;
let spawnZones = boss.BossZone || null;
let bossName = ClassDef_1.roleCase[boss.BossName.toLowerCase()] || boss.BossName;
const getRandomDifficulty = () => {
const availableDifficulties = ["easy", "normal", "hard", "impossible"];
const randomIndex = Math.floor(Math.random() * availableDifficulties.length);
return availableDifficulties[randomIndex];
};
let difficultyKey = boss.BossDifficult || config_json_1.default.BossDifficulty.toLowerCase();
let difficulty = difficultyKey === "asonline" ? getRandomDifficulty() : ClassDef_1.diffProper[difficultyKey];
let escortDifficultyKey = boss.BossEscortDifficult || config_json_1.default.BossEscortDifficulty.toLowerCase();
let escort_difficulty = escortDifficultyKey === "asonline" ? getRandomDifficulty() : ClassDef_1.diffProper[escortDifficultyKey];
boss?.Supports?.forEach((escort) => {
escort.BossEscortDifficult = [escort_difficulty];
escort.BossEscortType = ClassDef_1.roleCase[escort.BossEscortType.toLowerCase()];
});
// exclusive to bosses only
if (boss.BossName.startsWith("boss")) {
spawnChance = this.adjustBossSpawnChance(boss, globalmap);
}
// something other than bosses
else if (config_json_1.default.Spawns.useGlobalSpawnChance) {
spawnChance = config_json_1.default.Spawns[ClassDef_1.reverseBossNames[boss.BossName]][ClassDef_1.reverseMapNames[globalmap]];
}
else {
spawnChance = boss.BossChance || 0;
}
// zones
if (spawnZones != null) {
spawnZones = boss.BossZone || spawnZones;
if (spawnZones.length > 1) {
// let's just pick one zone, can't trust BSG to do this correctly
let random_zone = SWAG.getRandIntInclusive(0, spawnZones.length - 1);
spawnZones = spawnZones[random_zone];
}
// if it's not > 1 and not null, then we'll assume there's a single zone defined instead
else {
spawnZones = spawnZones[0];
}
}
// Using the SPT class here
const wave = {
BossName: bossName,
BossChance: spawnChance,
BossZone: !!spawnZones
? spawnZones
: SWAG.savedLocationData[globalmap].openZones &&
SWAG.savedLocationData[globalmap].openZones.length > 0
? randomUtil.getStringArrayValue(SWAG.savedLocationData[globalmap].openZones)
: "",
BossPlayer: false,
BossDifficult: difficulty,
BossEscortType: ClassDef_1.roleCase[boss.BossEscortType.toLowerCase()],
BossEscortDifficult: escort_difficulty,
BossEscortAmount: boss.BossEscortAmount || "0",
Time: boss.Time || -1,
Supports: boss.Supports || null,
RandomTimeSpawn: boss.RandomTimeSpawn || false,
TriggerId: boss.TriggerId || "",
TriggerName: boss.TriggerName || ""
};
if (spawnChance != 0) {
config_json_1.default.DebugOutput && logger.warning(`Configured Boss Wave: ${JSON.stringify(wave)}`);
}
return wave;
}
static adjustBossSpawnChance(boss, globalmap) {
// I need to refactor this garbage
if (boss.BossName === "bosspunisher") {
if (bossConfig_json_1.default.CustomBosses.punisher.enabled) {
if (bossConfig_json_1.default.CustomBosses.punisher.useProgressSpawnChance) {
const pmcProfile = profileHelper.getPmcProfile(sessionId);
const profileId = pmcProfile?._id;
const punisherBossProgressFilePath = path.resolve(__dirname, `../../WTT-RogueJustice/profiles/${profileId}/progress.json`);
try {
const progressData = JSON.parse(fs.readFileSync(punisherBossProgressFilePath, "utf8"));
return progressData?.actualPunisherChance ?? 1;
}
catch (error) {
logger.warning("SWAG: Unable to load Punisher Boss progress file, either you don't have the mod installed or you don't have a Punisher progress file yet.");
return 1;
}
}
else {
// if progress spawn chance is not enabled
return bossConfig_json_1.default.CustomBosses["punisher"][ClassDef_1.reverseMapNames[globalmap]];
}
}
else {
// if punisher is not enabled
return 0;
}
}
if (boss.BossName === "bosslegion") {
if (bossConfig_json_1.default.CustomBosses.legion.enabled) {
if (bossConfig_json_1.default.CustomBosses.legion.useProgressSpawnChance) {
const legionBossProgressFilePath = path.resolve(__dirname, "../../RaidOverhaul/config/LegionChance.json");
try {
const progressData = JSON.parse(fs.readFileSync(legionBossProgressFilePath, "utf8"));
return progressData?.legionChance ?? 15;
}
catch (error) {
logger.warning("SWAG: Unable to load Legion Boss progress file, either you don't have the mod installed or you deleted your LegionChance.json.");
}
}
// if progress spawn chance is not enabled
return bossConfig_json_1.default.CustomBosses["legion"][ClassDef_1.reverseMapNames[globalmap]];
}
// if legion is not enabled
else {
return 0;
}
}
// all other bosses...
else if (bossConfig_json_1.default.Bosses.useGlobalBossSpawnChance) {
// edge case, only applies to Kaban
if (boss.BossName == "bossboarsniper") {
return boss.BossChance;
}
return bossConfig_json_1.default.Bosses[ClassDef_1.reverseBossNames[boss.BossName]][ClassDef_1.reverseMapNames[globalmap]];
}
// if global boss chance is not enabled
else {
return boss.BossChance;
}
}
static getRandIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
static disableSpawnSystems() {
let map;
for (map in locations) {
if (map === "base" || map === "hideout") {
continue;
}
locations[map].base.OfflineNewSpawn = false;
locations[map].base.OfflineOldSpawn = true;
locations[map].base.NewSpawn = false;
locations[map].base.OldSpawn = true;
}
}
static ClearDefaultSpawns() {
let map;
for (map in locations) {
if (map === "base" || map === "hideout") {
continue;
}
// Save a backup of the wave data and the BossLocationSpawn to use when restoring defaults on raid end. Store openzones in this data as well
if (!SWAG.savedLocationData[map]) {
const locationBase = locations[map].base;
SWAG.savedLocationData[map] = {
waves: locationBase.waves,
BossLocationSpawn: locationBase.BossLocationSpawn,
openZones: this.GetOpenZones(map),
};
}
// Reset Database, Cringe -- i stole this code from LUA
locations[map].base.waves = [...SWAG.savedLocationData[map].waves];
locations[map].base.BossLocationSpawn = [
...SWAG.savedLocationData[map].BossLocationSpawn,
];
//Clear bots spawn
if (!config_json_1.default?.UseDefaultSpawns?.Waves) {
locations[map].base.waves = [];
}
//Clear boss spawn
const bossLocationSpawn = locations[map].base.BossLocationSpawn;
if (!config_json_1.default?.UseDefaultSpawns?.Bosses &&
!config_json_1.default?.UseDefaultSpawns?.TriggeredWaves) {
locations[map].base.BossLocationSpawn = [];
}
else {
// Remove Default Boss Spawns
if (!config_json_1.default?.UseDefaultSpawns?.Bosses) {
for (let i = 0; i < bossLocationSpawn.length; i++) {
// Triggered wave check
if (bossLocationSpawn[i]?.TriggerName?.length === 0) {
locations[map].base.BossLocationSpawn.splice(i--, 1);
}
}
}
// Remove Default Triggered Waves
if (!config_json_1.default?.UseDefaultSpawns?.TriggeredWaves) {
for (let i = 0; i < bossLocationSpawn.length; i++) {
// Triggered wave check
if (bossLocationSpawn[i]?.TriggerName?.length > 0) {
locations[map].base.BossLocationSpawn.splice(i--, 1);
}
}
}
}
}
}
}
module.exports = { mod: new SWAG() };
//# sourceMappingURL=SWAG.js.map
File diff suppressed because one or more lines are too long
+789
View File
@@ -0,0 +1,789 @@
import {
BossLocationSpawn,
ILocationBase,
Wave,
} from "@spt-aki/models/eft/common/ILocationBase";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { IPostDBLoadMod } from "@spt-aki/models/external/IPostDBLoadMod";
import { IPreAkiLoadMod } from "@spt-aki/models/external/IPreAkiLoadMod";
import { IBotConfig } from "@spt-aki/models/spt/config/IBotConfig";
import { ILocations } from "@spt-aki/models/spt/server/ILocations";
import { ILocationConfig } from "@spt-aki/models/spt/config/ILocationConfig";
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
import { IGlobals } from "@spt-aki/models/eft/common/IGlobals";
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
import { ContextVariableType } from "@spt-aki/context/ContextVariableType";
import { ApplicationContext } from "@spt-aki/context/ApplicationContext";
import { WeatherController } from "@spt-aki/controllers/WeatherController";
import { IGetRaidConfigurationRequestData } from "@spt-aki/models/eft/match/IGetRaidConfigurationRequestData";
import { HttpResponseUtil } from "@spt-aki/utils/HttpResponseUtil";
import { StaticRouterModService } from "@spt-aki/services/mod/staticRouter/StaticRouterModService";
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
import { DependencyContainer } from "tsyringe";
import { LocationCallbacks } from "@spt-aki/callbacks/LocationCallbacks";
import { SeasonalEventService } from "@spt-aki/services/SeasonalEventService";
import { ProfileHelper } from "@spt-aki/helpers/ProfileHelper";
import * as fs from "fs";
import * as path from "path";
import * as ClassDef from "./ClassDef";
import {
BossPattern,
GroupPattern,
aiAmountProper,
diffProper,
roleCase,
reverseMapNames,
reverseBossNames,
} from "./ClassDef";
// General SWAG Config
import config from "../config/config.json";
import bossConfig from "../config/bossConfig.json";
// Bosses
import gluhar from "../config/bosses/gluhar.json";
import goons from "../config/bosses/goons.json";
import kaban from "../config/bosses/kaban.json";
import killa from "../config/bosses/killa.json";
import kolontay from "../config/bosses/kolontay.json";
import reshala from "../config/bosses/reshala.json";
import sanitar from "../config/bosses/sanitar.json";
import shturman from "../config/bosses/shturman.json";
import tagilla from "../config/bosses/tagilla.json";
import zryachiy from "../config/bosses/zryachiy.json";
// Spawn Configs
import bloodhounds from "../config/other/bloodhounds.json";
import cultists from "../config/other/cultists.json";
import raiders from "../config/other/raiders.json";
import rogues from "../config/other/rogues.json";
import scav_snipers from "../config/other/scav_snipers.json";
// Custom
import punisher from "../config/custom/punisher.json"
import legion from "../config/custom/legion.json"
const otherSpawnConfigs = [
bloodhounds,
cultists,
scav_snipers,
raiders,
rogues
];
const bossSpawnConfigs = [
gluhar,
goons,
kaban,
killa,
kolontay,
reshala,
sanitar,
shturman,
tagilla,
zryachiy
];
const customSpawnConfigs = [
punisher,
legion
]
const modName = "SWAG";
let logger: ILogger;
let LocationCallbacks;
LocationCallbacks;
let jsonUtil;
JsonUtil;
let botConfig: IBotConfig;
let pmcConfig: IBotConfig;
let iGlobals: IGlobals;
let configServer: ConfigServer;
let databaseServer: DatabaseServer;
let locations: ILocations;
let seasonalEvents: SeasonalEventService;
let randomUtil: RandomUtil;
let profileHelper: ProfileHelper;
let sessionId : string;
let BossWaveSpawnedOnceAlready: boolean;
const customPatterns: Record<string, ClassDef.GroupPattern> = {};
type LocationName = keyof Omit<ILocations, "base">;
type LocationBackupData = Record<
LocationName,
| {
waves: Wave[];
BossLocationSpawn: BossLocationSpawn[];
openZones: string[];
}
| undefined
>;
type GlobalPatterns = Record<string, MapPatterns>;
type MapPatterns = {
MapGroups: GroupPattern[];
MapBosses: BossPattern[];
};
class SWAG implements IPreAkiLoadMod, IPostDBLoadMod {
public static savedLocationData: LocationBackupData = {
factory4_day: undefined,
factory4_night: undefined,
bigmap: undefined,
interchange: undefined,
laboratory: undefined,
lighthouse: undefined,
rezervbase: undefined,
shoreline: undefined,
tarkovstreets: undefined,
woods: undefined,
sandbox: undefined,
// unused
develop: undefined,
hideout: undefined,
privatearea: undefined,
suburbs: undefined,
terminal: undefined,
town: undefined,
};
public static pmcType: string[] = ["sptbear", "sptusec"];
public static randomWaveTimer = {
time_min: 0,
time_max: 0,
};
public static actual_timers = {
time_min: 0,
time_max: 0,
};
public static waveCounter = {
count: 1,
};
public static raid_time = {
time_of_day: "day",
};
public static bossCount = {
count: 0,
};
preAkiLoad(container: DependencyContainer): void {
const HttpResponse =
container.resolve<HttpResponseUtil>("HttpResponseUtil");
const staticRouterModService = container.resolve<StaticRouterModService>(
"StaticRouterModService"
);
staticRouterModService.registerStaticRouter(
`${modName}/client/match/offline/end`,
[
{
url: "/client/match/offline/end",
action: (
url: string,
info: any,
sessionID: string,
output: string
): any => {
sessionId = sessionID;
SWAG.ClearDefaultSpawns();
SWAG.ConfigureMaps();
return LocationCallbacks.getLocationData(url, info, sessionID);
},
},
],
"SWAG"
);
staticRouterModService.registerStaticRouter(
`${modName}/client/locations`,
[
{
url: "/client/locations",
action: (
url: string,
info: any,
sessionID: string,
output: string
): any => {
sessionId = sessionID;
SWAG.ClearDefaultSpawns();
SWAG.ConfigureMaps();
return LocationCallbacks.getLocationData(url, info, sessionID);
},
},
],
"SWAG"
);
staticRouterModService.registerStaticRouter(
`${modName}/client/items`,
[
{
url: "/client/items",
action: (
url: string,
info: any,
sessionID: string,
output: string
) => {
sessionId = sessionID;
const locationConfig = container.resolve<ConfigServer>("ConfigServer").getConfig<ILocationConfig>(ConfigTypes.LOCATION);
// as of SPT 3.6.0 we need to disable the new spawn system so that SWAG can clear spawns properly
if (
!config?.UseDefaultSpawns?.Waves ||
!config?.UseDefaultSpawns?.Bosses ||
!config?.UseDefaultSpawns?.TriggeredWaves
) {
SWAG.disableSpawnSystems();
}
// disable more vanilla spawn stuff
locationConfig.splitWaveIntoSingleSpawnsSettings.enabled = false;
locationConfig.rogueLighthouseSpawnTimeSettings.enabled = false;
locationConfig.fixEmptyBotWavesSettings.enabled = false;
locationConfig.addOpenZonesToAllMaps = false;
locationConfig.addCustomBotWavesToMaps = false;
locationConfig.enableBotTypeLimits = false;
logger.info(
"SWAG: Vanilla spawn systems disabled"
);
return output;
},
},
],
"SWAG"
);
staticRouterModService.registerStaticRouter(
`${modName}/client/raid/configuration`,
[{
url: "/client/raid/configuration",
action: (
url: string,
info: any,
sessionID: string,
output: string
): any => {
try {
// Retrieve configurations
const botConfig = container.resolve<ConfigServer>("ConfigServer").getConfig<IBotConfig>(ConfigTypes.BOT);
const pmcConfig = container.resolve<ConfigServer>("ConfigServer").getConfig<IBotConfig>(ConfigTypes.PMC);
// Disable PMC conversion
const conversionTypes = ["assault", "cursedassault", "pmcbot", "exusec", "arenafighter", "arenafighterevent", "crazyassaultevent"];
conversionTypes.forEach(type => {
pmcConfig.convertIntoPmcChance[type] = { min: 0, max: 0 };
});
logger.info("SWAG: PMC conversion is OFF (this is good - be sure this loads AFTER Realism/SVM)");
// Adjust time and map caps
const appContext = container.resolve<ApplicationContext>("ApplicationContext");
const weatherController = container.resolve<WeatherController>("WeatherController");
const matchInfoStartOff = appContext.getLatestValue(ContextVariableType.RAID_CONFIGURATION).getValue<IGetRaidConfigurationRequestData>();
const time = weatherController.generate().time;
let realTime = time;
if (matchInfoStartOff.timeVariant === "PAST") {
let [hours, minutes] = time.split(":").map(Number);
hours = (hours - 12 + 24) % 24; // Adjust time backwards by 12 hours and ensure it wraps correctly
realTime = `${hours}:${minutes}`;
}
// Determine Time of Day
let TOD = "day";
let [hours] = realTime.split(":").map(Number);
if ((matchInfoStartOff.location !== "factory4_night" && hours >= 5 && hours < 22) ||
matchInfoStartOff.location === "factory4_day" ||
matchInfoStartOff.location.toLowerCase() === "laboratory") {
TOD = "day";
} else {
TOD = "night";
}
// Set map caps based on Time of Day
if (TOD === "day") {
Object.keys(config.MaxBotCap).forEach(key => {
botConfig.maxBotCap[key] = config.MaxBotCap[key];
});
} else { // "night"
Object.keys(config.NightMaxBotCap).forEach(key => {
botConfig.maxBotCap[key] = config.NightMaxBotCap[key];
});
}
logger.info(`SWAG: ${TOD} Raid Max Bot Caps set`);
return HttpResponse.nullResponse();
} catch (e) {
logger.error(`SWAG: Failed To modify PMC conversion, you may have more PMCs than you're supposed to. Error: ${e}`);
return HttpResponse.nullResponse();
}
},
}],
"SWAG"
);
}
postDBLoad(container: DependencyContainer): void {
logger = container.resolve<ILogger>("WinstonLogger");
LocationCallbacks =
container.resolve<LocationCallbacks>("LocationCallbacks");
jsonUtil = container.resolve<JsonUtil>("JsonUtil");
configServer = container.resolve<ConfigServer>("ConfigServer");
botConfig = configServer.getConfig<IBotConfig>(ConfigTypes.BOT);
pmcConfig = configServer.getConfig<IBotConfig>(ConfigTypes.PMC);
databaseServer = container.resolve<DatabaseServer>("DatabaseServer");
locations = databaseServer.getTables().locations;
randomUtil = container.resolve<RandomUtil>("RandomUtil");
seasonalEvents = container.resolve<SeasonalEventService>("SeasonalEventService");
profileHelper = container.resolve<ProfileHelper>("ProfileHelper");
}
/**
* Returns all available OpenZones specified in location.base.OpenZones as well as any OpenZone found in the SpawnPointParams.
* Filters out all sniper zones
* @param map
* @returns
*/
static GetOpenZones(map: LocationName): string[] {
const baseobj: ILocationBase = locations[map]?.base;
// Get all OpenZones defined in the base obj that do not include sniper zones. Need to filter for empty strings as well.
const foundOpenZones =
baseobj?.OpenZones?.split(",")
.filter((name) => !name.includes("Snipe"))
.filter((name) => name.trim() !== "") ?? [];
// Sometimes there are zones in the SpawnPointParams that arent listed in the OpenZones, parse these and add them to the list of zones
baseobj?.SpawnPointParams?.forEach((spawn) => {
//check spawn for open zones and if it doesn't exist add to end of array
if (
spawn?.BotZoneName &&
!foundOpenZones.includes(spawn.BotZoneName) &&
!spawn.BotZoneName.includes("Snipe")
) {
foundOpenZones.push(spawn.BotZoneName);
}
});
//logger.info(`SWAG: Open Zones(${map}): ${JSON.stringify(foundOpenZones)}`);
return foundOpenZones;
}
static shuffleArray(array: any[]) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
static ConfigureMaps(): void {
const bossConfigs: { [key: string]: any[] } = {};
const otherConfigs: { [key: string]: any[] } = {};
const customConfigs: { [key: string]: any[] } = {};
bossSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (bossConfig.TotalBossesPerMap[mapKey] === 0 || config.disableAllSpawns.bosses) {
return;
}
if (!bossConfigs[mapKey]) {
bossConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
// ignore boarsniper
if (boss.BossName == "bossboarsniper") {
return false;
}
const shouldSkip = boss.BossChance === 0 ||
(bossConfig.Bosses.useGlobalBossSpawnChance &&
bossConfig.Bosses[reverseBossNames[boss.BossName]][mapKey] === 0);
return !shouldSkip;
});
bossConfigs[mapKey].push(...filteredBosses);
});
});
otherSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (!otherConfigs[mapKey]) {
otherConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
const bossType = reverseBossNames[boss.BossName];
if (config.disableAllSpawns[bossType]) {
return false;
}
const shouldSkip = boss.BossChance === 0 ||
(config.Spawns.useGlobalSpawnChance && config.Spawns[bossType][mapKey] === 0);
return !shouldSkip;
});
otherConfigs[mapKey].push(...filteredBosses);
});
});
customSpawnConfigs.forEach(data => {
Object.keys(data).forEach(mapKey => {
if (!customConfigs[mapKey]) {
customConfigs[mapKey] = [];
}
const filteredBosses = data[mapKey].filter(boss => {
if (boss.BossName == "gifter") {
if (!bossConfig.CustomBosses.santa.enabled ||
(!seasonalEvents.christmasEventEnabled() && !bossConfig.CustomBosses.santa.forceSpawnOutsideEvent)) {
return false;
}
}
const shouldSkip = boss.BossChance === 0 ||
!bossConfig.CustomBosses[reverseBossNames[boss.BossName]].enabled ||
(bossConfig.CustomBosses[reverseBossNames[boss.BossName]].enabled &&
bossConfig.CustomBosses[reverseBossNames[boss.BossName]][mapKey] === 0);
return !shouldSkip;
});
customConfigs[mapKey].push(...filteredBosses);
});
});
// Shuffle each array within the configuration objects
Object.values(bossConfigs).forEach(array => this.shuffleArray(array));
Object.values(otherConfigs).forEach(array => this.shuffleArray(array));
Object.values(customConfigs).forEach(array => this.shuffleArray(array));
ClassDef.validMaps.forEach((globalmap: LocationName) => {
if (bossConfigs[reverseMapNames[globalmap]]) {
bossConfigs[reverseMapNames[globalmap]].forEach(boss => {
SWAG.SpawnBosses(boss, globalmap);
SWAG.bossCount.count += 1;
});
}
// reset boss count for the next map
SWAG.bossCount.count = 0;
if (otherConfigs[reverseMapNames[globalmap]]) {
otherConfigs[reverseMapNames[globalmap]].forEach(spawn => {
SWAG.SpawnBots(spawn, globalmap);
});
}
if (customConfigs[reverseMapNames[globalmap]]) {
customConfigs[reverseMapNames[globalmap]].forEach(custom => {
SWAG.SpawnCustom(custom, globalmap);
});
}
logger.warning(`SWAG: Configured boss spawns for map ${globalmap}`);
});
}
static SpawnBosses(
boss: ClassDef.BossPattern,
globalmap: LocationName,
): void {
if (bossConfig.TotalBossesPerMap[reverseMapNames[globalmap]] == 0) {
config.DebugOutput &&
logger.info(
"SWAG: TotalBosses set to 0 for this map, skipping boss spawn"
);
return;
}
else if (bossConfig.TotalBossesPerMap[reverseMapNames[globalmap]] != -1 && (SWAG.bossCount.count >= bossConfig.TotalBossesPerMap[reverseMapNames[globalmap]])) {
config.DebugOutput &&
logger.info(
"SWAG: Skipping boss spawn as total boss count has been met already"
);
return;
}
else {
let wave: BossLocationSpawn = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
}
static SpawnBots(
boss: ClassDef.BossPattern,
globalmap: LocationName,
): void {
let wave: BossLocationSpawn = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
static SpawnCustom(
boss: ClassDef.BossPattern,
globalmap: LocationName,
): void {
let wave: BossLocationSpawn = SWAG.ConfigureBossWave(boss, globalmap);
locations[globalmap].base.BossLocationSpawn.push(wave);
}
static ConfigureBossWave(boss: BossLocationSpawn, globalmap: LocationName): BossLocationSpawn {
let spawnChance = 0;
let spawnZones = boss.BossZone || null;
let bossName = roleCase[boss.BossName.toLowerCase()] || boss.BossName;
const getRandomDifficulty = () => {
const availableDifficulties = ["easy", "normal", "hard", "impossible"];
const randomIndex = Math.floor(Math.random() * availableDifficulties.length);
return availableDifficulties[randomIndex];
};
let difficultyKey = boss.BossDifficult || config.BossDifficulty.toLowerCase();
let difficulty = difficultyKey === "asonline" ? getRandomDifficulty() : diffProper[difficultyKey];
let escortDifficultyKey = boss.BossEscortDifficult || config.BossEscortDifficulty.toLowerCase();
let escort_difficulty = escortDifficultyKey === "asonline" ? getRandomDifficulty() : diffProper[escortDifficultyKey];
boss?.Supports?.forEach((escort) => {
escort.BossEscortDifficult = [escort_difficulty];
escort.BossEscortType = roleCase[escort.BossEscortType.toLowerCase()];
});
// exclusive to bosses only
if (boss.BossName.startsWith("boss")) {
spawnChance = this.adjustBossSpawnChance(boss, globalmap);
}
// something other than bosses
else if (config.Spawns.useGlobalSpawnChance) {
spawnChance = config.Spawns[reverseBossNames[boss.BossName]][reverseMapNames[globalmap]];
}
else {
spawnChance = boss.BossChance || 0;
}
// zones
if (spawnZones != null) {
spawnZones = boss.BossZone || spawnZones;
if (spawnZones.length > 1) {
// let's just pick one zone, can't trust BSG to do this correctly
let random_zone = SWAG.getRandIntInclusive(0, spawnZones.length - 1);
spawnZones = spawnZones[random_zone];
}
// if it's not > 1 and not null, then we'll assume there's a single zone defined instead
else {
spawnZones = spawnZones[0];
}
}
// Using the SPT class here
const wave: BossLocationSpawn = {
BossName: bossName,
BossChance: spawnChance,
BossZone: !!spawnZones
? spawnZones
: SWAG.savedLocationData[globalmap].openZones &&
SWAG.savedLocationData[globalmap].openZones.length > 0
? randomUtil.getStringArrayValue(
SWAG.savedLocationData[globalmap].openZones
)
: "",
BossPlayer: false,
BossDifficult: difficulty,
BossEscortType: roleCase[boss.BossEscortType.toLowerCase()],
BossEscortDifficult: escort_difficulty,
BossEscortAmount: boss.BossEscortAmount || "0",
Time: boss.Time || -1,
Supports: boss.Supports || null,
RandomTimeSpawn: boss.RandomTimeSpawn || false,
TriggerId: boss.TriggerId || "",
TriggerName: boss.TriggerName || ""
};
if (spawnChance != 0) {
config.DebugOutput && logger.warning(`Configured Boss Wave: ${JSON.stringify(wave)}`);
}
return wave;
}
static adjustBossSpawnChance(boss: BossLocationSpawn, globalmap: LocationName): number {
// I need to refactor this garbage
if (boss.BossName === "bosspunisher") {
if (bossConfig.CustomBosses.punisher.enabled) {
if (bossConfig.CustomBosses.punisher.useProgressSpawnChance) {
const pmcProfile = profileHelper.getPmcProfile(sessionId);
const profileId = pmcProfile?._id;
const punisherBossProgressFilePath = path.resolve(
__dirname,
`../../WTT-RogueJustice/profiles/${profileId}/progress.json`
);
try {
const progressData = JSON.parse(
fs.readFileSync(punisherBossProgressFilePath, "utf8")
);
return progressData?.actualPunisherChance ?? 1;
} catch (error) {
logger.warning(
"SWAG: Unable to load Punisher Boss progress file, either you don't have the mod installed or you don't have a Punisher progress file yet.",
);
return 1;
}
} else {
// if progress spawn chance is not enabled
return bossConfig.CustomBosses["punisher"][reverseMapNames[globalmap]];
}
} else {
// if punisher is not enabled
return 0;
}
}
if (boss.BossName === "bosslegion") {
if (bossConfig.CustomBosses.legion.enabled) {
if (bossConfig.CustomBosses.legion.useProgressSpawnChance) {
const legionBossProgressFilePath = path.resolve(
__dirname,
"../../RaidOverhaul/config/LegionChance.json"
);
try {
const progressData = JSON.parse(
fs.readFileSync(legionBossProgressFilePath, "utf8")
);
return progressData?.legionChance ?? 15;
} catch (error) {
logger.warning(
"SWAG: Unable to load Legion Boss progress file, either you don't have the mod installed or you deleted your LegionChance.json."
);
}
}
// if progress spawn chance is not enabled
return bossConfig.CustomBosses["legion"][reverseMapNames[globalmap]];
}
// if legion is not enabled
else {
return 0;
}
}
// all other bosses...
else if (bossConfig.Bosses.useGlobalBossSpawnChance) {
// edge case, only applies to Kaban
if (boss.BossName == "bossboarsniper") {
return boss.BossChance;
}
return bossConfig.Bosses[reverseBossNames[boss.BossName]][reverseMapNames[globalmap]];
}
// if global boss chance is not enabled
else {
return boss.BossChance;
}
}
static getRandIntInclusive(min: number, max: number): number {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
static disableSpawnSystems(): void {
let map: keyof ILocations;
for (map in locations) {
if (map === "base" || map === "hideout") {
continue;
}
locations[map].base.OfflineNewSpawn = false;
locations[map].base.OfflineOldSpawn = true;
locations[map].base.NewSpawn = false;
locations[map].base.OldSpawn = true;
}
}
static ClearDefaultSpawns(): void {
let map: keyof ILocations;
for (map in locations) {
if (map === "base" || map === "hideout") {
continue;
}
// Save a backup of the wave data and the BossLocationSpawn to use when restoring defaults on raid end. Store openzones in this data as well
if (!SWAG.savedLocationData[map]) {
const locationBase = locations[map].base;
SWAG.savedLocationData[map] = {
waves: locationBase.waves,
BossLocationSpawn: locationBase.BossLocationSpawn,
openZones: this.GetOpenZones(map),
};
}
// Reset Database, Cringe -- i stole this code from LUA
locations[map].base.waves = [...SWAG.savedLocationData[map].waves];
locations[map].base.BossLocationSpawn = [
...SWAG.savedLocationData[map].BossLocationSpawn,
];
//Clear bots spawn
if (!config?.UseDefaultSpawns?.Waves) {
locations[map].base.waves = [];
}
//Clear boss spawn
const bossLocationSpawn = locations[map].base.BossLocationSpawn;
if (
!config?.UseDefaultSpawns?.Bosses &&
!config?.UseDefaultSpawns?.TriggeredWaves
) {
locations[map].base.BossLocationSpawn = [];
} else {
// Remove Default Boss Spawns
if (!config?.UseDefaultSpawns?.Bosses) {
for (let i = 0; i < bossLocationSpawn.length; i++) {
// Triggered wave check
if (bossLocationSpawn[i]?.TriggerName?.length === 0) {
locations[map].base.BossLocationSpawn.splice(i--, 1);
}
}
}
// Remove Default Triggered Waves
if (!config?.UseDefaultSpawns?.TriggeredWaves) {
for (let i = 0; i < bossLocationSpawn.length; i++) {
// Triggered wave check
if (bossLocationSpawn[i]?.TriggerName?.length > 0) {
locations[map].base.BossLocationSpawn.splice(i--, 1);
}
}
}
}
}
}
module.exports = { mod: new SWAG() };