diff --git a/config/PresetWeightings.json b/config/PresetWeightings.json index 14298a3..e24d9d9 100644 --- a/config/PresetWeightings.json +++ b/config/PresetWeightings.json @@ -2,6 +2,7 @@ "live-like": 25, "more-scavs": 8, "more-pmcs": 8, + "quiet-raids": 5, "more-scavs-and-pmcs": 5, "main-boss-roaming": 5, "sniper-buddies": 4, @@ -9,4 +10,4 @@ "rogue-invasion": 0, "raider-invasion": 0, "insanity": 0 -} +} \ No newline at end of file diff --git a/config/Presets.json b/config/Presets.json index 929d3fd..cbd6aa3 100644 --- a/config/Presets.json +++ b/config/Presets.json @@ -1,5 +1,15 @@ { "live-like": {}, + "quiet-raids": { + "randomSpawns": true, + "scavGroupChance": 0.1, + "scavMaxGroupSize": 2, + "pmcGroupChance": 0.1, + "pmcMaxGroupSize": 2, + "scavWaveQuantity": 0.7, + "pmcWaveQuantity": 0.6, + "mainBossChanceBuff": 0 + }, "more-scavs": { "scavGroupChance": 0.5, "scavMaxGroupSize": 5, @@ -11,13 +21,12 @@ "pmcWaveQuantity": 1.2 }, "more-scavs-and-pmcs": { - "scavGroupChance": 0.7, + "scavGroupChance": 0.5, "scavMaxGroupSize": 5, - "pmcGroupChance": 0.8, + "pmcGroupChance": 0.5, "pmcMaxGroupSize": 5, - "scavWaveQuantity": 1.2, - "pmcWaveQuantity": 1.2, - "mainBossChanceBuff": 25 + "scavWaveQuantity": 1.1, + "pmcWaveQuantity": 1.2 }, "boss-invasion": { "bossOpenZones": true, @@ -28,11 +37,11 @@ }, "rogue-invasion": { "randomRaiderGroup": true, - "randomRaiderGroupChance": 50 + "randomRaiderGroupChance": 100 }, "raider-invasion": { "randomRaiderGroup": true, - "randomRaiderGroupChance": 50 + "randomRaiderGroupChance": 100 }, "insanity": { "scavWaveQuantity": 1.3, @@ -41,7 +50,7 @@ "pmcGroupChance": 0.8, "pmcMaxGroupSize": 6, "scavMaxGroupSize": 6, - "sniperGroupChance": 1, + "sniperGroupChance": 0.5, "bossOpenZones": true, "randomRaiderGroup": true, "randomRaiderGroupChance": 50, @@ -53,10 +62,10 @@ }, "main-boss-roaming": { "bossOpenZones": true, - "mainBossChanceBuff": 35 + "mainBossChanceBuff": 50 }, "sniper-buddies": { - "sniperMaxGroupSize": 2.5, + "sniperMaxGroupSize": 2, "sniperGroupChance": 1 } } \ No newline at end of file diff --git a/config/advancedConfig.json b/config/advancedConfig.json new file mode 100644 index 0000000..3dee0c9 --- /dev/null +++ b/config/advancedConfig.json @@ -0,0 +1,3 @@ +{ + "ActivateSpawnCullingOnServerStart": false +} \ No newline at end of file diff --git a/config/bossConfig.json b/config/bossConfig.json index c31d04c..3bf47f9 100644 --- a/config/bossConfig.json +++ b/config/bossConfig.json @@ -36,8 +36,10 @@ }, "laboratory": {}, "lighthouse": { - "bossKnight": 30, - "bossPartisan": 30 + "exUsec": 35, + "bossKnight": 20, + "bossPartisan": 20, + "bossZryachiy": 30 }, "rezervbase": { "bossGluhar": 30 diff --git a/config/config.json b/config/config.json index a72c61e..e7f03bd 100644 --- a/config/config.json +++ b/config/config.json @@ -5,30 +5,30 @@ "pmcDifficulty": 0.6, "scavDifficulty": 0.4, - "scavWaveDistribution": 0.8, + "scavWaveDistribution": 1, "scavWaveQuantity": 1, "startingPmcs": false, "pmcWaveDistribution": 0.6, "pmcWaveQuantity": 1, - "disableCascadingSpawns": false, + "randomSpawns": false, "zombiesEnabled": false, "zombieWaveDistribution": 0.8, "zombieWaveQuantity": 1, "zombieHealth": 1, - "maxBotCap": 25, - "maxBotPerZone": 7, + "maxBotCap": 20, + "maxBotPerZone": 6, "sniperGroupChance": 0.1, "scavGroupChance": 0.2, "pmcGroupChance": 0.2, "pmcMaxGroupSize": 4, - "scavMaxGroupSize": 4, - "sniperMaxGroupSize": 1.7, + "scavMaxGroupSize": 3, + "sniperMaxGroupSize": 1, "bossOpenZones": false, diff --git a/config/mapConfig.json b/config/mapConfig.json index 06a5d31..bc89ffa 100644 --- a/config/mapConfig.json +++ b/config/mapConfig.json @@ -1,9 +1,11 @@ { "customs": { + "sniperQuantity": 3, "initialSpawnDelay": 15, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 30, + "mapCullingNearPointValuePlayer": 8, + "mapCullingNearPointValue": 15, + "spawnMinDistance": 60, "pmcWaveCount": 12, "scavWaveCount": 21, "zombieWaveCount": 9, @@ -15,9 +17,11 @@ ] }, "factoryDay": { + "sniperQuantity": 0, "initialSpawnDelay": 10, - "smoothingDistribution": 0.4, - "mapCullingNearPointValue": 3, + "smoothingDistribution": 0.6, + "mapCullingNearPointValuePlayer": 2, + "mapCullingNearPointValue": 1.5, "spawnMinDistance": 15, "maxBotCapOverride": 12, "maxBotPerZoneOverride": 12, @@ -26,9 +30,11 @@ "zombieWaveCount": 6 }, "factoryNight": { + "sniperQuantity": 0, "initialSpawnDelay": 10, - "smoothingDistribution": 0.4, - "mapCullingNearPointValue": 3, + "smoothingDistribution": 0.6, + "mapCullingNearPointValuePlayer": 2, + "mapCullingNearPointValue": 1.5, "spawnMinDistance": 15, "maxBotCapOverride": 12, "maxBotPerZoneOverride": 12, @@ -37,10 +43,12 @@ "zombieWaveCount": 6 }, "interchange": { + "sniperQuantity": 0, "initialSpawnDelay": 20, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 8, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 3, + "mapCullingNearPointValue": 3, + "spawnMinDistance": 70, "pmcWaveCount": 14, "scavWaveCount": 28, "zombieWaveCount": 12, @@ -50,19 +58,23 @@ ] }, "laboratory": { + "sniperQuantity": 0, "initialSpawnDelay": 15, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 3, - "spawnMinDistance": 20, + "mapCullingNearPointValuePlayer": 4, + "mapCullingNearPointValue": 0.9, + "spawnMinDistance": 30, "pmcWaveCount": 10, "scavWaveCount": 0, "zombieWaveCount": 12 }, "lighthouse": { + "sniperQuantity": 3, "initialSpawnDelay": 20, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 2.5, + "mapCullingNearPointValue": 2.5, + "spawnMinDistance": 50, "pmcWaveCount": 12, "scavWaveCount": 20, "zombieWaveCount": 10, @@ -72,10 +84,12 @@ ] }, "rezervbase": { + "sniperQuantity": 0, "initialSpawnDelay": 20, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 3, + "mapCullingNearPointValue": 2.5, + "spawnMinDistance": 50, "pmcWaveCount": 11, "scavWaveCount": 24, "zombieWaveCount": 9, @@ -87,10 +101,12 @@ ] }, "shoreline": { + "sniperQuantity": 4, "initialSpawnDelay": 20, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 5, + "mapCullingNearPointValue": 5, + "spawnMinDistance": 70, "pmcWaveCount": 14, "scavWaveCount": 28, "zombieWaveCount": 12, @@ -102,19 +118,23 @@ ] }, "tarkovstreets": { + "sniperQuantity": 5, "initialSpawnDelay": 20, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 4, + "mapCullingNearPointValue": 2, + "spawnMinDistance": 70, "pmcWaveCount": 14, "scavWaveCount": 26, "zombieWaveCount": 13 }, "woods": { - "initialSpawnDelay": 20, + "sniperQuantity": 2, + "initialSpawnDelay": 3, "smoothingDistribution": 0.9, - "mapCullingNearPointValue": 10, - "spawnMinDistance": 40, + "mapCullingNearPointValuePlayer": 6, + "mapCullingNearPointValue": 13, + "spawnMinDistance": 70, "pmcWaveCount": 14, "scavWaveCount": 28, "zombieWaveCount": 10, @@ -126,19 +146,25 @@ ] }, "gzLow": { + "sniperQuantity": 3, "initialSpawnDelay": 10, - "smoothingDistribution": 1, - "mapCullingNearPointValue": 7, - "spawnMinDistance": 30, + "smoothingDistribution": 0.7, + "mapCullingNearPointValuePlayer": 4, + "mapCullingNearPointValue": 2, + "maxBotCapOverride": 15, + "spawnMinDistance": 50, "pmcWaveCount": 10, "scavWaveCount": 18, "zombieWaveCount": 9 }, "gzHigh": { + "sniperQuantity": 3, "initialSpawnDelay": 10, - "smoothingDistribution": 1, - "mapCullingNearPointValue": 7, - "spawnMinDistance": 30, + "smoothingDistribution": 0.7, + "mapCullingNearPointValuePlayer": 4, + "mapCullingNearPointValue": 2, + "maxBotCapOverride": 15, + "spawnMinDistance": 50, "pmcWaveCount": 12, "scavWaveCount": 18, "zombieWaveCount": 9 diff --git a/dist/DewardianDev-MOAR-2.7.0.zip b/dist/DewardianDev-MOAR-2.7.0.zip deleted file mode 100644 index 09cf844..0000000 Binary files a/dist/DewardianDev-MOAR-2.7.0.zip and /dev/null differ diff --git a/dist/DewardianDev-MOAR-3.0.0-alpha.5.zip b/dist/DewardianDev-MOAR-3.0.0-alpha.5.zip new file mode 100644 index 0000000..42508cc Binary files /dev/null and b/dist/DewardianDev-MOAR-3.0.0-alpha.5.zip differ diff --git a/package-lock.json b/package-lock.json index d027ef6..8dcbef4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "MOAR", - "version": "2.5.6", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "MOAR", - "version": "2.5.6", + "version": "3.0.0", "license": "MIT", "devDependencies": { "@semantic-release/git": "^10.0.1", diff --git a/package.json b/package.json index 488d49a..7dd35c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "MOAR", - "version": "2.7.0", + "version": "3.0.0-alpha.5", "main": "src/mod.js", "license": "MIT", "author": "DewardianDev", diff --git a/src/GlobalValues.js.map b/src/GlobalValues.js.map index 0884523..0a49bc5 100644 --- a/src/GlobalValues.js.map +++ b/src/GlobalValues.js.map @@ -1 +1 @@ -{"version":3,"file":"GlobalValues.js","sourceRoot":"","sources":["GlobalValues.ts"],"names":[],"mappings":";;;AAGA,MAAa,YAAY;IAChB,MAAM,CAAC,UAAU,GAAkB,SAAS,CAAC;IAC7C,MAAM,CAAC,cAAc,GAA2B,SAAS,CAAC;IAC1D,MAAM,CAAC,aAAa,GAAoB,SAAS,CAAC;IAClD,MAAM,CAAC,aAAa,GAAW,EAAE,CAAC;IAClC,MAAM,CAAC,YAAY,GAAW,QAAQ,CAAC;IACvC,MAAM,CAAC,aAAa,GAA6B,EAAE,CAAC;IACpD,MAAM,CAAC,gBAAgB,GAAuC,EAAE,CAAA;;AAPzE,oCAQC"} \ No newline at end of file +{"version":3,"file":"GlobalValues.js","sourceRoot":"","sources":["GlobalValues.ts"],"names":[],"mappings":";;;AAOA,MAAa,YAAY;IAChB,MAAM,CAAC,UAAU,GAAkB,SAAS,CAAC;IAC7C,MAAM,CAAC,cAAc,GAA2B,SAAS,CAAC;IAC1D,MAAM,CAAC,aAAa,GAAoB,SAAS,CAAC;IAClD,MAAM,CAAC,aAAa,GAAW,EAAE,CAAC;IAClC,MAAM,CAAC,YAAY,GAAW,QAAQ,CAAC;IACvC,MAAM,CAAC,aAAa,GAA6B,EAAE,CAAC;IACpD,MAAM,CAAC,gBAAgB,GAAuC,EAAE,CAAC;;AAP1E,oCAQC"} \ No newline at end of file diff --git a/src/GlobalValues.ts b/src/GlobalValues.ts index 89584ac..d916833 100644 --- a/src/GlobalValues.ts +++ b/src/GlobalValues.ts @@ -1,5 +1,9 @@ +import { Ixyz } from "@spt/models/eft/common/Ixyz"; import config from "../config/config.json"; -import { ILocationBase, ISpawnPointParam } from "@spt/models/eft/common/ILocationBase"; +import { + ILocationBase, + ISpawnPointParam, +} from "@spt/models/eft/common/ILocationBase"; export class globalValues { public static baseConfig: typeof config = undefined; @@ -7,6 +11,6 @@ export class globalValues { public static locationsBase: ILocationBase[] = undefined; public static currentPreset: string = ""; public static forcedPreset: string = "random"; - public static addedMapZones: Record = {}; - public static indexedMapSpawns: Record = {} + public static addedMapZones: Record = {}; + public static indexedMapSpawns: Record = {}; } diff --git a/src/Routes/routes.ts b/src/Routes/routes.ts index 7090b72..aa84fb7 100644 --- a/src/Routes/routes.ts +++ b/src/Routes/routes.ts @@ -5,15 +5,99 @@ import { StaticRouterModService } from "@spt/services/mod/staticRouter/StaticRou import { globalValues } from "../GlobalValues"; import { kebabToTitle } from "../utils"; import PresetWeightingsConfig from "../../config/PresetWeightings.json"; +import { Ixyz } from "@spt/models/eft/common/Ixyz"; +import { + deleteBotSpawn, + updateBotSpawn, + updatePlayerSpawn, + updateSniperSpawn, +} from "../Spawns/updateUtils"; export const setupRoutes = (container: DependencyContainer) => { const staticRouterModService = container.resolve( "StaticRouterModService" ); - // const dynamicRouterModService = container.resolve( - // "DynamicRouterModService" - // ); + interface AddSpawnRequest { + map: string; + position: Ixyz; + } + + staticRouterModService.registerStaticRouter( + `moarAddBotSpawn`, + [ + { + url: "/moar/addBotSpawn", + action: async ( + url: string, + overrideConfig: AddSpawnRequest, + sessionID, + output + ) => { + updateBotSpawn(overrideConfig.map, overrideConfig.position); + return "success"; + }, + }, + ], + "moarAddBotSpawn" + ); + + staticRouterModService.registerStaticRouter( + `moarAddSniperSpawn`, + [ + { + url: "/moar/addSniperSpawn", + action: async ( + url: string, + overrideConfig: AddSpawnRequest, + sessionID, + output + ) => { + updateSniperSpawn(overrideConfig.map, overrideConfig.position); + return "success"; + }, + }, + ], + "moarAddSniperSpawn" + ); + + staticRouterModService.registerStaticRouter( + `moarDeleteBotSpawn`, + [ + { + url: "/moar/deleteBotSpawn", + action: async ( + url: string, + overrideConfig: AddSpawnRequest, + sessionID, + output + ) => { + deleteBotSpawn(overrideConfig.map, overrideConfig.position); + return "success"; + }, + }, + ], + "moarDeleteBotSpawn" + ); + + staticRouterModService.registerStaticRouter( + `moarAddPlayerSpawn`, + [ + { + url: "/moar/addPlayerSpawn", + action: async ( + url: string, + overrideConfig: AddSpawnRequest, + sessionID, + output + ) => { + updatePlayerSpawn(overrideConfig.map, overrideConfig.position); + return "success"; + }, + }, + ], + "moarAddPlayerSpawn" + ); // Make buildwaves run on game end staticRouterModService.registerStaticRouter( diff --git a/src/SpawnZoneChanges/setupSpawn.ts b/src/SpawnZoneChanges/setupSpawn.ts index ea80734..1ab7ac7 100644 --- a/src/SpawnZoneChanges/setupSpawn.ts +++ b/src/SpawnZoneChanges/setupSpawn.ts @@ -2,10 +2,21 @@ import { DatabaseServer } from "@spt/servers/DatabaseServer"; import { configLocations, originalMapList } from "../Spawning/constants"; import { DependencyContainer } from "tsyringe"; import mapConfig from "../../config/mapConfig.json"; +import advancedConfig from "../../config/advancedConfig.json"; import { ISpawnPointParam } from "@spt/models/eft/common/ILocationBase"; import { globalValues } from "../GlobalValues"; -import { cleanClosest } from "../Spawning/spawnZoneUtils"; +import { + AddCustomBotSpawnPoints, + AddCustomPlayerSpawnPoints, + AddCustomSniperSpawnPoints, + cleanClosest, + removeClosestSpawnsFromCustomBots, +} from "../Spawning/spawnZoneUtils"; import { shuffle } from "../Spawning/utils"; +import { saveToFile } from "../utils"; +import { Ixyz } from "@spt/models/eft/common/Ixyz"; +import { BotSpawns } from "../Spawns"; +import { updateAllBotSpawns } from "../Spawns/updateUtils"; export const setupSpawns = (container: DependencyContainer) => { const databaseServer = container.resolve("DatabaseServer"); @@ -13,44 +24,52 @@ export const setupSpawns = (container: DependencyContainer) => { const indexedMapSpawns: Record = {}; + const botSpawnHash = BotSpawns; + originalMapList.forEach((map, mapIndex) => { - const limit = mapConfig[configLocations[mapIndex]].spawnMinDistance; + const allZones = [ + ...new Set( + locations[map].base.SpawnPointParams.filter( + ({ BotZoneName }: ISpawnPointParam) => !!BotZoneName + ).map(({ BotZoneName }: ISpawnPointParam) => BotZoneName) + ), + ]; - locations[map].base.SpawnPointParams.forEach( - ( - { ColliderParams, Categories }: ISpawnPointParam, - innerIndex: number - ) => { - if ( - !Categories.includes("Boss") && - ColliderParams?._props?.Radius !== undefined && - ColliderParams?._props?.Radius < limit - ) { - locations[map].base.SpawnPointParams[ - innerIndex - ].ColliderParams._props.Radius = limit; - } - } - ); + locations[map].base.OpenZones = allZones.join(","); - let bossSpawnSpawns: ISpawnPointParam[] = []; + let bossSpawn: ISpawnPointParam[] = []; let nonBossSpawns: ISpawnPointParam[] = []; let sniperSpawnSpawnPoints: ISpawnPointParam[] = []; let coopSpawns: ISpawnPointParam[] = []; + const bossZoneList = new Set([ + "Zone_Blockpost", + "Zone_RoofRocks", + "Zone_RoofContainers", + "Zone_RoofBeach", + "Zone_TreatmentRocks", + "Zone_TreatmentBeach", + "Zone_Hellicopter", + "Zone_Island", + "BotZoneGate1", + "BotZoneGate2", + "BotZoneBasement", + ]); + const isGZ = map.includes("sandbox"); shuffle(locations[map].base.SpawnPointParams).forEach( (point) => { switch (true) { - case point.Categories.includes("Boss"): - bossSpawnSpawns.push(point); + case point.Categories.includes("Boss") || + bossZoneList.has(point.BotZoneName): + bossSpawn.push(point); break; + case point.BotZoneName?.toLowerCase().includes("snipe") || - point.DelayToCanSpawnSec > 40: + (map !== "lighthouse" && point.DelayToCanSpawnSec > 40): sniperSpawnSpawnPoints.push(point); break; - case (point.Categories.includes("Coop") || - point.Categories.includes("Player")) && + case point.Categories.includes("Player") && // (point.Categories.includes("Coop") || ) !!point.Infiltration: coopSpawns.push(point); break; @@ -62,40 +81,119 @@ export const setupSpawns = (container: DependencyContainer) => { } ); - coopSpawns = cleanClosest(coopSpawns, configLocations[mapIndex]).map( - (point, index) => !!point.Categories.length ? { - ...point, - Categories: ["Player"], - BotZoneName: point?.BotZoneName ? point.BotZoneName : "coop_" + index, - CorePointId: 0, - Sides: ["Pmc"], - } : point - ); + // fix GZ + if (isGZ) { + sniperSpawnSpawnPoints.map((point, index) => { + if (index < 2) { + point.BotZoneName = Math.random() + ? "ZoneSandSnipeCenter" + : "ZoneSandSnipeCenter2"; + } else { + point.BotZoneName = ["ZoneSandSnipeCenter", "ZoneSandSnipeCenter2"][ + index + ]; + } + return point; + }); + } - nonBossSpawns = cleanClosest( - nonBossSpawns, configLocations[mapIndex]).map((point, index) => !!point.Categories.length ? ({ - ...point, - BotZoneName: point?.BotZoneName ? point.BotZoneName : "open_" + index, - Categories: ["Bot"], - // Infiltration: "", - Sides: ["Savage"], - CorePointId: 1, - }) : point); + // console.log(map, sniperSpawnSpawnPoints.length); + sniperSpawnSpawnPoints.map((val, index) => { + if (!val.BotZoneName) val.BotZoneName = "custom_snipe_" + index; // TODO: Adjusted this watch for sniper weirdness + return val; + }); + const limit = mapConfig[configLocations[mapIndex]].spawnMinDistance; - locations[map].base.OpenZones = ""; + coopSpawns = cleanClosest( + AddCustomPlayerSpawnPoints(coopSpawns, map), + mapIndex, + true + ) + .map((point, index) => { + if (point.ColliderParams?._props?.Radius < limit) { + point.ColliderParams._props.Radius = limit; + } + return !!point.Categories.length + ? { + ...point, + Categories: ["Player"], + BotZoneName: point?.BotZoneName ? point.BotZoneName : "", + CorePointId: 0, + Sides: ["Pmc"], + } + : point; + }) + .filter((point) => { + // Now we transfer the extra spawns to the bots + // if (!point.Categories.length) { + // nonBossSpawns.push(point); + // } + return !!point.Categories.length; + }); + + if (advancedConfig.ActivateSpawnCullingOnServerStart) { + botSpawnHash[map] = + removeClosestSpawnsFromCustomBots( + nonBossSpawns, + map, + configLocations[mapIndex] + ) || []; + } - indexedMapSpawns[mapIndex] = [ - ...sniperSpawnSpawnPoints, - ...bossSpawnSpawns, - ...nonBossSpawns, - ...coopSpawns, - ]//.filter(({ Categories }) => Categories.length); + nonBossSpawns = cleanClosest( + AddCustomBotSpawnPoints(nonBossSpawns, map), + mapIndex + ).map((point) => { + if (point.ColliderParams?._props?.Radius < limit) { + point.ColliderParams._props.Radius = limit; + } + + return !!point.Categories.length + ? { + ...point, + BotZoneName: isGZ ? "ZoneSandbox" : point?.BotZoneName || "", + Categories: ["Bot"], + Sides: ["Savage"], + CorePointId: 1, + } + : point; + }); + + sniperSpawnSpawnPoints = AddCustomSniperSpawnPoints( + sniperSpawnSpawnPoints, + map + ); + indexedMapSpawns[mapIndex] = [ + ...sniperSpawnSpawnPoints.map((point) => ({ ...point, type: "sniper" })), + ...bossSpawn.map((point) => ({ ...point, type: "boss" })), + ...nonBossSpawns.map((point) => ({ ...point, type: "nonBoss" })), + ...coopSpawns.map((point) => ({ ...point, type: "coop" })), + ]; + + // const added = indexedMapSpawns[mapIndex].filter( + // ({ BotZoneName }) => BotZoneName?.slice(0, 6) === "Added_" + // ); + // console.log( + // map, + // "sniperSpawnSpawnPoints", + // sniperSpawnSpawnPoints.length, + // "bossSpawn", + // bossSpawn.length, + // "nonBossSpawns", + // nonBossSpawns.length, + // "coopSpawns", + // coopSpawns.length + // ); + + //; // console.log(locations[map].base.SpawnPointParams.length, indexedMapSpawns[mapIndex].filter(({ Categories }) => Categories.length).length) locations[map].base.SpawnPointParams = []; }); + advancedConfig.ActivateSpawnCullingOnServerStart && + updateAllBotSpawns(botSpawnHash); globalValues.indexedMapSpawns = indexedMapSpawns; }; diff --git a/src/Spawning/Spawning.ts b/src/Spawning/Spawning.ts index 3288c4a..f92f145 100644 --- a/src/Spawning/Spawning.ts +++ b/src/Spawning/Spawning.ts @@ -131,6 +131,17 @@ export const buildWaves = (container: DependencyContainer) => { rezervbase: { pmcbot: { min: 0, max: 0 } }, }; + if ( + config.startingPmcs && + (!config.randomSpawns || config.spawnSmoothing) + ) { + Logger.warning( + `[MOAR] Starting pmcs turned on, turning off cascade system and smoothing.\n` + ); + config.spawnSmoothing = false; + config.randomSpawns = true; + } + updateSpawnLocations(locationList); setEscapeTimeOverrides(locationList, _mapConfig, Logger, config); @@ -150,7 +161,7 @@ export const buildWaves = (container: DependencyContainer) => { // enableSmoothing if (config.spawnSmoothing) { - enforceSmoothing(locationList) + enforceSmoothing(locationList); } // saveToFile(locations.bigmap.base.SpawnPointParams, "spawns.json"); diff --git a/src/Spawning/buildBossWaves.ts b/src/Spawning/buildBossWaves.ts index 183e54f..2cb9458 100644 --- a/src/Spawning/buildBossWaves.ts +++ b/src/Spawning/buildBossWaves.ts @@ -258,7 +258,7 @@ export function buildBossWaves( // Apply the percentages on all bosses, cull those that won't spawn, make all bosses 100 chance that remain. locationList[index].base.BossLocationSpawn = locationList[ index - ].base.BossLocationSpawn.filter( + ].base.BossLocationSpawn.map( ({ BossChance, BossName, TriggerId }, bossIndex) => { if ( !TriggerId && @@ -266,16 +266,38 @@ export function buildBossWaves( BossChance < 100 && BossChance / 100 < Math.random() ) { - return false; + locationList[index].base.BossLocationSpawn[ + bossIndex + ].BossChance = 0; + + locationList[index].base.BossLocationSpawn[bossIndex].ForceSpawn = + false; + + locationList[index].base.BossLocationSpawn[ + bossIndex + ].IgnoreMaxBots = false; + } else { + locationList[index].base.BossLocationSpawn[ + bossIndex + ].BossChance = 100; } - return true; + + return locationList[index].base.BossLocationSpawn[bossIndex]; } - ).map((boss) => - bossesToSkip.has(boss.BossName) || !!boss.TriggerId - ? boss - : { ...boss, ...{ BossChance: 100 } } ); + // .map((boss) => + // bossesToSkip.has(boss.BossName) || !!boss.TriggerId + // ? boss + // : { ...boss, ...{ BossChance: 100 } } + // ); + // if (mapName === "lighthouse") { + // console.log( + // locationList[index].base.BossLocationSpawn.map( + // ({ BossName, BossChance }) => ({ BossName, BossChance }) + // ) + // ); + // } // if (mapName === "customs") // console.log(mapName, locationList[index].base.BossLocationSpawn); }); diff --git a/src/Spawning/buildPmcs.ts b/src/Spawning/buildPmcs.ts index 6baedc7..e9cd7d9 100644 --- a/src/Spawning/buildPmcs.ts +++ b/src/Spawning/buildPmcs.ts @@ -2,7 +2,7 @@ import { ILocation } from "@spt/models/eft/common/ILocation"; import _config from "../../config/config.json"; import mapConfig from "../../config/mapConfig.json"; import { defaultEscapeTimes, defaultHostility } from "./constants"; -import { buildBotWaves, MapSettings, shuffle } from "./utils"; +import { buildBotWaves, looselyShuffle, MapSettings, shuffle } from "./utils"; import { saveToFile } from "../utils"; import getSortedSpawnPointList from "./spawnZoneUtils"; @@ -20,33 +20,37 @@ export default function buildPmcs( locationList[index].base.BotLocationModifier.AdditionalHostilitySettings = defaultHostility; - const { pmcHotZones = [], pmcWaveCount, initialSpawnDelay } = - (mapConfig?.[map] as MapSettings) || {}; + const { + pmcHotZones = [], + pmcWaveCount, + initialSpawnDelay, + } = (mapConfig?.[map] as MapSettings) || {}; const { - Position: { x, z }, + Position: { x, y, z }, } = locationList[index].base.SpawnPointParams[ - locationList[index].base.SpawnPointParams.length - 1 + locationList[index].base.SpawnPointParams.length - 1 ]; - // console.log(map); let pmcZones = getSortedSpawnPointList( locationList[index].base.SpawnPointParams.filter( - ({ Categories, Sides }, index) => - (map === "laboratory" || index % 3 === 0) && Categories[0] === "Bot" - ), + (point) => point["type"] === "nonBoss" + ).filter((_, sIndex) => sIndex % 3 === 0), x, + y, z, 0.1 ).map(({ BotZoneName }) => BotZoneName); + looselyShuffle(pmcZones); + + // console.log(pmcZones); - // console.log(map, pmcZones.length) if (map === "laboratory") { pmcZones = new Array(10).fill(pmcZones).flat(1); } - if (config.disableCascadingSpawns) pmcZones = shuffle(pmcZones); + if (config.randomSpawns) pmcZones = shuffle(pmcZones); const escapeTimeLimitRatio = Math.round( locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map] @@ -104,7 +108,7 @@ export default function buildPmcs( const pmcBEAR = buildBotWaves( half, - config.startingPmcs ? Math.round(0.2 * timeLimit) : timeLimit, + config.startingPmcs ? Math.round(0.1 * timeLimit) : timeLimit, config.pmcMaxGroupSize - 1, config.pmcGroupChance, bearSpawns, @@ -116,7 +120,7 @@ export default function buildPmcs( ); const pmcs = [...pmcUSEC, ...pmcBEAR]; - + // console.log(pmcs.map(({ Time }) => Time)); if (pmcs.length) { // Add hotzones if exist pmcHotZones.forEach((hotzone) => { @@ -126,6 +130,11 @@ export default function buildPmcs( }); } + // console.log( + // map, + // pmcs.map(({ BossZone }) => BossZone) + // ); + locationList[index].base.BossLocationSpawn = [ ...pmcs, ...locationList[index].base.BossLocationSpawn, diff --git a/src/Spawning/buildScavMarksmanWaves.ts b/src/Spawning/buildScavMarksmanWaves.ts index 6d89298..192e01b 100644 --- a/src/Spawning/buildScavMarksmanWaves.ts +++ b/src/Spawning/buildScavMarksmanWaves.ts @@ -1,11 +1,8 @@ import { ILocation } from "@spt/models/eft/common/ILocation"; import _config from "../../config/config.json"; import mapConfig from "../../config/mapConfig.json"; -import { - defaultEscapeTimes, - originalMapList, -} from "./constants"; -import { buildBotWaves, MapSettings, shuffle } from "./utils"; +import { defaultEscapeTimes, originalMapList } from "./constants"; +import { buildBotWaves, looselyShuffle, MapSettings, shuffle } from "./utils"; import { WildSpawnType } from "@spt/models/eft/common/ILocationBase"; import { IBotConfig } from "@spt/models/spt/config/IBotConfig"; import { saveToFile } from "../utils"; @@ -62,8 +59,9 @@ export default function buildScavMarksmanWaves( maxBotCapOverride, EscapeTimeLimit, scavHotZones = [], + sniperQuantity = 1, scavWaveCount, - initialSpawnDelay + initialSpawnDelay, } = (mapConfig?.[map] as MapSettings) || {}; // Set per map EscapeTimeLimit @@ -78,6 +76,7 @@ export default function buildScavMarksmanWaves( // console.log(map, capToSet, maxBotCapOverride, maxBotCap); locationList[index].base.BotMax = capToSet; locationList[index].base.BotMaxPvE = capToSet; + locationList[index].base.BotMaxPlayer = capToSet; botConfig.maxBotCap[originalMapList[index]] = capToSet; } @@ -101,23 +100,35 @@ export default function buildScavMarksmanWaves( // ); const { - Position: { x, z }, + Position: { x, y, z }, } = locationList[index].base.SpawnPointParams[ - locationList[index].base.SpawnPointParams.length - 1 + locationList[index].base.SpawnPointParams.length - 1 ]; - let sniperLocations = getSortedSpawnPointList( - [...locationList[index].base.SpawnPointParams].filter( - ({ Categories, DelayToCanSpawnSec, BotZoneName, Sides }) => - !Categories.includes("Boss") && - Sides[0] === "Savage" && - (BotZoneName?.toLowerCase().includes("snipe") || - DelayToCanSpawnSec > 40) + const sniperSpawns = getSortedSpawnPointList( + locationList[index].base.SpawnPointParams.filter( + (point) => point["type"] === "sniper" ), x, + y, z - ).map(({ BotZoneName }) => BotZoneName); + ); + + let sniperLocations = sniperSpawns.map(({ BotZoneName }) => BotZoneName); + // console.log(sniperLocations); + + const sniperDelay = 20; + // Make sure that the sniper spawns permit snipers to actually spawn early. + const sniperIds = new Set(sniperSpawns.map(({ Id }) => Id)); + + locationList[index].base.SpawnPointParams.forEach((point, snipeIndex) => { + if (sniperIds.has(point.Id)) { + locationList[index].base.SpawnPointParams[ + snipeIndex + ].DelayToCanSpawnSec = 20; + } + }); if (sniperLocations.length) { locationList[index].base.MinMaxBots = [ @@ -129,17 +140,18 @@ export default function buildScavMarksmanWaves( ]; } - let scavZones = getSortedSpawnPointList( locationList[index].base.SpawnPointParams.filter( - ({ Categories, Sides }, index) => - index % 3 !== 0 && Categories[0] === "Bot" - ), + (point) => point["type"] === "nonBoss" + ).filter((_, sIndex) => sIndex % 3 !== 0), x, + y, z, 0.1 ).map(({ BotZoneName }) => BotZoneName); + looselyShuffle(scavZones); + const escapeTimeLimitRatio = Math.round( locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map] ); @@ -171,22 +183,24 @@ export default function buildScavMarksmanWaves( ); const timeLimit = locationList[index].base.EscapeTimeLimit * 60; - if (config.disableCascadingSpawns) - sniperLocations = shuffle(sniperLocations); + + // if (config.randomSpawns) + // sniperLocations = shuffle(sniperLocations); + // console.log(map); const snipers = buildBotWaves( - sniperLocations.length, + Math.min(sniperQuantity, sniperLocations.length), timeLimit, sniperMaxGroupSize, sniperGroupChance, sniperLocations, - 0.7, + 1.7, WildSpawnType.MARKSMAN, true, 0.3, - 60 + sniperDelay ); - if (config.disableCascadingSpawns) scavZones = shuffle(scavZones); + if (config.randomSpawns) scavZones = shuffle(scavZones); const scavWaves = buildBotWaves( scavTotalWaveCount, timeLimit, diff --git a/src/Spawning/constants.ts b/src/Spawning/constants.ts index 6698732..7b0da5d 100644 --- a/src/Spawning/constants.ts +++ b/src/Spawning/constants.ts @@ -35,7 +35,6 @@ export const defaultHostility = [ "bossKolontay", "followerKolontayAssault", "followerKolontaySecurity", - "shooterBTR", "bossPartisan", "spiritWinter", "spiritSpring", @@ -60,7 +59,7 @@ export const defaultHostility = [ BearPlayerBehaviour: "AlwaysEnemies", BotRole: "pmcBEAR", ChancedEnemies: [], - Neutral: [], + Neutral: ["shooterBTR"], SavagePlayerBehaviour: "AlwaysEnemies", UsecEnemyChance: 100, UsecPlayerBehaviour: "AlwaysEnemies", @@ -102,7 +101,6 @@ export const defaultHostility = [ "bossKolontay", "followerKolontayAssault", "followerKolontaySecurity", - "shooterBTR", "bossPartisan", "spiritWinter", "spiritSpring", @@ -127,7 +125,7 @@ export const defaultHostility = [ BearPlayerBehaviour: "AlwaysEnemies", BotRole: "pmcUSEC", ChancedEnemies: [], - Neutral: [], + Neutral: ["shooterBTR"], SavagePlayerBehaviour: "AlwaysEnemies", UsecEnemyChance: 100, UsecPlayerBehaviour: "AlwaysEnemies", diff --git a/src/Spawning/spawnZoneUtils.ts b/src/Spawning/spawnZoneUtils.ts index fbdee93..e50c3be 100644 --- a/src/Spawning/spawnZoneUtils.ts +++ b/src/Spawning/spawnZoneUtils.ts @@ -2,25 +2,65 @@ import _config from "../../config/config.json"; import { ISpawnPointParam } from "@spt/models/eft/common/ILocationBase"; import { shuffle } from "./utils"; import mapConfig from "../../config/mapConfig.json"; +import { BotSpawns, PlayerSpawns, SniperSpawns } from "../Spawns"; +import { Ixyz } from "@spt/models/eft/common/Ixyz"; +import { globalValues } from "../GlobalValues"; +import { configLocations } from "./constants"; -const getDistance = (x: number, z: number, mX: number, mZ: number) => { - const pA1 = x - mX; - const pB2 = z - mZ; +// const getDistance = (x: number, z: number, mX: number, mZ: number) => { +// const pA1 = x - mX; +// const pB2 = z - mZ; - return Math.sqrt(pA1 * pA1 + pB2 * pB2); +// return Math.sqrt(pA1 * pA1 + pB2 * pB2); +// }; + +function sq(n: number) { + return n * n; +} + +function pt(a: number, b: number) { + return Math.sqrt(sq(a) + sq(b)); +} + +export const getDistance = ( + x: number, + y: number, + z: number, + mX: number, + mY: number, + mZ: number +) => { + (x = Math.abs(x - mX)), (y = Math.abs(y - mY)), (z = Math.abs(z - mZ)); + + return pt(pt(x, z), y); }; export default function getSortedSpawnPointList( SpawnPointParams: ISpawnPointParam[], mX: number, + my: number, mZ: number, cull?: number ): ISpawnPointParam[] { let culledAmount = 0; const sortedCulledResult = SpawnPointParams.sort((a, b) => { - const a1 = getDistance(a.Position.x, a.Position.z, mX, mZ); - const b1 = getDistance(b.Position.x, b.Position.z, mX, mZ); + const a1 = getDistance( + a.Position.x, + a.Position.y, + a.Position.z, + mX, + my, + mZ + ); + const b1 = getDistance( + b.Position.x, + b.Position.y, + b.Position.z, + mX, + my, + mZ + ); return a1 - b1; }).filter((_, index) => { if (!cull) return true; @@ -33,10 +73,10 @@ export default function getSortedSpawnPointList( if (_config.debug && culledAmount > 0) { console.log( "Reduced to " + - Math.round( - (sortedCulledResult.length / SpawnPointParams.length) * 100 - ) + - "% of original spawns", + Math.round( + (sortedCulledResult.length / SpawnPointParams.length) * 100 + ) + + "% of original spawns", SpawnPointParams.length, ">", sortedCulledResult.length, @@ -48,70 +88,287 @@ export default function getSortedSpawnPointList( export function cleanClosest( SpawnPointParams: ISpawnPointParam[], - map: string + mapIndex: number, + player?: boolean ): ISpawnPointParam[] { - const mapCullingNearPointValue = - mapConfig[map as keyof typeof mapConfig].mapCullingNearPointValue; + const map = configLocations[mapIndex]; - const sortedSpawnPoints = getSortedSpawnPointList( - SpawnPointParams, - -100000, - -100000 - ); + const mapCullingNearPointValue = player + ? mapConfig[map].mapCullingNearPointValuePlayer + : mapConfig[map].mapCullingNearPointValue; + const okayList = new Set(); + const filteredParams = SpawnPointParams.map((point) => { + const { + Position: { x: X, y: Y, z: Z }, + } = point; + const result = !SpawnPointParams.some(({ Position: { z, x, y }, Id }) => { + const dist = getDistance(X, Y, Z, x, y, z); + return mapCullingNearPointValue > dist && dist !== 0 && !okayList.has(Id); + }); - let prev = undefined; - const culled = sortedSpawnPoints.map(({ Position, ...rest }) => { - // const fromMiddle = getDistance(Position.x, Position.z, mX, mZ) - if ( - !!prev && - getDistance(prev.x, prev.z, Position.x, Position.z) < - mapCullingNearPointValue - ) { - return ({ ...rest, Position, DelayToCanSpawnSec: 9999999, CorePointId: 99999, BotZoneName: "_removed", Categories: [], Sides: [], }); + if (!result) { + okayList.add(point.Id); } - prev = Position; - return ({ Position, ...rest }); + return result + ? point + : { + ...point, + ...(player + ? {} + : { + DelayToCanSpawnSec: 9999999, + }), + CorePointId: 99999, + Categories: [], + Sides: [], + }; }); if (_config.debug) { - const actualCulled = culled.filter(({ Categories }) => !!Categories.length) + const actualCulled = filteredParams.filter( + ({ Categories }) => !!Categories.length + ); console.log( map, - "Reduced to " + - Math.round((actualCulled.length / culled.length) * 100) + - "% of original spawns", - culled.length, + filteredParams.length, ">", actualCulled.length, - // "\n" + "Reduced to " + + Math.round((actualCulled.length / filteredParams.length) * 100) + + "% of original spawns", + player ? "player" : "bot" ); // high, low} } - return culled; + + return filteredParams; + + // if (!_config.debug) { + // const actualCulled = culled.filter(({ Categories }) => !!Categories.length); + // console.log( + // map, + // "Reduced to " + + // Math.round((actualCulled.length / culled.length) * 100) + + // "% of original spawns", + // culled.length, + // ">", + // actualCulled.length + // // "\n" + // ); // high, low} + // } +} + +function uuidv4() { + return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => + ( + +c ^ + (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (+c / 4))) + ).toString(16) + ); } +export const AddCustomBotSpawnPoints = ( + SpawnPointParams: ISpawnPointParam[], + map: string +) => { + if (!BotSpawns[map] || !BotSpawns[map].length) { + _config.debug && console.log("no custom Bot spawns for " + map); + return SpawnPointParams; + } + + const botSpawns = BotSpawns[map].map((coords: Ixyz, index: number) => ({ + BotZoneName: getClosestZone(SpawnPointParams, coords.x, coords.y, coords.z), + Categories: ["Bot"], + ColliderParams: { + _parent: "SpawnSphereParams", + _props: { + Center: { + x: 0, + y: 0, + z: 0, + }, + Radius: 20, + }, + }, + CorePointId: 1, + DelayToCanSpawnSec: 4, + Id: uuidv4(), + Infiltration: "", + Position: coords, + Rotation: random360(), + Sides: ["Savage"], + })); + + return [...SpawnPointParams, ...botSpawns]; +}; + +export const AddCustomSniperSpawnPoints = ( + SpawnPointParams: ISpawnPointParam[], + map: string +) => { + if (!SniperSpawns[map] || !SniperSpawns[map].length) { + _config.debug && console.log("no custom Player spawns for " + map); + return SpawnPointParams; + } + + const sniperSpawns = SniperSpawns[map].map((coords: Ixyz, index: number) => ({ + BotZoneName: + getClosestZone(SpawnPointParams, coords.x, coords.y, coords.z) || + "custom_snipe_" + index, + Categories: ["Bot"], + ColliderParams: { + _parent: "SpawnSphereParams", + _props: { + Center: { + x: 0, + y: 0, + z: 0, + }, + Radius: 20, + }, + }, + CorePointId: 1, + DelayToCanSpawnSec: 4, + Id: uuidv4(), + Infiltration: "", + Position: coords, + Rotation: random360(), + Sides: ["Savage"], + })); + + return [...SpawnPointParams, ...sniperSpawns]; +}; + +export const random360 = () => Math.random() * 360; +export const AddCustomPlayerSpawnPoints = ( + SpawnPointParams: ISpawnPointParam[], + map: string +) => { + if (!PlayerSpawns[map] || !PlayerSpawns[map].length) { + _config.debug && console.log("no custom Player spawns for " + map); + return SpawnPointParams; + } + + const infilHash: Record = {}; + + SpawnPointParams.forEach((point) => { + if (!infilHash[point.Infiltration]) { + infilHash[point.Infiltration] = point.Position; + } else { + infilHash[point.Infiltration].x = Math.round( + (infilHash[point.Infiltration].x + point.Position.x) / 2 + ); + infilHash[point.Infiltration].z = Math.round( + (infilHash[point.Infiltration].z + point.Position.z) / 2 + ); + } + }); + + const getClosestInfil = (x: number, y: number, z: number) => { + let closest = Infinity; + let selectedInfil = Object.keys(infilHash)[0]; + Object.keys(infilHash).forEach((infil) => { + const current = infilHash[infil]; + const dist = getDistance(current.x, current.y, current.z, x, y, z); + if (dist < closest) { + closest = dist; + selectedInfil = infil; + } + }); + + return selectedInfil; + }; + + const playerSpawns = PlayerSpawns[map].map((coords: Ixyz, index) => ({ + BotZoneName: "", + Categories: ["Player"], + ColliderParams: { + _parent: "SpawnSphereParams", + _props: { + Center: { + x: 0, + y: 0, + z: 0, + }, + Radius: 20, + }, + }, + CorePointId: 0, + DelayToCanSpawnSec: 4, + Id: uuidv4(), + Infiltration: getClosestInfil(coords.x, coords.y, coords.z), + Position: coords, + Rotation: random360(), + Sides: ["Pmc"], + })); + + return [...SpawnPointParams, ...playerSpawns]; +}; + +export const getClosestZone = ( + params: ISpawnPointParam[], + x: number, + y: number, + z: number +) => { + if ( + Array.isArray(params) && + !params.filter(({ BotZoneName }) => BotZoneName).length + ) + return ""; + + return ( + getSortedSpawnPointList(params, x, y, z).find( + ({ BotZoneName }) => !!BotZoneName + )?.BotZoneName || "" + ); +}; + +export const removeClosestSpawnsFromCustomBots = ( + SpawnPointParams: ISpawnPointParam[], + map: string, + mapConfigMap: string +) => { + if (!BotSpawns[map] || !BotSpawns[map].length) { + console.log("No map called ", map); + return; + } + + const coords: Ixyz[] = BotSpawns[map]; + + const mapCullingNearPointValue = + mapConfig[mapConfigMap].mapCullingNearPointValue; -// customs Reduced to 33% of original spawns 160 > 52 -// customs Reduced to 98% of original spawns 81 > 79 -// factoryDay Reduced to 66% of original spawns 126 > 83 -// factoryDay Reduced to 95% of original spawns 19 > 18 -// factoryNight Reduced to 66% of original spawns 126 > 83 -// factoryNight Reduced to 95% of original spawns 19 > 18 -// interchange Reduced to 34% of original spawns 171 > 58 -// interchange Reduced to 77% of original spawns 52 > 40 -// laboratory Reduced to 63% of original spawns 115 > 72 -// laboratory Reduced to NaN% of original spawns 0 > 0 -// lighthouse Reduced to 31% of original spawns 101 > 31 -// lighthouse Reduced to 78% of original spawns 90 > 70 -// rezervbase Reduced to 34% of original spawns 120 > 41 -// rezervbase Reduced to 75% of original spawns 60 > 45 -// shoreline Reduced to 30% of original spawns 171 > 51 -// shoreline Reduced to 94% of original spawns 81 > 76 -// tarkovstreets Reduced to 24% of original spawns 236 > 57 -// tarkovstreets Reduced to 60% of original spawns 186 > 112 -// woods Reduced to 32% of original spawns 181 > 58 -// woods Reduced to 88% of original spawns 129 > 114 -// gzLow Reduced to 34% of original spawns 140 > 47 -// gzLow Reduced to 56% of original spawns 59 > 33 -// gzHigh Reduced to 34% of original spawns 140 > 47 -// gzHigh Reduced to 52% of original spawns 50 > 26 \ No newline at end of file + let filteredCoords = coords.filter( + ({ x: X, y: Y, z: Z }) => + !SpawnPointParams.some(({ Position: { z, x, y } }) => { + return mapCullingNearPointValue > getDistance(X, Y, Z, x, y, z); + }) + ); + + const okayList = new Set(); + + filteredCoords = [...coords].filter(({ x: X, y: Y, z: Z }, index) => { + const result = !coords.some(({ z, x, y }) => { + const dist = getDistance(X, Y, Z, x, y, z); + return ( + mapCullingNearPointValue * 1.3 > dist && + dist !== 0 && + !okayList.has("" + x + y + z) + ); + }); + if (!result) okayList.add("" + X + Y + Z); + return result; + }); + + console.log( + map, + coords.length, + ">", + filteredCoords.length, + "culled", + coords.length - filteredCoords.length, + "spawns" + ); + return filteredCoords; +}; diff --git a/src/Spawning/updateSpawnLocations.ts b/src/Spawning/updateSpawnLocations.ts index 7884138..9e67ac5 100644 --- a/src/Spawning/updateSpawnLocations.ts +++ b/src/Spawning/updateSpawnLocations.ts @@ -4,40 +4,43 @@ import _config from "../../config/config.json"; import { getRandomInArray, shuffle } from "./utils"; import { ISpawnPointParam } from "@spt/models/eft/common/ILocationBase"; import { globalValues } from "../GlobalValues"; +import getSortedSpawnPointList from "./spawnZoneUtils"; export default function updateSpawnLocations(locationList: ILocation[]) { for (let index = 0; index < locationList.length; index++) { const map = configLocations[index]; const playerSpawns: ISpawnPointParam[] = []; + // const addedSpawns: ISpawnPointParam[] = []; const mapSpawns = globalValues.indexedMapSpawns[index]; - locationList[index].base.SpawnPointParams = [...mapSpawns].filter( - (point) => { - if (point?.Categories[0] === "Player") { - playerSpawns.push(point); - return false; - } - return true; + const filteredSpawns = [...mapSpawns].filter((point) => { + if (point?.Categories[0] === "Player") { + playerSpawns.push(point); + return false; } + + return true; + }); + + const playerSpawn: ISpawnPointParam = getRandomInArray(playerSpawns); + const { x, y, z } = playerSpawn.Position; + + // console.log(map, playerSpawn.BotZoneName, playerSpawn.Position); + + const sortedSpawnPointList = getSortedSpawnPointList( + filteredSpawns, + x, + y, + z ); - // console.log(playerSpawns.length); + // console.log(map, sortedSpawnPointList.filter((point) => point.CorePointId < 100).map((point) => point.CorePointId)) - const playerSpawn: ISpawnPointParam = getRandomInArray(playerSpawns); // playerSpawns[playerSpawns.length - 1] - playerSpawn.ColliderParams._props.Radius = 1 - // console.log(map, playerSpawn.Position); + // console.log(map, hash) - const spawnsToAdd = playerSpawns - .filter((point) => point.Id !== playerSpawn.Id) - .map((point, index) => ({ - ...point, - Categories: ["Bot"], - // Infiltration: "", - Sides: ["Savage"], - CorePointId: 1, - })); + locationList[index].base.SpawnPointParams = sortedSpawnPointList; - locationList[index].base.SpawnPointParams.push(...spawnsToAdd); + playerSpawn.ColliderParams._props.Radius = 1; const listToAddToOpenZones = shuffle([ ...new Set( diff --git a/src/Spawning/utils.ts b/src/Spawning/utils.ts index d01507e..59ecc64 100644 --- a/src/Spawning/utils.ts +++ b/src/Spawning/utils.ts @@ -227,7 +227,12 @@ export const buildBotWaves = ( ? Math.round(maxGroup * Math.random()) : 0; - if (bossEscortAmount < 0) bossEscortAmount = 0; + if ( + bossEscortAmount < 0 || + (bossEscortAmount > 0 && bossEscortAmount + 1 > maxSlotsReached) + ) { + bossEscortAmount = 0; + } const totalCountThisWave = isMarksman ? 1 : bossEscortAmount + 1; const totalCountThusFar = botTotal - maxSlotsReached; @@ -235,24 +240,19 @@ export const buildBotWaves = ( const BossDifficult = getDifficulty(difficulty); waves.push({ - BossChance: isMarksman ? 80 : 100, + BossChance: 100, BossDifficult, BossEscortAmount: bossEscortAmount.toString(), BossEscortDifficult: BossDifficult, BossEscortType: botType, BossName: botType, BossPlayer: false, - BossZone: - bossZones[ - isMarksman - ? totalCountThusFar - : Math.floor(totalCountThusFar * botToZoneTotal) - ] || "", + BossZone: bossZones[Math.floor(totalCountThusFar * botToZoneTotal)] || "", Delay: 0, DependKarma: false, DependKarmaPVE: false, ForceSpawn, - IgnoreMaxBots: true, + IgnoreMaxBots: ForceSpawn, RandomTimeSpawn: false, Time: startTime, Supports: null, @@ -263,16 +263,16 @@ export const buildBotWaves = ( startTime += Math.round(totalCountThisWave * averageTime); - maxSlotsReached -= 1 + bossEscortAmount; + maxSlotsReached -= 1 + (isMarksman ? 0 : bossEscortAmount); if (maxSlotsReached <= 0) break; } // isMarksman && - // console.log( - // // bossZones, - // botType, - // bossZones.length, - // waves.map(({ Time, BossZone }) => ({ Time, BossZone })) - // ); + // console.log( + // // bossZones, + // botType, + // bossZones.length, + // waves.map(({ Time, BossZone }) => ({ Time, BossZone })) + // ); return waves; }; @@ -341,6 +341,7 @@ export const buildZombie = ( }; export interface MapSettings { + sniperQuantity?: number; initialSpawnDelay: number; smoothingDistribution: number; mapCullingNearPointValue: number; @@ -420,7 +421,7 @@ export const setEscapeTimeOverrides = ( if ( !override && locationList[index].base.EscapeTimeLimit / defaultEscapeTimes[map] > - hardcodedEscapeLimitMax + hardcodedEscapeLimitMax ) { const maxLimit = defaultEscapeTimes[map] * hardcodedEscapeLimitMax; logger.warning( @@ -503,8 +504,9 @@ export const enforceSmoothing = (locationList: ILocation[]) => { const ratio = (index + 1) / notBosses.length; // console.log(ratio); notBosses[index].Time = start; - - start += Math.round(increment * ratio); + let inc = Math.round(increment * ratio); + if (inc < 10) inc = 5; + start += inc; } // console.log( @@ -516,3 +518,18 @@ export const enforceSmoothing = (locationList: ILocation[]) => { locationList[index].base.BossLocationSpawn = [...Bosses, ...notBosses]; } }; + +export const looselyShuffle = (arr: T[], shuffleStep: number = 3): T[] => { + const n = arr.length; + const halfN = Math.floor(n / 2); + for (let i = shuffleStep - 1; i < halfN; i += shuffleStep) { + // Pick a random index from the second half of the array to swap with the current index + const randomIndex = halfN + Math.floor(Math.random() * (n - halfN)); + // Swap the elements at the current index and the random index + const temp = arr[i]; + arr[i] = arr[randomIndex]; + arr[randomIndex] = temp; + } + + return arr; +}; diff --git a/src/Spawns/botSpawns.json b/src/Spawns/botSpawns.json new file mode 100644 index 0000000..0c7828e --- /dev/null +++ b/src/Spawns/botSpawns.json @@ -0,0 +1,1814 @@ +{ + "bigmap": [ + { + "x": 644.906433, + "y": 0.8981615299999999, + "z": 124.177345 + }, + { + "x": 626.361267, + "y": 2.281789, + "z": 97.45197 + }, + { + "x": 603.0844, + "y": 6.63166046, + "z": 109.145416 + }, + { + "x": 562.159058, + "y": 15.7497768, + "z": 147.763718 + }, + { + "x": 544.4945, + "y": 6.16559, + "z": 67.1485443 + }, + { + "x": 503.0341, + "y": 9.951932, + "z": 60.12894 + }, + { + "x": 484.279755, + "y": 11.595027, + "z": 81.32664 + }, + { + "x": 506.216034, + "y": 14.5007343, + "z": 122.326782 + }, + { + "x": 478.075165, + "y": 3.44185948, + "z": 161.85881 + }, + { + "x": 465.621368, + "y": 4.50928736, + "z": 140.425964 + }, + { + "x": 456.2658, + "y": 12.4092331, + "z": 99.6092453 + }, + { + "x": 418.384766, + "y": 3.013848, + "z": 70.34274 + }, + { + "x": 396.615173, + "y": 2.42234719, + "z": 77.499176 + }, + { + "x": 371.085266, + "y": 1.326120853, + "z": 78.38702 + }, + { + "x": 376.3876, + "y": 10.87682, + "z": 139.199188 + }, + { + "x": 385.614746, + "y": 13.8405361, + "z": 184.8955 + }, + { + "x": 426.6256, + "y": 10.248782, + "z": 197.895172 + }, + { + "x": 346.459351, + "y": 6.399575, + "z": 121.327972 + }, + { + "x": 344.132172, + "y": 2.27664137, + "z": 79.69861 + }, + { + "x": 328.555145, + "y": 1.79390025, + "z": 60.5217361 + }, + { + "x": 350.6124, + "y": 0.0010866520000000213, + "z": 52.32654 + }, + { + "x": 297.700684, + "y": -1.1482155300000003, + "z": 63.2100143 + }, + { + "x": 266.6165, + "y": -2.57164049, + "z": 82.3688354 + }, + { + "x": 254.3162, + "y": 0.6469844579999999, + "z": 150.997452 + }, + { + "x": 239.714874, + "y": -0.1937426, + "z": 182.810669 + }, + { + "x": 214.285873, + "y": -0.6202864599999999, + "z": 191.926 + }, + { + "x": 163.75354, + "y": -1.18064094, + "z": 199.564789 + }, + { + "x": 152.44104, + "y": -1.02730823, + "z": 179.044189 + }, + { + "x": 138.656036, + "y": -1.3767459400000002, + "z": 154.9155 + }, + { + "x": 105.77549, + "y": -2.40459538, + "z": 157.900436 + }, + { + "x": 59.79218, + "y": -3.840946, + "z": 119.544525 + }, + { + "x": 58.0996246, + "y": -3.09243417, + "z": 92.6208344 + }, + { + "x": 84.8447342, + "y": -1.4591472100000002, + "z": 68.26317 + }, + { + "x": 108.150818, + "y": -1.2258721600000002, + "z": 61.8904152 + }, + { + "x": 122.396339, + "y": -0.06853450000000005, + "z": 39.57657 + }, + { + "x": 202.368149, + "y": -0.85824311, + "z": 48.7537422 + }, + { + "x": 264.085541, + "y": 1.66909194, + "z": -10.8289251 + }, + { + "x": 203.49527, + "y": 4.3712194, + "z": 10.7429361 + }, + { + "x": 179.710632, + "y": 1.7927557199999997, + "z": 13.6136341 + }, + { + "x": 198.832474, + "y": -2.25874782, + "z": -143.868073 + }, + { + "x": 226.274445, + "y": 1.8120700000000003, + "z": -152.466934 + }, + { + "x": 256.12677, + "y": 1.7255953599999998, + "z": -148.035065 + }, + { + "x": 284.246155, + "y": 4.627302, + "z": -150.493774 + }, + { + "x": 287.6501, + "y": 2.05195332, + "z": -203.412674 + }, + { + "x": 330.932831, + "y": 4.700771, + "z": -120.073845 + }, + { + "x": 352.167236, + "y": 4.736766, + "z": -111.830849 + }, + { + "x": 390.7965, + "y": 1.6705870000000003, + "z": -115.596779 + }, + { + "x": 421.22998, + "y": 4.714122, + "z": -130.802536 + }, + { + "x": 483.3155, + "y": 1.6157716500000001, + "z": -40.8431053 + }, + { + "x": 426.0826, + "y": 1.63224256, + "z": -53.929306 + }, + { + "x": 396.652435, + "y": 1.63732862, + "z": -56.5637321 + }, + { + "x": 376.458038, + "y": 1.63391733, + "z": -77.90272 + }, + { + "x": 369.4044, + "y": 1.6490515500000003, + "z": -46.484272 + }, + { + "x": 364.615417, + "y": 1.6643312, + "z": -14.8107471 + }, + { + "x": 345.536652, + "y": 1.6643312, + "z": -7.421874 + }, + { + "x": 339.773926, + "y": 1.7952646000000003, + "z": -42.7292328 + }, + { + "x": 335.0259, + "y": 1.79291511, + "z": -65.39027 + }, + { + "x": 337.741577, + "y": 1.8020970800000002, + "z": -90.68583 + }, + { + "x": 348.3853, + "y": 1.60662079, + "z": -162.4169 + }, + { + "x": 246.582047, + "y": 1.62401426, + "z": -72.66881 + }, + { + "x": 198.178619, + "y": 1.60544419, + "z": -36.5095139 + }, + { + "x": 168.025085, + "y": 1.64992464, + "z": -63.5274277 + }, + { + "x": 107.300087, + "y": 1.89460659, + "z": -89.24351 + }, + { + "x": 59.10971, + "y": 1.78355861, + "z": -72.69168 + }, + { + "x": 69.4475, + "y": 1.62255371, + "z": -40.80853 + }, + { + "x": 49.4975929, + "y": 1.69499338, + "z": -11.2656345 + }, + { + "x": 57.7471161, + "y": 1.2125401500000001, + "z": 7.39377356 + }, + { + "x": 31.7893028, + "y": -0.57776749, + "z": 36.7203445 + }, + { + "x": -10.3683844, + "y": -0.05755339999999998, + "z": 35.80947 + }, + { + "x": -51.72802, + "y": -12.3136, + "z": 45.1565933 + }, + { + "x": -24.8628845, + "y": -8.340166, + "z": 85.35458 + }, + { + "x": -29.1821213, + "y": -10.4283419, + "z": 114.228783 + }, + { + "x": -2.24856186, + "y": -3.89206457, + "z": 107.59346 + }, + { + "x": 24.3358936, + "y": -0.5024679999999999, + "z": 93.39741 + }, + { + "x": -34.4313431, + "y": 0.813168645, + "z": -1.44573927 + }, + { + "x": -55.7129135, + "y": 0.9166388809999999, + "z": 6.919475 + }, + { + "x": -91.02421, + "y": 0.952377856, + "z": 13.643033 + }, + { + "x": -114.557045, + "y": 0.9437701700000001, + "z": 11.1768637 + }, + { + "x": -180.599655, + "y": 0.58265871, + "z": 5.27551126 + }, + { + "x": -215.955322, + "y": -0.013305400000000023, + "z": -13.3671389 + }, + { + "x": -259.435455, + "y": 1.3692214489999999, + "z": -78.33612 + }, + { + "x": -280.582581, + "y": 1.3692214489999999, + "z": -83.72153 + }, + { + "x": -235.118942, + "y": 0.669038743, + "z": -74.0859756 + }, + { + "x": -220.864914, + "y": 1.177674949, + "z": -60.190094 + }, + { + "x": -203.166962, + "y": 1.7511124599999999, + "z": -33.57056 + }, + { + "x": -177.894531, + "y": 1.4358563420000001, + "z": -45.2099152 + }, + { + "x": -157.088531, + "y": 1.8825273500000002, + "z": -54.9010544 + }, + { + "x": -154.064285, + "y": 1.4300753469999998, + "z": -74.9202957 + }, + { + "x": -163.1226, + "y": 3.6211976999999997, + "z": -145.316788 + }, + { + "x": -209.131683, + "y": 1.4477444, + "z": -182.339951 + }, + { + "x": -185.093231, + "y": 2.305265, + "z": -186.7409 + }, + { + "x": -207.87764, + "y": 1.7551697500000003, + "z": -210.167908 + }, + { + "x": -317.067, + "y": 1.4162192, + "z": -190.285339 + }, + { + "x": -317.486, + "y": 1.4685522, + "z": -166.049088 + }, + { + "x": -331.278442, + "y": 0.48691936, + "z": -123.1832 + }, + { + "x": -286.7494, + "y": -0.31516520000000003, + "z": -50.11011 + }, + { + "x": -272.3683, + "y": 0.17205542299999999, + "z": -26.6685658 + }, + { + "x": -131.165543, + "y": -1.6290636100000002, + "z": -29.30433 + }, + { + "x": -94.1864, + "y": -8.880024, + "z": -44.7925224 + }, + { + "x": -72.3187256, + "y": -9.208183, + "z": -49.1068764 + }, + { + "x": 19.31347, + "y": 0.44983119520000003, + "z": -25.515543 + }, + { + "x": 0.497767746, + "y": 1.57023323, + "z": -76.42957 + }, + { + "x": 1.38900924, + "y": 1.60138083, + "z": -126.827271 + }, + { + "x": 32.1375656, + "y": 1.6066588199999998, + "z": -112.356575 + }, + { + "x": 61.3254623, + "y": 1.6635679999999997, + "z": -109.5339 + }, + { + "x": 576.8831, + "y": 1.94585454, + "z": -58.348877 + }, + { + "x": 563.104065, + "y": -0.31062540000000005, + "z": 2.00142 + }, + { + "x": 543.3302, + "y": 0.320250139, + "z": -0.442697 + }, + { + "x": 81.6217346, + "y": 2.00750268, + "z": -151.027039 + }, + { + "x": 228.014847, + "y": 0.44975153, + "z": 158.021744 + } + ], + "factory4_day": [ + { + "x": 14.9062071, + "y": 5.108978, + "z": 46.65968 + }, + { + "x": 14.771657, + "y": 1.5306538300000003, + "z": 38.67751 + }, + { + "x": -39.7549133, + "y": 7.987152, + "z": 62.6642342 + }, + { + "x": -22.3375015, + "y": 7.987169, + "z": 9.725967 + }, + { + "x": 8.108521, + "y": 7.85232925, + "z": -0.255552679 + }, + { + "x": 34.8389435, + "y": 8.22901058, + "z": -6.220801 + }, + { + "x": 30.718338, + "y": 7.6758880000000005, + "z": -32.70795 + }, + { + "x": 17.4661484, + "y": 0.16427895400000003, + "z": -44.53234 + }, + { + "x": -8.074425, + "y": 0.14414432599999993, + "z": -49.441864 + } + ], + "factory4_night": [ + { + "x": 14.9062071, + "y": 5.108978, + "z": 46.65968 + }, + { + "x": 14.771657, + "y": 1.5306538300000003, + "z": 38.67751 + }, + { + "x": -39.7549133, + "y": 7.987152, + "z": 62.6642342 + }, + { + "x": -22.3375015, + "y": 7.987169, + "z": 9.725967 + }, + { + "x": 8.108521, + "y": 7.85232925, + "z": -0.255552679 + }, + { + "x": 34.8389435, + "y": 8.22901058, + "z": -6.220801 + }, + { + "x": 30.718338, + "y": 7.6758880000000005, + "z": -32.70795 + }, + { + "x": 17.4661484, + "y": 0.16427895400000003, + "z": -44.53234 + }, + { + "x": -8.074425, + "y": 0.14414432599999993, + "z": -49.441864 + } + ], + "interchange": [ + { + "x": 306.6949, + "y": 22.3703613, + "z": -163.197372 + }, + { + "x": 370.984, + "y": 18.8629875, + "z": -229.275665 + }, + { + "x": 431.68576, + "y": 18.074276, + "z": -320.8318 + }, + { + "x": 373.3453, + "y": 18.3586578, + "z": -375.009766 + }, + { + "x": 235.885757, + "y": 20.7026825, + "z": -276.835724 + }, + { + "x": 213.305908, + "y": 20.7839127, + "z": -213.397018 + }, + { + "x": 223.268372, + "y": 20.42921, + "z": -141.728333 + }, + { + "x": 214.012634, + "y": 20.7538376, + "z": -85.7485046 + }, + { + "x": 171.5519, + "y": 21.9475384, + "z": -65.2406 + }, + { + "x": 139.65799, + "y": 21.856554, + "z": 44.3145 + }, + { + "x": 67.2355347, + "y": 21.9292259, + "z": 204.827774 + }, + { + "x": -119.261528, + "y": 22.9796734, + "z": 261.25354 + }, + { + "x": -207.836472, + "y": 24.0151825, + "z": 257.108459 + }, + { + "x": -309.632141, + "y": 21.82544, + "z": 244.291122 + }, + { + "x": -347.45932, + "y": 25.7521248, + "z": 203.852646 + }, + { + "x": -295.677856, + "y": 23.1690922, + "z": 176.239868 + } + ], + "laboratory": [], + "lighthouse": [ + { + "x": -135.948944, + "y": 29.7065582, + "z": 261.309052 + }, + { + "x": -35.25838, + "y": 7.76675463, + "z": 240.817337 + }, + { + "x": 6.31064749, + "y": 6.59248972, + "z": 246.753387 + }, + { + "x": -1.88037038, + "y": 6.57795048, + "z": 295.319458 + }, + { + "x": -2.71696925, + "y": 6.57795048, + "z": 335.996 + }, + { + "x": 6.92733955, + "y": 6.59636354, + "z": 179.35527 + }, + { + "x": 40.35865, + "y": 10.430348, + "z": 139.536423 + }, + { + "x": 60.38063, + "y": 24.3006668, + "z": 118.797821 + }, + { + "x": 49.2740135, + "y": 15.7289438, + "z": 62.4863853 + }, + { + "x": 50.048172, + "y": 10.181008, + "z": 36.49277 + }, + { + "x": -390.437561, + "y": 15.1578426, + "z": -414.736542 + }, + { + "x": -335.245728, + "y": 0.5389716178, + "z": -350.177032 + }, + { + "x": -301.3966, + "y": 0.5476846956, + "z": -322.756256 + }, + { + "x": -274.1688, + "y": 1.2555660610000001, + "z": -307.504456 + }, + { + "x": -153.8565, + "y": 8.914719, + "z": -324.440125 + }, + { + "x": -184.331436, + "y": 13.2631092, + "z": -208.147415 + }, + { + "x": -277.284058, + "y": 14.2382278, + "z": -175.448 + }, + { + "x": -271.556183, + "y": 14.285676, + "z": -204.831665 + }, + { + "x": -203.8689, + "y": 6.60906649, + "z": 417.72403 + }, + { + "x": -227.730057, + "y": 6.641781, + "z": 422.753876 + }, + { + "x": -126.077072, + "y": 21.6456623, + "z": 307.16684 + }, + { + "x": -438.837921, + "y": 26.5393162, + "z": -402.1009 + }, + { + "x": -383.6268, + "y": 12.591733, + "z": -204.3279 + }, + { + "x": -384.19458, + "y": 14.95361, + "z": -443.422058 + }, + { + "x": -359.967651, + "y": 29.3489037, + "z": -554.192932 + } + ], + "rezervbase": [ + { + "x": -60.7591362, + "y": -6.47912836, + "z": 76.7873 + }, + { + "x": -90.6994553, + "y": -1.54958749, + "z": 140.122711 + }, + { + "x": -57.1098747, + "y": -15.3225021, + "z": 162.027344 + }, + { + "x": -70.86728, + "y": -18.0448246, + "z": 142.329178 + }, + { + "x": -93.04627, + "y": -15.704044299999998, + "z": 153.5963 + }, + { + "x": -59.9861, + "y": -19.3641968, + "z": 95.98342 + }, + { + "x": -70.7831345, + "y": -18.3293934, + "z": 70.56265 + }, + { + "x": -109.326, + "y": -10.1063776, + "z": 68.1899643 + } + ], + "shoreline": [ + { + "x": 21.7578163, + "y": -21.7658558, + "z": -116.816818 + }, + { + "x": 51.85456, + "y": -21.2345924, + "z": -120.915588 + }, + { + "x": 94.2967148, + "y": -32.8620949, + "z": -94.95909 + }, + { + "x": 136.4691, + "y": -40.0397949, + "z": -84.48611 + }, + { + "x": 277.8101, + "y": -49.2844, + "z": -56.9202156 + }, + { + "x": 320.6921, + "y": -47.4757919, + "z": 50.2625961 + }, + { + "x": 228.25061, + "y": -51.7036667, + "z": 222.827835 + }, + { + "x": 175.620438, + "y": -52.099472, + "z": 278.2336 + }, + { + "x": 143.395874, + "y": -51.7199, + "z": 291.1424 + }, + { + "x": 105.224106, + "y": -45.3506241, + "z": 285.132477 + }, + { + "x": 72.14921, + "y": -49.69929, + "z": 317.7179 + }, + { + "x": -40.3800163, + "y": -47.5226631, + "z": 302.809326 + }, + { + "x": -89.9393158, + "y": -47.8895874, + "z": 385.692047 + }, + { + "x": -119.667892, + "y": -45.9225769, + "z": 387.7154 + }, + { + "x": -340.330139, + "y": -40.96095, + "z": 199.740189 + }, + { + "x": -397.821136, + "y": -31.2467251, + "z": 168.270218 + }, + { + "x": -534.1599, + "y": -31.0766544, + "z": 122.78479 + }, + { + "x": -608.3026, + "y": -42.90004, + "z": 89.1378 + }, + { + "x": -694.9616, + "y": -29.0427952, + "z": 93.6625 + }, + { + "x": -720.35614, + "y": -27.035532, + "z": 103.138641 + }, + { + "x": -731.1302, + "y": -28.6101246, + "z": 82.78596 + }, + { + "x": -553.0381, + "y": -31.1007023, + "z": -122.218216 + }, + { + "x": -517.332031, + "y": -18.1244888, + "z": -331.826874 + }, + { + "x": 331.508453, + "y": -54.1240044, + "z": -122.091179 + } + ], + "tarkovstreets": [], + "woods": [ + { + "x": -367.8166, + "y": 1.5299747, + "z": 216.489624 + }, + { + "x": -355.625641, + "y": 1.6345452099999997, + "z": 236.7333 + }, + { + "x": -428.700623, + "y": 1.338670969, + "z": 212.33313 + }, + { + "x": -304.072327, + "y": 0.005421757999999999, + "z": 242.913086 + }, + { + "x": -448.8098, + "y": 1.4670438999999997, + "z": 224.85231 + }, + { + "x": -277.704, + "y": -0.7169679399999999, + "z": 250.8364 + }, + { + "x": -481.6612, + "y": 1.357273936, + "z": 237.128357 + }, + { + "x": -466.4007, + "y": 4.65177965, + "z": 132.510712 + }, + { + "x": -250.773041, + "y": -1.39268231, + "z": 282.419952 + }, + { + "x": -489.674, + "y": 7.554838, + "z": 126.403336 + }, + { + "x": -517.8711, + "y": 7.819247000000001, + "z": 147.575439 + }, + { + "x": -210.89325, + "y": -2.669741, + "z": 296.864471 + }, + { + "x": -181.263977, + "y": -1.31454265, + "z": 232.462677 + }, + { + "x": -428.517029, + "y": 6.793571, + "z": 35.4942551 + }, + { + "x": -378.195068, + "y": 7.07278252, + "z": 22.6268425 + }, + { + "x": -163.35112, + "y": -1.711656, + "z": 239.952072 + }, + { + "x": -430.651367, + "y": 8.555316, + "z": 6.447655 + }, + { + "x": -132.422562, + "y": -7.198452, + "z": 247.045151 + }, + { + "x": -316.197662, + "y": 15.5482187, + "z": -14.9898186 + }, + { + "x": -117.863922, + "y": -8.724307, + "z": 201.516327 + }, + { + "x": -97.31543, + "y": 0.8171915410000001, + "z": 113.906586 + }, + { + "x": -85.91561, + "y": -4.17538929, + "z": 147.257584 + }, + { + "x": -89.87441, + "y": 5.20825052, + "z": 85.265625 + }, + { + "x": -169.262314, + "y": 21.34261, + "z": -47.7785568 + }, + { + "x": -462.13913, + "y": 24.1336365, + "z": -117.927254 + }, + { + "x": -495.445251, + "y": 23.7535133, + "z": -112.491013 + }, + { + "x": -541.019, + "y": 9.908503, + "z": -107.516991 + }, + { + "x": -385.643646, + "y": 26.2474461, + "z": -154.487122 + }, + { + "x": -375.345367, + "y": 26.5590916, + "z": -184.149719 + }, + { + "x": -547.0925, + "y": 13.7237806, + "z": -143.77977 + }, + { + "x": -14.4089851, + "y": -3.13456535, + "z": 0.755433738 + }, + { + "x": -516.345, + "y": 16.3131075, + "z": -176.483322 + }, + { + "x": -339.7615, + "y": 31.6987228, + "z": -202.20076 + }, + { + "x": -531.747253, + "y": 14.3916121, + "z": -185.982559 + }, + { + "x": 2.31268787, + "y": -3.13456535, + "z": -33.8564453 + }, + { + "x": -316.546173, + "y": 36.1329842, + "z": -227.459656 + }, + { + "x": -254.624725, + "y": 60.1661339, + "z": -232.042465 + }, + { + "x": -559.7915, + "y": 20.9346943, + "z": -213.880737 + }, + { + "x": -232.025375, + "y": 68.20237, + "z": -230.872528 + }, + { + "x": -511.462, + "y": 22.172781, + "z": -248.92804 + }, + { + "x": 10.3727036, + "y": 6.879104, + "z": -126.07653 + }, + { + "x": -515.914, + "y": 22.3329887, + "z": -284.8565 + }, + { + "x": 28.5608654, + "y": 7.59594154, + "z": -148.208359 + }, + { + "x": -198.543365, + "y": 70.64696, + "z": -290.822 + }, + { + "x": -496.105835, + "y": 15.4777937, + "z": -327.011749 + }, + { + "x": -184.086792, + "y": 55.1406975, + "z": -319.1492 + }, + { + "x": -136.267685, + "y": 34.8288536, + "z": -318.203339 + }, + { + "x": 116.832344, + "y": 2.532036, + "z": -110.569809 + }, + { + "x": 137.45372, + "y": 1.1641575, + "z": -90.65133 + }, + { + "x": 152.758224, + "y": 0.966107547, + "z": -64.61185 + }, + { + "x": 103.807045, + "y": 7.737143, + "z": -146.0022 + }, + { + "x": -512.950439, + "y": 16.0324688, + "z": -387.301819 + }, + { + "x": -405.989166, + "y": 15.5477514, + "z": -407.3094 + }, + { + "x": -54.2721634, + "y": 28.0251751, + "z": -340.654572 + }, + { + "x": 234.365692, + "y": -1.4303108500000001, + "z": -39.79725 + }, + { + "x": 86.9553452, + "y": 23.222435, + "z": -260.8882 + }, + { + "x": -453.858734, + "y": 15.671413399999999, + "z": -439.50528 + }, + { + "x": -396.451263, + "y": 14.991972, + "z": -444.567352 + }, + { + "x": -536.5344, + "y": 13.1487293, + "z": -426.075 + }, + { + "x": 107.398819, + "y": 15.7541695, + "z": -250.02562 + }, + { + "x": 206.728928, + "y": 0.04770399999999997, + "z": -123.707054 + }, + { + "x": 62.7092819, + "y": 29.7554436, + "z": -295.579742 + }, + { + "x": 171.639832, + "y": 3.44120073, + "z": -187.104324 + }, + { + "x": -393.2641, + "y": 13.4295111, + "z": -463.9972 + }, + { + "x": -460.000519, + "y": 15.1067963, + "z": -460.3208 + }, + { + "x": 150.440338, + "y": 11.39805, + "z": -245.718033 + }, + { + "x": 321.049866, + "y": -10.5961428, + "z": 321.119019 + }, + { + "x": 332.753052, + "y": -12.5168514, + "z": 233.0787 + }, + { + "x": -475.572571, + "y": 15.6033182, + "z": -485.036865 + }, + { + "x": 64.2127, + "y": 34.08129, + "z": -347.296631 + }, + { + "x": -376.822418, + "y": 12.6085739, + "z": -494.413025 + }, + { + "x": -503.204834, + "y": 11.5744905, + "z": -485.498871 + }, + { + "x": 359.0837, + "y": -6.3338685, + "z": 66.74757 + }, + { + "x": 384.366516, + "y": -14.0767221, + "z": 211.104614 + }, + { + "x": -363.5584, + "y": 11.1137409, + "z": -545.356445 + }, + { + "x": -342.406, + "y": 9.84198, + "z": -554.570251 + }, + { + "x": -325.7032, + "y": 9.841121, + "z": -561.30304 + }, + { + "x": 397.3366, + "y": -6.360728, + "z": 56.2292328 + }, + { + "x": 198.63533, + "y": 28.4436016, + "z": -327.362152 + }, + { + "x": 419.818359, + "y": -15.733121899999999, + "z": 263.8511 + }, + { + "x": 183.154312, + "y": 17.3547249, + "z": -356.9713 + }, + { + "x": 225.707382, + "y": 25.55102, + "z": -316.272156 + }, + { + "x": -291.990234, + "y": 10.5934067, + "z": -581.269348 + }, + { + "x": 438.246429, + "y": -17.6965561, + "z": 283.138275 + }, + { + "x": 272.682129, + "y": 10.78617, + "z": -278.433929 + }, + { + "x": -265.428162, + "y": 11.0340672, + "z": -587.643066 + }, + { + "x": 391.62207, + "y": -1.5557944799999999, + "z": -83.4359055 + }, + { + "x": 236.677338, + "y": 28.3932362, + "z": -333.42572 + }, + { + "x": 459.435822, + "y": -17.6098919, + "z": 236.483841 + }, + { + "x": 443.479553, + "y": -8.517115, + "z": 51.0366745 + }, + { + "x": 458.2012, + "y": -18.5950489, + "z": 274.239471 + }, + { + "x": 397.907166, + "y": -1.2649157, + "z": -103.177422 + }, + { + "x": 450.1929, + "y": -9.5312262, + "z": 72.72984 + }, + { + "x": 191.69812, + "y": 16.5970421, + "z": -403.895325 + }, + { + "x": 119.32357, + "y": 16.1197472, + "z": -464.643066 + }, + { + "x": 460.334259, + "y": -10.4513264, + "z": 88.24868 + }, + { + "x": 139.936264, + "y": 15.688638699999998, + "z": -452.16272 + }, + { + "x": -259.789856, + "y": 12.6040115, + "z": -619.618958 + }, + { + "x": 474.6707, + "y": -14.8565722, + "z": 182.078461 + }, + { + "x": 344.15, + "y": 11.455224, + "z": -236.172928 + }, + { + "x": 473.9984, + "y": -13.3583174, + "z": 143.817062 + }, + { + "x": 113.907272, + "y": 12.5399017, + "z": -496.1842 + }, + { + "x": -220.563034, + "y": 12.9895353, + "z": -637.5554 + }, + { + "x": -101.616692, + "y": 8.488135, + "z": -618.0946 + }, + { + "x": 444.893982, + "y": -3.08344579, + "z": -118.232773 + }, + { + "x": -74.43431, + "y": 8.262597, + "z": -614.8273 + }, + { + "x": 367.111145, + "y": 14.7752094, + "z": -291.6535 + }, + { + "x": 107.839539, + "y": 9.87871, + "z": -545.37854 + }, + { + "x": -182.603683, + "y": 13.0685749, + "z": -662.7072 + }, + { + "x": 405.5572, + "y": 10.028961, + "z": -244.471786 + }, + { + "x": 357.372528, + "y": 17.9918385, + "z": -329.917847 + }, + { + "x": 122.562515, + "y": 8.610595, + "z": -563.561157 + }, + { + "x": -136.890182, + "y": 11.0281343, + "z": -682.508362 + }, + { + "x": -72.1027756, + "y": 8.2830224, + "z": -669.3367 + }, + { + "x": 32.444046, + "y": 8.211728, + "z": -630.614441 + }, + { + "x": 160.3424, + "y": 8.988352, + "z": -583.2388 + }, + { + "x": 51.9643135, + "y": 8.49915266, + "z": -660.1815 + }, + { + "x": 116.752419, + "y": 8.309252260000001, + "z": -648.1417 + }, + { + "x": 82.0800552, + "y": 8.33903027, + "z": -670.472961 + }, + { + "x": 304.846924, + "y": 23.6567, + "z": -611.956238 + }, + { + "x": 288.239624, + "y": 11.9912653, + "z": -563.44696 + }, + { + "x": 263.664825, + "y": 11.0223513, + "z": -549.5286 + }, + { + "x": 247.731781, + "y": 23.6235847, + "z": -432.028 + }, + { + "x": -7.00850534, + "y": 24.25184, + "z": -349.347656 + }, + { + "x": -48.5930557, + "y": 27.1022758, + "z": -366.4513 + }, + { + "x": -61.04769, + "y": 25.3034344, + "z": -299.036621 + }, + { + "x": -69.37161, + "y": 20.41965, + "z": -227.808273 + }, + { + "x": -136.658539, + "y": 34.5381241, + "z": -173.0647 + }, + { + "x": -550.546448, + "y": 15.6613741, + "z": -348.551636 + }, + { + "x": -494.7869, + "y": 15.3486805, + "z": -361.663 + } + ], + "sandbox": [ + { + "x": 45.7849464, + "y": 31.4172344, + "z": 146.52832 + }, + { + "x": 53.1306534, + "y": 31.4432926, + "z": 156.713211 + }, + { + "x": -48.11573, + "y": 24.6952629, + "z": 41.3987045 + }, + { + "x": -26.8314362, + "y": 24.6952629, + "z": 15.1404734 + } + ], + "sandbox_high": [ + { + "x": 45.7849464, + "y": 31.4172344, + "z": 146.52832 + }, + { + "x": 53.1306534, + "y": 31.4432926, + "z": 156.713211 + }, + { + "x": -48.11573, + "y": 24.6952629, + "z": 41.3987045 + }, + { + "x": -26.8314362, + "y": 24.6952629, + "z": 15.1404734 + }, + { + "x": 133.664734, + "y": 33.38064, + "z": 270.2769 + }, + { + "x": 112.163437, + "y": 33.3814163, + "z": 262.532 + }, + { + "x": 119.5076, + "y": 33.3750648, + "z": 292.139618 + }, + { + "x": 121.115387, + "y": 28.6773, + "z": 294.436523 + }, + { + "x": 119.409904, + "y": 23.96636, + "z": 292.651276 + }, + { + "x": 56.0442772, + "y": 23.2307186, + "z": 307.866364 + }, + { + "x": -7.96754551, + "y": 23.2979832, + "z": 329.9379 + }, + { + "x": 121.245872, + "y": 23.79131, + "z": 189.152176 + }, + { + "x": 93.13055, + "y": 27.789999, + "z": 220.553284 + }, + { + "x": 114.605194, + "y": 28.1641, + "z": 204.578232 + }, + { + "x": -19.0984421, + "y": 30.2464314, + "z": 84.90695 + }, + { + "x": -17.9085331, + "y": 30.2359924, + "z": 68.8605347 + }, + { + "x": -27.0813961, + "y": 30.2359924, + "z": 90.11642 + }, + { + "x": -42.79469, + "y": 30.1973877, + "z": 61.4844437 + }, + { + "x": 159.183121, + "y": 17.4658852, + "z": 9.621948 + }, + { + "x": 172.266251, + "y": 17.4887581, + "z": 33.6692543 + }, + { + "x": 105.27861, + "y": 29.41094, + "z": 155.103775 + }, + { + "x": 117.891991, + "y": 29.41094, + "z": 153.8198 + }, + { + "x": 126.5935, + "y": 29.45413, + "z": 164.84436 + } + ] +} \ No newline at end of file diff --git a/src/Spawns/index.ts b/src/Spawns/index.ts new file mode 100644 index 0000000..1bef436 --- /dev/null +++ b/src/Spawns/index.ts @@ -0,0 +1,4 @@ +// context/index.js +export { default as PlayerSpawns } from "./playerSpawns.json"; +export { default as BotSpawns } from "./botSpawns.json"; +export { default as SniperSpawns } from "./sniperSpawns.json"; diff --git a/src/Spawns/playerSpawns.json b/src/Spawns/playerSpawns.json new file mode 100644 index 0000000..bdb899f --- /dev/null +++ b/src/Spawns/playerSpawns.json @@ -0,0 +1,170 @@ +{ + "bigmap": [ + { + "x": -284.638641, + "y": -0.8085841, + "z": -51.5765533 + }, + { + "x": -2.39736366, + "y": -5.3431716, + "z": 128.833954 + }, + { + "x": 671.046265, + "y": 6.96879864, + "z": 78.8503342 + }, + { + "x": 402.660858, + "y": 13.4239016, + "z": 215.8655 + } + ], + "factory4_day": [], + "factory4_night": [], + "interchange": [], + "laboratory": [], + "lighthouse": [ + { + "x": 120.764587, + "y": 1.729217, + "z": 389.5385 + }, + { + "x": -134.055984, + "y": 22.3044567, + "z": 301.3149 + } + ], + "rezervbase": [], + "shoreline": [ + { + "x": 255.101135, + "y": -53.634388, + "z": -104.88662 + }, + { + "x": 247.563934, + "y": -64.2936859, + "z": 450.9826 + }, + { + "x": -629.215759, + "y": -21.0713081, + "z": -325.424957 + }, + { + "x": -636.5035, + "y": -39.57397, + "z": -12.2949867 + }, + { + "x": 171.53833, + "y": -34.23907, + "z": -299.059479 + } + ], + "tarkovstreets": [], + "woods": [ + { + "x": 104.282555, + "y": 17.1939659, + "z": -842.5501 + }, + { + "x": -253.314621, + "y": 18.64557, + "z": -656.4694 + }, + { + "x": -645.2799, + "y": 10.5486507, + "z": -271.707245 + }, + { + "x": -525.376465, + "y": 7.752978, + "z": 146.6656 + }, + { + "x": 261.598236, + "y": -9.6038618, + "z": 323.6364 + } + ], + "sandbox": [ + { + "x": -16.5156174, + "y": 23.2638969, + "z": 329.840424 + }, + { + "x": 148.870621, + "y": 23.2307129, + "z": 253.958176 + }, + { + "x": 214.353683, + "y": 16.550972, + "z": 37.1321335 + }, + { + "x": 112.585724, + "y": 28.2153511, + "z": 176.645386 + }, + { + "x": 125.6806, + "y": 29.437418, + "z": 113.8275 + }, + { + "x": 102.72731, + "y": 28.6717739, + "z": 314.5687 + }, + { + "x": 99.01148, + "y": 15.1962032, + "z": 41.1899948 + } + ], + "sandbox_high": [ + { + "x": -16.5156174, + "y": 23.2638969, + "z": 329.840424 + }, + { + "x": 148.870621, + "y": 23.2307129, + "z": 253.958176 + }, + { + "x": 214.353683, + "y": 16.550972, + "z": 37.1321335 + }, + { + "x": 112.585724, + "y": 28.2153511, + "z": 176.645386 + }, + { + "x": 125.6806, + "y": 29.437418, + "z": 113.8275 + }, + { + "x": 102.72731, + "y": 28.6717739, + "z": 314.5687 + }, + { + "x": 99.01148, + "y": 15.1962032, + "z": 41.1899948 + } + ] +} \ No newline at end of file diff --git a/src/Spawns/sniperSpawns.json b/src/Spawns/sniperSpawns.json new file mode 100644 index 0000000..c569f12 --- /dev/null +++ b/src/Spawns/sniperSpawns.json @@ -0,0 +1,93 @@ +{ + "bigmap": [ + { + "x": 369.272278, + "y": 11.2302418, + "z": -72.96668 + }, + { + "x": 197.6982, + "y": 20.6448269, + "z": -99.9941 + }, + { + "x": 655.7491, + "y": 13.0718241, + "z": 5.93848372 + }, + { + "x": -121.7867, + "y": 5.632545, + "z": -0.798637152 + }, + { + "x": 421.84375, + "y": 22.7934837, + "z": 212.3183 + } + ], + "factory4_day": [], + "factory4_night": [], + "interchange": [], + "laboratory": [], + "lighthouse": [ + { + "x": 52.6982346, + "y": 36.2576866, + "z": -66.2429047 + }, + { + "x": -50.28446, + "y": 25.192667, + "z": 108.342476 + }, + { + "x": -186.507446, + "y": 34.5950928, + "z": -155.675827 + } + ], + "rezervbase": [], + "shoreline": [ + { + "x": 386.443848, + "y": -49.36506, + "z": 281.6941 + }, + { + "x": -97.2247849, + "y": -33.9793243, + "z": 345.60022 + }, + { + "x": -600.110352, + "y": -21.88225, + "z": -178.341492 + }, + { + "x": -58.79216, + "y": -4.279404, + "z": -385.828857 + }, + { + "x": -0.367416143, + "y": -31.33284, + "z": 247.632156 + } + ], + "tarkovstreets": [], + "woods": [ + { + "x": -526.0752, + "y": 20.1364822, + "z": -134.8717 + }, + { + "x": 44.6502228, + "y": 4.92170954, + "z": 7.110855 + } + ], + "sandbox": [], + "sandbox_high": [] +} \ No newline at end of file diff --git a/src/Spawns/updateUtils.ts b/src/Spawns/updateUtils.ts new file mode 100644 index 0000000..68f0981 --- /dev/null +++ b/src/Spawns/updateUtils.ts @@ -0,0 +1,137 @@ +import { Ixyz } from "@spt/models/eft/common/Ixyz"; +import getSortedSpawnPointList, { + getDistance, +} from "../Spawning/spawnZoneUtils"; + +const fs = require("fs"); +const path = require("path"); +const currentDirectory = process.cwd(); +// Function to update JSON file +export const updateJsonFile = ( + filePath: string, + callback: (jsonData) => void, + successMessage: string +) => { + // Read the JSON file + fs.readFile(filePath, "utf8", (err, data) => { + if (err) { + console.error("Error reading the file:", err); + return; + } + + // Parse the JSON data + let jsonData; + try { + jsonData = JSON.parse(data); + } catch (parseError) { + console.error("Error parsing JSON data:", parseError); + return; + } + + callback(jsonData); + + // Update the JSON object + + // Write the updated JSON object back to the file + fs.writeFile( + filePath, + JSON.stringify(jsonData, null, 2), + "utf8", + (writeError) => { + if (writeError) { + console.error("Error writing the file:", writeError); + return; + } + + console.log(successMessage); + } + ); + }); +}; + +export const updateBotSpawn = (map: string, value: Ixyz) => { + map = map.toLowerCase(); + updateJsonFile( + currentDirectory + "/user/mods/DewardianDev-MOAR/src/Spawns/botSpawns.json", + (jsonData) => { + value.y = value.y + 0.5; + if (jsonData[map]) { + jsonData[map].push(value); + } else { + jsonData[map] = [value]; + } + }, + "Successfully added one bot spawn to " + map + ); +}; + +export const deleteBotSpawn = (map: string, value: Ixyz) => { + map = map.toLowerCase(); + updateJsonFile( + currentDirectory + "/user/mods/DewardianDev-MOAR/src/Spawns/botSpawns.json", + (jsonData) => { + if (jsonData[map]) { + const { x: X, y: Y, z: Z } = value; + let nearest = undefined; + let nearDist = Infinity; + jsonData[map].forEach(({ x, y, z }, index) => { + const dist = getDistance(x, y, z, X, Y, Z); + if (dist < nearDist) { + nearest = index; + nearDist = dist; + } + }); + + if (nearest) { + (jsonData[map] as Ixyz[]).splice(nearest, 1); + } else { + console.log("No nearest spawn on " + map); + } + } + }, + "Successfully removed one bot spawn from " + ); +}; + +export const updatePlayerSpawn = (map: string, value: Ixyz) => { + map = map.toLowerCase(); + updateJsonFile( + currentDirectory + + "/user/mods/DewardianDev-MOAR/src/Spawns/playerSpawns.json", + (jsonData) => { + value.y = value.y + 0.5; + if (jsonData[map]) { + jsonData[map].push(value); + } else { + jsonData[map] = [value]; + } + }, + "Successfully added one player spawn to " + map + ); +}; + +export const updateSniperSpawn = (map: string, value: Ixyz) => { + map = map.toLowerCase(); + updateJsonFile( + currentDirectory + + "/user/mods/DewardianDev-MOAR/src/Spawns/sniperSpawns.json", + (jsonData) => { + value.y = value.y + 0.5; + if (jsonData[map]) { + jsonData[map].push(value); + } else { + jsonData[map] = [value]; + } + }, + "Successfully added one player spawn to " + map + ); +}; + +export const updateAllBotSpawns = (values: Record) => + updateJsonFile( + currentDirectory + "/user/mods/DewardianDev-MOAR/src/Spawns/botSpawns.json", + (jsonData) => { + Object.keys(jsonData).forEach((map) => (jsonData[map] = values[map])); + }, + "Successfully updated all Spawns" + ); diff --git a/src/mod.js b/src/mod.js index 8a28dfa..26565ec 100644 --- a/src/mod.js +++ b/src/mod.js @@ -14,6 +14,14 @@ class Moar { preSptLoad(container) { if (config_json_1.enableBotSpawning) { (0, routes_1.setupRoutes)(container); + // Object.keys(BotSpawns).forEach((map) => { + // BotSpawns[map] = BotSpawns[map].map(({ x, y, z }) => ({ + // x, + // y: y + 0.4, + // z, + // })); + // }); + // updateAllBotSpawns(BotSpawns); } } postDBLoad(container) { diff --git a/src/mod.js.map b/src/mod.js.map index 4576474..24d421a 100644 --- a/src/mod.js.map +++ b/src/mod.js.map @@ -1 +1 @@ -{"version":3,"file":"mod.js","sourceRoot":"","sources":["mod.ts"],"names":[],"mappings":";;;;;AAIA,uDAA0D;AAC1D,kDAAiD;AACjD,wEAA2C;AAC3C,iDAA8C;AAE9C,4CAA8C;AAC9C,wEAAoD;AACpD,8DAA4D;AAE5D,MAAM,IAAI;IACR,UAAU,CAAC,SAA8B;QACvC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,UAAU,CAAC,SAA8B;QACvC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,wBAAW,EAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,SAA8B;QACxC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,sBAAgB,EAAC,SAAS,CAAC,CAAC;YAC5B,2BAAY,CAAC,UAAU,GAAG,qBAAM,CAAC;YACjC,2BAAY,CAAC,cAAc,GAAG,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC3E,IAAA,qBAAU,EAAC,SAAS,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"mod.js","sourceRoot":"","sources":["mod.ts"],"names":[],"mappings":";;;;;AAIA,uDAA0D;AAC1D,kDAAiD;AACjD,wEAA2C;AAC3C,iDAA8C;AAE9C,4CAA8C;AAC9C,wEAAoD;AACpD,8DAA4D;AAK5D,MAAM,IAAI;IACR,UAAU,CAAC,SAA8B;QACvC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,oBAAW,EAAC,SAAS,CAAC,CAAC;YACvB,4CAA4C;YAC5C,4DAA4D;YAC5D,SAAS;YACT,kBAAkB;YAClB,SAAS;YACT,SAAS;YACT,MAAM;YACN,iCAAiC;QACnC,CAAC;IACH,CAAC;IAED,UAAU,CAAC,SAA8B;QACvC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,wBAAW,EAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,WAAW,CAAC,SAA8B;QACxC,IAAI,+BAAiB,EAAE,CAAC;YACtB,IAAA,sBAAgB,EAAC,SAAS,CAAC,CAAC;YAC5B,2BAAY,CAAC,UAAU,GAAG,qBAAM,CAAC;YACjC,2BAAY,CAAC,cAAc,GAAG,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAI,CACT,6DAA6D,CAC9D,CAAC;YACF,IAAA,qBAAU,EAAC,SAAS,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC"} \ No newline at end of file diff --git a/src/mod.ts b/src/mod.ts index e4e9c53..c58722e 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -10,11 +10,22 @@ import { ILogger } from "@spt/models/spt/utils/ILogger"; import { setupRoutes } from "./Routes/routes"; import checkPresetLogic from "./Tests/checkPresets"; import { setupSpawns } from "./SpawnZoneChanges/setupSpawn"; +import { saveToFile } from "./utils"; +import { deleteBotSpawn, updateAllBotSpawns } from "./Spawns/updateUtils"; +import { BotSpawns } from "./Spawns"; class Moar implements IPostSptLoadMod, IPreSptLoadMod, IPostDBLoadMod { preSptLoad(container: DependencyContainer): void { if (enableBotSpawning) { setupRoutes(container); + // Object.keys(BotSpawns).forEach((map) => { + // BotSpawns[map] = BotSpawns[map].map(({ x, y, z }) => ({ + // x, + // y: y + 0.4, + // z, + // })); + // }); + // updateAllBotSpawns(BotSpawns); } } @@ -30,7 +41,9 @@ class Moar implements IPostSptLoadMod, IPreSptLoadMod, IPostDBLoadMod { globalValues.baseConfig = config; globalValues.overrideConfig = {}; const logger = container.resolve("WinstonLogger"); - logger.info("\n[MOAR]: Starting up, may the bots ever be in your favour!"); + logger.info( + "\n[MOAR]: Starting up, may the bots ever be in your favour!" + ); buildWaves(container); } } diff --git a/src/utils.js.map b/src/utils.js.map index b158567..cd7c497 100644 --- a/src/utils.js.map +++ b/src/utils.js.map @@ -1 +1 @@ -{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":";;;;;;AAAA,4FAA+D;AAC/D,0EAA6C;AAC7C,iDAA8C;AAEvC,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;IAC3C,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,IAAI,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAChD,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAC9B,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC;IACrC,EAAE,CAAC,SAAS,CACV,SAAS,GAAG,QAAQ,EACpB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAC7B,UAAU,GAAG;QACX,IAAI,GAAG;YAAE,MAAM,GAAG,CAAC;IACrB,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAdW,QAAA,UAAU,cAcrB;AAEK,MAAM,SAAS,GAAG,CAAC,aAAkB,EAAE,EAAE,CAC9C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAD/B,QAAA,SAAS,aACsB;AAErC,MAAM,wCAAwC,GAAG,GAAG,EAAE;IAC3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,2BAAY,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,QAAQ;YACvD,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,2BAAY,CAAC,YAAY;YAC7B,2BAAY,CAAC,YAAY,GAAG,QAAQ,CAAC;YACrC,MAAM;QACR,KAAK,2BAAY,CAAC,YAAY,KAAK,QAAQ;YACzC,MAAM;QAER;YACE,OAAO,sBAAO,CAAC,2BAAY,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC;IAEf,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,+BAAgB,CAAC,CAAC;IAE/C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,+BAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAW,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,2BAAY,CAAC,aAAa,GAAG,MAAM,CAAC;IACpC,OAAO,sBAAO,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC,CAAC;AA3BW,QAAA,wCAAwC,4CA2BnD;AAEK,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAClD,GAAG;KACA,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC7D,IAAI,CAAC,GAAG,CAAC,CAAC;AAJF,QAAA,YAAY,gBAIV"} \ No newline at end of file +{"version":3,"file":"utils.js","sourceRoot":"","sources":["utils.ts"],"names":[],"mappings":";;;;;;AAAA,4FAA+D;AAC/D,0EAA6C;AAC7C,iDAA8C;AAEvC,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;IAC3C,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,IAAI,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAChF,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC;IACvC,EAAE,CAAC,SAAS,CACV,SAAS,GAAG,QAAQ,EACpB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAC7B,UAAU,GAAG;QACX,IAAI,GAAG;YAAE,MAAM,GAAG,CAAC;IACrB,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAbW,QAAA,UAAU,cAarB;AAEK,MAAM,SAAS,GAAG,CAAC,aAAkB,EAAE,EAAE,CAC9C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAD/B,QAAA,SAAS,aACsB;AAErC,MAAM,wCAAwC,GAAG,GAAG,EAAE;IAC3D,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,2BAAY,CAAC,YAAY,CAAC,WAAW,EAAE,KAAK,QAAQ;YACvD,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,2BAAY,CAAC,YAAY;YAC7B,2BAAY,CAAC,YAAY,GAAG,QAAQ,CAAC;YACrC,MAAM;QACR,KAAK,2BAAY,CAAC,YAAY,KAAK,QAAQ;YACzC,MAAM;QAER;YACE,OAAO,sBAAO,CAAC,2BAAY,CAAC,YAAY,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,GAAG,GAAG,EAAE,CAAC;IAEf,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,+BAAgB,CAAC,CAAC;IAE/C,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,+BAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAW,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,2BAAY,CAAC,aAAa,GAAG,MAAM,CAAC;IACpC,OAAO,sBAAO,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC,CAAC;AA3BW,QAAA,wCAAwC,4CA2BnD;AAEK,MAAM,YAAY,GAAG,CAAC,GAAW,EAAU,EAAE,CAClD,GAAG;KACA,KAAK,CAAC,GAAG,CAAC;KACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KAC7D,IAAI,CAAC,GAAG,CAAC,CAAC;AAJF,QAAA,YAAY,gBAIV"} \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index 7f8a3bc..a72f393 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,9 +6,8 @@ export const saveToFile = (data, filePath) => { var fs = require("fs"); let dir = __dirname; let dirArray = dir.split("\\"); - const directory = `${dirArray[dirArray.length - 4]}/${ - dirArray[dirArray.length - 3] - }/${dirArray[dirArray.length - 2]}/`; + const directory = `${dirArray[dirArray.length - 4]}/${dirArray[dirArray.length - 3] + }/${dirArray[dirArray.length - 2]}/`; fs.writeFile( directory + filePath, JSON.stringify(data, null, 4),