Downgraded MOAR & Updated ModOrganizer.ini

This commit is contained in:
2025-01-03 03:29:19 -05:00
parent 3e8f90cd1a
commit b3cab2e572
37 changed files with 114 additions and 2594 deletions
+2 -2
View File
@@ -1,11 +1,11 @@
[General]
gameName=spt
modid=0
version=d2025.1.2.0
version=d2024.12.31.0
newestVersion=
category="1,"
nexusFileStatus=1
installationFile=DewardianDev-MOAR-2.6.5.zip
installationFile=DewardianDev-MOAR-2.6.1.zip
repository=Nexus
ignoredVersion=
comments=
@@ -1,19 +1,15 @@
{
"enableBotSpawning": true,
"pmcDifficulty": 0.6,
"scavDifficulty": 0.4,
"pmcDifficulty": 0.3,
"scavDifficulty": 0.3,
"scavWaveDistribution": 0.5,
"scavWaveQuantity": 1,
"startingPmcs": false,
"playerOpenZones": true,
"pmcOpenZones": true,
"allOpenZones": false,
"pmcWaveDistribution": 0.7,
"pmcWaveDistribution": 0.8,
"pmcWaveQuantity": 1,
"zombiesEnabled": false,
@@ -22,7 +18,7 @@
"zombieHealth": 1,
"maxBotCap": 25,
"maxBotPerZone": 5,
"maxBotPerZone": 7,
"moreScavGroups": false,
"morePmcGroups": false,
@@ -1,6 +1,6 @@
{
"name": "MOAR",
"version": "2.6.5",
"version": "2.6.1",
"main": "src/mod.js",
"license": "MIT",
"author": "DewardianDev",
@@ -7,11 +7,7 @@ import { ConfigServer } from "@spt/servers/ConfigServer";
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { DependencyContainer } from "tsyringe";
import { globalValues } from "../GlobalValues";
import {
cloneDeep,
getRandomPresetOrCurrentlySelectedPreset,
saveToFile,
} from "../utils";
import { cloneDeep, getRandomPresetOrCurrentlySelectedPreset } from "../utils";
import { ILocationConfig } from "@spt/models/spt/config/ILocationConfig.d";
import { originalMapList } from "./constants";
import { buildBossWaves } from "./buildBossWaves";
@@ -131,7 +127,7 @@ export const buildWaves = (container: DependencyContainer) => {
rezervbase: { pmcbot: { min: 0, max: 0 } },
};
updateSpawnLocations(locationList, config);
updateSpawnLocations(locationList);
setEscapeTimeOverrides(locationList, _mapConfig, Logger, config);
@@ -147,7 +143,7 @@ export const buildWaves = (container: DependencyContainer) => {
}
buildPmcs(config, locationList);
originalMapList.forEach((name, index) => {
if (!locations[name]) {
console.log("[MOAR] OH CRAP we have a problem!", name);
@@ -30,21 +30,25 @@ export default function buildPmcs(
.filter(
({ Categories, BotZoneName }) =>
!!BotZoneName &&
!BotZoneName.includes("snipe") &&
(Categories.includes("Player") || Categories.includes("All")) &&
!BotZoneName.includes("BotZoneGate")
(Categories.includes("Player") ||
(map === "laboratory" &&
!BotZoneName.includes("BotZoneGate"))) &&
!BotZoneName.includes("snipe")
)
.map(({ BotZoneName, ...rest }) => {
return BotZoneName;
})
),
...pmcHotZones,
]);
// Make labs have only named zones
if (map === "laboratory") {
pmcZones = new Array(10).fill(pmcZones).flat(1);
// console.log(pmcZones);
}
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
const { pmcWaveCount } = mapConfig[map];
const escapeTimeLimitRatio = Math.round(
@@ -54,12 +58,13 @@ export default function buildPmcs(
const totalWaves = Math.round(
pmcWaveCount * config.pmcWaveQuantity * escapeTimeLimitRatio
);
// console.log(pmcZones.length, totalWaves);
const numberOfZoneless = totalWaves - pmcZones.length;
if (numberOfZoneless > 0) {
const addEmpty = new Array(numberOfZoneless).fill("");
pmcZones = shuffle<string[]>([...pmcZones, ...addEmpty]);
}
// if (map === "laboratory") console.log(numberOfZoneless, pmcZones);
if (config.debug) {
console.log(`${map} PMC count ${totalWaves} \n`);
@@ -70,16 +75,10 @@ export default function buildPmcs(
);
}
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
const waves = buildPmcWaves(
totalWaves,
timeLimit,
config,
pmcZones,
pmcHotZones
);
const waves = buildPmcWaves(pmcWaveCount, timeLimit, config, pmcZones);
// if (map === "laboratory")
// console.log(waves.map(({ BossZone }) => BossZone));
// apply our new waves
locationList[index].base.BossLocationSpawn = [
...waves,
...locationList[index].base.BossLocationSpawn,
@@ -89,16 +89,19 @@ export default function buildScavMarksmanWaves(
const sniperLocations = new Set(
[...locationList[index].base.SpawnPointParams]
.filter(
({ Categories, DelayToCanSpawnSec, BotZoneName, Sides }) =>
!Categories.includes("Boss") &&
Sides[0] === "Savage" &&
(BotZoneName?.toLowerCase().includes("snipe") ||
DelayToCanSpawnSec > 40)
({ Categories, Sides, BotZoneName }) =>
!!BotZoneName &&
Sides.includes("Savage") &&
!Categories.includes("Boss")
)
.map(({ BotZoneName }) => BotZoneName || "")
.filter(
({ BotZoneName, DelayToCanSpawnSec }) =>
BotZoneName?.toLowerCase().includes("snipe") ||
DelayToCanSpawnSec > 300
)
.map(({ BotZoneName }) => BotZoneName)
);
if (sniperLocations.size) {
locationList[index].base.MinMaxBots = [
{
@@ -109,21 +112,32 @@ export default function buildScavMarksmanWaves(
];
}
let scavZones = shuffle<string[]>([
const scavZones = shuffle<string[]>([
...new Set(
[...locationList[index].base.SpawnPointParams]
.filter(
({ Categories, Sides, BotZoneName }) =>
!!BotZoneName &&
Categories.includes("Bot") &&
(Sides.includes("Savage") || Sides.includes("All"))
Sides.includes("Savage") &&
!Categories.includes("Boss")
)
.map(({ BotZoneName }) => BotZoneName)
.filter((name) => !sniperLocations.has(name))
),
]);
// Reduced Zone Delay
locationList[index].base.SpawnPointParams = locationList[
index
].base.SpawnPointParams.map((spawn) => ({
...spawn,
DelayToCanSpawnSec:
spawn.DelayToCanSpawnSec > 20
? Math.round(spawn.DelayToCanSpawnSec / 10)
: spawn.DelayToCanSpawnSec,
}));
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
const { scavWaveCount } = mapConfig[map];
const escapeTimeLimitRatio = Math.round(
@@ -135,19 +149,12 @@ export default function buildScavMarksmanWaves(
scavWaveCount * scavWaveQuantity * escapeTimeLimitRatio
);
const numberOfZoneless = scavTotalWaveCount - scavZones.length;
// console.log(numberOfZoneless);
if (numberOfZoneless > 0) {
const addEmpty = new Array(numberOfZoneless).fill("");
scavZones = shuffle<string[]>([...scavZones, ...addEmpty]);
}
// console.log(scavZones);
config.debug &&
escapeTimeLimitRatio !== 1 &&
console.log(
`${map} Scav wave count changed from ${scavWaveCount} to ${scavTotalWaveCount} due to escapeTimeLimit adjustment`
);
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
let snipers = waveBuilder(
sniperLocations.size,
Math.round(timeLimit / 4),
@@ -159,13 +166,14 @@ export default function buildScavMarksmanWaves(
[],
shuffle([...sniperLocations]),
80,
true,
false,
true
);
if (snipersHaveFriends)
snipers = snipers.map((wave) => ({
...wave,
slots_min: 0,
...(snipersHaveFriends && wave.slots_max < 2
? { slots_min: 1, slots_max: 2 }
: {}),
@@ -1,126 +1,36 @@
import { ILocation } from "@spt/models/eft/common/ILocation";
import { configLocations } from "./constants";
import mapConfig from "../../config/mapConfig.json";
import _config from "../../config/config.json";
export default function updateSpawnLocations(
locationList: ILocation[],
config: typeof _config
) {
export default function updateSpawnLocations(locationList: ILocation[]) {
for (let index = 0; index < locationList.length; index++) {
const map = configLocations[index];
// console.log(map);
const limit = mapConfig[map].spawnMinDistance;
const InfiltrationList = [
...new Set(
locationList[index].base.SpawnPointParams.filter(
({ Infiltration }) => Infiltration
).map(({ Infiltration }) => Infiltration)
),
];
// console.log(map, InfiltrationList);
const getRandomInfil = (): string =>
InfiltrationList[Math.floor(Math.random() * InfiltrationList.length)];
// console.log(InfiltrationList);
// console.log("\n" + map);
locationList[index].base.SpawnPointParams.forEach(
(
{
ColliderParams,
BotZoneName,
DelayToCanSpawnSec,
Categories,
Sides,
Infiltration,
},
{ ColliderParams, BotZoneName, DelayToCanSpawnSec, Categories, Sides },
innerIndex
) => {
if (
!Categories.includes("Boss") &&
ColliderParams?._props?.Radius !== undefined &&
ColliderParams?._props?.Radius < limit &&
!BotZoneName?.toLowerCase().includes("snipe") &&
DelayToCanSpawnSec < 41
DelayToCanSpawnSec < 300
) {
// Make it so players/pmcs can spawn anywhere.
if (
config.playerOpenZones &&
!!Infiltration &&
(Sides.includes("Pmc") || Sides.includes("All"))
) {
locationList[index].base.SpawnPointParams[innerIndex].Categories = [
"Player",
"Coop",
innerIndex % 2 === 0 ? "Group" : "Opposite",
];
// console.log(
// "----",
// ColliderParams._props.Radius,
// "=>",
// limit,
// BotZoneName
// );
locationList[index].base.SpawnPointParams[innerIndex].Sides = [
"Pmc",
"All",
];
// console.log(
// BotZoneName || "none",
// locationList[index].base.SpawnPointParams[innerIndex].Categories,
// locationList[index].base.SpawnPointParams[innerIndex].Sides
// );
}
if (
!config.allOpenZones &&
config.pmcOpenZones &&
Categories.includes("Bot") &&
Sides[0] === "Savage" &&
!Infiltration
) {
locationList[index].base.SpawnPointParams[innerIndex].Categories = [
"Player",
"Bot",
];
}
if (!Infiltration && config.allOpenZones) {
locationList[index].base.SpawnPointParams[innerIndex].Categories = [
"Bot",
"Player",
"Coop",
innerIndex % 2 === 0 ? "Group" : "Opposite",
];
locationList[index].base.SpawnPointParams[innerIndex].Infiltration =
getRandomInfil();
// console.log(
// locationList[index].base.SpawnPointParams[innerIndex].Infiltration
// );
locationList[index].base.SpawnPointParams[innerIndex].Sides = [
"Pmc",
"Savage",
"All",
];
}
if (
ColliderParams?._props?.Radius !== undefined &&
ColliderParams?._props?.Radius < limit
) {
locationList[index].base.SpawnPointParams[
innerIndex
].ColliderParams._props.Radius = limit;
}
} else {
if (!Categories.includes("Boss") && DelayToCanSpawnSec > 40) {
locationList[index].base.SpawnPointParams[
innerIndex
].DelayToCanSpawnSec = Math.round(
DelayToCanSpawnSec * Math.random() * Math.random() * 0.5
);
// console.log(
// BotZoneName,
// DelayToCanSpawnSec,
// locationList[index].base.SpawnPointParams[innerIndex]
// .DelayToCanSpawnSec
// );
}
locationList[index].base.SpawnPointParams[
innerIndex
].ColliderParams._props.Radius = limit;
}
}
);
@@ -44,7 +44,7 @@ export const waveBuilder = (
);
const min = !offset && waves.length < 1 ? 0 : timeStart;
const max = !offset && waves.length < 1 ? 0 : timeStart + 60;
const max = !offset && waves.length < 1 ? 0 : timeStart + 10;
if (waves.length >= 1 || offset) timeStart = timeStart + stage;
const BotPreset = getDifficulty(difficulty);
@@ -55,9 +55,8 @@ export const waveBuilder = (
);
if (slotMax < 1) slotMax = 1;
let slotMin = (Math.round(Math.random() * slotMax) || 1) - 1;
const slotMin = (Math.round(Math.random() * slotMax) || 1) - 1;
if (wildSpawnType === "marksman" && slotMin < 1) slotMin = 1;
waves.push({
BotPreset,
BotSide: getBotSide(wildSpawnType),
@@ -190,26 +189,11 @@ export const getRandomZombieType = () =>
zombieTypesCaps[Math.round((zombieTypesCaps.length - 1) * Math.random())];
export const buildPmcWaves = (
pmcTotal: number,
totalWaves: number,
escapeTimeLimit: number,
config: typeof _config,
bossZones: string[],
hotZones: string[]
bossZones: string[]
): IBossLocationSpawn[] => {
// console.log(pmcTotal)
if (!pmcTotal) return [];
const halfIndex = Math.round(bossZones.length * 0.75); //Put hotzones in the 2 - 4 spawns
// console.log(bossZones.length);
bossZones = [
...bossZones.slice(0, halfIndex),
...hotZones,
...bossZones.slice(halfIndex),
];
// console.log(bossZones.length, hotZones.length);
// console.log(bossZones);
pmcTotal = pmcTotal + hotZones.length;
let {
pmcMaxGroupSize,
pmcDifficulty,
@@ -218,12 +202,14 @@ export const buildPmcWaves = (
pmcWaveDistribution,
} = config;
const averageTime = (escapeTimeLimit * 0.8) / pmcTotal;
const averageTime = escapeTimeLimit / totalWaves;
const firstHalf = Math.round(averageTime * (1 - pmcWaveDistribution));
const secondHalf = Math.round(averageTime * (1 + pmcWaveDistribution));
let timeStart = -1;
const waves: IBossLocationSpawn[] = [];
let maxSlotsReached = pmcTotal;
let maxSlotsReached = totalWaves;
while (pmcTotal > 0) {
while (totalWaves > 0) {
let bossEscortAmount = Math.round(
(morePmcGroups ? 1 : Math.random()) *
Math.random() *
@@ -231,24 +217,20 @@ export const buildPmcWaves = (
);
if (bossEscortAmount < 0) bossEscortAmount = 0;
const accelerate = totalWaves > 5 && waves.length < totalWaves / 3;
const stage = startingPmcs
? 10
: Math.round(
waves.length < Math.round(totalWaves * 0.5)
? accelerate
? firstHalf / 3
: firstHalf
: secondHalf
);
// const totalCountThisWave = bossEscortAmount + 1;
const totalCountThusFar = pmcTotal - maxSlotsReached;
const timeToUse =
totalCountThusFar < pmcTotal * pmcWaveDistribution
? Math.round(
averageTime * (1 - pmcWaveDistribution) * totalCountThusFar
)
: Math.round(
escapeTimeLimit * (1 - pmcWaveDistribution) +
(1 - pmcWaveDistribution) * totalCountThusFar * averageTime
);
let timeStart =
(startingPmcs ? totalCountThusFar * totalCountThusFar * 3 : timeToUse) ||
-1;
if (waves.length >= 1) timeStart = timeStart + stage;
// console.log(timeStart, BossEscortAmount);
const side = Math.random() > 0.5 ? "pmcBEAR" : "pmcUSEC";
const BossDifficult = getDifficulty(pmcDifficulty);
@@ -278,10 +260,7 @@ export const buildPmcWaves = (
maxSlotsReached -= 1 + bossEscortAmount;
if (maxSlotsReached <= 0) break;
}
// console.log(
// escapeTimeLimit,
// waves.map(({ Time }) => Time)
// );
return waves;
};
@@ -291,7 +270,6 @@ export const buildZombie = (
waveDistribution: number,
BossChance: number = 100
): IBossLocationSpawn[] => {
if (!totalWaves) return [];
const averageTime = (escapeTimeLimit * 60) / totalWaves;
const firstHalf = Math.round(averageTime * (1 - waveDistribution));
const secondHalf = Math.round(averageTime * (1 + waveDistribution));