This commit is contained in:
GetParanoid 2025-07-18 16:05:06 -05:00
parent 25820f46bc
commit 02e1c5c0b9
91 changed files with 8393 additions and 2 deletions

View file

@ -0,0 +1,211 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
Scabbard: [
"54491bb74bdc2d09088b4567",
"57cd379a24597778e7682ecf",
"57e26ea924597715ca604a09",
"57e26fc7245977162a14b800",
"5bc9c1e2d4351e00367fbcf0",
"5c010e350db83400232feec7",
"5c07df7f0db834001b73588a",
"5fc64ea372b0dd78d51159dc",
"601948682627df266209af05",
"63495c500c297e20065a08b1",
],
Backpack: [
"56e335e4d2720b6c058b456d",
"56e33634d2720bd8058b456b",
"59e763f286f7742ee57895da",
"5e997f0b86f7741ac73993e2",
"5f5e45cc5021ce62144be7aa",
"6034d103ca006d2dca39b3f0",
"61b9e1aaef9a1b5d6a79899a",
"628bc7fb408e2b2e9c0801b1",
"628e1ffc83ec92260c0f437f",
],
Headwear: [
"572b7d8524597762b472f9d1",
"572b7fa124597762b472f9d2",
"59e7708286f7742cbd762753",
"59e770f986f7742cbe3164ef",
"59ef13ca86f77445fd0e2483",
"5a43943586f77416ad2f06e2",
"5a43957686f7742a2c2f11b0",
"5aa2b89be5b5b0001569311f",
"5aa2b8d7e5b5b00014028f4a",
"5aa7e276e5b5b000171d0647",
"5ab8f20c86f7745cdb629fb2",
"5b4329075acfc400153b78ff",
"5bd073c986f7747f627e796c",
"5c08f87c0db8340019124324",
"5c0d2727d174af02a012cf58",
"5c0e874186f7745dc7616606",
"5ca20ee186f774799474abc2",
"5d96141523f0ea1b7f2aacab",
"5df8a58286f77412631087ed",
"5e4bfc1586f774264f7582d3",
"5ea05cf85ad9772e6624305d",
"5ea17ca01412a1425304d1c0",
"5f60b34a41e30a4ab12a6947",
"5f60c74e3b85f6263c145586",
"5f99418230835532b445e954",
"5f994730c91ed922dd355de3",
"603618feffd42c541047f771",
"603619720ca681766b6a0fc4",
"60361a7497633951dc245eb4",
"60361b0b5a45383c122086a1",
"60361b5a9a15b10d96792291",
"6040de02647ad86262233012",
"60a7acf20c5cb24b01346648",
"60bf74184a63fc79b60c57f6",
"618aef6d0a5a59657e5f55ee",
"61bca7cda0eae612383adf57",
"61c18db6dfd64163ea78fbb4",
"628e4dd1f477aa12234918aa",
"636270263f2495c26f00b007",
],
FaceCover: [
"572b7fa524597762b747ce82",
"59e7715586f7742ee5789605",
"5b4326435acfc433000ed01d",
"5b432c305acfc40019478128",
"5bd06f5d86f77427101ad47c",
"5bd0716d86f774171822ef4b",
"5bd071d786f7747e707b93a3",
"5bd073a586f7747e6f135799",
"5c1a1e3f2e221602b66cc4c2",
"5e54f76986f7740366043752",
"5e54f79686f7744022011103",
"5e71f6be86f77429f2683c44",
"5e71fad086f77422443d4604",
"5fd8d28367cb5e077335170f",
"60363c0c92ec1c31037959f5",
"607f201b3c672b3b3a24a800",
"60a7ad2a2198820d95707a2e",
"60a7ad3a0c5cb24b0134664a",
"6176a40f0b8c0312ac75a3d3",
"6176a48d732a664031271438",
"62963c18dbc8ab5f0d382d0b",
"62a09dd4621468534a797ac7",
"62a09e08de7ac81993580532",
"62a5c2c98ec41a51b34739c0",
"62a5c333ec21e50cad3b5dc6",
"62a5c41e8ec41a51b34739c3",
"62a61bbf8ec41a51b34758d2",
"635267ab3c89e2112001f826",
"63626d904aa74b8fe30ab426",
],
Eyewear: [
"59e770b986f7742cbd762754",
"5aa2b923e5b5b000137b7589",
"5aa2b9aee5b5b00015693121",
"5e71f70186f77429ee09f183",
"61c18d83b00456371a66814b",
"62a09e410b9d3c46de5b6e78",
],
Holster: ["5b3b713c5acfc4330140bd8d"],
ArmorVest: [
"5b44cf1486f77431723e3d05",
"5c0e541586f7747fa54205c9",
"5c0e625a86f7742d77340f62",
"5c0e655586f774045612eeb2",
"5fd4c474dd870108a754b241",
"6038b4b292ec1c3103795a0b",
"6038b4ca92ec1c3103795a0d",
"607f20859ee58b18e41ecd90",
"62a09d79de7ac81993580530",
],
FirstPrimaryWeapon: [
"6275303a9f372d6ea97f9ec7",
"5bf3e0490db83400196199af",
"5de7bd7bfd6b4e6e2276dc25",
"639af924d0446708ee62294e",
"639c3fbbd0446708ee622ee9",
"64637076203536ad5600c990",
"64ca3d3954fc657e230529cc",
],
ammo: [
"5c0d56a986f774449d5de529",
"5c0d591486f7744c505b416f",
"5c0d5ae286f7741e46554302",
"5d70e500a4b9364de70d38ce",
"5ede4739e0350d05467f73e8",
"5ede47405b097655935d7d16",
"5ede474b0c226a66f5402622",
"5ede475339ee016e8c534742",
"5f0c892565703e5c461894e9",
"64b8ee384b75259c590fa89b",
"5d6e68a8a4b9360b6c0d54e2",
"5efb0cabfb3e451d70735af5",
"5a26ac0ec4a28200741e1e18",
"5cc80f38e4a949001152b560",
"61962d879bb3d20b0946d385",
"5c0d688c86f77413ae3407b2",
"56dff026d2720bb8668b4567",
"5c0d5e4486f77478390952fe",
"59e690b686f7746c9f75e848",
"5fd20ff893a8961fc660a954",
"5a6086ea4f39f99cd479502f",
"560d61e84bdc2da74d8b4571",
"5cadf6eeae921500134b2799",
"5fc382a9d724d907e2077dab",
],
TacticalVest: [
"5c0e9f2c86f77432297fe0a3",
"5f5f41f56760b4138443b352",
"5fd4c4fa16cac650092f6771",
"5fd4c5477a8d854fa0105061",
"6040dd4ddcf9592f401632d2",
"609e860ebd219504d8507525",
"628b9784bcf6e2659e09b8a2",
"628b9c7d45122232a872358f",
"628baf0b967de16aab5a4f36",
"63611865ba5b90db0c0399d1",
"64a536392d2c4e6e970f4121",
"64a5366719bab53bd203bf33",
],
Earpiece: [
"5e4d34ca86f774264f758330",
"5f60cd6cf2bcbb675b00dac6",
"628e4e576d783146b124c64d",
],
ArmBand: [
"5f9949d869e2777a0e779ba5",
"60b0f988c4449e4cb624c1da",
"619bc61e86e01e16f839a999",
"619bdd8886e01e16f839a99c",
"619bddc6c9546643a67df6ee",
"619bddffc9546643a67df6f0",
"619bde3dc9546643a67df6f2",
"619bde7fc9546643a67df6f4",
"619bdeb986e01e16f839a99e",
"619bdef8c9546643a67df6f6",
"619bdf9cc9546643a67df6f8",
"619bdfd4c9546643a67df6fa",
],
StimsMeds: [
"5751a89d24597722aa0e8db0",
"5755383e24597772cb798966",
"5ed515c8d380ab312177c0fa",
"5ed515e03a40a50460332579",
"5ed515ece452db0eb56fc028",
"5ed515f6915ec335206e4152",
"5ed5160a87bb8443d10680b5",
"5ed51652f6c34d2cc26336a1",
"5ed5166ad380ab312177c100",
"5fca138c2a7b221b2852a5c6",
"5fca13ca637ee0341a484f46",
"637b60c3b7afa97bfc3d7001",
"637b612fb7afa97bfc3d7005",
"637b6179104668754b72f8f5",
"637b620db7afa97bfc3d7009",
"637b6251104668754b72f8f9",
],
Grenades: [
"5e340dcdcb6d5863cc5e5efb",
"617fd91e5539a84ec44ce155",
"618a431df1eb8e24b8741deb",
],
};
//# sourceMappingURL=Tier5.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "Tier5.js",
"sourceRoot": "",
"sources": [
"Tier5.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,49 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = BotLevelChanges;
const config_json_1 = require("../../config/config.json");
const utils_1 = require("../LoadoutChanges/utils");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const config_json_2 = __importDefault(require("../../config/config.json"));
function BotLevelChanges(container) {
const profileHelper = container.resolve("ProfileHelper");
const botLevelGenerator = container.resolve("BotLevelGenerator");
const configServer = container.resolve("ConfigServer");
const pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
pmcConfig.botRelativeLevelDeltaMax = 1;
container.afterResolution("BotLevelGenerator", (_t, result) => {
result.generateBotLevel = (levelDetails, botGenerationDetails, bot) => {
if (!botGenerationDetails.isPmc)
return botLevelGenerator.generateBotLevel(levelDetails, botGenerationDetails, bot);
const { playerLevel } = botGenerationDetails;
const currentLevelRange = (0, utils_1.getCurrentLevelRange)(playerLevel);
const currentRangeArray = config_json_1.botRangeAtLevel[currentLevelRange];
const test = currentRangeArray.map((val, k) => ({
levelRange: k + 1,
val: Math.random() * val,
}));
const randomizedRange = test.sort((a, b) => b.val - a.val)[0]
.levelRange;
const range = { ...config_json_1.levelRange[randomizedRange] };
if (range.max > 79) {
range.max = 79;
}
if (range.min > 70) {
range.min = 50;
}
const level = Math.round((range.max - range.min) * Math.random()) + range.min;
const final = {
level,
exp: profileHelper.getExperience(level),
};
// debug && console.log(final)
return final;
};
}, { frequency: "Always" });
config_json_2.default.debug &&
console.log("Algorthimic Progression: BotLevelGenerator registered");
}
//# sourceMappingURL=BotLevelChanges.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "BotLevelChanges.js",
"sourceRoot": "",
"sources": [
"BotLevelChanges.ts"
],
"names": [],
"mappings": ";;;;;AAcA,kCA+DC;AAxED,0DAAuE;AACvE,mDAA+D;AAC/D,kFAA+E;AAI/E,2EAA8C;AAG9C,SAAwB,eAAe,CACrC,SAA8B;IAE9B,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAgB,eAAe,CAAC,CAAC;IACxE,MAAM,iBAAiB,GACrB,SAAS,CAAC,OAAO,CAAoB,mBAAmB,CAAC,CAAC;IAC5D,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAe,cAAc,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;IAEtE,SAAS,CAAC,wBAAwB,GAAG,CAAC,CAAC;IAEvC,SAAS,CAAC,eAAe,CACvB,mBAAmB,EACnB,CAAC,EAAE,EAAE,MAAyB,EAAE,EAAE;QAChC,MAAM,CAAC,gBAAgB,GAAG,CACxB,YAAoB,EACpB,oBAA2C,EAC3C,GAAa,EACc,EAAE;YAC7B,IAAI,CAAC,oBAAoB,CAAC,KAAK;gBAC7B,OAAO,iBAAiB,CAAC,gBAAgB,CACvC,YAAY,EACZ,oBAAoB,EACpB,GAAG,CACJ,CAAC;YAEJ,MAAM,EAAE,WAAW,EAAE,GAAG,oBAAoB,CAAC;YAE7C,MAAM,iBAAiB,GAAG,IAAA,4BAAoB,EAAC,WAAW,CAAC,CAAC;YAC5D,MAAM,iBAAiB,GAAG,6BAAe,CAAC,iBAAiB,CAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC9C,UAAU,EAAE,CAAC,GAAG,CAAC;gBACjB,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG;aACzB,CAAC,CAAC,CAAC;YAEJ,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;iBAC1D,UAAU,CAAC;YACd,MAAM,KAAK,GAAG,EAAE,GAAG,wBAAU,CAAC,eAAe,CAAC,EAAY,CAAC;YAC3D,IAAI,KAAK,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC;gBACnB,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC;gBACnB,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC;YACjB,CAAC;YAED,MAAM,KAAK,GACT,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;YAElE,MAAM,KAAK,GAAG;gBACZ,KAAK;gBACL,GAAG,EAAE,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC;aACxC,CAAC;YAEF,8BAA8B;YAE9B,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;IACJ,CAAC,EACD,EAAE,SAAS,EAAE,QAAQ,EAAE,CACxB,CAAC;IAEF,qBAAM,CAAC,KAAK;QACV,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;AACzE,CAAC"
}

View file

@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = ClothingChanges;
const utils_1 = require("./utils");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const GlobalValues_1 = require("./GlobalValues");
function ClothingChanges(container) {
const databaseServer = container.resolve("DatabaseServer");
const tables = databaseServer.getTables();
const configServer = container.resolve("ConfigServer");
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const usecAppearance = tables.bots.types.usec.appearance;
const bearAppearance = tables.bots.types.bear.appearance;
const traders = tables.traders;
const customization = tables.templates.customization;
let allTradersSuits = Object.values(traders)
.filter(({ suits }) => !!suits?.length)
.map(({ suits }) => suits)
.flat(1);
(0, utils_1.buildClothingWeighting)(allTradersSuits, customization, botConfig, usecAppearance, bearAppearance);
GlobalValues_1.globalValues.originalBotTypes = (0, utils_1.cloneDeep)(tables.bots.types);
GlobalValues_1.globalValues.originalWeighting = (0, utils_1.cloneDeep)(botConfig.equipment.pmc);
}
//# sourceMappingURL=ClothingChanges.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "ClothingChanges.js",
"sourceRoot": "",
"sources": [
"ClothingChanges.ts"
],
"names": [],
"mappings": ";;AAQA,kCA4BC;AAnCD,mCAA4D;AAI5D,kFAA+E;AAC/E,iDAA8C;AAE9C,SAAwB,eAAe,CACrC,SAA8B;IAE9B,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;IAE1C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAe,cAAc,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;IAEtE,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;IACzD,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;IACzD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,CAAC,aAAa,CAAC;IAErD,IAAI,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;SACzC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC;SACtC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC;SACzB,IAAI,CAAC,CAAC,CAAC,CAAC;IAEX,IAAA,8BAAsB,EACpB,eAAe,EACf,aAAa,EACb,SAAS,EACT,cAAc,EACd,cAAc,CACf,CAAC;IACF,2BAAY,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,2BAAY,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AACtE,CAAC"
}

View file

@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.fixSpecificItemIssues = void 0;
const fixSpecificItemIssues = (inventory) => {
const removeAccentScopeList = new Set([
"6171407e50224f204c1da3c5", // Recknagel Era-Tac 30mm ring scope mount
"61713cc4d8e3106d9806c109", // Recknagel Era-Tac 34mm ring scope mount
"5b2389515acfc4771e1be0c0", // Burris AR-P.E.P.R. 30mm ring scope mount
"5addc00b5acfc4001669f144", // M14 Vltor CASV-14 rail system
"5a37ca54c4a282000d72296a", // JP Enterprises Flat-Top 30mm ring scope mount
"5aa66c72e5b5b00016327c93", // Nightforce Magmount 34mm ring scope mount with Ruggedized Accessory Platform
]);
removeAccentScopeList.forEach((id) => {
if (inventory.mods?.[id]?.mod_scope_001) {
inventory.mods[id].mod_scope_001 = [];
}
if (inventory.mods?.[id]?.mod_scope_002) {
inventory.mods[id].mod_scope_002 = [];
}
if (inventory.mods?.[id]?.mod_scope_003) {
inventory.mods[id].mod_scope_003 = [];
}
});
};
exports.fixSpecificItemIssues = fixSpecificItemIssues;
//# sourceMappingURL=FixSpecificScopeIssues.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "FixSpecificScopeIssues.js",
"sourceRoot": "",
"sources": [
"FixSpecificScopeIssues.ts"
],
"names": [],
"mappings": ";;;AAEO,MAAM,qBAAqB,GAAG,CAAC,SAAqB,EAAE,EAAE;IAC7D,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;QACpC,0BAA0B,EAAE,0CAA0C;QACtE,0BAA0B,EAAE,0CAA0C;QACtE,0BAA0B,EAAE,2CAA2C;QACvE,0BAA0B,EAAE,gCAAgC;QAC5D,0BAA0B,EAAE,gDAAgD;QAC5E,0BAA0B,EAAE,+EAA+E;KAC5G,CAAC,CAAC;IAEH,qBAAqB,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE;QACnC,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC;QACxC,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC;QACxC,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,aAAa,GAAG,EAAE,CAAC;QACxC,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AArBW,QAAA,qBAAqB,yBAqBhC"
}

View file

@ -0,0 +1,143 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalValues = void 0;
const utils_1 = require("./utils");
const config_json_1 = __importDefault(require("../../config/config.json"));
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const OnGameStartUtils_1 = require("./OnGameStartUtils");
const NonPmcUtils_1 = require("../NonPmcBotChanges/NonPmcUtils");
class globalValues {
static Logger;
static profileHelper;
static storedEquipmentValues = {};
static tables;
static originalBotTypes;
static config = config_json_1.default;
static advancedConfig = advancedConfig_json_1.default;
static originalWeighting;
static configServer;
static updateInventory(currentLevel, location) {
const items = this.tables.templates.items;
const nameList = Object.keys(this.storedEquipmentValues);
if (!nameList.length || !currentLevel)
return;
const botConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const firstPrimaryWeaponMultiplier = advancedConfig_json_1.default.locations[location].weightingAdjustments
.FirstPrimaryWeapon;
nameList.forEach((botName) => {
const copiedInventory = (0, utils_1.cloneDeep)(this.originalBotTypes[botName].inventory);
const currentLevelIndex = this.storedEquipmentValues[botName].findIndex(({ levelRange: { min, max } }) => currentLevel <= max && currentLevel >= min);
const weightingToUpdate = this.storedEquipmentValues[botName][currentLevelIndex];
if (!weightingToUpdate)
return;
if (weightingToUpdate?.ammo) {
for (const caliber in weightingToUpdate.ammo) {
copiedInventory.Ammo[caliber] = {
...copiedInventory.Ammo[caliber],
...weightingToUpdate.ammo[caliber],
};
}
}
if (weightingToUpdate?.equipment) {
for (const equipmentType in weightingToUpdate.equipment) {
copiedInventory.equipment[equipmentType] = {
...copiedInventory.equipment[equipmentType],
...weightingToUpdate.equipment[equipmentType],
};
try {
//update weapon type weightings per map here
if (equipmentType === "FirstPrimaryWeapon" &&
botName !== "marksman") {
// console.log("Updating", botName, " weapons for map", location);
const firstPrimary = (0, utils_1.cloneDeep)(copiedInventory.equipment[equipmentType]);
const firstPrimaryKeys = Object.keys(firstPrimary);
firstPrimaryKeys?.forEach((weaponId) => {
const parentId = items[weaponId]?._parent;
const parent = items?.[parentId]?._name;
if (parent && firstPrimaryWeaponMultiplier[parent]) {
const multiplier = (firstPrimaryWeaponMultiplier[parent] - 1) / 2 + 1;
copiedInventory.equipment[equipmentType][weaponId] =
Math.round(multiplier * firstPrimary[weaponId]);
// if (botName === "assault") {
// console.log(
// multiplier,
// location,
// botName,
// firstPrimary[weaponId],
// " to ",
// copiedInventory.equipment[equipmentType][weaponId],
// parent,
// items[weaponId]._name
// );
// }
}
else {
console.log(`[AlgorithmicLevelProgression]: Unable to set map settings for bot ${botName}'s item ${items[weaponId]._name} - ${weaponId} `);
}
});
}
}
catch (error) {
`[AlgorithmicLevelProgression]: Failed to update bot ${botName}'s ${equipmentType}`;
}
}
if (botName === "assault") {
//adjust randomization
(0, NonPmcUtils_1.buffScavGearAsLevel)(botConfig.equipment[botName], currentLevelIndex);
}
(0, NonPmcUtils_1.setPlateWeightings)(botName, botConfig.equipment[botName], currentLevelIndex);
// if (botName === "assault") {
// saveToFile(this.tables.bots.types[botName], `refDBS/assault.json`);
// }
}
this.tables.bots.types[botName].inventory = copiedInventory;
});
}
static setValuesForLocation(location, hours) {
if (location === "factory4_day")
hours = 12;
if (location === "factory4_night")
hours = 1;
if (location === "laboratory")
hours = 12;
this.config.debug &&
this.Logger.info(`Algorthimic LevelProgression: Setting up values for map ${location}`);
const botConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const mapWeightings = advancedConfig_json_1.default.locations?.[location]?.weightingAdjustments;
const items = this.tables.templates.items;
if (!mapWeightings) {
return this.Logger.warning(`Algorthimic LevelProgression: did not recognize 'location': ${location}, using defaults`);
}
if (!this.originalWeighting) {
return this.Logger.error(`Algorthimic LevelProgression: 'originalWeighting' was not set correctly`);
}
if (!items) {
return this.Logger.error(`Algorthimic LevelProgression: 'items' was not set correctly`);
}
const finalEquipment = (0, utils_1.cloneDeep)(this.originalWeighting);
const isNight = hours < 7 || hours >= 19;
config_json_1.default.debug &&
console.log("The server thinks it is ", isNight ? "NIGHT" : "DAY", hours, " do appropriate things.");
const randomisation = finalEquipment.randomisation;
(0, OnGameStartUtils_1.makeRandomisationAdjustments)(isNight, this.originalWeighting, randomisation, location);
const originalBotTypesCopy = (0, utils_1.cloneDeep)(this.originalBotTypes);
(0, OnGameStartUtils_1.cullModItems)(originalBotTypesCopy.usec.inventory.mods, isNight, items, location);
(0, OnGameStartUtils_1.updateScopes)(originalBotTypesCopy.usec.inventory.mods, isNight, items, location);
originalBotTypesCopy.bear.inventory.mods =
originalBotTypesCopy.usec.inventory.mods;
const pmcWeighting = finalEquipment.weightingAdjustmentsByBotLevel;
(0, OnGameStartUtils_1.makeMapSpecificWeaponWeightings)(location, items, this.originalWeighting, pmcWeighting);
// saveToFile(originalBotTypesCopy.usec.inventory.mods, "updated.json")
// saveToFile(originalBotTypesCopy.usec.inventory, "refDBS/usecInventoryRef.json")
// saveToFile(finalEquipment, "finalEquipment.json");
// saveToFile(this.originalWeighting, "originalWeighting.json")
botConfig.equipment.pmc = finalEquipment;
this.tables.bots.types = originalBotTypesCopy;
}
}
exports.globalValues = globalValues;
//# sourceMappingURL=GlobalValues.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,270 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = [
"544a3f024bdc2d1d388b4568", //ELCAN Specter OS4x assault scope
///
"5af99e9186f7747c447120b8", // Bad pockets
"60c7272c204bc17802313365",
"627a4e6b255f7527fb05a0f6",
"64cbd95a29b9b4283e216ff5",
///
"622b4f54dc8dcc0ba8742f85", //HK G36 Hensoldt HKV ZF 1.5x carry handle
"622b4d7df9cfc87d675d2ded", //HK G36 Hensoldt HKV 3x carry handle
// armasight vulcan universal base
// Geissele Super Precision 30mm
"5aa66a9be5b5b0214e506e89", // Nightforce Magmount 34mm ring scope mount > stupid long scope mount
"5a1ead28fcdbcb001912fa9f", // Reap-ir Mount
"5c86592b2e2216000e69e77c", // IEA Mil-Optics KH/F 34mm one-piece magmount <Stupid Long distance scopes>
"5c11046cd174af02a012e42b", // Wilcox Interface for PVS-7 > Thermal night vision connector
"5ea058e01dbce517f324b3e2", // Tac-Kek Heavy Trooper mask for Ops-Core-type helmets
"5c0558060db834001b735271", // GPNVG-18 Night Vision goggles
"5648b62b4bdc2d9d488b4585", // gp-34
"5e99711486f7744bfc4af328", // Sanitarsmedkit
"5d52cc5ba4b9367408500062",
"6087e570b998180e9f76dc24",
"58ac60eb86f77401897560ff", // golden balaclava!
"6241c316234b593b5676b637", // bb ammo
"5cdeb229d7f00c000e7ce174", // stationary gun
"5943d9c186f7745a13413ac9", // shrapnel bullets?
"5996f6cb86f774678763a6ca", // shrapnel bullets?
"5996f6fc86f7745e585b4de3", // shrapnel bullets?
"63b35f281745dd52341e5da7", // shrapnel bullets?
"5d2f2ab648f03550091993ca", // shrapnel bullets?
"5cde8864d7f00c0010373be1",
"64b9cf0ac12b9c38db26923a", // << no idea
"627a137bf21bc425b06ab944",
"610720f290b75a49ff2e5e25",
"5996f6d686f77467977ba6cc", // shrapnel bullets?
"5ae083b25acfc4001a5fc702", // Master hand ?
"544a3d0a4bdc2d1b388b4567",
"5a16bb52fcdbcb001a3b00dc", // skull lock
"5a1eaa87fcdbcb001865f75e", // reap-ir
"5d1b5e94d7ad1a2b865a96b0", // flir
"5c066ef40db834001966a595", // helmet_armasight_nvg_googles_mask
"5a0c59791526d8dba737bba7", // butt pad
"57371aab2459775a77142f22",
//small mags
"57838f0b2459774a256959b2",
"5aaa5e60e5b5b000140293d6",
"5b1fd4e35acfc40018633c39",
"59e5d83b86f7745aed03d262",
"5b7bef1e5acfc43d82528402",
"617130016c780c1e710c9a24",
"55d4837c4bdc2d1d4e8b456c",
"5c503ac82e221602b21d6e9a",
"6241c2c2117ad530666a5108",
//large mags
// "55d485804bdc2d8c2f8b456b", shotgun 153/155 extended /7/8
// "56deeefcd2720bc8328b4568", shotgun 153/155 extended /7/8
// "5882163224597757561aa920", shotgun 153/155 extended /7/8
"5a78832ec5856700155a6ca3",
"5a966f51a2750c00156aacf6",
"5cf8f3b0d7f00c00217872ef",
"625ff2eb9f5537057932257d",
"625ff3046d721f05d93bf2ee",
"625ff31daaaa8c1130599f64",
"627bce33f21bc425b06ab967",
"564ca9df4bdc2d35148b4569",
// '55d481904bdc2d8c2f8b456a', //45 round ak
"55d482194bdc2d1d4e8b456b",
"5bed625c0db834001c062946",
"55d485be4bdc2d962f8b456f",
"5cbdc23eae9215001136a407",
"5c6175362e221600133e3b94",
"5cfe8010d7ad1a59283b14c6",
"61695095d92c473c7702147a",
"61695095d92c473c7702147a",
"59c1383d86f774290a37e0ca",
"5c6592372e221600133e47d7",
"544a37c44bdc2d25388b4567",
"5a718f958dc32e00094b97e7",
"5c5db6742e2216000f1b2852",
"5a351711c4a282000b1521a4",
"5addccf45acfc400185c2989",
"5b7bef9c5acfc43d102852ec",
// "5b1fb3e15acfc4001637f068", 40 round ak
// "59e5f5a486f7746c530b3ce2", 40 round
// "544a378f4bdc2d30388b4567", 40 round
// "5d1340bdd7ad1a0e8d245aab", 40-round 556 45
// "630e295c984633f1fb0e7c30",
// "5ba26586d4351e44f824b340", MP7 40
"5c5db6652e221600113fba51",
"5cffa483d7ad1a049e54ef1c",
"5d52d479a4b936793d58c76b",
// stm-9
// stocks
"5c0faeddd174af02a962601f",
"5d120a10d7ad1a4e1026ba85",
"5b0800175acfc400153aebd4",
"5947e98b86f774778f1448bc",
"5947eab886f77475961d96c5",
// "602e3f1254072b51b239f713",
"5c793fb92e221644f31bfb64",
"5c793fc42e221600114ca25d",
"591aef7986f774139d495f03",
"591af10186f774139d495f0e",
"627254cc9c563e6e442c398f",
"638de3603a1a4031d8260b8c",
"5a33ca0fc4a282000d72292f",
// Saiga-9 9x19 carbine
// stocks
"5cf50fc5d7f00c056c53f83c", //AK-74M CAA AKTS AK74 buffer tube > 25
"5ac78eaf5acfc4001926317a", //AK-74M/AK-100 Zenit PT Lock >2
//Full Size AK mods
// stocks
// "628a6678ccaab13006640e49", //AKM/AK-74 RD AK to M4 buffer tube adapter > 17
"5b222d335acfc4771e1be099", //AKM/AK-74 Zenit PT Lock > 1
"59ecc28286f7746d7a68aa8c", // AK-74U Zenit PT Lock > 1
"5839a40f24597726f856b511", // bufferTubes > 21
"5cf518cfd7f00c065b422214",
"5649b2314bdc2d79388b4576",
"5b04473a5acfc40018632f70", //beefy Stock
"5e217ba4c1434648c13568cd", //Red funky stock
"5b0e794b5acfc47a877359b2", // Zhokov black
"6087e2a5232e5a31c233d552", //Archangel
//DustCovers
"59d6507c86f7741b846413a2", // AKM dust cover (6P1 0-1) allowing one
"59e6449086f7746c9f75e822",
"628a665a86cbd9750d2ff5e5",
"5649af094bdc2df8348b4586",
"5ac50da15acfc4001718d287",
//bullets that think they are guns
"624c0b3340357b5f566e8766",
"624c0b3340357b5f566e8766",
"6217726288ed9f0845317459",
"62178be9d0050232da3485d9",
//Mosin shorty,
"5bfd36ad0db834001c38ef66",
"5bfd36290db834001966869a",
"5a16b9fffcdbcb0176308b34",
"5c07c9660db834001a66b588",
"5d2f25bc48f03502573e5d85",
"5a7c74b3e899ef0014332c29",
//Waffle 545
"615d8f8567085e45ef1409ca",
//Mosin stocks
"5bbdb870d4351e00367fb67d",
"5bae13bad4351e00320204af",
//IR lasers
"57fd23e32459772d0805bcf1",
"544909bb4bdc2d6f028b4577",
"5d10b49bd7ad1a1a560708b0",
"5c06595c0db834001a66af6c",
"5c5952732e2216398b5abda2",
"5a5f1ce64f39f90b401987bc",
"61605d88ffa6e502ac5e7eeb",
//pistolGrips
"5b07db875acfc40dc528a5f6",
"615d8faecabb9b7ad90f4d5d",
"59db3acc86f7742a2c4ab912",
"59db3b0886f77429d72fb895",
"59db3a1d86f77429e05b4e92",
"5d025cc1d7ad1a53845279ef",
"5f6341043ada5942720e2dc5",
"6087e663132d4d12c81fd96b",
"5e2192a498a36665e8337386",
"5cf54404d7f00c108840b2ef",
"5b30ac585acfc433000eb79c",
"628a664bccaab13006640e47",
"628c9ab845c59e5b80768a81",
"5c6bf4aa2e2216001219b0ae",
"5649ae4a4bdc2d1b2b8b4588",
"6113c3586c780c1e710c90bc",
"6113cce3d92c473c770200c7",
"6113cc78d3a39d50044c065a",
"5b7d679f5acfc4001a5c4024",
//Handguards
"595cfa8b86f77427437e845b",
"595cf16b86f77427440c32e2",
"55f84c3c4bdc2d5f408b4576",
"619b5db699fb192e7430664f",
"5b2cfa535acfc432ff4db7a0",
"5c9a25172e2216000f20314e",
"55f84c3c4bdc2d5f408b4576",
"588b56d02459771481110ae2",
"5c9a26332e2216001219ea70",
"5ea16ada09aa976f2e7a51be",
"5ea16acdfadf1d18c87b0784",
"5d4405f0a4b9361e6a4e6bd9",
"5c78f2492e221600114c9f04",
"5c78f2612e221600114c9f0d",
"6034e3e20ddce744014cb878",
"6034e3d953a60014f970617b",
"6034e3cb0ddce744014cb870",
"5c6d5d8b2e221644fc630b39",
"5d00e0cbd7ad1a6c6566a42d",
"5d00f63bd7ad1a59283b1c1e",
"6087e0336d0bd7580617bb7a",
"63888bbd28e5cc32cc09d2b6",
//Foregrips
"5fc0f9b5d724d907e2077d82",
"5cda9bcfd7f00c0c0b53e900",
"59f8a37386f7747af3328f06",
"5a7dbfc1159bd40016548fde",
"619386379fb0c665d5490dbe",
"5de8fbad2fbe23140d3ee9c4",
"5b057b4f5acfc4771e1bd3e9",
"5c791e872e2216001219c40a",
"5f6340d3ca442212f4047eb2",
"591af28e86f77414a27a9e1d",
"5c1bc5612e221602b5429350",
"5c1cd46f2e22164bef5cfedb",
"5c1bc5af2e221602b412949b",
"648c1a965043c4052a4f8505", // Ebudal (bad stim)
"5d02778e86f774203e7dedbe", // CMS surgical kit
"5d02797c86f774203f38e30a", // Surv kit
"590c657e86f77412b013051d", //grizzly
"5d1c702ad7ad1a632267f429", //long handgun stock
"620109578d82e67e7911abf2", // signal pistol
"62178c4d4ecf221597654e3d",
"624c0570c9b794431568f5d5",
"624c09da2cec124eb67c1046",
"624c09e49b98e019a3315b66",
"624c09cfbc2e27219346d955",
"62389aaba63f32501b1b444f", // signal ammo
"62389ba9a63f32501b1b4451",
"62389bc9423ed1685422dc57",
"62389be94d5d474bf712e709",
"635267f063651329f75a4ee8",
"633a98eab8b0506e48497c1a", // sr-2m 20 round mag
"5caf1041ae92157c28402e3f", // ash12 10 round
"5d0a29fed7ad1a002769ad08",
"62811f461d5df4475f46a332",
"6275303a9f372d6ea97f9ec7", //revolver grenadeLauncher
"6422e1ea3c0f06190302161a", //SVT-40 7.62x54R 10-round magazine
"5c471c442e221602b542a6f8", //SVD 7.62x54R 10-round magazine
"57d14e1724597714010c3f4b", //PP-91 "Kedr" 9x18PM 20-round magazine
"5d2f213448f0355009199284", //HK MP5 9x19 20-round magazine
"5a43957686f7742a2c2f11b0", //Santahat
"639af924d0446708ee62294e", // FN40GL Mk2
"639c3fbbd0446708ee622ee9", // FN40GL Mk25e81ebcd8e146c7080625e15
"5e81ebcd8e146c7080625e15", // FN40GL Mk2 40mm grenade launcher
"59f32c3b86f77472a31742f0", // dogtags
"59f32bb586f774757e1e8442", // dogtags
"6662e9f37fa79a6d83730fa0", // dogtags
"6662ea05f6259762c56f3189", // dogtags
"6662e9aca7e0b43baa3d5f74", // dogtags
"6662e9cda7e0b43baa3d5f76", // dogtags
"5b9b9020e7ef6f5716480215", // dogtags
"65392f611406374f82152ba5", // mount_all_gbrs_hydra_micro_kit
"653931da5db71d30ab1d6296", // GBRS Aimpoint Hydra Mount Kit (FDE)
"618b9682a3884f56c957ca78", //Reptilia ROF-90 RMR mount for Geissele scope mounts
"618ba92152ecee1505530bd3", //Reptilia ROF-90 RMR mount for Geissele scope mounts ddc
"6601546f86889319850bd566",
"66015072e9f84d5680039678",
"66015dc4aaad2f54cb04c56a",
"5d70e500a4b9364de70d38ce",
"670e8eab8c1bb0e5a7075acf", //mag_pm_izhmeh_9x18pm_999_infectedMagazin
"671d85439ae8365d69117ba6", //mag_tt_toz_std_762x25tt_999_infectedMagazin
"671d8617a3e45c1f5908278c", //mag_mp443_izhmeh_std_9x19_999_infectedMagazin
"671d8ac8a3e45c1f59082799", //mag_glock_glock_w_pad_9x19_999_fde_Infected
"671d8b38b769f0d88c0950f8", //mag_m1911_colt_m45a1_std_1143x23_999_infected
"671d8b8c0959c721a50ca838", //mag_usp_hk_usp_tactical_1143x23_999_infected
"628120f210e26c1f344e6558", // mxc broken mod
"66d98233302686954b0c6f81", // RSP-30 reactive signal cartridge (Blue)
];
//5d0a29fed7ad1a002769ad08
//62811f461d5df4475f46a332
//56ea70acd2720b844b8b4594 optic
// 6275303a9f372d6ea97f9ec7
//# sourceMappingURL=InternalBlacklist.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "InternalBlacklist.js",
"sourceRoot": "",
"sources": [
"InternalBlacklist.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocationUpdater = void 0;
const GlobalValues_1 = require("./GlobalValues");
const config_json_1 = require("../../config/config.json");
const LocationUpdater = (container) => {
const staticRouterModService = container.resolve("StaticRouterModService");
const weatherController = container.resolve("WeatherController");
staticRouterModService.registerStaticRouter(`AlgorithmicLevelProgressionMapUpdater`, [
{
url: "/client/match/local/start",
action: async (_url, info, sessionId, output) => {
const time = weatherController.generate().time;
const hours = getTime(time, info.timeVariant === "PAST" ? 12 : 0);
// console.log("hours", hours);
try {
GlobalValues_1.globalValues.setValuesForLocation(info.location.toLowerCase(), hours);
if (config_json_1.enableNonPMCBotChanges) {
const pmcData = GlobalValues_1.globalValues.profileHelper.getPmcProfile(sessionId);
GlobalValues_1.globalValues.updateInventory(pmcData?.Info?.Level || 1, info.location.toLowerCase());
}
console.log("Algorthimic LevelProgression: Loaded");
}
catch (error) {
console.log(`"Algorthimic LevelProgression: failed to make equipment changes.
` + error?.message);
}
return output;
},
},
], "aki");
GlobalValues_1.globalValues.config.debug &&
console.log("Algorthimic LevelProgression: Custom router AlgorithmicLevelProgressionMapUpdater Registered");
};
exports.LocationUpdater = LocationUpdater;
function getTime(time, hourDiff) {
let [hours, minutes] = time.split(":");
if (hourDiff == 12 && parseInt(hours) >= 12) {
return Math.abs(parseInt(hours) - hourDiff);
}
return Math.abs(parseInt(hours) + hourDiff);
}
//# sourceMappingURL=LocationUpdater.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "LocationUpdater.js",
"sourceRoot": "",
"sources": [
"LocationUpdater.ts"
],
"names": [],
"mappings": ";;;AAEA,iDAA8C;AAK9C,0DAAkE;AAE3D,MAAM,eAAe,GAAG,CAAC,SAA8B,EAAa,EAAE;IAC3E,MAAM,sBAAsB,GAAG,SAAS,CAAC,OAAO,CAC9C,wBAAwB,CACzB,CAAC;IAEF,MAAM,iBAAiB,GACrB,SAAS,CAAC,OAAO,CAAoB,mBAAmB,CAAC,CAAC;IAE5D,sBAAsB,CAAC,oBAAoB,CACzC,uCAAuC,EACvC;QACE;YACE,GAAG,EAAE,2BAA2B;YAChC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE;gBAC9C,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC;gBAE/C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClE,+BAA+B;gBAC/B,IAAI,CAAC;oBACH,2BAAY,CAAC,oBAAoB,CAC/B,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAC3B,KAAK,CACN,CAAC;oBACF,IAAI,oCAAsB,EAAE,CAAC;wBAC3B,MAAM,OAAO,GACX,2BAAY,CAAC,aAAa,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;wBACtD,2BAAY,CAAC,eAAe,CAC1B,OAAO,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EACzB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAC5B,CAAC;oBACJ,CAAC;oBACD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;gBACtD,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,GAAG,CACT;iBACG,GAAG,KAAK,EAAE,OAAO,CACrB,CAAC;gBACJ,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;SACF;KACF,EACD,KAAK,CACN,CAAC;IAEF,2BAAY,CAAC,MAAM,CAAC,KAAK;QACvB,OAAO,CAAC,GAAG,CACT,8FAA8F,CAC/F,CAAC;AACN,CAAC,CAAC;AAlDW,QAAA,eAAe,mBAkD1B;AAEF,SAAS,OAAO,CAAC,IAAY,EAAE,QAAgB;IAC7C,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEvC,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC,CAAC;AAC9C,CAAC"
}

View file

@ -0,0 +1,137 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildLootChanges = void 0;
const utils_1 = require("./utils");
const nonPmcBotConfig_json_1 = __importDefault(require("../../config/nonPmcBotConfig.json"));
const BaseClasses_1 = require("C:/snapshot/project/obj/models/enums/BaseClasses");
const buildLootChanges = (items, handbook, prices, _, botConfig, types) => {
const assaultInventory = types.assault.inventory;
const handbookMapper = {};
// Zero out all current items
for (const key in assaultInventory.items.Backpack) {
assaultInventory.items.Backpack[key] = 1;
}
for (const key in assaultInventory.items.Pockets) {
assaultInventory.items.Pockets[key] = 1;
}
for (const key in assaultInventory.items.TacticalVest) {
assaultInventory.items.TacticalVest[key] = 1;
}
handbook.Items.forEach(({ Id, Price }) => {
handbookMapper[Id] = Price;
});
const getFleaPrice = (itemID) => {
if (typeof prices[itemID] != "undefined") {
return prices[itemID];
}
else {
return handbookMapper[itemID];
}
};
const newToAdd = {
[BaseClasses_1.BaseClasses.BARTER_ITEM]: 50,
[BaseClasses_1.BaseClasses.HOUSEHOLD_GOODS]: 50,
[BaseClasses_1.BaseClasses.FOOD_DRINK]: 50,
[BaseClasses_1.BaseClasses.ELECTRONICS]: 1,
[BaseClasses_1.BaseClasses.JEWELRY]: 2,
[BaseClasses_1.BaseClasses.OTHER]: 1,
[BaseClasses_1.BaseClasses.TOOL]: 5,
[BaseClasses_1.BaseClasses.REPAIR_KITS]: 1,
[BaseClasses_1.BaseClasses.MONEY]: 1,
"60b0f6c058e0b0481a09ad11": 1, //gingy
"62a09d3bcf4a99369e262447": 1, //wallet
"5783c43d2459774bbe137486": 1, //walletz
};
if (nonPmcBotConfig_json_1.default.addRandomizedKeysToScavs) {
newToAdd[BaseClasses_1.BaseClasses.KEY_MECHANICAL] = 1;
}
const itemsToRemove = new Set([
BaseClasses_1.BaseClasses.AMMO_BOX,
BaseClasses_1.BaseClasses.GEAR_MOD,
BaseClasses_1.BaseClasses.SILENCER,
BaseClasses_1.BaseClasses.KNIFE,
BaseClasses_1.BaseClasses.ASSAULT_SCOPE,
BaseClasses_1.BaseClasses.COLLIMATOR,
BaseClasses_1.BaseClasses.SPECIAL_SCOPE,
BaseClasses_1.BaseClasses.OPTIC_SCOPE,
BaseClasses_1.BaseClasses.FOREGRIP,
BaseClasses_1.BaseClasses.ARMOR,
BaseClasses_1.BaseClasses.VEST,
BaseClasses_1.BaseClasses.TACTICAL_COMBO,
]);
const addList = Object.keys(newToAdd);
const removeList = [...itemsToRemove];
//limit keys on scavs
botConfig.itemSpawnLimits.assault[BaseClasses_1.BaseClasses.KEY_MECHANICAL] = 1;
const randomlyAllowKey = (id) => {
if ((0, utils_1.checkParentRecursive)(id, items, [BaseClasses_1.BaseClasses.KEY_MECHANICAL]) &&
Math.random() > nonPmcBotConfig_json_1.default.percentageOfKeysInSpawnPool) {
// console.log(items[id]._name);
return false;
}
return true;
};
const scavLootBlacklist = new Set(nonPmcBotConfig_json_1.default.scavLootBlacklist);
const loot = Object.keys(items).filter((id) => !scavLootBlacklist.has(id) &&
!utils_1.blacklistedItems.has(id) &&
randomlyAllowKey(id) &&
(0, utils_1.checkParentRecursive)(id, items, addList) &&
!(0, utils_1.checkParentRecursive)(id, items, [BaseClasses_1.BaseClasses.MONEY, ...removeList]) &&
!items[id]?._props?.QuestItem &&
!!getFleaPrice(id));
const importedCustomLoot = nonPmcBotConfig_json_1.default?.additionalScavLoot.filter((id) => !!items[id] && !!getFleaPrice(id));
const configmultiplier = 100 / nonPmcBotConfig_json_1.default.lootDisparityMultiplier;
const allLoot = [...loot, ...importedCustomLoot]
.map((id) => ({
id,
value: Math.round(getFleaPrice(id) / configmultiplier) || 1,
name: items[id]._name,
}))
.sort(({ value: b }, { value: a }) => b - a);
const reverseLoot = [...allLoot].reverse().map(({ value }) => value);
const top = reverseLoot[Math.round(reverseLoot.length * 0.15)];
const bottom = reverseLoot[Math.round(allLoot.length * 0.7)];
const finalValues = {};
allLoot.forEach(({ value, id, name }, index) => {
let rarity = reverseLoot[index];
switch (true) {
case reverseLoot[index] > top:
rarity = top;
break;
case reverseLoot[index] < bottom:
rarity = Math.round(rarity * (0.3 / nonPmcBotConfig_json_1.default.lootDisparityMultiplier));
break;
default:
}
if ((0, utils_1.checkParentRecursive)(id, items, [utils_1.keyMechanical])) {
rarity = Math.round(rarity * (Math.random() * Math.random())) || 1;
}
finalValues[id] = rarity;
});
// saveToFile(finalValues, "refDBS/allLoot.json");
assaultInventory.items.Backpack = finalValues;
assaultInventory.items.Pockets = finalValues;
assaultInventory.items.TacticalVest = finalValues;
// botConfig.walletLoot.chancePercent = 35;
// botConfig.walletLoot.walletTplPool = [];
itemsToRemove.forEach((id) => {
if (botConfig.itemSpawnLimits.assault[id])
delete botConfig.itemSpawnLimits.assault[id];
if (assaultInventory.items.Backpack[id])
delete assaultInventory.items.Backpack[id];
if (assaultInventory.items.TacticalVest[id])
delete assaultInventory.items.TacticalVest[id];
if (assaultInventory.items.Pockets[id])
delete assaultInventory.items.Pockets[id];
});
Object.keys(newToAdd).forEach((id) => {
botConfig.itemSpawnLimits.assault[id] = newToAdd[id];
botConfig.itemSpawnLimits.assaultgroup[id] = newToAdd[id];
});
return finalValues;
};
exports.buildLootChanges = buildLootChanges;
//# sourceMappingURL=LootChanges.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,262 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateScopes = exports.cullModItems = exports.makeMapSpecificWeaponWeightings = exports.makeRandomisationAdjustments = void 0;
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const utils_1 = require("./utils");
const InternalBlacklist_1 = __importDefault(require("./InternalBlacklist"));
const GlobalValues_1 = require("./GlobalValues");
const makeRandomisationAdjustments = (isNight, originalWeight, randomisation, location) => {
const noNvgNeeded = ["factory4_day", "factory4_night", "laboratory"].includes(location);
// levelRange: MinMax;
// generation?: Record<string, GenerationData>;
// /** Mod slots that should be fully randomised -ignores mods from bottype.json and instaed creates a pool using items.json */
// randomisedWeaponModSlots?: string[];
// /** Armor slots that should be randomised e.g. 'Headwear, Armband' */
// randomisedArmorSlots?: string[];
// /** Equipment chances */
// equipment?: Record<string, number>;
// /** Weapon mod chances */
// weaponMods?: Record<string, number>;
// /** Equipment mod chances */
// equipmentMods?: Record<string, number>;
originalWeight.randomisation.forEach((_, index) => {
// NVG's
if (!noNvgNeeded &&
randomisation?.[index]?.equipmentMods?.mod_nvg !== undefined) {
randomisation[index].equipmentMods.mod_nvg = isNight
? (index + 1) * 18
: 0;
if (randomisation[index].equipmentMods.mod_nvg > 100)
randomisation[index].equipmentMods.mod_nvg = 100;
}
// Silencers??
if (randomisation?.[index]?.weaponMods?.mod_muzzle !== undefined) {
randomisation[index].weaponMods.mod_muzzle += isNight ? 18 : 0;
if (randomisation[index].weaponMods.mod_muzzle > 100)
randomisation[index].weaponMods.mod_muzzle = 100;
}
// Flashlights
if (location === "laboratory" ||
randomisation?.[index]?.weaponMods?.mod_flashlight !== undefined) {
randomisation[index].weaponMods.mod_flashlight += isNight ? 45 : 0;
if (randomisation[index].weaponMods.mod_flashlight > 100)
randomisation[index].weaponMods.mod_flashlight = 100;
}
if (location === "laboratory") {
[
"mod_equipment",
"mod_equipment_000",
"mod_equipment_001",
"mod_equipment_002", //TODO: check if this is still needed
"mod_pistol_grip_akms",
"mod_tactical",
"mod_tactical_2",
"mod_tactical001",
"mod_tactical002",
"mod_tactical_000",
"mod_tactical_001",
"mod_tactical_002",
"mod_tactical_003",
].forEach((modName) => {
if (randomisation?.[index]?.weaponMods?.[modName] !== undefined) {
randomisation[index].weaponMods[modName] += 30;
if (randomisation[index].weaponMods[modName] > 100)
randomisation[index].weaponMods[modName] = 100;
}
});
}
});
};
exports.makeRandomisationAdjustments = makeRandomisationAdjustments;
const makeMapSpecificWeaponWeightings = (location, items, originalWeight, pmcWeighting) => {
const firstPrimaryWeaponTypes = advancedConfig_json_1.default.locations[location].weightingAdjustments.FirstPrimaryWeapon;
originalWeight.weightingAdjustmentsByBotLevel.forEach((weightTier, index) => {
const firstPrimary = weightTier.equipment.edit.FirstPrimaryWeapon;
const firstPrimaryKeys = Object.keys(firstPrimary);
firstPrimaryKeys?.forEach((weaponId) => {
const parentId = items[weaponId]?._parent;
const parent = items?.[parentId]?._name;
if (parent && firstPrimaryWeaponTypes[parent]) {
const multiplier = firstPrimaryWeaponTypes[parent];
pmcWeighting[index].equipment.edit.FirstPrimaryWeapon[weaponId] =
Math.round(multiplier * firstPrimary[weaponId]);
// console.log(firstPrimary[weaponId], " to ", pmcWeighting[index].equipment.edit.FirstPrimaryWeapon[weaponId], parent, items[weaponId]._name)
}
else {
console.log(`Algorthimic LevelProgression: Unable to set map settings for ${items[weaponId]._name} - ${weaponId} `);
}
});
});
};
exports.makeMapSpecificWeaponWeightings = makeMapSpecificWeaponWeightings;
const cullModItems = (mods, isNight, items, location) => {
const cullList = new Set([
...(isNight ? nightTimeCullList : dayTimeCullList),
...InternalBlacklist_1.default,
]);
if (location === "laboratory") {
cullList.delete("5a1ead28fcdbcb001912fa9f");
cullList.delete("5c11046cd174af02a012e42b");
cullList.delete("5a1eaa87fcdbcb001865f75e");
cullList.delete("5d1b5e94d7ad1a2b865a96b0");
cullList.delete("5ea058e01dbce517f324b3e2");
}
for (let key in mods) {
if (cullList.has(key) ||
!checkDaytimeSilencer(key, isNight, items, cullList)) {
delete mods[key];
}
else {
for (const modType in mods[key]) {
if (mods?.[key]?.[modType].length) {
mods[key][modType] = mods[key][modType].filter((id) => !cullList.has(id) &&
checkDaytimeSilencer(id, isNight, items, cullList));
if (mods[key][modType].length === 0 &&
Object.keys(mods[key]).length === 1) {
delete mods[key];
}
}
}
}
}
};
exports.cullModItems = cullModItems;
const checkDaytimeSilencer = (id, isNight, items, cullList) => {
const item = items[id];
if (!item?._props)
return false;
switch (true) {
case !isNight &&
(0, utils_1.checkParentRecursive)(id, items, [utils_1.muzzleParent]) &&
item._props.Loudness < GlobalValues_1.globalValues.advancedConfig.daytimeSilencerCutoff:
// console.log(item._name);
cullList.add(id);
return false;
default:
break;
}
return true;
};
const nightTimeCullList = [
"5cc9c20cd7f00c001336c65d", // tactical_all_ncstar_tactical_blue_laser
"560d657b4bdc2da74d8b4572", // tactical_all_zenit_2p_kleh_vis_laser
];
const dayTimeCullList = [
"5b3b6dc75acfc47a8773fb1e",
"644a3df63b0b6f03e101e065", // tactical_all_bemeyers_mawl_c1_plus
"5b3a337e5acfc4704b4a19a0", // tactical_all_zenit_2u_kleh
"626becf9582c3e319310b837", // tactical_all_insight_wmx200
"57fd23e32459772d0805bcf1", // tactical_all_holosun_ls321
"544909bb4bdc2d6f028b4577", // tactical_all_insight_anpeq15
];
const smgUpperRails = new Set([
"5926dad986f7741f82604363",
"5a966ec8a2750c00171b3f36",
"602e63fb6335467b0c5ac94d",
"5894a5b586f77426d2590767",
"5de8e67c4a9f347bc92edbd7",
]);
const marksmanUpperRails = new Set([
"5df8e4080b92095fd441e594",
"5dfcd0e547101c39625f66f9",
]);
const updateScopes = (mods, isNight, items, location) => {
const weaponTypeMapper = buildOutWeaponTypeMapper(location, isNight);
for (let key in mods) {
if (smgUpperRails.has(key) ||
marksmanUpperRails.has(key) ||
(0, utils_1.checkParentRecursive)(key, items, [utils_1.weaponParent])) {
const parent = items[key]._parent;
let scopeTypes = weaponTypeMapper[parent];
if (smgUpperRails.has(key)) {
scopeTypes = weaponTypeMapper[utils_1.weaponTypeNameToId.Smg];
}
if (marksmanUpperRails.has(key)) {
scopeTypes = weaponTypeMapper[utils_1.weaponTypeNameToId.MarksmanRifle];
}
if (!scopeTypes) {
// console.log("UNABLE TO FIND PARENT FOR", key, items[key]._name)
break;
}
if (!!mods[key]?.mod_scope?.length) {
const result = mods[key].mod_scope.filter((id) => scopeTypes.has(items[id]?._parent) ||
checkIfChildHasScopes(id, items, scopeTypes, mods));
if (result.length)
mods[key].mod_scope = result;
}
if (!!mods[key]?.mod_mount) {
const mountResult = mods[key].mod_mount.filter((id) => scopeTypes.has(items[id]?._parent) ||
checkIfChildHasScopes(id, items, scopeTypes, mods, true));
// console.log(key, items[key]._name, mods[key].mod_mount.length, mountResult.length)
if (mountResult.length)
mods[key].mod_mount = mountResult;
mods[key]?.mod_mount;
}
[
"mod_mount_001",
"mod_mount_002",
"mod_mount_003",
"mod_mount_004",
].forEach((mountType) => {
if (!!mods[key]?.[mountType]) {
const mountResult = mods[key][mountType].filter((id) => !(0, utils_1.checkParentRecursive)(id, items, [utils_1.mountParent, utils_1.sightParent]) ||
(items[id]?._parent === utils_1.mountParent && !mods[id]?.mod_scope) ||
scopeTypes.has(items[id]?._parent) ||
checkIfChildHasScopes(id, items, scopeTypes, mods, true));
// console.log(mountType, key, items[key]._name, mods[key][mountType].length, mountResult.length)
if (mountResult.length)
mods[key][mountType] = mountResult;
mods[key]?.[mountType];
}
});
if (!!mods[key]?.mod_reciever) {
const receiverScopetypes = checkAssaultScopeTypes(items, key, scopeTypes, weaponTypeMapper);
const receiverResult = mods[key].mod_reciever.filter((id) => scopeTypes.has(items[id]?._parent) ||
checkIfChildHasScopes(id, items, receiverScopetypes, mods, true));
// console.log(key, items[key]._name, mods[key].mod_reciever.length, receiverResult.length)
if (receiverResult?.length)
mods[key].mod_reciever = receiverResult;
mods[key]?.mod_reciever;
}
}
}
};
exports.updateScopes = updateScopes;
const akType = "reciever_ak";
const checkAssaultScopeTypes = (items, id, originalScopeType, weaponTypeMapper) => {
if (items[id]?._name?.includes(akType))
return weaponTypeMapper["5447b5f14bdc2d61278b4567"]; //assault rifle type
return originalScopeType;
};
const checkIfChildHasScopes = (id, items, scopeTypes, mods, clean) => {
const result = !!mods[id]?.mod_scope?.find((scopeId) => scopeTypes.has(items[scopeId]?._parent));
if (result && clean) {
const filtered = mods[id]?.mod_scope.filter((id) => scopeTypes.has(items[id]?._parent) ||
checkIfChildHasScopes(id, items, scopeTypes, mods));
if (filtered?.length)
mods[id].mod_scope = filtered;
}
return result;
};
const buildOutWeaponTypeMapper = (location, isNight) => {
const mapper = {};
const sightConfiguration = (0, utils_1.cloneDeep)(advancedConfig_json_1.default.locations[location].sightConfiguration);
if (isNight) {
["SniperRifle", "MarksmanRifle", "AssaultCarbine", "AssaultRifle"].forEach((type) => {
sightConfiguration[type].push("NightVision");
});
}
for (const weaponType in sightConfiguration) {
const weaponTypeUUID = utils_1.weaponTypeNameToId[weaponType];
mapper[weaponTypeUUID] = new Set(sightConfiguration[weaponType].map((name) => utils_1.SightType[name]));
}
return mapper;
};
// check if item is scope, if so ignore (allow for child scopes)
// check if item is weapon, if so, filter mod_scope
// if scope, check
// if "55818b224bdc2dde698b456f" Mount, check if any mod_scope within contain correct scopes, if not remove
//# sourceMappingURL=OnGameStartUtils.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,470 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = ProgressionChanges;
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const config_json_1 = __importDefault(require("../../config/config.json"));
const utils_1 = require("./utils");
const Tier5_1 = __importDefault(require("../Constants/Tier5"));
const botConfigequipmentpmc_json_1 = __importDefault(require("../Cache/botConfigequipmentpmc.json"));
const tablesbotstypesusec_json_1 = __importDefault(require("../Cache/tablesbotstypesusec.json"));
const LootChanges_1 = require("./LootChanges");
const FixSpecificScopeIssues_1 = require("./FixSpecificScopeIssues");
function ProgressionChanges(container) {
const databaseServer = container.resolve("DatabaseServer");
const tables = databaseServer.getTables();
const configServer = container.resolve("ConfigServer");
// const presets = tables.globals.ItemPresets;
// let mappedPresets = {};
// Object.values(presets).forEach((preset) => {
// if (preset._encyclopedia) {
// const newPreset = {};
// let mainId = "";
// const otherPresets = {};
// const mapper = {};
// preset._items.forEach((item) => {
// if (item._tpl === preset._encyclopedia) {
// mainId = item._id;
// }
// if (item.parentId && item.slotId) {
// mapper[item._id] = item._tpl;
// if (item.parentId === mainId) {
// if (!newPreset[item.slotId]) newPreset[item.slotId] = [];
// newPreset[item.slotId].push(item._tpl);
// } else {
// if (!otherPresets[mapper[item.parentId]])
// otherPresets[mapper[item.parentId]] = {};
// if (!otherPresets[mapper[item.parentId]][item.slotId]) {
// otherPresets[mapper[item.parentId]][item.slotId] = [item._tpl];
// } else {
// otherPresets[mapper[item.parentId]][item.slotId].push(item._tpl);
// }
// }
// }
// });
// mappedPresets[preset._encyclopedia] = newPreset;
// if (Object.keys(otherPresets))
// mappedPresets = { ...mappedPresets, ...otherPresets };
// }
// });
// saveToFile(mappedPresets, "Constants/mappedPresets.json");
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
const Logger = container.resolve("WinstonLogger");
const items = tables.templates.items;
const traders = tables.traders;
const usecInventory = tables.bots.types.usec.inventory;
const bearInventory = tables.bots.types.bear.inventory;
const prices = tables.templates.prices;
const handbook = tables.templates.handbook;
let loot = {};
if (config_json_1.default.enableLootChanges && !config_json_1.default.forceCached) {
try {
loot = (0, LootChanges_1.buildLootChanges)(items, handbook, prices, pmcConfig, botConfig, tables.bots.types);
}
catch (error) {
Logger.error("Algorthimic Progression: buildLootChanges failed, maybe try turning off 'enableLootChanges', \nError: " +
error);
}
}
if (botConfig.secureContainerAmmoStackCount < 80)
botConfig.secureContainerAmmoStackCount = 80;
if (!pmcConfig.forceHealingItemsIntoSecure)
pmcConfig.forceHealingItemsIntoSecure = true;
pmcConfig.looseWeaponInBackpackChancePercent = 2;
pmcConfig.looseWeaponInBackpackLootMinMax = { min: 0, max: 1 };
if (config_json_1.default?.forceCached !== true) {
try {
const tradersToInclude = [
"Prapor",
"Therapist",
"Skier",
"Peacekeeper",
"Mechanic",
"Ragman",
"Jaeger",
"Arena",
];
const tradersToExclude = [
"Unknown",
"caretaker",
"Fence",
"БТР",
...config_json_1.default.customTradersToExclude,
];
const traderList = Object.values(traders).filter(({ base }) => {
if (config_json_1.default.addCustomTraderItems) {
return !tradersToExclude.includes(base.nickname);
}
return tradersToInclude.includes(base.nickname);
});
botConfig.equipment.pmc.nvgIsActiveChanceNightPercent = 85;
botConfig.equipment.pmc.lightIsActiveNightChancePercent = 45;
botConfig.equipment.pmc.lightIsActiveDayChancePercent = 25;
botConfig.equipment.pmc.laserIsActiveChancePercent = 90;
botConfig.equipment.pmc.armorPlateWeighting = [
{
levelRange: {
min: 1,
max: 99,
},
front_plate: {
"1": 1,
"2": 3,
"3": 15,
"4": 35,
"5": 15,
"6": 5,
},
back_plate: {
"1": 1,
"2": 3,
"3": 15,
"4": 35,
"5": 15,
"6": 5,
},
side_plate: {
"1": 1,
"2": 3,
"3": 15,
"4": 35,
"5": 15,
"6": 5,
},
left_side_plate: {
"1": 1,
"2": 3,
"3": 15,
"4": 35,
"5": 15,
"6": 5,
},
right_side_plate: {
"1": 1,
"2": 3,
"3": 15,
"4": 35,
"5": 15,
"6": 5,
},
},
];
// botConfig.equipment.pmc.forceOnlyArmoredRigWhenNoArmor = false;
botConfig.equipment.pmc.faceShieldIsActiveChancePercent = 100;
botConfig.equipment.pmc.weightingAdjustmentsByBotLevel =
(0, utils_1.buildEmptyWeightAdjustments)();
// >>>>>>>>>>>>>>> Working tradersMasterList <<<<<<<<<<<<<<<<<<
const tradersMasterList = {
1: new Set(["572b7adb24597762ae139821", "5fd4c4fa16cac650092f6771"]),
2: new Set(),
3: new Set(),
4: new Set(),
5: new Set(Object.values(Tier5_1.default).flat(1)),
};
const mods = { "1": {}, "2": {}, "3": {}, "4": {}, "5": {} };
// SetBaseWhitelist
botConfig.equipment.pmc.whitelist = (0, utils_1.setupBaseWhiteList)();
traderList.forEach(({ base: { nickname }, questassort, assort: { items: tradeItems, loyal_level_items, barter_scheme, } = {}, }, index) => {
if (!tradeItems || !nickname)
return;
if (config_json_1.default.addCustomTraderItems &&
![...tradersToExclude, ...tradersToInclude].includes(nickname)) {
console.log(`[AlgorithmicLevelProgression]: Attempting to add items for custom trader > ${nickname}!`);
}
tradeItems.forEach(({ _tpl, _id, parentId, slotId }) => {
if (utils_1.blacklistedItems.has(_tpl) ||
(0, utils_1.checkParentRecursive)(_tpl, items, [utils_1.armorPlateParent]))
return; //Remove blacklisted items and bullets
const item = items[_tpl];
if (!item)
return console.log("[AlgorithmicLevelProgression]: Skipping custom item: ", _tpl, " for trader: ", nickname);
const parent = item._parent;
if (!parent || !items[parent])
return console.log("[AlgorithmicLevelProgression]: Skipping custom item: ", _tpl, " for trader: ", nickname);
const equipmentType = (0, utils_1.getEquipmentType)(parent, items);
switch (true) {
//Add Ammo
case (0, utils_1.checkParentRecursive)(parent, items, [utils_1.AmmoParent]):
const calibre = item._props.Caliber || item._props.ammoCaliber;
if (calibre) {
usecInventory.Ammo[calibre] = {
...(usecInventory.Ammo[calibre] || {}),
[_tpl]: 1,
};
bearInventory.Ammo[calibre] = {
...(bearInventory.Ammo[calibre] || {}),
[_tpl]: 1,
};
// usecInventory.items.SecuredContainer[_tpl] = 1;
// bearInventory.items.SecuredContainer[_tpl] = 1;
}
else {
console.log(item._name, " likely has the incorrect calibre: ", calibre);
}
break;
case (0, utils_1.checkParentRecursive)(parent, items, [utils_1.magParent]):
// usecInventory.items.SecuredContainer[_tpl] = 1;
// bearInventory.items.SecuredContainer[_tpl] = 1;
break;
// case equipmentType === "mod_scope":
// break;
// Check if revolver shotgun
case _tpl === "60db29ce99594040e04c4a27":
if (!usecInventory.equipment["FirstPrimaryWeapon"])
usecInventory.equipment["FirstPrimaryWeapon"] = {};
if (!bearInventory.equipment["FirstPrimaryWeapon"])
bearInventory.equipment["FirstPrimaryWeapon"] = {};
usecInventory.equipment["FirstPrimaryWeapon"][_tpl] = 1;
bearInventory.equipment["FirstPrimaryWeapon"][_tpl] = 1;
break;
// Check if sawed-off shotgun
case _tpl === "64748cb8de82c85eaf0a273a":
if (!usecInventory.equipment["Holster"])
usecInventory.equipment["Holster"] = {};
if (!bearInventory.equipment["Holster"])
bearInventory.equipment["Holster"] = {};
usecInventory.equipment["Holster"][_tpl] = 1;
bearInventory.equipment["Holster"][_tpl] = 1;
break;
// Add matching equipment
case !!equipmentType:
if (!usecInventory.equipment[equipmentType])
usecInventory.equipment[equipmentType] = {};
if (!bearInventory.equipment[equipmentType])
bearInventory.equipment[equipmentType] = {};
usecInventory.equipment[equipmentType][_tpl] = 1;
bearInventory.equipment[equipmentType][_tpl] = 1;
break;
default:
break;
}
const loyaltyLevel = loyal_level_items[_id] || loyal_level_items[parentId];
//Set trader list for levels
if (loyaltyLevel) {
const barterSchemeRef = barter_scheme[_id] || barter_scheme[parentId];
switch (true) {
// If large magazine
case (0, utils_1.checkParentRecursive)(_tpl, items, [utils_1.magParent]) &&
item?._props?.Cartridges?.[0]?._max_count > 39:
// if (item?._props?.Cartridges?.[0]?._max_count > 39) {
// tradersMasterList[5].add(_tpl)
// return
// }
// tradersMasterList[loyaltyLevel].add(_tpl)
// addToModsObject(mods, _tpl, items, loyaltyLevel, slotId)
break;
// Check if its a quest unlocked trade
case !!questassort.success[_id]:
if (!config_json_1.default?.questUnlockedItemsShifted) {
tradersMasterList[loyaltyLevel].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, loyaltyLevel, slotId);
}
else {
if (loyaltyLevel === 4) {
tradersMasterList[4].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, 4, slotId);
}
else {
tradersMasterList[loyaltyLevel + 1].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, loyaltyLevel + 1, slotId);
}
}
break;
// Only add the item if it's a cash trade or if tradeItems are not shifted
case items[barterSchemeRef?.[0]?.[0]?._tpl]?._parent ===
utils_1.moneyParent || !config_json_1.default?.tradedItemsShifted:
tradersMasterList[loyaltyLevel].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, loyaltyLevel, slotId);
break;
// Then it's a tradeItem
default:
if (loyaltyLevel + 2 > 4) {
tradersMasterList[4].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, 4, slotId);
}
else {
tradersMasterList[loyaltyLevel + 2].add(_tpl);
(0, utils_1.addToModsObject)(mods, _tpl, items, loyaltyLevel + 2, slotId);
}
break;
}
}
});
});
//Setup beast mod level 5
tradersMasterList[5].forEach((id) => {
if (utils_1.blacklistedItems.has(id)) {
tradersMasterList[5].delete(id);
}
else {
const item = items[id];
const parent = items[id]?._parent;
if (!item || !parent)
return;
const equipmentType = (0, utils_1.getEquipmentType)(parent, items);
switch (true) {
case (0, utils_1.checkParentRecursive)(parent, items, [utils_1.AmmoParent]):
const calibre = item._props.Caliber || item._props.ammoCaliber;
if (calibre) {
usecInventory.Ammo[calibre] = {
...(usecInventory.Ammo[calibre] || {}),
[id]: 1,
};
bearInventory.Ammo[calibre] = {
...(bearInventory.Ammo[calibre] || {}),
[id]: 1,
};
}
break;
case !!equipmentType:
if (!usecInventory.equipment[equipmentType])
usecInventory.equipment[equipmentType] = {};
if (!bearInventory.equipment[equipmentType])
bearInventory.equipment[equipmentType] = {};
usecInventory.equipment[equipmentType][id] = 1;
bearInventory.equipment[equipmentType][id] = 1;
break;
default:
break;
}
}
});
const combinedNumList = new Set([
...tradersMasterList[1],
...tradersMasterList[2],
...tradersMasterList[3],
...tradersMasterList[4],
]);
//TODO: keep an eye on this.. this might be a bad idea.
const combinedNumWith5List = new Set([
...combinedNumList,
...tradersMasterList[5],
]);
(0, utils_1.buildWeaponSightWhitelist)(items, botConfig, tradersMasterList);
(0, utils_1.buildOutModsObject)(combinedNumWith5List, items, usecInventory, botConfig);
bearInventory.mods = (0, utils_1.cloneDeep)(usecInventory.mods);
(0, utils_1.setupMods)(mods);
// lets disable this for now
// addKeysToPockets(combinedNumList, items, tables.bots.types.assault.inventory);
//Make everything level 1 in equipment
(0, utils_1.reduceEquipmentChancesTo1)(usecInventory);
(0, utils_1.reduceEquipmentChancesTo1)(bearInventory);
(0, utils_1.reduceAmmoChancesTo1)(usecInventory);
(0, utils_1.reduceAmmoChancesTo1)(bearInventory);
// Eliminates duplicate id's in later levels
utils_1.numList.forEach((num) => {
tradersMasterList[num].forEach((id) => {
utils_1.numList.slice(num, 5).forEach((numListNum) => {
tradersMasterList[numListNum].delete(id);
});
});
});
if (botConfig.equipment.pmc.blacklist?.[0]?.equipment) {
if (!botConfig.equipment.pmc.blacklist?.[0]?.equipment?.FirstPrimaryWeapon)
botConfig.equipment.pmc.blacklist[0].equipment.FirstPrimaryWeapon =
[];
if (!botConfig.equipment.pmc.blacklist?.[0]?.equipment?.mod_scope)
botConfig.equipment.pmc.blacklist[0].equipment.mod_scope = [];
if (!botConfig.equipment.pmc.blacklist?.[0]?.equipment?.mod_handguard)
botConfig.equipment.pmc.blacklist[0].equipment.mod_handguard = [];
if (!botConfig.equipment.pmc.blacklist?.[0]?.equipment?.Headwear)
botConfig.equipment.pmc.blacklist[0].equipment.Headwear = [];
botConfig.equipment.pmc.blacklist[0].equipment.FirstPrimaryWeapon.push("624c0b3340357b5f566e8766", "624c0b3340357b5f566e8766", "6217726288ed9f0845317459", "62389be94d5d474bf712e709");
botConfig.equipment.pmc.blacklist[0].equipment.mod_scope.push("544a3d0a4bdc2d1b388b4567");
botConfig.equipment.pmc.blacklist[0].equipment.mod_stock.push("5a0c59791526d8dba737bba7");
botConfig.equipment.pmc.blacklist[0].equipment.Headwear.push("5c066ef40db834001966a595");
}
(0, utils_1.setWhitelists)(items, botConfig, tradersMasterList, mods);
(0, utils_1.setWeightingAdjustments)(items, botConfig, tradersMasterList, mods);
let lootingBotsDetected = false;
if (tables?.bots?.types?.bear?.generation?.items?.backpackLoot?.weights &&
new Set(Object.values(tables?.bots?.types?.bear?.generation?.items?.backpackLoot.weights)).size === 1) {
console.log("[AlgorithmicLevelProgression] Looting bots detected, removing pmc loot");
lootingBotsDetected = true;
}
(0, utils_1.buildInitialRandomization)(items, botConfig, tradersMasterList, lootingBotsDetected);
(0, utils_1.deleteBlacklistedItemsFromInventory)(usecInventory, utils_1.blacklistedItems);
(0, utils_1.deleteBlacklistedItemsFromInventory)(bearInventory, utils_1.blacklistedItems);
// add ai2 and surv to bot containerq
// cms
usecInventory.items.SecuredContainer["5d02778e86f774203e7dedbe"] = 1;
bearInventory.items.SecuredContainer["5d02778e86f774203e7dedbe"] = 1;
// ai2
usecInventory.items.SecuredContainer["5755356824597772cb798962"] = 1;
bearInventory.items.SecuredContainer["5755356824597772cb798962"] = 1;
// Splint
usecInventory.items.SecuredContainer["5af0454c86f7746bf20992e8"] = 1;
bearInventory.items.SecuredContainer["5af0454c86f7746bf20992e8"] = 1;
// Esmarch5e831507ea0a7c419c2f9bd9
usecInventory.items.SecuredContainer["5e831507ea0a7c419c2f9bd9"] = 1;
bearInventory.items.SecuredContainer["5e831507ea0a7c419c2f9bd9"] = 1;
// ensureAllAmmoInSecuredContainer(usecInventory);
// ensureAllAmmoInSecuredContainer(bearInventory);
(0, utils_1.addBossSecuredContainer)(usecInventory);
(0, utils_1.addBossSecuredContainer)(bearInventory);
// addAllMedsToInventory(combinedNumWith5List, usecInventory, items);
(0, utils_1.fixEmptyChancePlates)(botConfig);
(0, FixSpecificScopeIssues_1.fixSpecificItemIssues)(usecInventory);
(0, FixSpecificScopeIssues_1.fixSpecificItemIssues)(bearInventory);
tables.bots.types.usec.inventory = usecInventory;
tables.bots.types.bear.inventory = bearInventory;
tables.bots.types.bear.inventory = tables.bots.types.usec.inventory; // TESTING << REMOVE IF SLOWER
}
catch (error) {
config_json_1.default.forceCached = true;
throw Error("Failed to dynamically update items, likely a mod conflict, turning on forceCached and will try again! \nError: " +
error);
}
}
else {
botConfig.equipment.pmc = botConfigequipmentpmc_json_1.default;
tables.bots.types.usec = tablesbotstypesusec_json_1.default;
tables.bots.types.bear = tablesbotstypesusec_json_1.default;
}
if (config_json_1.default.strictEquipmentTiering === false) {
(0, utils_1.combineWhitelist)(botConfig.equipment.pmc);
}
Object.keys(advancedConfig_json_1.default.otherBotTypes).forEach((botType) => {
botConfig.equipment[botType] = {
...botConfig.equipment[botType],
...advancedConfig_json_1.default.otherBotTypes[botType],
};
});
if (tables?.bots?.types?.assault?.generation?.items?.backpackLoot?.weights &&
new Set(Object.values(tables.bots.types.assault.generation.items.backpackLoot.weights)).size === 1) {
console.log("[AlgorithmicLevelProgression] Looting bots detected, removing scav loot");
const generation = botConfig.equipment.assault.randomisation[0]
.generation;
generation.backpackLoot = {
...(generation.looseLoot || {}),
weights: { "0": 1 },
whitelist: {},
};
generation.pocketLoot = {
...(generation.looseLoot || {}),
weights: { "0": 1 },
whitelist: {},
};
generation.vestLoot = {
...(generation.looseLoot || {}),
weights: { "0": 1 },
whitelist: {},
};
}
// saveToFile(botConfig, "botConfig.json");
// saveToFile(pmcConfig, "pmcConfig.json");
// tables.bots.types.usec
// botConfig.equipment.pmc
// saveToFile(tables.bots.types.usec, `Cache/tablesbotstypesusec.json`);
// saveToFile(botConfig.equipment.pmc, `Cache/botConfigequipmentpmc.json`);
config_json_1.default.debug ||
(config_json_1.default.forceCached &&
console.log("Algorthimic Progression: Progression Changes completed"));
}
//59ef13ca86f77445fd0e2483
//5b4329f05acfc47a86086aa1
//# sourceMappingURL=ProgressionChanges.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,22 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SetupLocationGlobals = void 0;
const GlobalValues_1 = require("./GlobalValues");
const utils_1 = require("./utils");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const SetupLocationGlobals = (container) => {
const configServer = container.resolve("ConfigServer");
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const databaseServer = container.resolve("DatabaseServer");
const profileHelper = container.resolve("ProfileHelper");
const tables = databaseServer.getTables();
GlobalValues_1.globalValues.Logger = container.resolve("WinstonLogger");
GlobalValues_1.globalValues.tables = tables;
GlobalValues_1.globalValues.profileHelper = profileHelper;
GlobalValues_1.globalValues.originalBotTypes = (0, utils_1.cloneDeep)(tables.bots.types);
GlobalValues_1.globalValues.configServer = configServer;
GlobalValues_1.globalValues.originalWeighting = (0, utils_1.cloneDeep)(botConfig.equipment.pmc);
// globalValues.setValuesForLocation("woods", 1);
};
exports.SetupLocationGlobals = SetupLocationGlobals;
//# sourceMappingURL=SetupLocationGlobals.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "SetupLocationGlobals.js",
"sourceRoot": "",
"sources": [
"SetupLocationGlobals.ts"
],
"names": [],
"mappings": ";;;AACA,iDAA8C;AAE9C,mCAAoC;AAEpC,kFAA+E;AAIxE,MAAM,oBAAoB,GAAG,CAClC,SAA8B,EACnB,EAAE;IACb,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAe,cAAc,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;IACtE,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAgB,eAAe,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;IAC1C,2BAAY,CAAC,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACzD,2BAAY,CAAC,MAAM,GAAG,MAAM,CAAC;IAC7B,2BAAY,CAAC,aAAa,GAAG,aAAa,CAAC;IAC3C,2BAAY,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,2BAAY,CAAC,YAAY,GAAG,YAAY,CAAC;IACzC,2BAAY,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACpE,iDAAiD;AACnD,CAAC,CAAC;AAfW,QAAA,oBAAoB,wBAe/B"
}

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,603 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.applyValuesToStoredEquipment = exports.buildEmptyWeightAdjustmentsByDevision = exports.buffScavGearAsLevel = exports.setPlateWeightings = exports.addItemsToBotInventory = exports.normalizeMedianInventoryValues = exports.buldTieredItemTypes = void 0;
const utils_1 = require("../LoadoutChanges/utils");
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const nonPmcBotConfig_json_1 = __importDefault(require("../../config/nonPmcBotConfig.json"));
const tablesbotstypesusec_json_1 = require("../Cache/tablesbotstypesusec.json");
const botConfigequipmentpmc_json_1 = require("../Cache/botConfigequipmentpmc.json");
const tieredItems_json_1 = __importDefault(require("../Constants/tieredItems.json"));
const mappedPresets_json_1 = __importDefault(require("../Constants/mappedPresets.json"));
const objectToOrderedList = (equipment, items) => Object.keys(equipment)
.sort((a, b) => equipment[a] - equipment[b])
.map((id) => ({ id, value: equipment[id], name: items[id]._name }));
const blackList = new Set([
"5e4abc6786f77406812bd572",
"628bc7fb408e2b2e9c0801b1",
"5b3b713c5acfc4330140bd8d",
"5e997f0b86f7741ac73993e2",
"5c0126f40db834002a125382",
"601948682627df266209af05",
"63495c500c297e20065a08b1",
"59ef13ca86f77445fd0e2483",
"670e8eab8c1bb0e5a7075acf", //mag_pm_izhmeh_9x18pm_999_infectedMagazin
"671d85439ae8365d69117ba6", //mag_tt_toz_std_762x25tt_999_infectedMagazin
"671d8617a3e45c1f5908278c", //mag_mp443_izhmeh_std_9x19_999_infectedMagazin
"671d8ac8a3e45c1f59082799", //mag_glock_glock_w_pad_9x19_999_fde_Infected
"671d8b38b769f0d88c0950f8", //mag_m1911_colt_m45a1_std_1143x23_999_infected
"671d8b8c0959c721a50ca838", //mag_usp_hk_usp_tactical_1143x23_999_infected
"628120f210e26c1f344e6558", // mxc broken mag
]);
const makeRare = new Set([
"6038b4ca92ec1c3103795a0d",
"6038b4b292ec1c3103795a0b",
"5fd4c474dd870108a754b241",
"628b9c7d45122232a872358f",
"628baf0b967de16aab5a4f36",
"628b9784bcf6e2659e09b8a2",
"628baf0b967de16aab5a4f36",
"5c0e541586f7747fa54205c9",
"5bffdd7e0db834001b734a1a",
]);
const buldTieredItemTypes = (items) => {
const result = {};
botConfigequipmentpmc_json_1.weightingAdjustmentsByBotLevel.forEach((weight, index) => {
if (index < 4)
// Prevents boss related gear appearing on normal bots
for (const key in weight.equipment.edit) {
Object.keys(weight.equipment.edit[key]).forEach((id) => {
if (blackList.has(id))
return;
if (!result[key])
result[key] = {};
result[key][id] = Math.max(result[key][id] || 1, weight.equipment.edit[key][id]);
});
}
});
for (const key in result) {
for (const id in result[key]) {
if (makeRare.has(id)) {
result[key][id] = result[key][id] * 3;
}
}
}
for (const key in result) {
const equipmentSet = result[key];
result[key] = objectToOrderedList(equipmentSet, items);
}
// AMMO
const ammo = {};
for (const caliber in tablesbotstypesusec_json_1.inventory.Ammo) {
for (const ammoId in tablesbotstypesusec_json_1.inventory.Ammo[caliber]) {
if (items[ammoId]) {
ammo[ammoId] = (0, utils_1.getAmmoWeighting)(items[ammoId]);
}
}
}
result["Ammo"] = objectToOrderedList(ammo, items);
const map = {};
for (const key in result) {
result[key].forEach(({ id, value }) => {
map[id] = value;
});
}
result["mapper"] = map;
return result;
};
exports.buldTieredItemTypes = buldTieredItemTypes;
const equipmentTypesTochange = new Set([
"TacticalVest",
"ArmorVest",
"Backpack",
"Earpiece",
"Eyewear",
"Headwear",
"FaceCover",
// "Scabbard",
"FirstPrimaryWeapon",
"Holster",
]);
const getRating = (id, dflt = 10) => tieredItems_json_1.default.mapper[id] || dflt;
const normalizeMedianInventoryValues = (inventory) => {
for (const caliber in inventory.Ammo) {
let highest = 0;
Object.values(inventory.Ammo[caliber]).forEach((value) => {
if (value > highest)
highest = value;
});
const multiplier = 100 / highest;
Object.keys(inventory.Ammo[caliber]).forEach((id) => {
inventory.Ammo[caliber][id] =
Math.round(inventory.Ammo[caliber][id] * multiplier) || 10;
});
}
for (const equipmentType in inventory.equipment) {
if (equipmentTypesTochange.has(equipmentType)) {
let highest = 0;
Object.values(inventory.equipment[equipmentType]).forEach((value) => {
if (value > highest)
highest = value;
});
const multiplier = 200 / highest;
Object.keys(inventory.equipment[equipmentType]).forEach((id) => {
inventory.equipment[equipmentType][id] =
Math.round(inventory.equipment[equipmentType][id] * multiplier) || 10;
});
}
}
};
exports.normalizeMedianInventoryValues = normalizeMedianInventoryValues;
const addItemsToBotInventory = (inventory, botToUpdate, items, isMarksman = false) => {
const { Ammo: botToUpdateAmmo, BasePlateChance, ...equipment } = botToUpdate;
const ammoToAdd = new Set([]);
Object.keys(tieredItems_json_1.default).forEach((key) => {
if (equipment[key]) {
const equipmentStart = equipment[key][0];
const equipmentEnd = equipment[key][1];
if (equipmentStart || equipmentEnd) {
const startIndex = Math.floor(tieredItems_json_1.default[key].length * equipmentStart);
const endIndex = Math.floor(tieredItems_json_1.default[key].length * equipmentEnd);
tieredItems_json_1.default[key]
.slice(startIndex, endIndex)
.forEach(({ id, value }) => {
if ((!botToUpdate.AllowSniperRifles &&
(0, utils_1.checkParentRecursive)(id, items, [
utils_1.weaponTypeNameToId.SniperRifle,
utils_1.weaponTypeNameToId.MarksmanRifle,
])) ||
(isMarksman &&
key === "FirstPrimaryWeapon" &&
!(0, utils_1.checkParentRecursive)(id, items, [
utils_1.weaponTypeNameToId.SniperRifle,
utils_1.weaponTypeNameToId.MarksmanRifle,
utils_1.weaponTypeNameToId.AssaultCarbine,
]))) {
// if (isMarksman && key === "FirstPrimaryWeapon")
// console.log(items[id]._name);
return;
}
if (utils_1.blacklistedItems.has(id) || blackList.has(id))
return;
if (!inventory.equipment[key][id]) {
inventory.equipment[key][id] = value;
}
const item = items[id];
if (inventory.mods[id])
return;
switch (key) {
case "Headwear":
case "ArmorVest":
case "TacticalVest":
if (!inventory.mods[id]) {
const newModObject = {};
item._props.Slots.forEach((mod) => {
if (mod._props.filters[0].Plate) {
newModObject[mod._name] = newModObject[mod._name] = [
mod._props.filters[0].Plate,
];
}
});
inventory.mods[id] = newModObject;
}
break;
case "FirstPrimaryWeapon":
case "Holster":
if (!tablesbotstypesusec_json_1.inventory.mods[id] || !mappedPresets_json_1.default[id]) {
break;
}
inventory.mods[id] = mappedPresets_json_1.default[id];
// if (isMarksman) console.log(items[id]._name);
if (tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon"]) {
mappedPresets_json_1.default[id]["patron_in_weapon"] =
tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon"];
}
if (tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_000"]) {
mappedPresets_json_1.default[id]["patron_in_weapon_000"] =
tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_000"];
}
if (tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_001"]) {
mappedPresets_json_1.default[id]["patron_in_weapon_001"] =
tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_001"];
}
const ammo = [
...(tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon"]
? tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon"]
: []),
...(tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_000"]
? tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_000"]
: []),
...(tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_001"]
? tablesbotstypesusec_json_1.inventory.mods[id]["patron_in_weapon_001"]
: []),
];
ammo.forEach((id) => {
ammoToAdd.add(id);
});
break;
default:
break;
}
});
}
}
});
if (botToUpdate?.Ammo?.[1] > 0) {
const Ammo = tieredItems_json_1.default.Ammo;
const ammoStart = botToUpdateAmmo[0];
const ammoEnd = botToUpdateAmmo[1];
if (ammoStart || ammoEnd) {
const startIndex = Math.floor(Ammo.length * ammoStart);
const endIndex = Math.floor(Ammo.length * ammoEnd);
const toAddAmmo = [...ammoToAdd]
.map((id) => ({
id,
value: tieredItems_json_1.default.mapper[id],
}))
.sort((a, b) => a.value - b.value);
const toAddAmmoStartIndex = Math.floor(toAddAmmo.length * ammoStart);
const toAddAmmoEndIndex = Math.floor(toAddAmmo.length * ammoEnd);
[
...toAddAmmo.slice(toAddAmmoStartIndex, toAddAmmoEndIndex),
...Ammo.slice(startIndex, endIndex),
].forEach(({ id, value }) => {
const calibre = items[id]?._props?.Caliber || items[id]?._props?.ammoCaliber;
if (calibre &&
inventory.Ammo[calibre] &&
!inventory.Ammo?.[calibre]?.[id]) {
inventory.Ammo[calibre][id] = value;
}
});
}
}
// Add all plates to all equipment for all bots <<PLATE VARIETY>>
Object.keys(inventory.mods).forEach((id) => {
if (!(0, utils_1.checkParentRecursive)(id, items, [utils_1.headwearParent]) &&
(0, utils_1.checkParentRecursive)(id, items, [utils_1.armorParent, utils_1.rigParent])) {
const item = items[id];
if (item?._props?.Slots?.length > 0) {
// if (!inventory.mods[id]) {
const newModObject = {};
item._props.Slots.forEach((mod) => {
if (mod._props.filters[0].Plate) {
newModObject[mod._name] = mod._props.filters[0].Filter;
}
});
if (Object.keys(newModObject).length)
inventory.mods[id] = newModObject;
}
}
});
const itemsToAdd = new Set([]);
Object.keys(inventory.mods).forEach((id) => {
Object.values(inventory.mods[id])
.flat(1)
.forEach((item) => {
if (!inventory.mods[item])
itemsToAdd.add(item);
});
});
while (itemsToAdd.size) {
const [id] = itemsToAdd;
if (!inventory.mods[id]) {
if (mappedPresets_json_1.default[id]) {
inventory.mods[id] = mappedPresets_json_1.default[id];
}
else if (tablesbotstypesusec_json_1.inventory.mods[id]) {
inventory.mods[id] = tablesbotstypesusec_json_1.inventory.mods[id];
}
}
itemsToAdd.delete(id);
}
(0, utils_1.deleteBlacklistedItemsFromInventory)(inventory, blackList);
};
exports.addItemsToBotInventory = addItemsToBotInventory;
const defaultRandomisation = [
{
levelRange: {
min: 1,
max: 100,
},
equipmentMods: { mod_nvg: 0 },
},
];
const setPlateWeightings = (name, equipmentFilters, index) => {
equipmentFilters.armorPlateWeighting = [
{
levelRange: {
min: 1,
max: 100,
},
front_plate: {
"1": 1,
"2": 3,
"3": 20,
"4": 20,
"5": 4,
"6": 1,
},
back_plate: {
"1": 1,
"2": 3,
"3": 20,
"4": 20,
"5": 4,
"6": 1,
},
side_plate: {
"1": 1,
"2": 3,
"3": 20,
"4": 20,
"5": 4,
"6": 1,
},
left_side_plate: {
"1": 1,
"2": 3,
"3": 20,
"4": 20,
"5": 4,
"6": 1,
},
right_side_plate: {
"1": 1,
"2": 3,
"3": 20,
"4": 20,
"5": 4,
"6": 1,
},
},
];
if (!nonPmcBotConfig_json_1.default.nonPmcBots?.[name]?.BasePlateChance) {
return;
}
//=========================================
// UPDATE PLATE SPAWN CHANCE
if (!equipmentFilters?.randomisation) {
equipmentFilters.randomisation = defaultRandomisation;
}
const randomizationToUpdate = (0, utils_1.cloneDeep)(equipmentFilters.randomisation[0]);
if (nonPmcBotConfig_json_1.default.nonPmcBots[name].BasePlateChance < 101) {
let front = nonPmcBotConfig_json_1.default.nonPmcBots[name].BasePlateChance + index * 15;
if (front > 100)
front = 100;
randomizationToUpdate.equipmentMods["front_plate"] = front;
let back = nonPmcBotConfig_json_1.default.nonPmcBots[name].BasePlateChance - 20 + index * 15;
if (back > 100)
back = 100;
randomizationToUpdate.equipmentMods["back_plate"] = back;
}
if (nonPmcBotConfig_json_1.default.nonPmcBots?.[name]?.SidePlateChance) {
["left_side_plate", "right_side_plate"].forEach((key) => {
let value = nonPmcBotConfig_json_1.default.nonPmcBots[name].SidePlateChance + index * 10;
if (value > 100)
value = 100;
if (value < 0)
value = 0;
randomizationToUpdate.equipmentMods[key] = value;
});
}
else {
["left_side_plate", "right_side_plate"].forEach((key) => {
let value = nonPmcBotConfig_json_1.default.nonPmcBots[name].BasePlateChance - 30 + index * 10;
if (value > 100)
value = 100;
if (value < 0)
value = 0;
randomizationToUpdate.equipmentMods[key] = value;
});
}
// console.log(name, randomizationToUpdate.equipmentMods);
equipmentFilters.randomisation[0] = randomizationToUpdate;
//=========================================
};
exports.setPlateWeightings = setPlateWeightings;
const buffScavGearAsLevel = (equipmentFilters, index) => {
equipmentFilters.weightingAdjustmentsByPlayerLevel = [
{
levelRange: {
min: 1,
max: 99,
},
},
];
if (!index)
return;
const randomizationToUpdate = (0, utils_1.cloneDeep)(advancedConfig_json_1.default.otherBotTypes.assault.randomisation[0]);
[
"Headwear",
"Earpiece",
"ArmorVest",
"FaceCover",
// "Scabbard",
"Eyewear",
"Backpack",
].forEach((key) => {
randomizationToUpdate.equipment[key] += index * 15;
if (randomizationToUpdate.equipment[key] > 99)
randomizationToUpdate.equipment[key] = 99;
});
equipmentFilters.randomisation[0] = randomizationToUpdate;
equipmentFilters.blacklist = advancedConfig_json_1.default.otherBotTypes.assault.blacklist;
equipmentFilters.whitelist = advancedConfig_json_1.default.otherBotTypes.assault.whitelist;
};
exports.buffScavGearAsLevel = buffScavGearAsLevel;
const buildEmptyWeightAdjustmentsByDevision = (botToUpdate) => {
const { tiers } = botToUpdate;
const result = [];
tiers.forEach((tier) => {
result.push({
levelRange: {
min: tier[0],
max: tier[1],
},
ammo: {},
equipment: {},
});
});
return result;
};
exports.buildEmptyWeightAdjustmentsByDevision = buildEmptyWeightAdjustmentsByDevision;
const applyValuesToStoredEquipment = (inventory, items, storedWeightingAdjustmentDetails) => {
const ammoList = {};
Object.keys(inventory.Ammo).forEach((key) => {
ammoList[key] = [];
Object.keys(inventory.Ammo[key]).forEach((id) => {
//Zero out ammo
ammoList[key].push({
id,
rating: (0, utils_1.getAmmoWeighting)(items[id]), // + inventory.Ammo[key][id],
});
});
});
Object.keys(ammoList).forEach((key) => {
ammoList[key] = ammoList[key].sort((a, b) => a.rating - b.rating);
});
const equipmentList = {};
Object.keys(inventory.equipment).forEach((key) => {
if (equipmentTypesTochange.has(key)) {
equipmentList[key] = [];
Object.keys(inventory.equipment[key]).forEach((id) => {
//Zero out equipment
if (key === "FirstPrimaryWeapon" || key === "Holster") {
const defAmmoWeight = (0, utils_1.getAmmoWeighting)(items[items[id]._props.defAmmo]);
equipmentList[key].push({
id,
rating: getRating(id),
// + inventory.equipment[key][id],
});
}
else {
equipmentList[key].push({
id,
rating: getRating(id), //+ inventory.equipment[key][id],
});
}
});
}
});
Object.keys(equipmentList).forEach((key) => {
equipmentList[key] = equipmentList[key].sort((a, b) => a.rating - b.rating);
});
const division = storedWeightingAdjustmentDetails.length;
for (let index = 0; index < division; index++) {
const currentLevelRange = storedWeightingAdjustmentDetails[index];
Object.keys(ammoList).forEach((key) => {
const listPortion = ammoList[key];
const quantityPerLevel = Math.round(listPortion.length / division);
const resultingList = listPortion.slice(0, index === division - 1
? listPortion.length
: index * quantityPerLevel + quantityPerLevel);
resultingList.forEach(({ id, rating }) => {
if (!currentLevelRange.ammo[key])
currentLevelRange.ammo[key] = {};
currentLevelRange.ammo[key][id] =
Math.round(rating + rating * (index * 0.4)) + inventory.Ammo[key][id];
});
});
Object.keys(equipmentList).forEach((key) => {
const listPortion = equipmentList[key];
const quantityPerLevel = Math.round(listPortion.length / division);
const resultingList = listPortion.slice(0, index === division - 1
? listPortion.length
: index * quantityPerLevel + quantityPerLevel);
resultingList.forEach(({ id, rating }) => {
if (!currentLevelRange.equipment[key])
currentLevelRange.equipment[key] = {};
currentLevelRange.equipment[key][id] =
Math.round(rating + rating * (index * 0.4)) +
inventory.equipment[key][id];
});
});
}
storedWeightingAdjustmentDetails.forEach((_, index) => {
const weight = storedWeightingAdjustmentDetails[index];
Object.keys(weight.ammo).forEach((caliber) => {
const caliberList = Object.keys(weight.ammo[caliber]).sort((a, b) => weight.ammo[caliber][b] - weight.ammo[caliber][a]);
caliberList.forEach((id, rank) => {
if (caliberList.length > 1 && rank > 0) {
if (rank > 3) {
weight.ammo[caliber][id] = Math.round(weight.ammo[caliber][id] * 0.5);
}
else {
const modifier = (caliberList.length - rank) / caliberList.length;
weight.ammo[caliber][id] =
Math.round(weight.ammo[caliber][id] * modifier) || 1;
}
}
});
});
// Apply randomness
for (const category in weight.ammo) {
const randomnessMultiplier = nonPmcBotConfig_json_1.default.botAmmoRandomness;
if (!randomnessMultiplier)
return;
const list = weight.ammo[category];
const keys = Object.keys(list);
const sortedValues = Object.values(list).sort((a, b) => a - b);
const middleIndex = 0 + Math.round((sortedValues.length - 1) / 2);
const medianValue = sortedValues[middleIndex];
const highestValue = sortedValues[sortedValues.length - 1];
const lowestValue = sortedValues[0];
const betterValue = Math.round((medianValue + highestValue + lowestValue) / 3);
if (betterValue > 1) {
keys.forEach((key) => {
const valToAdjust = list[key];
if (valToAdjust > 5) {
const adjustedAmountMax = betterValue - valToAdjust;
const amountAfterAdjustment = Math.round(valToAdjust + adjustedAmountMax * randomnessMultiplier);
if (weight.ammo[category][key]) {
weight.ammo[category][key] = Math.abs(amountAfterAdjustment);
}
}
});
}
}
// Fix weapon weightings
Object.keys(weight.equipment?.FirstPrimaryWeapon || []).forEach((id) => {
const calibre = items[id]?._props?.Caliber || items[id]?._props?.ammoCaliber;
if (calibre && weight.ammo[calibre]) {
let highestRating = 0;
Object.keys(weight.ammo[calibre]).forEach((key) => {
if (weight.ammo[calibre][key] > highestRating) {
highestRating = weight.ammo[calibre][key];
}
});
if (highestRating) {
weight.equipment.FirstPrimaryWeapon[id] = (0, utils_1.getWeaponWeighting)(items[id], highestRating);
}
}
});
for (const category in weight.equipment) {
const randomnessMultiplier = nonPmcBotConfig_json_1.default.botEquipmentRandomness;
if (!randomnessMultiplier)
return;
const list = weight.equipment[category];
const keys = Object.keys(list);
const sortedValues = Object.values(list).sort((a, b) => a - b);
const middleIndex = 0 + Math.round((sortedValues.length - 1) / 2);
const medianValue = sortedValues[middleIndex];
const highestValue = sortedValues[sortedValues.length - 1];
const lowestValue = sortedValues[0];
const betterValue = Math.round((medianValue + highestValue + lowestValue) / 3);
if (betterValue > 1) {
keys.forEach((key) => {
const valToAdjust = list[key];
if (valToAdjust > 5) {
const adjustedAmountMax = betterValue - valToAdjust;
const amountAfterAdjustment = Math.round(valToAdjust + adjustedAmountMax * randomnessMultiplier);
if (weight.equipment[category][key]) {
weight.equipment[category][key] = Math.abs(amountAfterAdjustment);
}
}
});
}
}
});
};
exports.applyValuesToStoredEquipment = applyValuesToStoredEquipment;
//# sourceMappingURL=NonPmcUtils.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,98 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = SetupNonPMCBotChanges;
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const config_json_1 = __importDefault(require("../../config/config.json"));
const nonPmcBotConfig_json_1 = __importDefault(require("../../config/nonPmcBotConfig.json"));
const NonPmcUtils_1 = require("./NonPmcUtils");
const GlobalValues_1 = require("../LoadoutChanges/GlobalValues");
function SetupNonPMCBotChanges(container) {
const databaseServer = container.resolve("DatabaseServer");
const tables = databaseServer.getTables();
const items = tables.templates.items;
const botsForUpdate = nonPmcBotConfig_json_1.default?.nonPmcBots;
const configServer = container.resolve("ConfigServer");
// const tieredItemTypes = buldTieredItemTypes(items);
// saveToFile(tieredItemTypes, "Constants/tieredItems.json");
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
Object.keys(botsForUpdate).forEach((name) => {
if (nonPmcBotConfig_json_1.default.ignoreList.includes(name))
return;
if (botConfig.equipment?.[name]?.weightingAdjustmentsByPlayerLevel) {
botConfig.equipment[name].weightingAdjustmentsByPlayerLevel = [];
}
if (botConfig.equipment[name] &&
!botConfig.equipment[name]?.forceOnlyArmoredRigWhenNoArmor &&
nonPmcBotConfig_json_1.default.nonPmcBots[name].forceOnlyArmoredRigWhenNoArmor) {
botConfig.equipment[name]["forceOnlyArmoredRigWhenNoArmor"] = true;
}
if (!tables.bots.types[name]?.inventory?.Ammo)
return;
const inventory = tables.bots.types[name].inventory;
const chances = tables.bots.types[name].chances;
if (name !== "assault") {
Object.keys(nonPmcBotConfig_json_1.default.nonPmcBots[name]).forEach((key) => {
if (chances.equipment[key] !== undefined &&
chances.equipment[key] < 30 &&
nonPmcBotConfig_json_1.default.nonPmcBots[name][key][1] > 0) {
switch (key) {
case "Scabbard":
break;
case "Backpack":
case "Holster":
case "Eyewear":
case "FaceCover":
case "Earpiece":
chances.equipment[key] = 30;
break;
default:
if (name.includes("infected")) {
chances.equipment[key] = 50;
break;
}
chances.equipment[key] = 70;
break;
}
}
});
if (chances.equipment.SecondPrimaryWeapon) {
chances.equipment.SecondPrimaryWeapon = 10;
}
else {
chances.equipment.SecondPrimaryWeapon = 0;
}
// console.log("\n");
}
// if (name === "marksman") {
// saveToFile(tables.bots.types[name].inventory, `refDBS/marksman.json`);
// }
// console.log("\n", name);
(0, NonPmcUtils_1.addItemsToBotInventory)(inventory, nonPmcBotConfig_json_1.default.nonPmcBots[name], items, name === "marksman");
if (nonPmcBotConfig_json_1.default.nonPmcBots[name].HasModdedWeapons) {
inventory.mods = tables.bots.types.usec.inventory.mods;
}
(0, NonPmcUtils_1.normalizeMedianInventoryValues)(inventory);
const storedEquipmentValues = (0, NonPmcUtils_1.buildEmptyWeightAdjustmentsByDevision)(nonPmcBotConfig_json_1.default.nonPmcBots[name]);
(0, NonPmcUtils_1.applyValuesToStoredEquipment)(inventory, items, storedEquipmentValues);
// if (name === "marksman") {
// saveToFile(tables.bots.types[name].inventory, `refDBS/marksman2.json`);
// }
GlobalValues_1.globalValues.storedEquipmentValues[name] = storedEquipmentValues;
});
// console.log(bots);
// saveToFile(
// globalValues.storedEquipmentValues,
// `refDBS/storedEquipmentValues.json`
// );
// saveToFile(botConfig.equipment.assault, "refDBS/equipmentAssault.json");
// saveToFile(
// globalValues.tables.bots.types["assault"]?.inventory,
// `NonPmcBotChanges/botsRef/storedAssault.json`
// );
config_json_1.default.debug &&
console.log("Algorthimic Progression: nonPmcBots equipment stored!");
}
//# sourceMappingURL=SetupNonPMCBotChanges.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "SetupNonPMCBotChanges.js",
"sourceRoot": "",
"sources": [
"SetupNonPMCBotChanges.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,66 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const BotLevelChanges_1 = __importDefault(require("./LevelChanges/BotLevelChanges"));
const config_json_1 = require("../config/config.json");
const ProgressionChanges_1 = __importDefault(require("./LoadoutChanges/ProgressionChanges"));
const SetupLocationGlobals_1 = require("./LoadoutChanges/SetupLocationGlobals");
const LocationUpdater_1 = require("./LoadoutChanges/LocationUpdater");
const SetupNonPMCBotChanges_1 = __importDefault(require("./NonPmcBotChanges/SetupNonPMCBotChanges"));
const ClothingChanges_1 = __importDefault(require("./LoadoutChanges/ClothingChanges"));
const GlobalValues_1 = require("./LoadoutChanges/GlobalValues");
const utils_1 = require("./LoadoutChanges/utils");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
class AlgorithmicLevelProgression {
preSptLoad(container) {
config_json_1.enableLevelChanges && (0, BotLevelChanges_1.default)(container);
config_json_1.enableProgressionChanges && (0, LocationUpdater_1.LocationUpdater)(container);
}
postDBLoad(container) {
if (config_json_1.enableProgressionChanges) {
try {
(0, ProgressionChanges_1.default)(container);
}
catch (error) {
const Logger = container.resolve("WinstonLogger");
const hasForceCachedChanged = !!error?.message?.includes("forceCached");
if (hasForceCachedChanged) {
Logger.error(`Algorithmic Level Progression failed to make progression changes.
Trying again using "forceCached" enabled.
Try changing your mod loader so ALP is earlier than mods that add custom items to avoid this message in the future.
Error: ` + error?.message);
(0, ProgressionChanges_1.default)(container);
}
else {
Logger.error(`Algorithmic Level Progression failed to make progression changes.
Try changing your mod loader so ALP is earlier than mods that add custom items
Error: ` + error?.message);
}
}
(0, SetupLocationGlobals_1.SetupLocationGlobals)(container);
}
config_json_1.enableNonPMCBotChanges && (0, SetupNonPMCBotChanges_1.default)(container);
const databaseServer = container.resolve("DatabaseServer");
const tables = databaseServer.getTables();
const configServer = container.resolve("ConfigServer");
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
GlobalValues_1.globalValues.originalBotTypes = (0, utils_1.cloneDeep)(tables.bots.types);
GlobalValues_1.globalValues.originalWeighting = (0, utils_1.cloneDeep)(botConfig.equipment.pmc);
// globalValues.updateInventory(1, "woods"); // REMOVE
}
postSptLoad(container) {
try {
config_json_1.leveledClothing && (0, ClothingChanges_1.default)(container);
}
catch (error) {
const Logger = container.resolve("WinstonLogger");
Logger.error(`Algorithmic Level Progression failed to makeclothing changes.
Try turning off custom clothing in the config!
Error: ` + error?.message);
}
}
}
module.exports = { mod: new AlgorithmicLevelProgression() };
//# sourceMappingURL=mod.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "mod.js",
"sourceRoot": "",
"sources": [
"mod.ts"
],
"names": [],
"mappings": ";;;;;AAKA,qFAA6D;AAC7D,uDAK+B;AAC/B,6FAAqE;AACrE,gFAA6E;AAC7E,sEAAmE;AACnE,qGAA6E;AAC7E,uFAA+D;AAE/D,gEAA6D;AAC7D,kDAAmD;AAInD,kFAA+E;AAE/E,MAAM,2BAA2B;IAG/B,UAAU,CAAC,SAA8B;QACvC,gCAAkB,IAAI,IAAA,yBAAe,EAAC,SAAS,CAAC,CAAC;QACjD,sCAAwB,IAAI,IAAA,iCAAe,EAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAED,UAAU,CAAC,SAA8B;QACvC,IAAI,sCAAwB,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,IAAA,4BAAkB,EAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;gBAC3D,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;gBACxE,IAAI,qBAAqB,EAAE,CAAC;oBAC1B,MAAM,CAAC,KAAK,CACV;;;oBAGQ,GAAG,KAAK,EAAE,OAAO,CAC1B,CAAC;oBACF,IAAA,4BAAkB,EAAC,SAAS,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,KAAK,CACV;;oBAEQ,GAAG,KAAK,EAAE,OAAO,CAC1B,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,IAAA,2CAAoB,EAAC,SAAS,CAAC,CAAC;QAClC,CAAC;QACD,oCAAsB,IAAI,IAAA,+BAAqB,EAAC,SAAS,CAAC,CAAC;QAC3D,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;QAC1C,MAAM,YAAY,GAAG,SAAS,CAAC,OAAO,CAAe,cAAc,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;QACtE,2BAAY,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7D,2BAAY,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QACpE,sDAAsD;IACxD,CAAC;IAED,WAAW,CAAC,SAA8B;QACxC,IAAI,CAAC;YACH,6BAAe,IAAI,IAAA,yBAAe,EAAC,SAAS,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;YAC3D,MAAM,CAAC,KAAK,CACV;;gBAEQ,GAAG,KAAK,EAAE,OAAO,CAC1B,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,2BAA2B,EAAE,EAAE,CAAC"
}

View file

@ -39,7 +39,7 @@
"excluded_bosses": [ "sptBear", "sptUsec" ]
},
"only_make_changes_just_after_spawning": {
"enabled": false,
"enabled": true,
"time_limit": 5,
"affected_systems" : {
"loot_destruction": true,

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,116 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommonUtils = void 0;
const config_json_1 = __importDefault(require("../config/config.json"));
class CommonUtils {
logger;
databaseTables;
localeService;
static fenceID = "579dc571d53a0658a154fbec";
debugMessagePrefix = "[Late to the Party] ";
translations;
constructor(logger, databaseTables, localeService) {
this.logger = logger;
this.databaseTables = databaseTables;
this.localeService = localeService;
// Get all translations for the current locale
this.translations = this.localeService.getLocaleDb();
}
logInfo(message, alwaysShow = false) {
if (config_json_1.default.debug.enabled || alwaysShow)
this.logger.info(this.debugMessagePrefix + message);
}
logWarning(message) {
this.logger.warning(this.debugMessagePrefix + message);
}
logError(message) {
this.logger.error(this.debugMessagePrefix + message);
}
getItemName(itemID) {
const translationKey = `${itemID} Name`;
if (translationKey in this.translations)
return this.translations[translationKey];
// If a key can't be found in the translations dictionary, fall back to the template data if possible
if (!(itemID in this.databaseTables.templates.items)) {
return undefined;
}
const item = this.databaseTables.templates.items[itemID];
return item._name;
}
getMaxItemPrice(itemID) {
// Get the handbook.json price, if any exists
const matchingHandbookItems = this.databaseTables.templates.handbook.Items.filter((i) => i.Id === itemID);
let handbookPrice = 0;
if (matchingHandbookItems.length === 1) {
handbookPrice = matchingHandbookItems[0].Price;
// Some mods add a record with a junk value
if ((handbookPrice == null) || Number.isNaN(handbookPrice)) {
this.logWarning(`Invalid handbook price (${handbookPrice}) for ${this.getItemName(itemID)} (${itemID}). Defaulting to 0.`);
handbookPrice = 0;
}
}
// Get the prices.json price, if any exists
let price = 0;
if (itemID in this.databaseTables.templates.prices) {
price = this.databaseTables.templates.prices[itemID];
// Some mods add a record with a junk value
if ((price == null) || Number.isNaN(price)) {
// Only show a warning if the method will return 0
if (handbookPrice === 0) {
this.logWarning(`Invalid price (${price}) for ${this.getItemName(itemID)} (${itemID}). Defaulting to 0.`);
}
price = 0;
}
}
return Math.max(handbookPrice, price);
}
/**
* Check if @param item is a child of the item with ID @param parentID
*/
static hasParent(item, parentID, databaseTables) {
const allParents = CommonUtils.getAllParents(item, databaseTables);
return allParents.includes(parentID);
}
static getAllParents(item, databaseTables) {
if ((item._parent === null) || (item._parent === undefined) || (item._parent === ""))
return [];
const allParents = CommonUtils.getAllParents(databaseTables.templates.items[item._parent], databaseTables);
allParents.push(item._parent);
return allParents;
}
static canItemDegrade(item, databaseTables) {
if (item.upd === undefined) {
return false;
}
if ((item.upd.MedKit === undefined) && (item.upd.Repairable === undefined) && (item.upd.Resource === undefined)) {
return false;
}
const itemTpl = databaseTables.templates.items[item._tpl];
if ((itemTpl._props.armorClass !== undefined) && (itemTpl._props.armorClass.toString() === "0")) {
return false;
}
return true;
}
static interpolateForFirstCol(array, value) {
if (array.length === 1) {
return array[array.length - 1][1];
}
if (value <= array[0][0]) {
return array[0][1];
}
for (let i = 1; i < array.length; i++) {
if (array[i][0] >= value) {
if (array[i][0] - array[i - 1][0] === 0) {
return array[i][1];
}
return array[i - 1][1] + (value - array[i - 1][0]) * (array[i][1] - array[i - 1][1]) / (array[i][0] - array[i - 1][0]);
}
}
return array[array.length - 1][1];
}
}
exports.CommonUtils = CommonUtils;
//# sourceMappingURL=CommonUtils.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "CommonUtils.js",
"sourceRoot": "",
"sources": [
"CommonUtils.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,422 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LootRankingGenerator = void 0;
const config_json_1 = __importDefault(require("../config/config.json"));
const CommonUtils_1 = require("./CommonUtils");
const verboseLogging = false;
const lootFilePath = `${__dirname}/../db/lootRanking.json`;
class LootRankingGenerator {
commonUtils;
databaseTables;
fileSystem;
botWeaponGenerator;
hashUtil;
constructor(commonUtils, databaseTables, fileSystem, botWeaponGenerator, hashUtil) {
this.commonUtils = commonUtils;
this.databaseTables = databaseTables;
this.fileSystem = fileSystem;
this.botWeaponGenerator = botWeaponGenerator;
this.hashUtil = hashUtil;
}
getLootRankingDataFromFile() {
if (!this.fileSystem.exists(lootFilePath)) {
this.commonUtils.logWarning("Loot ranking data not found. Creating empty loot ranking file...");
// Generate empty file
const rankingData = {
costPerSlot: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.cost_per_slot,
weight: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.weight,
size: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.size,
gridSize: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.gridSize,
maxDim: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.max_dim,
armorClass: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.armor_class,
parentWeighting: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents,
items: {}
};
const rankingDataStr = JSON.stringify(rankingData);
this.fileSystem.write(lootFilePath, rankingDataStr);
}
const rankingDataStr = this.fileSystem.read(lootFilePath);
return JSON.parse(rankingDataStr);
}
generateLootRankingData(sessionId) {
if (!config_json_1.default.destroy_loot_during_raid.loot_ranking.enabled) {
this.commonUtils.logInfo("Loot ranking is disabled in config.json.");
return;
}
if (this.validLootRankingDataExists()) {
this.commonUtils.logInfo("Using existing loot ranking data.");
return;
}
this.commonUtils.logInfo("Creating loot ranking data...", true);
// Create ranking data for each item found in the server database
const items = {};
for (const itemID in this.databaseTables.templates.items) {
if (this.databaseTables.templates.items[itemID]._type === "Node") {
continue;
}
if (this.databaseTables.templates.items[itemID]._props.QuestItem) {
continue;
}
items[this.databaseTables.templates.items[itemID]._id] = this.generateLookRankingForItem(this.databaseTables.templates.items[itemID], sessionId);
}
// Generate the file contents
const rankingData = {
costPerSlot: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.cost_per_slot,
weight: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.weight,
size: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.size,
gridSize: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.gridSize,
maxDim: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.max_dim,
armorClass: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.armor_class,
parentWeighting: config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents,
items: items
};
const rankingDataStr = JSON.stringify(rankingData);
this.fileSystem.write(lootFilePath, rankingDataStr);
this.commonUtils.logInfo("Creating loot ranking data...done.", true);
}
generateLookRankingForItem(item, sessionId) {
// Get required item properties from the server database
const cost = this.commonUtils.getMaxItemPrice(item._id);
let weight = item._props.Weight;
let size = item._props.Width * item._props.Height;
let maxDim = Math.max(item._props.Width, item._props.Height);
// If the item is a weapon, find a suitable assembled version of it
if (item._props.weapClass !== undefined) {
// First try to find the most desirable weapon from the traders
let bestWeaponMatch = this.findBestWeaponMatchfromTraders(item);
// If the weapon isn't offered by any traders, find the most desirable version in the presets
if (bestWeaponMatch.length === 0) {
if (verboseLogging)
this.commonUtils.logInfo(`Could not find ${this.commonUtils.getItemName(item._id)} in trader assorts.`);
bestWeaponMatch = this.findBestWeaponInPresets(item);
}
// Ensure a weapon has been generated
if (bestWeaponMatch.length === 0) {
this.commonUtils.logError(`Could not generate a weapon for ${this.commonUtils.getItemName(item._id)}`);
}
else {
const [weaponWidth, weaponHeight, weaponWeight] = this.getWeaponProperties(item, bestWeaponMatch);
if (verboseLogging)
this.commonUtils.logInfo(`Found weapon ${this.commonUtils.getItemName(item._id)}: Width=${weaponWidth},Height=${weaponHeight},Weight=${weaponWeight}`);
weight = weaponWeight;
size = weaponWidth * weaponHeight;
maxDim = Math.max(weaponWidth, weaponHeight);
}
}
// Check if the item has a grid in which other items can be placed (i.e. a backpack)
let gridSize = 0;
if (item._props.Grids !== undefined) {
for (const grid in item._props.Grids) {
gridSize += item._props.Grids[grid]._props.cellsH * item._props.Grids[grid]._props.cellsV;
}
}
// Get the armor class for the item if applicable
let armorClass = 0;
if (item._props.armorClass !== undefined) {
armorClass = Number(item._props.armorClass);
}
// Calculate the cost per slot
// If the item can be equipped (backpacks, weapons, etc.), use the inventory slot size (1) instead of the item's total size
let costPerSlot = cost;
if (!this.canEquipItem(item)) {
costPerSlot /= size;
}
// Generate the loot-ranking value based on the item properties and weighting in config.json
let value = costPerSlot * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.cost_per_slot;
value += weight * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.weight;
value += size * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.size;
value += gridSize * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.gridSize;
value += maxDim * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.max_dim;
value += armorClass * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.armor_class;
// Determine how much additional weighting to apply if the item is a parent of any defined in config.json
let parentWeighting = 0;
for (const parentID in config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents) {
if (CommonUtils_1.CommonUtils.hasParent(item, parentID, this.databaseTables)) {
parentWeighting += config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents[parentID].value;
}
}
value += parentWeighting;
// Create the object to store in lootRanking.json
const data = {
id: item._id,
name: this.commonUtils.getItemName(item._id),
value: value,
costPerSlot: costPerSlot,
weight: weight,
size: size,
gridSize: gridSize,
maxDim: maxDim,
armorClass: armorClass,
parentWeighting: parentWeighting
};
return data;
}
findBestWeaponInPresets(item) {
let weapon = [];
for (const presetID in this.databaseTables.globals.ItemPresets) {
const preset = this.databaseTables.globals.ItemPresets[presetID];
if (preset._items[0]._tpl === item._id) {
// Store the initial weapon selection
if (weapon.length === 0) {
weapon = preset._items;
continue;
}
// Determine if the weapon is better than the previous one found
if (this.weaponBaseValue(item, preset._items) > this.weaponBaseValue(item, weapon)) {
weapon = preset._items;
}
}
}
// If there are no presets for the weapon, create one
if (weapon.length === 0) {
return this.generateWeaponPreset(item)._items;
}
return weapon;
}
generateWeaponPreset(item) {
const baseWeapon = {
_id: this.hashUtil.generate(),
_tpl: item._id
};
const weapon = this.fillItemSlots(baseWeapon, []);
if (verboseLogging)
this.commonUtils.logInfo(`Creating preset for ${this.commonUtils.getItemName(item._id)}...`);
for (const weaponPart in weapon) {
if (verboseLogging)
this.commonUtils.logInfo(`Creating preset for ${this.commonUtils.getItemName(item._id)}...found ${this.commonUtils.getItemName(weapon[weaponPart]._tpl)}`);
}
const preset = {
_id: this.hashUtil.generate(),
_type: "Preset",
_changeWeaponName: false,
_name: `${item._name}_autoGen`,
_parent: weapon[0]._id,
_items: weapon
};
return preset;
}
/**
* Iterate through all possible slots in the object and add an item for all that are required
* @param item the base item containing slots
* @returns an array of Item objects containing the base item and all required attachments generated for it
*/
fillItemSlots(item, initialBannedParts) {
if (item._tpl === undefined) {
this.commonUtils.logError("Found an item with an undefined template ID. Cannot fill item slots.");
return [];
}
const itemTemplate = this.databaseTables.templates.items[item._tpl];
if (itemTemplate === undefined) {
this.commonUtils.logError(`Could not find item with template ${item._tpl}. Cannot fill item slots.`);
return [];
}
let isValid = false;
let filledItem;
const bannedParts = [].concat(initialBannedParts);
while (!isValid) {
// Create the initial candidate for the array that will be returned
filledItem = [];
filledItem.push(item);
for (const slot in itemTemplate._props.Slots) {
if ((itemTemplate._props.Slots[slot]._required !== undefined) && !itemTemplate._props.Slots[slot]._required) {
continue;
}
// Sort the array of items that can be attached to the slot in order of ascending price
const filters = itemTemplate._props.Slots[slot]._props.filters[0].Filter;
const validFilters = filters.filter((f) => this.databaseTables.templates.items[f] !== undefined && this.databaseTables.templates.items[f]._id !== undefined);
const filtersSorted = validFilters.sort((f1, f2) => {
const f1Price = this.databaseTables.templates.items[f1]._id;
const f2Price = this.databaseTables.templates.items[f2]._id;
if (f1Price > f2Price)
return -1;
if (f1Price < f2Price)
return 1;
return 0;
});
// Add the first valid item to the slot along with all of the items attached to its (child) slots
let itemPart;
for (const filter in filtersSorted) {
if (!bannedParts.includes(filters[filter])) {
itemPart = {
_id: this.hashUtil.generate(),
_tpl: filters[filter],
parentId: item._id,
slotId: itemTemplate._props.Slots[slot]._name
};
filledItem = filledItem.concat(this.fillItemSlots(itemPart, bannedParts));
break;
}
}
if (itemPart === undefined) {
this.commonUtils.logError(`Could not find valid part to put in ${itemTemplate._props.Slots[slot]._name} for ${this.commonUtils.getItemName(item._tpl)}`);
}
}
isValid = true;
for (const itemPart in filledItem) {
// Check if any conflicting parts exist in the Item array. If so, prevent the conflicting item from being used in the next candidate
const conflictingItems = this.databaseTables.templates.items[filledItem[itemPart]._tpl]._props.ConflictingItems;
for (const conflictingItem in conflictingItems) {
if (filledItem.map(p => p._tpl).includes(conflictingItems[conflictingItem])) {
if (!bannedParts.includes(conflictingItems[conflictingItem])) {
bannedParts.push(conflictingItems[conflictingItem]);
}
isValid = false;
if (verboseLogging)
this.commonUtils.logInfo(`Finding parts for ${this.commonUtils.getItemName(item._tpl)}...${this.commonUtils.getItemName(conflictingItems[conflictingItem])} has a conflict with another part`);
break;
}
}
if (!isValid) {
break;
}
//this.commonUtils.logInfo(`Finding parts for ${this.commonUtils.getItemName(item._tpl)}...found ${this.commonUtils.getItemName(filledItem[itemPart]._tpl)}`);
}
}
return filledItem;
}
findBestWeaponMatchfromTraders(item) {
let weapon = [];
// Search all traders to see if they sell the weapon
for (const traderID in this.databaseTables.traders) {
const assort = this.databaseTables.traders[traderID].assort;
// Ignore traders who don't sell anything (i.e. Lightkeeper)
if ((assort === null) || (assort === undefined))
continue;
//if (verboseLogging) this.commonUtils.logInfo(`Searching ${this.databaseTables.traders[traderID].base.nickname}...`);
for (const assortID in assort.items) {
const weaponCandidate = [];
if (assort.items[assortID]._tpl === item._id) {
// Get all parts attached to the weapon
const matchingSlots = this.findChildSlotIndexesInTraderAssort(assort, assortID);
for (const matchingSlot in matchingSlots) {
weaponCandidate.push(assort.items[matchingSlots[matchingSlot]]);
}
// Store the initial weapon selection
if (weapon.length === 0) {
weapon = weaponCandidate;
continue;
}
// Determine if the weapon is better than the previous one found
if (this.weaponBaseValue(item, weaponCandidate) > this.weaponBaseValue(item, weapon)) {
weapon = weaponCandidate;
}
}
}
}
return weapon;
}
weaponBaseValue(baseWeaponItem, weaponParts) {
const [width, height, weight] = this.getWeaponProperties(baseWeaponItem, weaponParts);
let value = weight * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.weight;
value += width * height * config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.size;
return value;
}
/**
* Gets relevant weapon properties
* @param baseWeaponItem The base weapon template (namely the receiver)
* @param weaponParts All parts attached to the weapon (which may include the base weapon item itself)
* @returns [length, width, weight] of the assembled weapon
*/
getWeaponProperties(baseWeaponItem, weaponParts) {
if (baseWeaponItem._props === undefined) {
this.commonUtils.logError(`The properties of ${baseWeaponItem._id} (${this.commonUtils.getItemName(baseWeaponItem._id)}) are undefined. Cannot create loot value.`);
}
let width = baseWeaponItem._props.Width;
let height = baseWeaponItem._props.Height;
let weight = baseWeaponItem._props.Weight;
//if (verboseLogging) this.commonUtils.logInfo(`Getting properties for ${this.commonUtils.getItemName(baseWeaponItem._id)}... Base: Width=${width},Height=${height},Weight=${weight}`);
for (const weaponPart in weaponParts) {
const templateID = weaponParts[weaponPart]._tpl;
const slotID = weaponParts[weaponPart].slotId;
if (baseWeaponItem._id === templateID) {
continue;
}
weight += this.databaseTables.templates.items[templateID]._props.Weight ?? 0;
// Fold the weapon if possible
if (baseWeaponItem._props.FoldedSlot !== undefined) {
if (baseWeaponItem._props.FoldedSlot === slotID) {
//if (verboseLogging) this.commonUtils.logInfo(`Getting properties for ${this.commonUtils.getItemName(baseWeaponItem._id)}...folds with ${this.commonUtils.getItemName(templateID)} => Width=${width},Height=${height},Weight=${weight}`);
continue;
}
}
width += this.databaseTables.templates.items[templateID]._props.ExtraSizeLeft ?? 0;
width += this.databaseTables.templates.items[templateID]._props.ExtraSizeRight ?? 0;
height += this.databaseTables.templates.items[templateID]._props.ExtraSizeUp ?? 0;
height += this.databaseTables.templates.items[templateID]._props.ExtraSizeDown ?? 0;
//if (verboseLogging) this.commonUtils.logInfo(`Getting properties for ${this.commonUtils.getItemName(baseWeaponItem._id)}...found ${this.commonUtils.getItemName(templateID)} => Width=${width},Height=${height},Weight=${weight}`);
}
if (verboseLogging)
this.commonUtils.logInfo(`Getting properties for ${this.commonUtils.getItemName(baseWeaponItem._id)}... Final: Width=${width},Height=${height},Weight=${weight}`);
return [width, height, weight];
}
findChildSlotIndexesInTraderAssort(assort, parentIndex) {
let matchingSlots = [];
const parentID = assort.items[parentIndex]._id;
for (const assortID in assort.items) {
if (assort.items[assortID].parentId === parentID) {
matchingSlots.push(assortID);
matchingSlots = matchingSlots.concat(this.findChildSlotIndexesInTraderAssort(assort, assortID));
}
}
return matchingSlots;
}
validLootRankingDataExists() {
if (!this.fileSystem.exists(lootFilePath)) {
this.commonUtils.logInfo("Loot ranking data not found.");
return false;
}
if (config_json_1.default.destroy_loot_during_raid.loot_ranking.alwaysRegenerate) {
this.commonUtils.logInfo("Loot ranking data forced to regenerate.");
this.fileSystem.remove(lootFilePath);
return false;
}
// Get the current file data
const rankingData = this.getLootRankingDataFromFile();
// Check if the parent weighting in config.json matches the file data
let parentParametersMatch = true;
for (const parentID in config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents) {
if (!(parentID in rankingData.parentWeighting)) {
parentParametersMatch = false;
break;
}
if (rankingData.parentWeighting[parentID].value !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.parents[parentID].value) {
parentParametersMatch = false;
break;
}
}
// Check if the general weighting parameters in config.json match the file data
if (rankingData.costPerSlot !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.cost_per_slot ||
rankingData.maxDim !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.max_dim ||
rankingData.size !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.size ||
rankingData.gridSize !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.gridSize ||
rankingData.weight !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.weight ||
rankingData.armorClass !== config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.armor_class ||
!parentParametersMatch) {
this.commonUtils.logInfo("Loot ranking parameters have changed; deleting cached data.");
this.fileSystem.remove(lootFilePath);
return false;
}
return true;
}
canEquipItem(item) {
const defaultInventory = this.databaseTables.templates.items[config_json_1.default.destroy_loot_during_raid.loot_ranking.weighting.default_inventory_id];
if (defaultInventory === undefined) {
return false;
}
for (const slot in defaultInventory._props.Slots) {
const filters = defaultInventory._props.Slots[slot]._props.filters[0].Filter;
for (const filter in filters) {
if (CommonUtils_1.CommonUtils.hasParent(item, filters[filter], this.databaseTables)) {
//this.commonUtils.logInfo(`${this.commonUtils.getItemName(item._id)} can be equipped in ${defaultInventory._props.Slots[slot]._name}`);
return true;
}
}
}
return false;
}
}
exports.LootRankingGenerator = LootRankingGenerator;
//# sourceMappingURL=LootRankingGenerator.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,211 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/naming-convention */
const config_json_1 = __importDefault(require("../config/config.json"));
const CommonUtils_1 = require("./CommonUtils");
const LootRankingGenerator_1 = require("./LootRankingGenerator");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const modName = "LateToTheParty";
class LateToTheParty {
commonUtils;
lootRankingGenerator;
logger;
locationConfig;
inRaidConfig;
configServer;
databaseServer;
databaseTables;
fileSystem;
localeService;
botWeaponGenerator;
hashUtil;
originalLooseLootMultipliers;
originalStaticLootMultipliers;
preSptLoad(container) {
const staticRouterModService = container.resolve("StaticRouterModService");
const dynamicRouterModService = container.resolve("DynamicRouterModService");
this.logger = container.resolve("WinstonLogger");
// Get config.json settings for the bepinex plugin
staticRouterModService.registerStaticRouter(`StaticGetConfig${modName}`, [{
url: "/LateToTheParty/GetConfig",
action: async () => {
return JSON.stringify(config_json_1.default);
}
}], "GetConfig");
if (!config_json_1.default.enabled) {
return;
}
// Game start
// Needed to initialize loot ranking generator after any other mods have potentially changed config settings
staticRouterModService.registerStaticRouter(`StaticAkiGameStart${modName}`, [{
url: "/client/game/start",
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
action: async (url, info, sessionId, output) => {
this.generateLootRankingData(sessionId);
return output;
}
}], "aki");
// Get lootRanking.json for loot ranking
staticRouterModService.registerStaticRouter(`StaticGetLootRankingData${modName}`, [{
url: "/LateToTheParty/GetLootRankingData",
action: async () => {
return JSON.stringify(this.lootRankingGenerator.getLootRankingDataFromFile());
}
}], "GetLootRankingData");
// Get an array of all car extract names
staticRouterModService.registerStaticRouter(`StaticGetCarExtractNames${modName}`, [{
url: "/LateToTheParty/GetCarExtractNames",
action: async () => {
return JSON.stringify(this.inRaidConfig.carExtracts);
}
}], "GetCarExtractNames");
// Adjust the static and loose loot multipliers
dynamicRouterModService.registerDynamicRouter(`DynamicSetLootMultipliers${modName}`, [{
url: "/LateToTheParty/SetLootMultiplier/",
action: async (url) => {
const urlParts = url.split("/");
const factor = Number(urlParts[urlParts.length - 1]);
this.setLootMultipliers(factor);
return JSON.stringify({ resp: "OK" });
}
}], "SetLootMultiplier");
}
postDBLoad(container) {
this.configServer = container.resolve("ConfigServer");
this.databaseServer = container.resolve("DatabaseServer");
this.fileSystem = container.resolve("FileSystemSync");
this.localeService = container.resolve("LocaleService");
this.botWeaponGenerator = container.resolve("BotWeaponGenerator");
this.hashUtil = container.resolve("HashUtil");
this.locationConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.LOCATION);
this.inRaidConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.IN_RAID);
this.databaseTables = this.databaseServer.getTables();
this.commonUtils = new CommonUtils_1.CommonUtils(this.logger, this.databaseTables, this.localeService);
if (!config_json_1.default.enabled) {
this.commonUtils.logInfo("Mod disabled in config.json.");
return;
}
if (!this.doesFileIntegrityCheckPass()) {
config_json_1.default.enabled = false;
return;
}
this.adjustSPTScavRaidChanges();
}
postSptLoad() {
if (!config_json_1.default.enabled) {
return;
}
// Store the original static and loose loot multipliers
this.getLootMultipliers();
}
adjustSPTScavRaidChanges() {
this.commonUtils.logInfo("Adjusting SPT Scav-raid changes...");
for (const map in this.locationConfig.scavRaidTimeSettings.maps) {
if (config_json_1.default.scav_raid_adjustments.always_spawn_late) {
this.locationConfig.scavRaidTimeSettings.maps[map].reducedChancePercent = 100;
}
if (config_json_1.default.destroy_loot_during_raid.enabled) {
this.locationConfig.scavRaidTimeSettings.maps[map].reduceLootByPercent = false;
}
}
}
getLootMultipliers() {
this.originalLooseLootMultipliers =
{
bigmap: this.locationConfig.looseLootMultiplier.bigmap,
develop: this.locationConfig.looseLootMultiplier.develop,
factory4_day: this.locationConfig.looseLootMultiplier.factory4_day,
factory4_night: this.locationConfig.looseLootMultiplier.factory4_night,
hideout: this.locationConfig.looseLootMultiplier.hideout,
interchange: this.locationConfig.looseLootMultiplier.interchange,
laboratory: this.locationConfig.looseLootMultiplier.laboratory,
lighthouse: this.locationConfig.looseLootMultiplier.lighthouse,
privatearea: this.locationConfig.looseLootMultiplier.privatearea,
rezervbase: this.locationConfig.looseLootMultiplier.rezervbase,
shoreline: this.locationConfig.looseLootMultiplier.shoreline,
suburbs: this.locationConfig.looseLootMultiplier.suburbs,
tarkovstreets: this.locationConfig.looseLootMultiplier.tarkovstreets,
terminal: this.locationConfig.looseLootMultiplier.terminal,
town: this.locationConfig.looseLootMultiplier.town,
woods: this.locationConfig.looseLootMultiplier.woods,
sandbox: this.locationConfig.looseLootMultiplier.sandbox
};
this.originalStaticLootMultipliers =
{
bigmap: this.locationConfig.staticLootMultiplier.bigmap,
develop: this.locationConfig.staticLootMultiplier.develop,
factory4_day: this.locationConfig.staticLootMultiplier.factory4_day,
factory4_night: this.locationConfig.staticLootMultiplier.factory4_night,
hideout: this.locationConfig.staticLootMultiplier.hideout,
interchange: this.locationConfig.staticLootMultiplier.interchange,
laboratory: this.locationConfig.staticLootMultiplier.laboratory,
lighthouse: this.locationConfig.staticLootMultiplier.lighthouse,
privatearea: this.locationConfig.staticLootMultiplier.privatearea,
rezervbase: this.locationConfig.staticLootMultiplier.rezervbase,
shoreline: this.locationConfig.staticLootMultiplier.shoreline,
suburbs: this.locationConfig.staticLootMultiplier.suburbs,
tarkovstreets: this.locationConfig.staticLootMultiplier.tarkovstreets,
terminal: this.locationConfig.staticLootMultiplier.terminal,
town: this.locationConfig.staticLootMultiplier.town,
woods: this.locationConfig.staticLootMultiplier.woods,
sandbox: this.locationConfig.staticLootMultiplier.sandbox
};
}
setLootMultipliers(factor) {
this.commonUtils.logInfo(`Adjusting loot multipliers by a factor of ${factor}...`);
this.locationConfig.looseLootMultiplier.bigmap = this.originalLooseLootMultipliers.bigmap * factor;
this.locationConfig.looseLootMultiplier.develop = this.originalLooseLootMultipliers.develop * factor;
this.locationConfig.looseLootMultiplier.factory4_day = this.originalLooseLootMultipliers.factory4_day * factor;
this.locationConfig.looseLootMultiplier.factory4_night = this.originalLooseLootMultipliers.factory4_night * factor;
this.locationConfig.looseLootMultiplier.hideout = this.originalLooseLootMultipliers.hideout * factor;
this.locationConfig.looseLootMultiplier.interchange = this.originalLooseLootMultipliers.interchange * factor;
this.locationConfig.looseLootMultiplier.laboratory = this.originalLooseLootMultipliers.laboratory * factor;
this.locationConfig.looseLootMultiplier.lighthouse = this.originalLooseLootMultipliers.lighthouse * factor;
this.locationConfig.looseLootMultiplier.privatearea = this.originalLooseLootMultipliers.privatearea * factor;
this.locationConfig.looseLootMultiplier.rezervbase = this.originalLooseLootMultipliers.rezervbase * factor;
this.locationConfig.looseLootMultiplier.shoreline = this.originalLooseLootMultipliers.shoreline * factor;
this.locationConfig.looseLootMultiplier.suburbs = this.originalLooseLootMultipliers.suburbs * factor;
this.locationConfig.looseLootMultiplier.tarkovstreets = this.originalLooseLootMultipliers.tarkovstreets * factor;
this.locationConfig.looseLootMultiplier.terminal = this.originalLooseLootMultipliers.terminal * factor;
this.locationConfig.looseLootMultiplier.town = this.originalLooseLootMultipliers.town * factor;
this.locationConfig.looseLootMultiplier.woods = this.originalLooseLootMultipliers.woods * factor;
this.locationConfig.looseLootMultiplier.sandbox = this.originalLooseLootMultipliers.sandbox * factor;
this.locationConfig.staticLootMultiplier.bigmap = this.originalStaticLootMultipliers.bigmap * factor;
this.locationConfig.staticLootMultiplier.develop = this.originalStaticLootMultipliers.develop * factor;
this.locationConfig.staticLootMultiplier.factory4_day = this.originalStaticLootMultipliers.factory4_day * factor;
this.locationConfig.staticLootMultiplier.factory4_night = this.originalStaticLootMultipliers.factory4_night * factor;
this.locationConfig.staticLootMultiplier.hideout = this.originalStaticLootMultipliers.hideout * factor;
this.locationConfig.staticLootMultiplier.interchange = this.originalStaticLootMultipliers.interchange * factor;
this.locationConfig.staticLootMultiplier.laboratory = this.originalStaticLootMultipliers.laboratory * factor;
this.locationConfig.staticLootMultiplier.lighthouse = this.originalStaticLootMultipliers.lighthouse * factor;
this.locationConfig.staticLootMultiplier.privatearea = this.originalStaticLootMultipliers.privatearea * factor;
this.locationConfig.staticLootMultiplier.rezervbase = this.originalStaticLootMultipliers.rezervbase * factor;
this.locationConfig.staticLootMultiplier.shoreline = this.originalStaticLootMultipliers.shoreline * factor;
this.locationConfig.staticLootMultiplier.suburbs = this.originalStaticLootMultipliers.suburbs * factor;
this.locationConfig.staticLootMultiplier.tarkovstreets = this.originalStaticLootMultipliers.tarkovstreets * factor;
this.locationConfig.staticLootMultiplier.terminal = this.originalStaticLootMultipliers.terminal * factor;
this.locationConfig.staticLootMultiplier.town = this.originalStaticLootMultipliers.town * factor;
this.locationConfig.staticLootMultiplier.woods = this.originalStaticLootMultipliers.woods * factor;
this.locationConfig.staticLootMultiplier.sandbox = this.originalStaticLootMultipliers.sandbox * factor;
}
generateLootRankingData(sessionId) {
this.lootRankingGenerator = new LootRankingGenerator_1.LootRankingGenerator(this.commonUtils, this.databaseTables, this.fileSystem, this.botWeaponGenerator, this.hashUtil);
this.lootRankingGenerator.generateLootRankingData(sessionId);
}
doesFileIntegrityCheckPass() {
const path = `${__dirname}/..`;
if (this.fileSystem.exists(`${path}/log/`)) {
this.commonUtils.logWarning("Found obsolete log folder 'user\\mods\\DanW-LateToTheParty\\log'. Logs are now saved in 'BepInEx\\plugins\\DanW-LateToTheParty\\log'.");
}
if (this.fileSystem.exists(`${path}/../../../BepInEx/plugins/LateToTheParty.dll`)) {
this.commonUtils.logError("Please remove BepInEx/plugins/LateToTheParty.dll from the previous version of this mod and restart the server, or it will NOT work correctly.");
return false;
}
return true;
}
}
module.exports = { mod: new LateToTheParty() };
//# sourceMappingURL=mod.js.map

File diff suppressed because one or more lines are too long

View file

@ -265,7 +265,7 @@
}
},
"bot_spawns": {
"enabled": true,
"enabled": false,
"blacklisted_pmc_bot_brains": [ "bossKilla", "bossTagilla", "exUsec", "followerGluharAssault", "followerGluharProtect", "crazyAssaultEvent", "bossKnight" ],
"spawn_retry_time": 10,
"delay_game_start_until_bot_gen_finishes": true,

View file

@ -0,0 +1,181 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BotUtil = void 0;
const config_json_1 = __importDefault(require("../config/config.json"));
class BotUtil {
commonUtils;
databaseTables;
iLocationConfig;
iBotConfig;
iPmcConfig;
static pmcRoles = ["pmcBEAR", "pmcUSEC"];
constructor(commonUtils, databaseTables, iLocationConfig, iBotConfig, iPmcConfig) {
this.commonUtils = commonUtils;
this.databaseTables = databaseTables;
this.iLocationConfig = iLocationConfig;
this.iBotConfig = iBotConfig;
this.iPmcConfig = iPmcConfig;
}
adjustAllBotHostilityChances() {
if (!config_json_1.default.bot_spawns.pmc_hostility_adjustments.enabled) {
return;
}
this.commonUtils.logInfo("Adjusting bot hostility chances...");
for (const location in this.databaseTables.locations) {
this.adjustAllBotHostilityChancesForLocation(this.databaseTables.locations[location]);
}
this.adjustSptPmcHostilityChances(this.iPmcConfig.hostilitySettings["pmcusec"]);
this.adjustSptPmcHostilityChances(this.iPmcConfig.hostilitySettings["pmcbear"]);
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmcs_always_hostile_against_scavs) {
this.databaseTables.bots.types.assault.difficulty.easy.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assault.difficulty.normal.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assault.difficulty.hard.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assault.difficulty.impossible.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assaultgroup.difficulty.easy.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assaultgroup.difficulty.normal.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assaultgroup.difficulty.hard.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.assaultgroup.difficulty.impossible.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.marksman.difficulty.easy.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.marksman.difficulty.normal.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.marksman.difficulty.hard.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
this.databaseTables.bots.types.marksman.difficulty.impossible.Mind.ENEMY_BOT_TYPES = BotUtil.pmcRoles;
}
this.commonUtils.logInfo("Adjusting bot hostility chances...done.");
}
adjustAllBotHostilityChancesForLocation(location) {
if ((location.base === undefined) || (location.base.BotLocationModifier === undefined)) {
return;
}
const settings = location.base.BotLocationModifier.AdditionalHostilitySettings;
if (settings === undefined) {
return;
}
for (const botType in settings) {
if (!BotUtil.pmcRoles.includes(settings[botType].BotRole)) {
//this.commonUtils.logWarning(`Did not adjust ${settings[botType].BotRole} hostility settings on ${location.base.Name}`);
continue;
}
this.adjustBotHostilityChances(settings[botType]);
}
}
adjustBotHostilityChances(settings) {
// This seems to be undefined for most maps
if (settings.SavageEnemyChance !== undefined) {
settings.SavageEnemyChance = config_json_1.default.bot_spawns.pmc_hostility_adjustments.global_scav_enemy_chance;
}
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmcs_always_hostile_against_scavs) {
settings.SavagePlayerBehaviour = "AlwaysEnemies";
}
for (const chancedEnemy in settings.ChancedEnemies) {
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmc_enemy_roles.includes(settings.ChancedEnemies[chancedEnemy].Role)) {
settings.ChancedEnemies[chancedEnemy].EnemyChance = 100;
continue;
}
// This allows Questing Bots to set boss hostilities when the bot spawns
settings.ChancedEnemies[chancedEnemy].EnemyChance = 0;
}
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmcs_always_hostile_against_pmcs) {
settings.BearEnemyChance = 100;
settings.UsecEnemyChance = 100;
this.addMissingPMCRolesToChancedEnemies(settings);
}
}
addMissingPMCRolesToChancedEnemies(settings) {
for (const pmcRole of BotUtil.pmcRoles) {
if (!config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmc_enemy_roles.includes(pmcRole)) {
continue;
}
let foundRole = false;
for (const chancedEnemy in settings.ChancedEnemies) {
if (settings.ChancedEnemies[chancedEnemy].Role === pmcRole) {
foundRole = true;
break;
}
}
if (foundRole) {
continue;
}
const newEnemy = {
EnemyChance: 100,
Role: pmcRole
};
settings.ChancedEnemies.push(newEnemy);
}
}
adjustSptPmcHostilityChances(settings) {
settings.savageEnemyChance = config_json_1.default.bot_spawns.pmc_hostility_adjustments.global_scav_enemy_chance;
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmcs_always_hostile_against_scavs) {
settings.savagePlayerBehaviour = "AlwaysEnemies";
}
for (const chancedEnemy in settings.chancedEnemies) {
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmc_enemy_roles.includes(settings.chancedEnemies[chancedEnemy].Role)) {
settings.chancedEnemies[chancedEnemy].EnemyChance = 100;
continue;
}
}
if (config_json_1.default.bot_spawns.pmc_hostility_adjustments.pmcs_always_hostile_against_pmcs) {
settings.bearEnemyChance = 100;
settings.usecEnemyChance = 100;
}
}
disablePvEBossWaves() {
let removedWaves = 0;
for (const location in this.databaseTables.locations) {
removedWaves += this.removePvEBossWavesFromLocation(this.databaseTables.locations[location]);
}
if (removedWaves > 0) {
this.commonUtils.logInfo(`Disabled ${removedWaves} PvE boss waves`);
}
}
removePvEBossWavesFromLocation(location) {
let removedWaves = 0;
if ((location.base === undefined) || (location.base.BossLocationSpawn === undefined)) {
return removedWaves;
}
const modifiedBossLocationSpawn = [];
for (const bossLocationSpawnId in location.base.BossLocationSpawn) {
const bossLocationSpawn = location.base.BossLocationSpawn[bossLocationSpawnId];
if (BotUtil.pmcRoles.includes(bossLocationSpawn.BossName)) {
removedWaves++;
continue;
}
modifiedBossLocationSpawn.push(bossLocationSpawn);
}
location.base.BossLocationSpawn = modifiedBossLocationSpawn;
return removedWaves;
}
disableBotWaves(waves, botType) {
let originalWaves = 0;
for (const location in waves) {
originalWaves += waves[location].length;
waves[location] = [];
}
if (originalWaves > 0) {
this.commonUtils.logInfo(`Disabled ${originalWaves} custom ${botType} waves`);
}
}
useEFTBotCaps() {
for (const location in this.iBotConfig.maxBotCap) {
if ((this.databaseTables.locations[location] === undefined) || (this.databaseTables.locations[location].base === undefined)) {
continue;
}
const originalSPTCap = this.iBotConfig.maxBotCap[location];
const eftCap = this.databaseTables.locations[location].base.BotMax;
const shouldChangeBotCap = (originalSPTCap > eftCap) || !config_json_1.default.bot_spawns.bot_cap_adjustments.only_decrease_bot_caps;
if (config_json_1.default.bot_spawns.bot_cap_adjustments.use_EFT_bot_caps && shouldChangeBotCap) {
this.iBotConfig.maxBotCap[location] = eftCap;
}
const fixedAdjustment = config_json_1.default.bot_spawns.bot_cap_adjustments.map_specific_adjustments[location];
this.iBotConfig.maxBotCap[location] += fixedAdjustment;
const newCap = this.iBotConfig.maxBotCap[location];
if (newCap !== originalSPTCap) {
this.commonUtils.logInfo(`Updated bot cap for ${location} to ${newCap} (Original SPT: ${originalSPTCap}, EFT: ${eftCap}, fixed adjustment: ${fixedAdjustment})`);
}
}
}
}
exports.BotUtil = BotUtil;
//# sourceMappingURL=BotLocationUtil.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,48 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommonUtils = void 0;
const config_json_1 = __importDefault(require("../config/config.json"));
class CommonUtils {
logger;
databaseTables;
localeService;
debugMessagePrefix = "[Questing Bots] ";
translations;
constructor(logger, databaseTables, localeService) {
this.logger = logger;
this.databaseTables = databaseTables;
this.localeService = localeService;
// Get all translations for the current locale
this.translations = this.localeService.getLocaleDb();
}
logDebug(message, alwaysShow = false) {
if (config_json_1.default.enabled || alwaysShow)
this.logger.debug(this.debugMessagePrefix + message);
}
logInfo(message, alwaysShow = false) {
if (config_json_1.default.enabled || alwaysShow)
this.logger.info(this.debugMessagePrefix + message);
}
logWarning(message) {
this.logger.warning(this.debugMessagePrefix + message);
}
logError(message) {
this.logger.error(this.debugMessagePrefix + message);
}
getItemName(itemID) {
const translationKey = `${itemID} Name`;
if (translationKey in this.translations)
return this.translations[translationKey];
// If a key can't be found in the translations dictionary, fall back to the template data if possible
if (!(itemID in this.databaseTables.templates.items)) {
return undefined;
}
const item = this.databaseTables.templates.items[itemID];
return item._name;
}
}
exports.CommonUtils = CommonUtils;
//# sourceMappingURL=CommonUtils.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "CommonUtils.js",
"sourceRoot": "",
"sources": [
"CommonUtils.ts"
],
"names": [],
"mappings": ";;;;;;AAAA,wEAA8C;AAM9C,MAAa,WAAW;IAKC;IAAyB;IAAyC;IAH/E,kBAAkB,GAAG,kBAAkB,CAAC;IACxC,YAAY,CAAyB;IAE7C,YAAqB,MAAe,EAAU,cAA+B,EAAU,aAA4B;QAA9F,WAAM,GAAN,MAAM,CAAS;QAAU,mBAAc,GAAd,cAAc,CAAiB;QAAU,kBAAa,GAAb,aAAa,CAAe;QAE/G,8CAA8C;QAC9C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;IACzD,CAAC;IAEM,QAAQ,CAAC,OAAe,EAAE,UAAU,GAAG,KAAK;QAE/C,IAAI,qBAAS,CAAC,OAAO,IAAI,UAAU;YAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC;IAC7D,CAAC;IAEM,OAAO,CAAC,OAAe,EAAE,UAAU,GAAG,KAAK;QAE9C,IAAI,qBAAS,CAAC,OAAO,IAAI,UAAU;YAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC;IAC5D,CAAC;IAEM,UAAU,CAAC,OAAe;QAE7B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC;IAC3D,CAAC;IAEM,QAAQ,CAAC,OAAe;QAE3B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,CAAC;IACzD,CAAC;IAEM,WAAW,CAAC,MAAc;QAE7B,MAAM,cAAc,GAAG,GAAG,MAAM,OAAO,CAAC;QACxC,IAAI,cAAc,IAAI,IAAI,CAAC,YAAY;YACnC,OAAO,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;QAE7C,qGAAqG;QACrG,IAAI,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,EACpD,CAAC;YACG,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;CACJ;AAhDD,kCAgDC"
}

View file

@ -0,0 +1,48 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PMCConversionUtil = void 0;
const config_json_1 = __importDefault(require("../config/config.json"));
class PMCConversionUtil {
commonUtils;
iPmcConfig;
iBotConfig;
constructor(commonUtils, iPmcConfig, iBotConfig) {
this.commonUtils = commonUtils;
this.iPmcConfig = iPmcConfig;
this.iBotConfig = iBotConfig;
}
removeBlacklistedBrainTypes() {
const badBrains = config_json_1.default.bot_spawns.blacklisted_pmc_bot_brains;
let removedBrains = 0;
for (const pmcType in this.iPmcConfig.pmcType) {
for (const map in this.iPmcConfig.pmcType[pmcType]) {
const mapBrains = this.iPmcConfig.pmcType[pmcType][map];
for (const i in badBrains) {
if (mapBrains[badBrains[i]] === undefined) {
continue;
}
// this.commonUtils.logInfo(`Removing ${badBrains[i]} from ${pmcType} in ${map}...`);
delete mapBrains[badBrains[i]];
removedBrains++;
}
}
}
for (const map in this.iBotConfig.playerScavBrainType) {
const mapBrains = this.iBotConfig.playerScavBrainType[map];
for (const i in badBrains) {
if (mapBrains[badBrains[i]] === undefined) {
continue;
}
// this.commonUtils.logInfo(`Removing ${badBrains[i]} from playerscavs in ${map}...`);
delete mapBrains[badBrains[i]];
removedBrains++;
}
}
this.commonUtils.logInfo(`Removed ${removedBrains} blacklisted brain types from being used for PMC's and Player Scav's`);
}
}
exports.PMCConversionUtil = PMCConversionUtil;
//# sourceMappingURL=PMCConversionUtil.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "PMCConversionUtil.js",
"sourceRoot": "",
"sources": [
"PMCConversionUtil.ts"
],
"names": [],
"mappings": ";;;;;;AAAA,wEAA8C;AAM9C,MAAa,iBAAiB;IAEN;IAAkC;IAAgC;IAAtF,YAAoB,WAAwB,EAAU,UAAsB,EAAU,UAAsB;QAAxF,gBAAW,GAAX,WAAW,CAAa;QAAU,eAAU,GAAV,UAAU,CAAY;QAAU,eAAU,GAAV,UAAU,CAAY;IAG5G,CAAC;IAEM,2BAA2B;QAE9B,MAAM,SAAS,GAAG,qBAAS,CAAC,UAAU,CAAC,0BAA0B,CAAC;QAElE,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAC7C,CAAC;YACG,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,EAClD,CAAC;gBACG,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC;gBAExD,KAAK,MAAM,CAAC,IAAI,SAAS,EACzB,CAAC;oBACG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EACzC,CAAC;wBACG,SAAS;oBACb,CAAC;oBAED,qFAAqF;oBACrF,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC/B,aAAa,EAAE,CAAC;gBACpB,CAAC;YACL,CAAC;QACL,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,mBAAmB,EACrD,CAAC;YACG,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAE3D,KAAK,MAAM,CAAC,IAAI,SAAS,EACzB,CAAC;gBACG,IAAI,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EACzC,CAAC;oBACG,SAAS;gBACb,CAAC;gBAED,sFAAsF;gBACtF,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/B,aAAa,EAAE,CAAC;YACpB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,aAAa,sEAAsE,CAAC,CAAC;IAC7H,CAAC;CACJ;AAnDD,8CAmDC"
}

View file

@ -0,0 +1,293 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_json_1 = __importDefault(require("../config/config.json"));
const eftQuestSettings_json_1 = __importDefault(require("../config/eftQuestSettings.json"));
const zoneAndItemQuestPositions_json_1 = __importDefault(require("../config/zoneAndItemQuestPositions.json"));
const CommonUtils_1 = require("./CommonUtils");
const BotLocationUtil_1 = require("./BotLocationUtil");
const PMCConversionUtil_1 = require("./PMCConversionUtil");
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const GameEditions_1 = require("C:/snapshot/project/obj/models/enums/GameEditions");
const MemberCategory_1 = require("C:/snapshot/project/obj/models/enums/MemberCategory");
const modName = "SPTQuestingBots";
const spawningModNames = ["SWAG", "DewardianDev-MOAR", "PreyToLive-BetterSpawnsPlus", "RealPlayerSpawn", "acidphantasm-botplacementsystem"];
class QuestingBots {
commonUtils;
botUtil;
pmcConversionUtil;
logger;
configServer;
databaseServer;
databaseTables;
localeService;
questHelper;
fileSystem;
httpResponseUtil;
randomUtil;
weightedRandomHelper;
botController;
botNameService;
iBotConfig;
iPmcConfig;
iLocationConfig;
basePScavConversionChance;
preSptLoad(container) {
this.logger = container.resolve("WinstonLogger");
const staticRouterModService = container.resolve("StaticRouterModService");
const dynamicRouterModService = container.resolve("DynamicRouterModService");
// Get config.json settings for the bepinex plugin
staticRouterModService.registerStaticRouter(`StaticGetConfig${modName}`, [{
url: "/QuestingBots/GetConfig",
action: async () => {
return JSON.stringify(config_json_1.default);
}
}], "GetConfig");
if (!config_json_1.default.enabled) {
return;
}
// Apply a scalar factor to the SPT-AKI PScav conversion chance
dynamicRouterModService.registerDynamicRouter(`DynamicAdjustPScavChance${modName}`, [{
url: "/QuestingBots/AdjustPScavChance/",
action: async (url) => {
const urlParts = url.split("/");
const factor = Number(urlParts[urlParts.length - 1]);
this.iBotConfig.chanceAssaultScavHasPlayerScavName = Math.round(this.basePScavConversionChance * factor);
this.commonUtils.logInfo(`Adjusted PScav spawn chance to ${this.iBotConfig.chanceAssaultScavHasPlayerScavName}%`);
return JSON.stringify({ resp: "OK" });
}
}], "AdjustPScavChance");
// Get all EFT quest templates
// NOTE: This includes custom quests added by mods
staticRouterModService.registerStaticRouter(`GetAllQuestTemplates${modName}`, [{
url: "/QuestingBots/GetAllQuestTemplates",
action: async () => {
return JSON.stringify({ templates: this.questHelper.getQuestsFromDb() });
}
}], "GetAllQuestTemplates");
// Get override settings for EFT quests
staticRouterModService.registerStaticRouter(`GetEFTQuestSettings${modName}`, [{
url: "/QuestingBots/GetEFTQuestSettings",
action: async () => {
return JSON.stringify({ settings: eftQuestSettings_json_1.default });
}
}], "GetEFTQuestSettings");
// Get override settings for quest zones and items
staticRouterModService.registerStaticRouter(`GetZoneAndItemQuestPositions${modName}`, [{
url: "/QuestingBots/GetZoneAndItemQuestPositions",
action: async () => {
return JSON.stringify({ zoneAndItemPositions: zoneAndItemQuestPositions_json_1.default });
}
}], "GetZoneAndItemQuestPositions");
// Get Scav-raid settings to determine PScav conversion chances
staticRouterModService.registerStaticRouter(`GetScavRaidSettings${modName}`, [{
url: "/QuestingBots/GetScavRaidSettings",
action: async () => {
return JSON.stringify({ maps: this.iLocationConfig.scavRaidTimeSettings.maps });
}
}], "GetScavRaidSettings");
// Get the chance that a PMC will be a USEC
staticRouterModService.registerStaticRouter(`GetUSECChance${modName}`, [{
url: "/QuestingBots/GetUSECChance",
action: async () => {
return JSON.stringify({ usecChance: this.iPmcConfig.isUsec });
}
}], "GetUSECChance");
// Intercept the EFT bot-generation request to include a PScav conversion chance
container.afterResolution("BotCallbacks", (_t, result) => {
result.generateBots = async (url, info, sessionID) => {
const bots = await this.generateBots({ conditions: info.conditions }, sessionID, info.GeneratePScav);
return this.httpResponseUtil.getBody(bots);
};
}, { frequency: "Always" });
}
postDBLoad(container) {
this.configServer = container.resolve("ConfigServer");
this.databaseServer = container.resolve("DatabaseServer");
this.localeService = container.resolve("LocaleService");
this.questHelper = container.resolve("QuestHelper");
this.fileSystem = container.resolve("FileSystemSync");
this.httpResponseUtil = container.resolve("HttpResponseUtil");
this.randomUtil = container.resolve("RandomUtil");
this.weightedRandomHelper = container.resolve("WeightedRandomHelper");
this.botController = container.resolve("BotController");
this.botNameService = container.resolve("BotNameService");
this.iBotConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
this.iPmcConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
this.iLocationConfig = this.configServer.getConfig(ConfigTypes_1.ConfigTypes.LOCATION);
this.databaseTables = this.databaseServer.getTables();
this.commonUtils = new CommonUtils_1.CommonUtils(this.logger, this.databaseTables, this.localeService);
this.botUtil = new BotLocationUtil_1.BotUtil(this.commonUtils, this.databaseTables, this.iLocationConfig, this.iBotConfig, this.iPmcConfig);
this.pmcConversionUtil = new PMCConversionUtil_1.PMCConversionUtil(this.commonUtils, this.iPmcConfig, this.iBotConfig);
if (!config_json_1.default.enabled) {
return;
}
if (!this.doesFileIntegrityCheckPass()) {
config_json_1.default.enabled = false;
return;
}
if (!this.areArraysValid()) {
config_json_1.default.enabled = false;
return;
}
}
postSptLoad(container) {
if (!config_json_1.default.enabled) {
this.commonUtils.logInfo("Mod disabled in config.json", true);
return;
}
const presptModLoader = container.resolve("PreSptModLoader");
this.pmcConversionUtil.removeBlacklistedBrainTypes();
// Disable the Questing Bots spawning system if another spawning mod has been loaded
if (this.shouldDisableSpawningSystem(presptModLoader.getImportedModsNames())) {
config_json_1.default.bot_spawns.enabled = false;
}
// Make Questing Bots control PScav spawning
this.basePScavConversionChance = this.iBotConfig.chanceAssaultScavHasPlayerScavName;
if (config_json_1.default.adjust_pscav_chance.enabled || (config_json_1.default.bot_spawns.enabled && config_json_1.default.bot_spawns.player_scavs.enabled)) {
this.iBotConfig.chanceAssaultScavHasPlayerScavName = 0;
}
this.configureSpawningSystem();
}
configureSpawningSystem() {
if (!config_json_1.default.bot_spawns.enabled) {
return;
}
this.commonUtils.logInfo("Configuring game for bot spawning...");
// Overwrite BSG's chances of bots being friendly toward each other
this.botUtil.adjustAllBotHostilityChances();
// Remove all of BSG's PvE-only boss waves
this.botUtil.disablePvEBossWaves();
// Currently these are all PMC waves, which are unnecessary with PMC spawns in this mod
this.botUtil.disableBotWaves(this.iLocationConfig.customWaves.boss, "boss");
// Disable all of the extra Scavs that spawn into Factory
this.botUtil.disableBotWaves(this.iLocationConfig.customWaves.normal, "Scav");
// Disable SPT's PMC wave generator
this.botUtil.disableBotWaves(this.iPmcConfig.customPmcWaves, "PMC");
// Use EFT's bot caps instead of SPT's
this.botUtil.useEFTBotCaps();
// If Rogues don't spawn immediately, PMC spawns will be significantly delayed
if (config_json_1.default.bot_spawns.limit_initial_boss_spawns.disable_rogue_delay && (this.iLocationConfig.rogueLighthouseSpawnTimeSettings.waitTimeSeconds > -1)) {
this.iLocationConfig.rogueLighthouseSpawnTimeSettings.waitTimeSeconds = -1;
this.commonUtils.logInfo("Removed SPT Rogue spawn delay");
}
this.commonUtils.logInfo("Configuring game for bot spawning...done.");
}
async generateBots(info, sessionID, shouldBePScavGroup) {
const bots = await this.botController.generate(sessionID, info);
if (!shouldBePScavGroup) {
return bots;
}
for (const bot in bots) {
if (bots[bot].Info.Settings.Role !== "assault") {
this.commonUtils.logDebug(`Tried generating a player Scav, but a bot with role ${bots[bot].Info.Settings.Role} was returned`);
continue;
}
this.botNameService.addRandomPmcNameToBotMainProfileNicknameProperty(bots[bot]);
this.setRandomisedGameVersionAndCategory(bots[bot].Info);
}
return bots;
}
setRandomisedGameVersionAndCategory(botInfo) {
/* SPT CODE - BotGenerator.setRandomisedGameVersionAndCategory(bot.Info) */
// Special case
if (botInfo.Nickname?.toLowerCase() === "nikita") {
botInfo.GameVersion = GameEditions_1.GameEditions.UNHEARD;
botInfo.MemberCategory = MemberCategory_1.MemberCategory.DEVELOPER;
return botInfo.GameVersion;
}
// Choose random weighted game version for bot
botInfo.GameVersion = this.weightedRandomHelper.getWeightedValue(this.iPmcConfig.gameVersionWeight);
// Choose appropriate member category value
switch (botInfo.GameVersion) {
case GameEditions_1.GameEditions.EDGE_OF_DARKNESS:
botInfo.MemberCategory = MemberCategory_1.MemberCategory.UNIQUE_ID;
break;
case GameEditions_1.GameEditions.UNHEARD:
botInfo.MemberCategory = MemberCategory_1.MemberCategory.UNHEARD;
break;
default:
// Everyone else gets a weighted randomised category
botInfo.MemberCategory = Number.parseInt(this.weightedRandomHelper.getWeightedValue(this.iPmcConfig.accountTypeWeight), 10);
}
// Ensure selected category matches
botInfo.SelectedMemberCategory = botInfo.MemberCategory;
return botInfo.GameVersion;
}
doesFileIntegrityCheckPass() {
const path = `${__dirname}/..`;
if (this.fileSystem.exists(`${path}/quests/`)) {
this.commonUtils.logWarning("Found obsolete quests folder 'user\\mods\\DanW-SPTQuestingBots\\quests'. Only quest files in 'BepInEx\\plugins\\DanW-SPTQuestingBots\\quests' will be used.");
}
if (this.fileSystem.exists(`${path}/log/`)) {
this.commonUtils.logWarning("Found obsolete log folder 'user\\mods\\DanW-SPTQuestingBots\\log'. Logs are now saved in 'BepInEx\\plugins\\DanW-SPTQuestingBots\\log'.");
}
if (this.fileSystem.exists(`${path}/../../../BepInEx/plugins/SPTQuestingBots.dll`)) {
this.commonUtils.logError("Please remove BepInEx/plugins/SPTQuestingBots.dll from the previous version of this mod and restart the server, or it will NOT work correctly.");
return false;
}
return true;
}
areArraysValid() {
if (!this.isChanceArrayValid(config_json_1.default.questing.bot_quests.eft_quests.level_range, true)) {
this.commonUtils.logError("questing.bot_quests.eft_quests.level_range has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.bot_spawns.pmcs.fraction_of_max_players_vs_raidET, false)) {
this.commonUtils.logError("bot_spawns.pmcs.fraction_of_max_players_vs_raidET has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.bot_spawns.pmcs.bots_per_group_distribution, true)) {
this.commonUtils.logError("bot_spawns.pmcs.bots_per_group_distribution has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.bot_spawns.pmcs.bot_difficulty_as_online, true)) {
this.commonUtils.logError("bot_spawns.pmcs.bot_difficulty_as_online has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.bot_spawns.player_scavs.bots_per_group_distribution, true)) {
this.commonUtils.logError("bot_spawns.player_scavs.bots_per_group_distribution has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.bot_spawns.player_scavs.bot_difficulty_as_online, true)) {
this.commonUtils.logError("bot_spawns.player_scavs.bot_difficulty_as_online has invalid data. Mod disabled.");
return false;
}
if (!this.isChanceArrayValid(config_json_1.default.adjust_pscav_chance.chance_vs_time_remaining_fraction, false)) {
this.commonUtils.logError("adjust_pscav_chance.chance_vs_time_remaining_fraction has invalid data. Mod disabled.");
return false;
}
return true;
}
isChanceArrayValid(array, shouldLeftColumnBeIntegers) {
if (array.length === 0) {
return false;
}
for (const row of array) {
if (row.length !== 2) {
return false;
}
if (shouldLeftColumnBeIntegers && !Number.isInteger(row[0])) {
this.commonUtils.logError("Found a chance array with an invalid value in its left column. Please ensure you are not using an outdated version of config.json.");
return false;
}
}
return true;
}
shouldDisableSpawningSystem(importedModNames) {
if (!config_json_1.default.bot_spawns.enabled) {
return false;
}
for (const spawningModName of spawningModNames) {
if (importedModNames.includes(spawningModName)) {
this.commonUtils.logWarning(`${spawningModName} detected. Disabling the Questing Bots spawning system.`);
return true;
}
}
return false;
}
}
module.exports = { mod: new QuestingBots() };
//# sourceMappingURL=mod.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.globalValues = void 0;
class globalValues {
static baseConfig = undefined;
static overrideConfig = undefined;
static locationsBase = undefined;
static currentPreset = "";
static forcedPreset = "random";
static addedMapZones = {};
static indexedMapSpawns = {};
static playerSpawn;
}
exports.globalValues = globalValues;
//# sourceMappingURL=GlobalValues.js.map

View file

@ -0,0 +1,10 @@
{
"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;IACjE,MAAM,CAAC,WAAW,CAAmB;;AAR9C,oCASC"
}

View file

@ -0,0 +1,130 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupRoutes = void 0;
const Spawning_1 = require("../Spawning/Spawning");
const GlobalValues_1 = require("../GlobalValues");
const utils_1 = require("../utils");
const PresetWeightings_json_1 = __importDefault(require("../../config/PresetWeightings.json"));
const updateUtils_1 = require("../SpawnZoneChanges/updateUtils");
const setupRoutes = (container) => {
const staticRouterModService = container.resolve("StaticRouterModService");
staticRouterModService.registerStaticRouter(`moarAddBotSpawn`, [
{
url: "/moar/addBotSpawn",
action: async (url, req, sessionID, output) => {
(0, updateUtils_1.updateBotSpawn)(req.map, req.position, req.type);
return "success";
},
},
], "moarAddBotSpawn");
staticRouterModService.registerStaticRouter(`moarDeleteBotSpawn`, [
{
url: "/moar/deleteBotSpawn",
action: async (url, req, sessionID, output) => {
// console.log(req);
(0, updateUtils_1.deleteBotSpawn)(req.map, req.position, req.type);
return "success";
},
},
], "moarDeleteBotSpawn");
// Make buildwaves run on game end
staticRouterModService.registerStaticRouter(`moarUpdater`, [
{
url: "/client/match/local/end",
action: async (_url, info, sessionId, output) => {
(0, Spawning_1.buildWaves)(container);
return output;
},
},
], "moarUpdater");
staticRouterModService.registerStaticRouter(`moarGetCurrentPreset`, [
{
url: "/moar/currentPreset",
action: async () => {
return GlobalValues_1.globalValues.forcedPreset || "random";
},
},
], "moarGetCurrentPreset");
staticRouterModService.registerStaticRouter(`moarGetAnnouncePreset`, [
{
url: "/moar/announcePreset",
action: async () => {
if (GlobalValues_1.globalValues.forcedPreset?.toLowerCase() === "random") {
return GlobalValues_1.globalValues.currentPreset;
}
return GlobalValues_1.globalValues.forcedPreset || GlobalValues_1.globalValues.currentPreset;
},
},
], "moarGetAnnouncePreset");
staticRouterModService.registerStaticRouter(`getDefaultConfig`, [
{
url: "/moar/getDefaultConfig",
action: async () => {
return JSON.stringify(GlobalValues_1.globalValues.baseConfig);
},
},
], "getDefaultConfig");
staticRouterModService.registerStaticRouter(`getServerConfigWithOverrides`, [
{
url: "/moar/getServerConfigWithOverrides",
action: async () => {
return JSON.stringify({
...(GlobalValues_1.globalValues.baseConfig || {}),
...(GlobalValues_1.globalValues.overrideConfig || {}),
});
},
},
], "getServerConfigWithOverrides");
staticRouterModService.registerStaticRouter(`getServerConfigWithOverrides`, [
{
url: "/moar/getServerConfigWithOverrides",
action: async () => {
return JSON.stringify({
...GlobalValues_1.globalValues.baseConfig,
...GlobalValues_1.globalValues.overrideConfig,
});
},
},
], "getServerConfigWithOverrides");
staticRouterModService.registerStaticRouter(`moarGetPresetsList`, [
{
url: "/moar/getPresets",
action: async () => {
let result = [
...Object.keys(PresetWeightings_json_1.default).map((preset) => ({
Name: (0, utils_1.kebabToTitle)(preset),
Label: preset,
})),
{ Name: "Random", Label: "random" },
{ Name: "Custom", Label: "custom" },
];
return JSON.stringify({ data: result });
},
},
], "moarGetPresetsList");
staticRouterModService.registerStaticRouter("setOverrideConfig", [
{
url: "/moar/setOverrideConfig",
action: async (url, overrideConfig = {}, sessionID, output) => {
GlobalValues_1.globalValues.overrideConfig = overrideConfig;
(0, Spawning_1.buildWaves)(container);
return "Success";
},
},
], "setOverrideConfig");
staticRouterModService.registerStaticRouter("moarSetPreset", [
{
url: "/moar/setPreset",
action: async (url, { Preset }, sessionID, output) => {
GlobalValues_1.globalValues.forcedPreset = Preset;
(0, Spawning_1.buildWaves)(container);
return `Current Preset: ${(0, utils_1.kebabToTitle)(GlobalValues_1.globalValues.forcedPreset || "Random")}`;
},
},
], "moarSetPreset");
};
exports.setupRoutes = setupRoutes;
//# sourceMappingURL=routes.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "routes.js",
"sourceRoot": "",
"sources": [
"routes.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,16 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PmcSpawns = exports.SniperSpawns = exports.ScavSpawns = exports.PlayerSpawns = void 0;
// context/index.js
var playerSpawns_json_1 = require("../../config/Spawns/playerSpawns.json");
Object.defineProperty(exports, "PlayerSpawns", { enumerable: true, get: function () { return __importDefault(playerSpawns_json_1).default; } });
var scavSpawns_json_1 = require("../../config/Spawns/scavSpawns.json");
Object.defineProperty(exports, "ScavSpawns", { enumerable: true, get: function () { return __importDefault(scavSpawns_json_1).default; } });
var sniperSpawns_json_1 = require("../../config/Spawns/sniperSpawns.json");
Object.defineProperty(exports, "SniperSpawns", { enumerable: true, get: function () { return __importDefault(sniperSpawns_json_1).default; } });
var pmcSpawns_json_1 = require("../../config/Spawns/pmcSpawns.json");
Object.defineProperty(exports, "PmcSpawns", { enumerable: true, get: function () { return __importDefault(pmcSpawns_json_1).default; } });
//# sourceMappingURL=index.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "index.js",
"sourceRoot": "",
"sources": [
"index.ts"
],
"names": [],
"mappings": ";;;;;;AAAA,mBAAmB;AACnB,2EAAgF;AAAvE,kIAAA,OAAO,OAAgB;AAChC,uEAA4E;AAAnE,8HAAA,OAAO,OAAc;AAC9B,2EAAgF;AAAvE,kIAAA,OAAO,OAAgB;AAChC,qEAA0E;AAAjE,4HAAA,OAAO,OAAa"
}

View file

@ -0,0 +1,150 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupSpawns = void 0;
const constants_1 = require("../Spawning/constants");
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const GlobalValues_1 = require("../GlobalValues");
const spawnZoneUtils_1 = require("../Spawning/spawnZoneUtils");
const utils_1 = require("../Spawning/utils");
const _1 = require(".");
const updateUtils_1 = require("./updateUtils");
const advancedConfig_json_2 = require("../../config/advancedConfig.json");
const setupSpawns = (container) => {
const databaseServer = container.resolve("DatabaseServer");
const { locations } = databaseServer.getTables();
const indexedMapSpawns = {};
const mapsToExcludeFromPlayerCulling = new Set([
"factory4_day",
"factory4_night",
"laboratory",
]);
constants_1.originalMapList.forEach((map, mapIndex) => {
const configMap = constants_1.configLocations[mapIndex];
const allZones = [
...new Set(locations[map].base.SpawnPointParams.filter(({ BotZoneName }) => !!BotZoneName).map(({ BotZoneName }) => BotZoneName)),
];
locations[map].base.OpenZones = allZones.join(",");
let bossSpawns = [];
let scavSpawns = [];
let sniperSpawns = [];
let pmcSpawns = [];
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");
(0, utils_1.shuffle)(locations[map].base.SpawnPointParams).forEach((point) => {
switch (true) {
case point.Categories.includes("Boss") ||
bossZoneList.has(point.BotZoneName):
bossSpawns.push(point);
break;
case point.BotZoneName?.toLowerCase().includes("snipe") ||
(map !== "lighthouse" && point.DelayToCanSpawnSec > 40):
sniperSpawns.push(point);
break;
case !!point.Infiltration || point.Categories.includes("Coop"):
pmcSpawns.push(point);
break;
default:
scavSpawns.push(point);
break;
}
});
// fix GZ
if (isGZ) {
sniperSpawns.map((point, index) => {
if (index < 2) {
point.BotZoneName = Math.random()
? "ZoneSandSnipeCenter"
: "ZoneSandSnipeCenter2";
}
else {
point.BotZoneName = ["ZoneSandSnipeCenter", "ZoneSandSnipeCenter2"][index];
}
return point;
});
}
if (advancedConfig_json_1.default.ActivateSpawnCullingOnServerStart) {
_1.ScavSpawns[map] =
(0, spawnZoneUtils_1.removeClosestSpawnsFromCustomBots)(_1.ScavSpawns, scavSpawns, map, constants_1.configLocations[mapIndex]) || [];
_1.PmcSpawns[map] =
(0, spawnZoneUtils_1.removeClosestSpawnsFromCustomBots)(_1.PmcSpawns, pmcSpawns, map, constants_1.configLocations[mapIndex]) || [];
_1.PlayerSpawns[map] =
(0, spawnZoneUtils_1.removeClosestSpawnsFromCustomBots)(_1.PlayerSpawns, pmcSpawns, map, constants_1.configLocations[mapIndex]) || [];
_1.SniperSpawns[map] =
(0, spawnZoneUtils_1.removeClosestSpawnsFromCustomBots)(_1.SniperSpawns, sniperSpawns, map, constants_1.configLocations[mapIndex]) || [];
}
const { spawnMinDistance: limit } = mapConfig_json_1.default[constants_1.configLocations[mapIndex]];
let playerSpawns = (0, spawnZoneUtils_1.BuildCustomPlayerSpawnPoints)(map, locations[map].base.SpawnPointParams);
playerSpawns = (0, spawnZoneUtils_1.cleanClosest)(playerSpawns, mapIndex, mapConfig_json_1.default[configMap].mapCullingNearPointValuePlayer);
scavSpawns = (0, spawnZoneUtils_1.cleanClosest)((0, spawnZoneUtils_1.AddCustomBotSpawnPoints)(scavSpawns, map), mapIndex, mapConfig_json_1.default[configMap].mapCullingNearPointValueScav).map((point, botIndex) => {
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;
});
pmcSpawns = (0, spawnZoneUtils_1.cleanClosest)((0, spawnZoneUtils_1.AddCustomPmcSpawnPoints)(pmcSpawns, map), mapIndex, mapConfig_json_1.default[configMap].mapCullingNearPointValuePmc).map((point, pmcIndex) => {
if (point.ColliderParams?._props?.Radius < limit) {
point.ColliderParams._props.Radius = limit;
}
return !!point.Categories.length
? {
...point,
BotZoneName: isGZ
? "ZoneSandbox"
: (0, spawnZoneUtils_1.getClosestZone)(scavSpawns, point.Position.x, point.Position.y, point.Position.z),
Categories: ["Coop", Math.random() ? "Group" : "Opposite"],
Sides: ["Pmc"],
CorePointId: 0,
}
: point;
});
sniperSpawns = (0, spawnZoneUtils_1.AddCustomSniperSpawnPoints)(sniperSpawns, map);
indexedMapSpawns[mapIndex] = [
...sniperSpawns.map((point) => ({ ...point, type: "sniper" })),
...bossSpawns.map((point) => ({ ...point, type: "boss" })),
...scavSpawns.map((point) => ({ ...point, type: "scav" })),
...pmcSpawns.map((point) => ({ ...point, type: "pmc" })),
...playerSpawns.map((point) => ({ ...point, type: "player" })),
];
advancedConfig_json_2.showMapCullingDebug &&
console.log("sniperSpawns", sniperSpawns.length, "bossSpawns", bossSpawns.length, "scavSpawns", scavSpawns.length, "pmcSpawns", pmcSpawns.length, "playerSpawns", playerSpawns.length, map);
locations[map].base.SpawnPointParams = indexedMapSpawns[mapIndex];
const listToAddToOpenZones = [
...new Set(locations[map].base.SpawnPointParams.map(({ BotZoneName }) => BotZoneName).filter((zone) => !!zone)),
];
locations[map].base.OpenZones = listToAddToOpenZones.join(",");
});
// PlayerSpawns, PmcSpawns, ScavSpawns, SniperSpawns
if (advancedConfig_json_1.default.ActivateSpawnCullingOnServerStart) {
(0, updateUtils_1.updateAllBotSpawns)(_1.PlayerSpawns, "playerSpawns");
(0, updateUtils_1.updateAllBotSpawns)(_1.PmcSpawns, "pmcSpawns");
(0, updateUtils_1.updateAllBotSpawns)(_1.ScavSpawns, "scavSpawns");
(0, updateUtils_1.updateAllBotSpawns)(_1.SniperSpawns, "sniperSpawns");
}
GlobalValues_1.globalValues.indexedMapSpawns = indexedMapSpawns;
};
exports.setupSpawns = setupSpawns;
//# sourceMappingURL=setupSpawn.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,79 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateAllBotSpawns = exports.deleteBotSpawn = exports.updateBotSpawn = exports.updateJsonFile = void 0;
const spawnZoneUtils_1 = require("../Spawning/spawnZoneUtils");
const fs = require("fs");
const path = require("path");
const currentDirectory = process.cwd();
// Function to update JSON file
const updateJsonFile = (filePath, callback, successMessage) => {
// 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);
});
});
};
exports.updateJsonFile = updateJsonFile;
const updateBotSpawn = (map, value, type) => {
map = map.toLowerCase();
(0, exports.updateJsonFile)(`${currentDirectory}/user/mods/DewardianDev-MOAR/config/Spawns/${type}Spawns.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);
};
exports.updateBotSpawn = updateBotSpawn;
const deleteBotSpawn = (map, value, type) => {
map = map.toLowerCase();
(0, exports.updateJsonFile)(`${currentDirectory}/user/mods/DewardianDev-MOAR/config/Spawns/${type}Spawns.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 = (0, spawnZoneUtils_1.getDistance)(x, y, z, X, Y, Z);
if (dist < nearDist) {
nearest = index;
nearDist = dist;
}
});
if (nearest) {
jsonData[map].splice(nearest, 1);
}
else {
console.log("No nearest spawn on " + map);
}
}
}, "Successfully removed one bot spawn from ");
};
exports.deleteBotSpawn = deleteBotSpawn;
const updateAllBotSpawns = (values, targetType) => (0, exports.updateJsonFile)(`${currentDirectory}/user/mods/DewardianDev-MOAR/config/Spawns/${targetType}.json`, (jsonData) => {
Object.keys(jsonData).forEach((map) => (jsonData[map] = values[map]));
}, "Successfully updated all Spawns");
exports.updateAllBotSpawns = updateAllBotSpawns;
//# sourceMappingURL=updateUtils.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "updateUtils.js",
"sourceRoot": "",
"sources": [
"updateUtils.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,119 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildWaves = void 0;
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const GlobalValues_1 = require("../GlobalValues");
const utils_1 = require("../utils");
const constants_1 = require("./constants");
const buildBossWaves_1 = require("./buildBossWaves");
const buildZombieWaves_1 = __importDefault(require("./buildZombieWaves"));
const buildScavMarksmanWaves_1 = __importDefault(require("./buildScavMarksmanWaves"));
const buildPmcs_1 = __importDefault(require("./buildPmcs"));
const utils_2 = require("./utils");
const updateSpawnLocations_1 = __importDefault(require("./updateSpawnLocations"));
const marksmanChanges_1 = __importDefault(require("./marksmanChanges"));
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const buildWaves = (container) => {
const configServer = container.resolve("ConfigServer");
const Logger = container.resolve("WinstonLogger");
const pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const locationConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.LOCATION);
locationConfig.rogueLighthouseSpawnTimeSettings.waitTimeSeconds = 60;
locationConfig.enableBotTypeLimits = false;
locationConfig.fitLootIntoContainerAttempts = 1; // Move to ALP
locationConfig.addCustomBotWavesToMaps = false;
locationConfig.customWaves = { boss: {}, normal: {} };
const databaseServer = container.resolve("DatabaseServer");
const { locations, bots } = databaseServer.getTables();
let config = (0, utils_1.cloneDeep)(GlobalValues_1.globalValues.baseConfig);
const preset = (0, utils_1.getRandomPresetOrCurrentlySelectedPreset)();
Object.keys(GlobalValues_1.globalValues.overrideConfig).forEach((key) => {
if (config[key] !== GlobalValues_1.globalValues.overrideConfig[key]) {
config.debug &&
console.log(`[MOAR] overrideConfig ${key} changed from ${config[key]} to ${GlobalValues_1.globalValues.overrideConfig[key]}`);
config[key] = GlobalValues_1.globalValues.overrideConfig[key];
}
});
// Set from preset if preset above is not empty
Object.keys(preset).forEach((key) => {
if (config[key] !== preset[key]) {
config.debug &&
console.log(`[MOAR] preset ${GlobalValues_1.globalValues.currentPreset}: ${key} changed from ${config[key]} to ${preset[key]}`);
config[key] = preset[key];
}
});
// config.debug &&
console.log(GlobalValues_1.globalValues.forcedPreset === "custom"
? "custom"
: GlobalValues_1.globalValues.forcedPreset
? GlobalValues_1.globalValues.forcedPreset
: GlobalValues_1.globalValues.currentPreset);
const { bigmap: customs, factory4_day: factoryDay, factory4_night: factoryNight, interchange, laboratory, lighthouse, rezervbase, shoreline, tarkovstreets, woods, sandbox: gzLow, sandbox_high: gzHigh, } = locations;
let locationList = [
customs,
factoryDay,
factoryNight,
interchange,
laboratory,
lighthouse,
rezervbase,
shoreline,
tarkovstreets,
woods,
gzLow,
gzHigh,
];
// This resets all locations to original state
if (!GlobalValues_1.globalValues.locationsBase) {
GlobalValues_1.globalValues.locationsBase = locationList.map(({ base }) => (0, utils_1.cloneDeep)(base));
}
else {
locationList = locationList.map((item, key) => ({
...item,
base: (0, utils_1.cloneDeep)(GlobalValues_1.globalValues.locationsBase[key]),
}));
}
pmcConfig.removeExistingPmcWaves = true;
Object.keys(pmcConfig.customPmcWaves).forEach(key => {
pmcConfig.customPmcWaves[key] = [];
});
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;
}
if (advancedConfig_json_1.default.MarksmanDifficultyChanges) {
(0, marksmanChanges_1.default)(bots);
}
(0, updateSpawnLocations_1.default)(locationList, config);
(0, utils_2.setEscapeTimeOverrides)(locationList, mapConfig_json_1.default, Logger, config);
// BOSS RELATED STUFF!
(0, buildBossWaves_1.buildBossWaves)(config, locationList);
//Zombies
if (config.zombiesEnabled) {
(0, buildZombieWaves_1.default)(config, locationList, bots);
}
(0, buildPmcs_1.default)(config, locationList);
// Make main waves
(0, buildScavMarksmanWaves_1.default)(config, locationList, botConfig);
// enableSmoothing
if (config.spawnSmoothing) {
(0, utils_2.enforceSmoothing)(locationList);
}
// saveToFile(locations.bigmap.base.SpawnPointParams, "spawns.json");
constants_1.originalMapList.forEach((name, index) => {
if (!locations[name]) {
console.log("[MOAR] OH CRAP we have a problem!", name);
}
else {
locations[name] = locationList[index];
}
});
};
exports.buildWaves = buildWaves;
//# sourceMappingURL=Spawning.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "Spawning.js",
"sourceRoot": "",
"sources": [
"Spawning.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,230 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildBossWaves = buildBossWaves;
const bossConfig_json_1 = __importDefault(require("../../config/bossConfig.json"));
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const utils_2 = require("../utils");
function buildBossWaves(config, locationList) {
let { randomRaiderGroup, randomRaiderGroupChance, randomRogueGroup, randomRogueGroupChance, mainBossChanceBuff, bossInvasion, bossInvasionSpawnChance, disableBosses, bossOpenZones, gradualBossInvasion, } = config;
const bossList = constants_1.mainBossNameList.filter((bossName) => !["bossKnight"].includes(bossName));
const allBosses = {};
for (const key in locationList) {
locationList[key].base.BossLocationSpawn.forEach((boss) => {
if (!allBosses[boss.BossName]) {
allBosses[boss.BossName] = boss;
}
});
}
// CreateBossList
const bosses = {};
for (let indx = 0; indx < locationList.length; indx++) {
// Disable Bosses
if (disableBosses && !!locationList[indx].base?.BossLocationSpawn) {
locationList[indx].base.BossLocationSpawn = [];
}
else {
//Remove all other spawns from pool now that we have the spawns zone list
locationList[indx].base.BossLocationSpawn = locationList[indx].base.BossLocationSpawn.filter((boss) => !constants_1.bossesToRemoveFromPool.has(boss.BossName));
// Performance changes
if (advancedConfig_json_1.default.EnableBossPerformanceImprovements) {
locationList[indx].base.BossLocationSpawn.forEach((Boss, bIndex) => {
if (Boss.BossChance < 1)
return;
if (!!constants_1.bossPerformanceHash[Boss.BossName || ""]) {
const varsToUpdate = constants_1.bossPerformanceHash[Boss.BossName];
// make it so bossPartisan has a random spawn time
if (Boss.BossName === "bossPartisan") {
const max = locationList[indx].base.EscapeTimeLimit;
varsToUpdate.Time = Math.floor(Math.random() * 50 * max);
// console.log(varsToUpdate, max * 60)
}
locationList[indx].base.BossLocationSpawn[bIndex] = {
...Boss,
...varsToUpdate,
};
}
});
}
const location = locationList[indx];
const defaultBossSettings = mapConfig_json_1.default?.[constants_1.configLocations[indx]]?.defaultBossSettings;
// Sets bosses spawn chance from settings
if (location?.base?.BossLocationSpawn &&
defaultBossSettings &&
Object.keys(defaultBossSettings)?.length) {
const filteredBossList = Object.keys(defaultBossSettings).filter((name) => defaultBossSettings[name]?.BossChance !== undefined);
if (filteredBossList?.length) {
filteredBossList.forEach((bossName) => {
location.base.BossLocationSpawn =
location.base.BossLocationSpawn.map((boss) => ({
...boss,
...(boss.BossName === bossName
? { BossChance: defaultBossSettings[bossName].BossChance }
: {}),
}));
});
}
}
if (randomRaiderGroup) {
const raiderWave = (0, utils_1.buildBossBasedWave)(randomRaiderGroupChance, "1,2,2,2,3", "pmcBot", "pmcBot", "", locationList[indx].base.EscapeTimeLimit);
location.base.BossLocationSpawn.push(raiderWave);
}
if (randomRogueGroup) {
const rogueWave = (0, utils_1.buildBossBasedWave)(randomRogueGroupChance, "1,2,2,2,3", "exUsec", "exUsec", "", locationList[indx].base.EscapeTimeLimit);
location.base.BossLocationSpawn.push(rogueWave);
}
//Add each boss from each map to bosses object
const filteredBosses = location.base.BossLocationSpawn?.filter(({ BossName }) => constants_1.mainBossNameList.includes(BossName));
if (filteredBosses.length) {
for (let index = 0; index < filteredBosses.length; index++) {
const boss = filteredBosses[index];
if (!bosses[boss.BossName] ||
(bosses[boss.BossName] &&
bosses[boss.BossName].BossChance < boss.BossChance)) {
bosses[boss.BossName] = { ...boss };
}
}
}
}
}
if (!disableBosses) {
// Make boss Invasion
if (bossInvasion) {
if (bossInvasionSpawnChance) {
bossList.forEach((bossName) => {
if (bosses[bossName])
bosses[bossName].BossChance = bossInvasionSpawnChance;
});
}
for (let key = 0; key < locationList.length; key++) {
//Gather bosses to avoid duplicating.
const duplicateBosses = [
...locationList[key].base.BossLocationSpawn.filter(({ BossName, BossZone }) => bossList.includes(BossName)).map(({ BossName }) => BossName),
"bossKnight", // So knight doesn't invade
];
//Build bosses to add
const bossesToAdd = (0, utils_1.shuffle)(Object.values(bosses))
.filter(({ BossName }) => !duplicateBosses.includes(BossName))
.map((boss, j) => ({
...boss,
BossZone: "",
BossEscortAmount: boss.BossEscortAmount === "0" ? boss.BossEscortAmount : "1",
...(gradualBossInvasion ? { Time: j * 20 + 1 } : {}),
}));
// UpdateBosses
locationList[key].base.BossLocationSpawn = [
...locationList[key].base.BossLocationSpawn,
...bossesToAdd,
];
}
}
let hasChangedBossSpawns = false;
// console.log(Object.keys(allBosses));
constants_1.configLocations.forEach((mapName, index) => {
const bossLocationSpawn = locationList[index].base.BossLocationSpawn;
const mapBossConfig = (0, utils_2.cloneDeep)(bossConfig_json_1.default[mapName] || {});
// if (Object.keys(mapBossConfig).length === 0) console.log(name, "empty");
const adjusted = new Set([]);
bossLocationSpawn.forEach(({ BossName, BossChance }, bossIndex) => {
if (typeof mapBossConfig[BossName] === "number") {
if (BossChance !== mapBossConfig[BossName]) {
if (!hasChangedBossSpawns) {
console.log(`\n[MOAR]: --- Adjusting default boss spawn rates from bossConfig.json --- `);
hasChangedBossSpawns = true;
}
console.log(`[MOAR]: ${mapName} ${BossName}: ${locationList[index].base.BossLocationSpawn[bossIndex].BossChance} => ${mapBossConfig[BossName]}`);
locationList[index].base.BossLocationSpawn[bossIndex].BossChance =
mapBossConfig[BossName];
}
adjusted.add(BossName);
}
});
const bossesToAdd = Object.keys(mapBossConfig)
.filter((adjustName) => !adjusted.has(adjustName) && !!allBosses[adjustName])
.map((bossName) => {
`[MOAR]: Adding non-default boss ${bossName} to ${constants_1.originalMapList[index]}`;
const newBoss = (0, utils_2.cloneDeep)(allBosses[bossName] || {});
newBoss.BossChance = mapBossConfig[bossName];
// console.log(
// "Adding boss",
// bossName,
// "to ",
// originalMapList[index],
// "spawn chance =>",
// mapBossConfig[bossName]
// );
return newBoss;
});
// console.log(bossesToAdd);
if (bossOpenZones || mainBossChanceBuff) {
locationList[index].base?.BossLocationSpawn?.forEach((boss, key) => {
if (bossList.includes(boss.BossName)) {
if (bossOpenZones) {
locationList[index].base.BossLocationSpawn[key] = {
...locationList[index].base.BossLocationSpawn[key],
BossZone: "",
};
}
if (!!boss.BossChance && mainBossChanceBuff > 0) {
locationList[index].base.BossLocationSpawn[key] = {
...locationList[index].base.BossLocationSpawn[key],
BossChance: boss.BossChance + mainBossChanceBuff > 100
? 100
: Math.round(boss.BossChance + mainBossChanceBuff),
};
}
}
});
}
locationList[index].base.BossLocationSpawn = [
...locationList[index].base.BossLocationSpawn,
...bossesToAdd,
];
bossesToAdd.length &&
console.log(`[MOAR] Adding the following bosses to map ${constants_1.configLocations[index]}: ${bossesToAdd.map(({ BossName }) => BossName)}`);
// console.log(locationList[index].base.BossLocationSpawn.length);
const bossesToSkip = new Set(["sectantPriest", "pmcBot"]);
// 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.map(({ BossChance, BossName, TriggerId }, bossIndex) => {
if (BossChance < 1) {
return locationList[index].base.BossLocationSpawn[bossIndex];
}
if (!TriggerId &&
!bossesToSkip.has(BossName) &&
BossChance < 100) {
if (BossChance / 100 < Math.random()) {
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 locationList[index].base.BossLocationSpawn[bossIndex];
}).filter(({ BossChance, BossName, ...rest }) => {
if (BossChance < 1) {
return false;
}
return true;
});
// if (mapName === "lighthouse") {
// console.log(
// locationList[index].base.BossLocationSpawn.map(
// ({ BossName, BossChance }) => ({ BossName, BossChance })
// )
// );
// }
});
if (hasChangedBossSpawns) {
console.log(`[MOAR]: --- Adjusting default boss spawn rates complete --- \n`);
}
}
}
//# sourceMappingURL=buildBossWaves.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,73 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = buildPmcs;
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const spawnZoneUtils_1 = __importDefault(require("./spawnZoneUtils"));
const GlobalValues_1 = require("../GlobalValues");
function buildPmcs(config, locationList) {
for (let index = 0; index < locationList.length; index++) {
const mapSettingsList = Object.keys(mapConfig_json_1.default);
const map = mapSettingsList[index];
// Set pmcs hostile to everything
locationList[index].base.BotLocationModifier.AdditionalHostilitySettings =
constants_1.defaultHostility;
const { pmcHotZones = [], pmcWaveCount, initialSpawnDelay, } = mapConfig_json_1.default?.[map] || {};
const { Position: { x, y, z }, } = GlobalValues_1.globalValues.playerSpawn;
let pmcZones = (0, spawnZoneUtils_1.default)(locationList[index].base.SpawnPointParams.filter((point) => point["type"] === "pmc"), x, y, z, 0.05).map(({ BotZoneName }) => BotZoneName);
(0, utils_1.looselyShuffle)(pmcZones, 3);
// console.log(pmcZones);
if (map === "laboratory") {
pmcZones = new Array(10).fill(pmcZones).flat(1);
}
if (config.randomSpawns)
pmcZones = (0, utils_1.shuffle)(pmcZones);
const escapeTimeLimitRatio = Math.round(locationList[index].base.EscapeTimeLimit / constants_1.defaultEscapeTimes[map]);
let totalWaves = Math.round(pmcWaveCount * config.pmcWaveQuantity * escapeTimeLimitRatio);
if (!!pmcHotZones.length && totalWaves > 0) {
totalWaves = totalWaves + pmcHotZones.length;
}
while (totalWaves - pmcZones.length > 0) {
console.log(`${map} ran out of appropriate zones for pmcs, duplicating zones`);
// const addEmpty = new Array(numberOfZoneless).fill("");
pmcZones = [...pmcZones, ...pmcZones];
if (pmcZones.length === 0) {
pmcZones = [""];
}
}
if (config.debug) {
console.log(`${map} PMC count ${totalWaves} \n`);
escapeTimeLimitRatio !== 1 &&
console.log(`${map} PMC wave count changed from ${pmcWaveCount} to ${totalWaves} due to escapeTimeLimit adjustment`);
}
const timeLimit = locationList[index].base.EscapeTimeLimit * 60;
const half = Math.round(totalWaves % 2 === 0 ? totalWaves / 2 : (totalWaves + 1) / 2);
const usecSpawns = pmcZones.filter((_, i) => i % 2 === 0);
const bearSpawns = pmcZones.filter((_, i) => i % 2 !== 0);
const pmcUSEC = (0, utils_1.buildBotWaves)(half, config.startingPmcs ? Math.round(0.2 * timeLimit) : timeLimit, config.pmcMaxGroupSize - 1, config.pmcGroupChance, usecSpawns, config.pmcDifficulty, "pmcUSEC", false, config.pmcWaveDistribution, initialSpawnDelay + Math.round(10 * Math.random()));
const pmcBEAR = (0, utils_1.buildBotWaves)(half, config.startingPmcs ? Math.round(0.1 * timeLimit) : timeLimit, config.pmcMaxGroupSize - 1, config.pmcGroupChance, bearSpawns, config.pmcDifficulty, "pmcBEAR", false, config.pmcWaveDistribution, initialSpawnDelay + Math.round(10 * Math.random()));
const pmcs = [...pmcUSEC, ...pmcBEAR];
// console.log(pmcs.map(({ Time }) => Time));
if (pmcs.length) {
// Add hotzones if exist
pmcHotZones.forEach((hotzone) => {
const index = Math.floor(pmcs.length * Math.random());
pmcs[index].BossZone = hotzone;
// console.log(pmcs[index]);
});
}
// console.log(
// map,
// pmcs.map(({ BossZone }) => BossZone)
// );
locationList[index].base.BossLocationSpawn = [
...pmcs,
...locationList[index].base.BossLocationSpawn,
];
}
}
//# sourceMappingURL=buildPmcs.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "buildPmcs.js",
"sourceRoot": "",
"sources": [
"buildPmcs.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,135 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = buildScavMarksmanWaves;
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const ILocationBase_1 = require("C:/snapshot/project/obj/models/eft/common/ILocationBase");
const spawnZoneUtils_1 = __importDefault(require("./spawnZoneUtils"));
const GlobalValues_1 = require("../GlobalValues");
function buildScavMarksmanWaves(config, locationList, botConfig) {
let { maxBotCap, scavWaveQuantity, scavWaveDistribution, sniperMaxGroupSize, maxBotPerZone, scavMaxGroupSize, scavDifficulty, sniperGroupChance, scavGroupChance, } = config;
for (let index = 0; index < locationList.length; index++) {
const mapSettingsList = Object.keys(mapConfig_json_1.default);
const map = mapSettingsList[index];
locationList[index].base.waves = [];
locationList[index].base = {
...locationList[index].base,
...{
NewSpawn: false,
OcculsionCullingEnabled: true,
OfflineNewSpawn: false,
OfflineOldSpawn: true,
OldSpawn: true,
BotSpawnCountStep: 0,
},
};
locationList[index].base.NonWaveGroupScenario.Enabled = false;
locationList[index].base["BotStartPlayer"] = 0;
if (locationList[index].base.BotStop <
locationList[index].base.EscapeTimeLimit * 60) {
locationList[index].base.BotStop =
locationList[index].base.EscapeTimeLimit * 60;
}
const { maxBotPerZoneOverride, maxBotCapOverride, EscapeTimeLimit, scavHotZones = [], sniperQuantity = 1, scavWaveCount, initialSpawnDelay, } = mapConfig_json_1.default?.[map] || {};
// Set per map EscapeTimeLimit
if (EscapeTimeLimit) {
locationList[index].base.EscapeTimeLimit = EscapeTimeLimit;
locationList[index].base.exit_access_time = EscapeTimeLimit + 1;
}
// Set default or per map maxBotCap
if (maxBotCapOverride || maxBotCap) {
const capToSet = maxBotCapOverride || maxBotCap;
// console.log(map, capToSet, maxBotCapOverride, maxBotCap);
locationList[index].base.BotMax = capToSet;
locationList[index].base.BotMaxPvE = capToSet;
locationList[index].base.BotMaxPlayer = capToSet;
botConfig.maxBotCap[constants_1.originalMapList[index]] = capToSet;
}
// Adjust botZone quantity
if (maxBotPerZoneOverride || maxBotPerZone) {
const BotPerZone = maxBotPerZoneOverride || maxBotPerZone;
// console.log(map, BotPerZone, maxBotPerZoneOverride, maxBotPerZone);
locationList[index].base.MaxBotPerZone = BotPerZone;
}
// 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)
// )
// .map(({ BotZoneName }) => BotZoneName || "")
// );
const { Position: { x, y, z }, } = GlobalValues_1.globalValues.playerSpawn;
const sniperSpawns = (0, spawnZoneUtils_1.default)(locationList[index].base.SpawnPointParams.filter((point) => point["type"] === "sniper"), x, y, z);
let sniperLocations = sniperSpawns.map(({ BotZoneName }) => BotZoneName);
// console.log(sniperLocations);
const sniperDelay = 25;
// 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 = [
{
WildSpawnType: "marksman",
max: sniperLocations.length * 5,
min: sniperLocations.length,
},
];
}
let scavZones = (0, spawnZoneUtils_1.default)(locationList[index].base.SpawnPointParams.filter((point) => point["type"] === "scav"), x, y, z, 0.05).map(({ BotZoneName }) => BotZoneName);
(0, utils_1.looselyShuffle)(scavZones, 3);
const escapeTimeLimitRatio = Math.round(locationList[index].base.EscapeTimeLimit / constants_1.defaultEscapeTimes[map]);
// Scavs
let scavTotalWaveCount = Math.round(scavWaveCount * scavWaveQuantity * escapeTimeLimitRatio);
if (scavHotZones.length && scavTotalWaveCount > 0) {
scavTotalWaveCount = scavTotalWaveCount + scavHotZones.length;
}
while (scavTotalWaveCount - scavZones.length > 0) {
console.log(`${map} ran out of appropriate zones for scavs, duplicating zones`);
// const addEmpty = new Array(numberOfZoneless).fill("");
scavZones = [...scavZones, ...scavZones];
if (scavZones.length === 0) {
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;
// if (config.randomSpawns)
// sniperLocations = shuffle<string[]>(sniperLocations);
// console.log(map);
const snipers = (0, utils_1.buildBotWaves)(Math.min(sniperQuantity, sniperLocations.length), timeLimit, ///30,
sniperMaxGroupSize, sniperGroupChance, sniperLocations, 0.8, ILocationBase_1.WildSpawnType.MARKSMAN, true, 0.3, sniperDelay);
if (config.randomSpawns)
scavZones = (0, utils_1.shuffle)(scavZones);
const scavWaves = (0, utils_1.buildBotWaves)(scavTotalWaveCount, timeLimit, scavMaxGroupSize, scavGroupChance, scavZones, scavDifficulty, ILocationBase_1.WildSpawnType.ASSAULT, false, scavWaveDistribution, initialSpawnDelay + Math.round(10 * Math.random()));
// Add hotzones if exist
if (scavWaves.length) {
scavHotZones.forEach((hotzone) => {
const index = Math.floor(scavWaves.length * Math.random());
scavWaves[index].BossZone = hotzone;
// console.log(scavWaves[index].BossZone);
});
}
// if (map === "shoreline") console.log(scavWaves.map(({ Time }) => Time));
// console.log(snipers, scavWaves)
locationList[index].base.BossLocationSpawn = [
...snipers,
...scavWaves,
...locationList[index].base.BossLocationSpawn,
];
}
}
//# sourceMappingURL=buildScavMarksmanWaves.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,45 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = buildZombieWaves;
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const utils_1 = require("./utils");
function buildZombieWaves(config, locationList, bots) {
let { debug, zombieWaveDistribution, zombieWaveQuantity, zombieHealth } = config;
const zombieBodyParts = (0, utils_1.getHealthBodyPartsByPercentage)(zombieHealth);
utils_1.zombieTypes.forEach((type) => {
bots.types?.[type]?.health?.BodyParts?.forEach((_, index) => {
bots.types[type].health.BodyParts[index] = zombieBodyParts;
});
});
for (let indx = 0; indx < locationList.length; indx++) {
const location = locationList[indx].base;
const mapSettingsList = Object.keys(mapConfig_json_1.default);
const map = mapSettingsList[indx];
const { zombieWaveCount } = mapConfig_json_1.default?.[constants_1.configLocations[indx]];
// if (location.Events?.Halloween2024?.MaxCrowdAttackSpawnLimit)
// location.Events.Halloween2024.MaxCrowdAttackSpawnLimit = 100;
// if (location.Events?.Halloween2024?.CrowdCooldownPerPlayerSec)
// location.Events.Halloween2024.CrowdCooldownPerPlayerSec = 60;
// if (location.Events?.Halloween2024?.CrowdCooldownPerPlayerSec)
// location.Events.Halloween2024.CrowdsLimit = 10;
// if (location.Events?.Halloween2024?.CrowdAttackSpawnParams)
// location.Events.Halloween2024.CrowdAttackSpawnParams = [];
if (!zombieWaveCount)
return;
const escapeTimeLimitRatio = Math.round(locationList[indx].base.EscapeTimeLimit / constants_1.defaultEscapeTimes[map]);
const zombieTotalWaveCount = Math.round(zombieWaveCount * zombieWaveQuantity * escapeTimeLimitRatio);
config.debug &&
escapeTimeLimitRatio !== 1 &&
console.log(`${map} Zombie wave count changed from ${zombieWaveCount} to ${zombieTotalWaveCount} due to escapeTimeLimit adjustment`);
const zombieWaves = (0, utils_1.buildZombie)(zombieTotalWaveCount, location.EscapeTimeLimit * 60, zombieWaveDistribution, 9999);
debug &&
console.log(constants_1.configLocations[indx], " generated ", zombieWaves.length, "Zombies");
location.BossLocationSpawn.push(...zombieWaves);
// console.log(zombieWaves[0], zombieWaves[7]);
}
}
//# sourceMappingURL=buildZombieWaves.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "buildZombieWaves.js",
"sourceRoot": "",
"sources": [
"buildZombieWaves.ts"
],
"names": [],
"mappings": ";;;;;AAWA,mCAoEC;AA7ED,iFAAoD;AACpD,2CAAkE;AAClE,mCAIiB;AAGjB,SAAwB,gBAAgB,CACtC,MAAsB,EACtB,YAAyB,EACzB,IAAW;IAEX,IAAI,EAAE,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,YAAY,EAAE,GACrE,MAAM,CAAC;IAET,MAAM,eAAe,GAAG,IAAA,sCAA8B,EAAC,YAAY,CAAC,CAAC;IACrE,mBAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QAC3B,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YAC1D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,eAAe,CAAC;QAC7D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;QACzC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,wBAAS,CAE5C,CAAC;QACF,MAAM,GAAG,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QAElC,MAAM,EAAE,eAAe,EAAE,GAAG,wBAAS,EAAE,CAAC,2BAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QAE/D,gEAAgE;QAChE,kEAAkE;QAClE,iEAAiE;QACjE,kEAAkE;QAClE,iEAAiE;QACjE,oDAAoD;QACpD,8DAA8D;QAC9D,+DAA+D;QAE/D,IAAI,CAAC,eAAe;YAAE,OAAO;QAE7B,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CACrC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,eAAe,GAAG,8BAAkB,CAAC,GAAG,CAAC,CAClE,CAAC;QAEF,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CACrC,eAAe,GAAG,kBAAkB,GAAG,oBAAoB,CAC5D,CAAC;QAEF,MAAM,CAAC,KAAK;YACV,oBAAoB,KAAK,CAAC;YAC1B,OAAO,CAAC,GAAG,CACT,GAAG,GAAG,mCAAmC,eAAe,OAAO,oBAAoB,oCAAoC,CACxH,CAAC;QAEJ,MAAM,WAAW,GAAG,IAAA,mBAAW,EAC7B,oBAAoB,EACpB,QAAQ,CAAC,eAAe,GAAG,EAAE,EAC7B,sBAAsB,EACtB,IAAI,CACL,CAAC;QAEF,KAAK;YACH,OAAO,CAAC,GAAG,CACT,2BAAe,CAAC,IAAI,CAAC,EACrB,aAAa,EACb,WAAW,CAAC,MAAM,EAClB,SAAS,CACV,CAAC;QAEJ,QAAQ,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;QAEhD,+CAA+C;IACjD,CAAC;AACH,CAAC"
}

View file

@ -0,0 +1,230 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bossPerformanceHash = exports.defaultEscapeTimes = exports.mainBossNameList = exports.bossesToRemoveFromPool = exports.originalMapList = exports.configLocations = exports.defaultHostility = void 0;
exports.defaultHostility = [
{
AlwaysEnemies: [
"bossTest",
"followerTest",
"bossKilla",
"bossKojaniy",
"followerKojaniy",
"cursedAssault",
"bossGluhar",
"followerGluharAssault",
"followerGluharSecurity",
"followerGluharScout",
"followerGluharSnipe",
"followerSanitar",
"bossSanitar",
"test",
"assaultGroup",
"sectantWarrior",
"sectantPriest",
"bossTagilla",
"followerTagilla",
"bossKnight",
"followerBigPipe",
"followerBirdEye",
"bossBoar",
"followerBoar",
"arenaFighter",
"arenaFighterEvent",
"bossBoarSniper",
"crazyAssaultEvent",
"sectactPriestEvent",
"followerBoarClose1",
"followerBoarClose2",
"bossKolontay",
"followerKolontayAssault",
"followerKolontaySecurity",
"bossPartisan",
"spiritWinter",
"spiritSpring",
"peacemaker",
"skier",
"assault",
"marksman",
"pmcUSEC",
"exUsec",
"pmcBot",
"bossBully",
],
AlwaysFriends: [
"bossZryachiy",
"followerZryachiy",
"peacefullZryachiyEvent",
"ravangeZryachiyEvent",
"gifter",
],
BearEnemyChance: 100,
BearPlayerBehaviour: "AlwaysEnemies",
BotRole: "pmcBEAR",
ChancedEnemies: [],
Neutral: ["shooterBTR"],
SavagePlayerBehaviour: "AlwaysEnemies",
UsecEnemyChance: 100,
UsecPlayerBehaviour: "AlwaysEnemies",
Warn: ["sectactPriestEvent"],
},
{
AlwaysEnemies: [
"bossTest",
"followerTest",
"bossKilla",
"bossKojaniy",
"followerKojaniy",
"cursedAssault",
"bossGluhar",
"followerGluharAssault",
"followerGluharSecurity",
"followerGluharScout",
"followerGluharSnipe",
"followerSanitar",
"bossSanitar",
"test",
"assaultGroup",
"sectantWarrior",
"sectantPriest",
"bossTagilla",
"followerTagilla",
"bossKnight",
"followerBigPipe",
"followerBirdEye",
"bossBoar",
"followerBoar",
"arenaFighter",
"arenaFighterEvent",
"bossBoarSniper",
"crazyAssaultEvent",
"sectactPriestEvent",
"followerBoarClose1",
"followerBoarClose2",
"bossKolontay",
"followerKolontayAssault",
"followerKolontaySecurity",
"bossPartisan",
"spiritWinter",
"spiritSpring",
"peacemaker",
"skier",
"assault",
"marksman",
"pmcBEAR",
"exUsec",
"pmcBot",
"bossBully",
],
AlwaysFriends: [
"bossZryachiy",
"followerZryachiy",
"peacefullZryachiyEvent",
"ravangeZryachiyEvent",
"gifter",
],
BearEnemyChance: 100,
BearPlayerBehaviour: "AlwaysEnemies",
BotRole: "pmcUSEC",
ChancedEnemies: [],
Neutral: ["shooterBTR"],
SavagePlayerBehaviour: "AlwaysEnemies",
UsecEnemyChance: 100,
UsecPlayerBehaviour: "AlwaysEnemies",
Warn: ["sectactPriestEvent"],
},
];
exports.configLocations = [
"customs",
"factoryDay",
"factoryNight",
"interchange",
"laboratory",
"lighthouse",
"rezervbase",
"shoreline",
"tarkovstreets",
"woods",
"gzLow",
"gzHigh",
];
exports.originalMapList = [
"bigmap",
"factory4_day",
"factory4_night",
"interchange",
"laboratory",
"lighthouse",
"rezervbase",
"shoreline",
"tarkovstreets",
"woods",
"sandbox",
"sandbox_high",
];
exports.bossesToRemoveFromPool = new Set([
"assault",
"pmcBEAR",
"pmcUSEC",
"infectedAssault",
"infectedTagilla",
"infectedLaborant",
"infectedCivil",
]);
exports.mainBossNameList = [
"bossKojaniy",
"bossGluhar",
"bossSanitar",
"bossKilla",
"bossTagilla",
"bossKnight",
"bossBoar",
"bossKolontay",
"bossPartisan",
"bossBully",
];
exports.defaultEscapeTimes = {
customs: 40,
factoryDay: 20,
factoryNight: 25,
interchange: 40,
laboratory: 35,
lighthouse: 40,
rezervbase: 40,
shoreline: 45,
tarkovstreets: 50,
woods: 40,
gzLow: 35,
gzHigh: 35,
};
exports.bossPerformanceHash = {
bossZryachiy: {
BossChance: 50,
BossEscortAmount: "0",
},
exUsec: {
BossEscortAmount: "1",
BossChance: 40,
},
bossBully: {
BossEscortAmount: "2,3",
},
bossBoar: {
BossEscortAmount: "1,2,2,2",
},
bossBoarSniper: {
BossEscortAmount: "1",
},
bossKojaniy: {
BossEscortAmount: "1,2,2",
},
bossPartisan: {
TriggerId: "",
TriggerName: "",
RandomTimeSpawn: false,
Time: 120,
},
// bossSanitar: {
// BossEscortAmount: "1,2,3",
// },
};
//# sourceMappingURL=constants.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "constants.js",
"sourceRoot": "",
"sources": [
"constants.ts"
],
"names": [],
"mappings": ";;;AAAa,QAAA,gBAAgB,GAAG;IAC9B;QACE,aAAa,EAAE;YACb,UAAU;YACV,cAAc;YACd,WAAW;YACX,aAAa;YACb,iBAAiB;YACjB,eAAe;YACf,YAAY;YACZ,uBAAuB;YACvB,wBAAwB;YACxB,qBAAqB;YACrB,qBAAqB;YACrB,iBAAiB;YACjB,aAAa;YACb,MAAM;YACN,cAAc;YACd,gBAAgB;YAChB,eAAe;YACf,aAAa;YACb,iBAAiB;YACjB,YAAY;YACZ,iBAAiB;YACjB,iBAAiB;YACjB,UAAU;YACV,cAAc;YACd,cAAc;YACd,mBAAmB;YACnB,gBAAgB;YAChB,mBAAmB;YACnB,oBAAoB;YACpB,oBAAoB;YACpB,oBAAoB;YACpB,cAAc;YACd,yBAAyB;YACzB,0BAA0B;YAC1B,cAAc;YACd,cAAc;YACd,cAAc;YACd,YAAY;YACZ,OAAO;YACP,SAAS;YACT,UAAU;YACV,SAAS;YACT,QAAQ;YACR,QAAQ;YACR,WAAW;SACZ;QACD,aAAa,EAAE;YACb,cAAc;YACd,kBAAkB;YAClB,wBAAwB;YACxB,sBAAsB;YACtB,QAAQ;SACT;QACD,eAAe,EAAE,GAAG;QACpB,mBAAmB,EAAE,eAAe;QACpC,OAAO,EAAE,SAAS;QAClB,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,CAAC,YAAY,CAAC;QACvB,qBAAqB,EAAE,eAAe;QACtC,eAAe,EAAE,GAAG;QACpB,mBAAmB,EAAE,eAAe;QACpC,IAAI,EAAE,CAAC,oBAAoB,CAAC;KAC7B;IACD;QACE,aAAa,EAAE;YACb,UAAU;YACV,cAAc;YACd,WAAW;YACX,aAAa;YACb,iBAAiB;YACjB,eAAe;YACf,YAAY;YACZ,uBAAuB;YACvB,wBAAwB;YACxB,qBAAqB;YACrB,qBAAqB;YACrB,iBAAiB;YACjB,aAAa;YACb,MAAM;YACN,cAAc;YACd,gBAAgB;YAChB,eAAe;YACf,aAAa;YACb,iBAAiB;YACjB,YAAY;YACZ,iBAAiB;YACjB,iBAAiB;YACjB,UAAU;YACV,cAAc;YACd,cAAc;YACd,mBAAmB;YACnB,gBAAgB;YAChB,mBAAmB;YACnB,oBAAoB;YACpB,oBAAoB;YACpB,oBAAoB;YACpB,cAAc;YACd,yBAAyB;YACzB,0BAA0B;YAC1B,cAAc;YACd,cAAc;YACd,cAAc;YACd,YAAY;YACZ,OAAO;YACP,SAAS;YACT,UAAU;YACV,SAAS;YACT,QAAQ;YACR,QAAQ;YACR,WAAW;SACZ;QACD,aAAa,EAAE;YACb,cAAc;YACd,kBAAkB;YAClB,wBAAwB;YACxB,sBAAsB;YACtB,QAAQ;SACT;QACD,eAAe,EAAE,GAAG;QACpB,mBAAmB,EAAE,eAAe;QACpC,OAAO,EAAE,SAAS;QAClB,cAAc,EAAE,EAAE;QAClB,OAAO,EAAE,CAAC,YAAY,CAAC;QACvB,qBAAqB,EAAE,eAAe;QACtC,eAAe,EAAE,GAAG;QACpB,mBAAmB,EAAE,eAAe;QACpC,IAAI,EAAE,CAAC,oBAAoB,CAAC;KAC7B;CACF,CAAC;AAEW,QAAA,eAAe,GAAG;IAC7B,SAAS;IACT,YAAY;IACZ,cAAc;IACd,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,eAAe;IACf,OAAO;IACP,OAAO;IACP,QAAQ;CACT,CAAC;AAEW,QAAA,eAAe,GAAG;IAC7B,QAAQ;IACR,cAAc;IACd,gBAAgB;IAChB,aAAa;IACb,YAAY;IACZ,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,eAAe;IACf,OAAO;IACP,SAAS;IACT,cAAc;CACf,CAAC;AAEW,QAAA,sBAAsB,GAAG,IAAI,GAAG,CAAC;IAC5C,SAAS;IACT,SAAS;IACT,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;CAChB,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAG;IAC9B,aAAa;IACb,YAAY;IACZ,aAAa;IACb,WAAW;IACX,aAAa;IACb,YAAY;IACZ,UAAU;IACV,cAAc;IACd,cAAc;IACd,WAAW;CACZ,CAAC;AAEW,QAAA,kBAAkB,GAAG;IAChC,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,EAAE;IACd,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,EAAE;IACf,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,EAAE;IACd,SAAS,EAAE,EAAE;IACb,aAAa,EAAE,EAAE;IACjB,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,EAAE;CACX,CAAC;AAEW,QAAA,mBAAmB,GAAG;IACjC,YAAY,EAAE;QACZ,UAAU,EAAE,EAAE;QACd,gBAAgB,EAAE,GAAG;KACtB;IACD,MAAM,EAAE;QACN,gBAAgB,EAAE,GAAG;QACrB,UAAU,EAAE,EAAE;KACf;IACD,SAAS,EAAE;QACT,gBAAgB,EAAE,KAAK;KACxB;IACD,QAAQ,EAAE;QACR,gBAAgB,EAAE,SAAS;KAC5B;IACD,cAAc,EAAE;QACd,gBAAgB,EAAE,GAAG;KACtB;IACD,WAAW,EAAE;QACX,gBAAgB,EAAE,OAAO;KAC1B;IACD,YAAY,EAAE;QACZ,SAAS,EAAE,EAAE;QACb,WAAW,EAAE,EAAE;QACf,eAAe,EAAE,KAAK;QACtB,IAAI,EAAC,GAAG;KACT;IACD,iBAAiB;IACjB,+BAA+B;IAC/B,KAAK;CACN,CAAC"
}

View file

@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = marksmanChanges;
function marksmanChanges(bots) {
// saveToFile(bots.types.marksman.difficulty, "marksmanDifficulty.json");
for (const diff in bots.types.marksman.difficulty) {
bots.types.marksman.difficulty[diff].Core = {
...bots.types.marksman.difficulty[diff].Core,
VisibleAngle: 300,
VisibleDistance: 245,
ScatteringPerMeter: 0.1,
HearingSense: 2.85,
};
bots.types.marksman.difficulty[diff].Mind = {
...bots.types.marksman.difficulty[diff].Mind,
BULLET_FEEL_DIST: 360,
CHANCE_FUCK_YOU_ON_CONTACT_100: 10,
};
bots.types.marksman.difficulty[diff].Hearing = {
...bots.types.marksman.difficulty[diff].Hearing,
CHANCE_TO_HEAR_SIMPLE_SOUND_0_1: 0.7,
DISPERSION_COEF: 3.6,
CLOSE_DIST: 10,
FAR_DIST: 30,
};
}
// saveToFile(bots.types.marksman.difficulty, "marksmanDifficulty2.json");
}
//# sourceMappingURL=marksmanChanges.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "marksmanChanges.js",
"sourceRoot": "",
"sources": [
"marksmanChanges.ts"
],
"names": [],
"mappings": ";;AAIA,kCA0BC;AA1BD,SAAwB,eAAe,CAAC,IAAW;IACjD,yEAAyE;IACzE,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QACjD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAA2B,CAAC,IAAI,GAAG;YACrE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI;YAC5C,YAAY,EAAE,GAAG;YACjB,eAAe,EAAE,GAAG;YACpB,kBAAkB,EAAE,GAAG;YACvB,YAAY,EAAE,IAAI;SACnB,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAA2B,CAAC,IAAI,GAAG;YACrE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI;YAC5C,gBAAgB,EAAE,GAAG;YACrB,8BAA8B,EAAE,EAAE;SACnC,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAA2B,CAAC,OAAO,GAAG;YACxE,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO;YAC/C,+BAA+B,EAAE,GAAG;YACpC,eAAe,EAAE,GAAG;YACpB,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb,CAAC;IACJ,CAAC;IACD,0EAA0E;AAC5E,CAAC"
}

View file

@ -0,0 +1,282 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeClosestSpawnsFromCustomBots = exports.getClosestZone = exports.BuildCustomPlayerSpawnPoints = exports.random360 = exports.AddCustomSniperSpawnPoints = exports.AddCustomBotSpawnPoints = exports.AddCustomPmcSpawnPoints = exports.getDistance = void 0;
exports.default = getSortedSpawnPointList;
exports.cleanClosest = cleanClosest;
exports.uuidv4 = uuidv4;
const config_json_1 = __importDefault(require("../../config/config.json"));
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const SpawnZoneChanges_1 = require("../SpawnZoneChanges");
function sq(n) {
return n * n;
}
function pt(a, b) {
return Math.sqrt(sq(a) + sq(b));
}
const getDistance = (x, y, z, mX, mY, mZ) => {
(x = Math.abs(x - mX)), (y = Math.abs(y - mY)), (z = Math.abs(z - mZ));
return pt(pt(x, z), y);
};
exports.getDistance = getDistance;
function getSortedSpawnPointList(SpawnPointParams, mX, my, mZ, cull) {
let culledAmount = 0;
const sorted = SpawnPointParams.sort((a, b) => {
const a1 = (0, exports.getDistance)(a.Position.x, a.Position.y, a.Position.z, mX, my, mZ);
const b1 = (0, exports.getDistance)(b.Position.x, b.Position.y, b.Position.z, mX, my, mZ);
return a1 - b1;
}).filter((_, index) => {
if (!cull)
return true;
const result = index > SpawnPointParams.length * cull;
if (!result)
culledAmount++;
return result;
});
if (config_json_1.default.debug && culledAmount > 0) {
console.log("Reduced to " +
Math.round((sorted.length / SpawnPointParams.length) * 100) +
"% of original spawns", SpawnPointParams.length, ">", sorted.length, "\n");
}
return sorted;
}
function cleanClosest(SpawnPointParams, mapIndex, mapCullingNearPointValue) {
const map = constants_1.configLocations[mapIndex];
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 = (0, exports.getDistance)(X, Y, Z, x, y, z);
return mapCullingNearPointValue > dist && dist !== 0 && !okayList.has(Id);
});
if (!result) {
okayList.add(point.Id);
}
return result
? point
: {
...point,
DelayToCanSpawnSec: 9999999,
CorePointId: 99999,
Categories: [],
Sides: [],
};
});
if (config_json_1.default.debug) {
const actualCulled = filteredParams.filter(({ Categories }) => !!Categories.length);
console.log(map, filteredParams.length, ">", actualCulled.length, "Reduced to " +
Math.round((actualCulled.length / filteredParams.length) * 100) +
"% of original spawns"); // high, low}
}
return filteredParams.filter((point) => !!point.Categories.length);
// 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));
}
const AddCustomPmcSpawnPoints = (SpawnPointParams, map) => {
if (!SpawnZoneChanges_1.PmcSpawns[map] || !SpawnZoneChanges_1.PmcSpawns[map].length) {
config_json_1.default.debug && console.log("no custom Bot spawns for " + map);
return SpawnPointParams;
}
const playerSpawns = SpawnZoneChanges_1.PmcSpawns[map].map((coords, index) => ({
BotZoneName: (0, exports.getClosestZone)(SpawnPointParams, coords.x, coords.y, coords.z),
Categories: ["Coop", Math.random() ? "Group" : "Opposite"],
Sides: ["Pmc"],
CorePointId: 0,
ColliderParams: {
_parent: "SpawnSphereParams",
_props: {
Center: {
x: 0,
y: 0,
z: 0,
},
Radius: 20,
},
},
DelayToCanSpawnSec: 4,
Id: uuidv4(),
Infiltration: "",
Position: coords,
Rotation: (0, exports.random360)(),
}));
return [...SpawnPointParams, ...playerSpawns];
};
exports.AddCustomPmcSpawnPoints = AddCustomPmcSpawnPoints;
const AddCustomBotSpawnPoints = (SpawnPointParams, map) => {
if (!SpawnZoneChanges_1.ScavSpawns[map] || !SpawnZoneChanges_1.ScavSpawns[map].length) {
config_json_1.default.debug && console.log("no custom Bot spawns for " + map);
return SpawnPointParams;
}
const scavSpawns = SpawnZoneChanges_1.ScavSpawns[map].map((coords) => ({
BotZoneName: (0, exports.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: (0, exports.random360)(),
Sides: ["Savage"],
}));
return [...SpawnPointParams, ...scavSpawns];
};
exports.AddCustomBotSpawnPoints = AddCustomBotSpawnPoints;
const AddCustomSniperSpawnPoints = (SpawnPointParams, map) => {
if (!SpawnZoneChanges_1.SniperSpawns[map] || !SpawnZoneChanges_1.SniperSpawns[map].length) {
config_json_1.default.debug && console.log("no custom Player spawns for " + map);
return SpawnPointParams;
}
const sniperSpawns = SpawnZoneChanges_1.SniperSpawns[map].map((coords, index) => ({
BotZoneName: (0, exports.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: (0, exports.random360)(),
Sides: ["Savage"],
}));
return [...SpawnPointParams, ...sniperSpawns];
};
exports.AddCustomSniperSpawnPoints = AddCustomSniperSpawnPoints;
const random360 = () => Math.random() * 360;
exports.random360 = random360;
const BuildCustomPlayerSpawnPoints = (map, refSpawns) => {
const playerOnlySpawns = refSpawns
.filter((item) => !!item.Infiltration && item.Categories[0] === "Player")
.map((point) => {
point.ColliderParams._props.Radius = 1;
point.Position.y = point.Position.y + 0.5;
return {
...point,
BotZoneName: "",
isCustom: true,
Id: uuidv4(),
Sides: ["Pmc"],
};
});
// console.log(map, playerOnlySpawns.length);
if (!SpawnZoneChanges_1.PlayerSpawns[map] || !SpawnZoneChanges_1.PlayerSpawns[map].length) {
config_json_1.default.debug && console.log("no custom Player spawns for " + map);
return playerOnlySpawns;
}
const getClosestInfil = (X, Y, Z) => {
let closest = Infinity;
let selectedInfil = "";
playerOnlySpawns.forEach(({ Infiltration, Position: { x, y, z } }) => {
const dist = (0, exports.getDistance)(X, Y, Z, x, y, z);
if (!!Infiltration && dist < closest) {
closest = dist;
selectedInfil = Infiltration;
}
});
return selectedInfil;
};
const playerSpawns = SpawnZoneChanges_1.PlayerSpawns[map].map((coords, index) => ({
BotZoneName: "",
Categories: ["Player"],
ColliderParams: {
_parent: "SpawnSphereParams",
_props: {
Center: {
x: 0,
y: 0,
z: 0,
},
Radius: 1,
},
},
isCustom: true,
CorePointId: 0,
DelayToCanSpawnSec: 4,
Id: uuidv4(),
Infiltration: getClosestInfil(coords.x, coords.y, coords.z),
Position: coords,
Rotation: (0, exports.random360)(),
Sides: ["Pmc"],
}));
// TODO: Check infils
// console.log(map);
// console.log(playerOnlySpawns[0], playerSpawns[0]);
return [...playerOnlySpawns, ...playerSpawns];
};
exports.BuildCustomPlayerSpawnPoints = BuildCustomPlayerSpawnPoints;
const getClosestZone = (params, x, y, z) => {
if (Array.isArray(params) &&
!params.filter(({ BotZoneName }) => BotZoneName).length)
return "";
return (getSortedSpawnPointList(params, x, y, z).find(({ BotZoneName }) => !!BotZoneName)?.BotZoneName || "");
};
exports.getClosestZone = getClosestZone;
const removeClosestSpawnsFromCustomBots = (CustomBots, SpawnPointParams, map, mapConfigMap) => {
if (!CustomBots[map] || !CustomBots[map].length) {
console.log(map, "Is empty");
return;
}
const coords = CustomBots[map];
const { mapCullingNearPointValuePlayer, mapCullingNearPointValuePmc, mapCullingNearPointValueScav } = mapConfig_json_1.default[mapConfigMap];
const mapCullingNearPointValue = (mapCullingNearPointValuePlayer +
mapCullingNearPointValuePmc +
mapCullingNearPointValueScav) / 3;
let filteredCoords = coords.filter(({ x: X, y: Y, z: Z }) => !SpawnPointParams.some(({ Position: { z, x, y } }) => {
return mapCullingNearPointValue > (0, exports.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 = (0, exports.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;
};
exports.removeClosestSpawnsFromCustomBots = removeClosestSpawnsFromCustomBots;
//# sourceMappingURL=spawnZoneUtils.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = updateSpawnLocations;
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const advancedConfig_json_1 = __importDefault(require("../../config/advancedConfig.json"));
const GlobalValues_1 = require("../GlobalValues");
const spawnZoneUtils_1 = __importDefault(require("./spawnZoneUtils"));
function updateSpawnLocations(locationList, config) {
for (let index = 0; index < locationList.length; index++) {
const map = constants_1.configLocations[index];
const mapSpawns = [...GlobalValues_1.globalValues.indexedMapSpawns[index]];
const playerSpawns = mapSpawns.filter((point) => point?.["type"] === "player");
const playerSpawn = (0, utils_1.getRandomInArray)(playerSpawns);
GlobalValues_1.globalValues.playerSpawn = playerSpawn;
const { x, y, z } = playerSpawn.Position;
const sortedSpawnPointList = (0, spawnZoneUtils_1.default)(mapSpawns, x, y, z);
const possibleSpawnList = [];
sortedSpawnPointList.forEach((point) => {
if (possibleSpawnList.length < advancedConfig_json_1.default.SpawnpointAreaTarget &&
point?.["type"] === "player") {
point.ColliderParams._props.Radius = 1;
possibleSpawnList.push(point);
}
});
// const possibleSpawnListSet = new Set(possibleSpawnList.map(({ Id }) => Id));
locationList[index].base.SpawnPointParams = [
...possibleSpawnList,
...sortedSpawnPointList.filter((point) => point["type"] !== "player"),
];
// {
// if (point["type"] === "player" && !possibleSpawnListSet.has(point.Id)) {
// point.Categories = [];
// point.Sides = [];
// }
// return point;
// }
// console.log(
// map,
// locationList[index].base.SpawnPointParams.filter(
// (point) => point?.["type"] === "player"
// ).length,
// locationList[index].base.SpawnPointParams.filter(
// (point) => point?.Categories[0] === "Player"
// ).length
// );
}
}
//# sourceMappingURL=updateSpawnLocations.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "updateSpawnLocations.js",
"sourceRoot": "",
"sources": [
"updateSpawnLocations.ts"
],
"names": [],
"mappings": ";;;;;AAaA,uCAyDC;AArED,2CAA8C;AAE9C,mCAAoD;AACpD,2FAA8D;AAE9D,kDAA+C;AAC/C,sEAI0B;AAE1B,SAAwB,oBAAoB,CAC1C,YAAyB,EACzB,MAAsB;IAEtB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACzD,MAAM,GAAG,GAAG,2BAAe,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,SAAS,GAAG,CAAC,GAAG,2BAAY,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QAE5D,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM,CACnC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,CACxC,CAAC;QAEF,MAAM,WAAW,GAAqB,IAAA,wBAAgB,EAAC,YAAY,CAAC,CAAC;QACrE,2BAAY,CAAC,WAAW,GAAG,WAAW,CAAC;QAEvC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC;QAEzC,MAAM,oBAAoB,GAAG,IAAA,wBAAuB,EAAC,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzE,MAAM,iBAAiB,GAAuB,EAAE,CAAC;QAEjD,oBAAoB,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACrC,IACE,iBAAiB,CAAC,MAAM,GAAG,6BAAc,CAAC,oBAAoB;gBAC9D,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,EAC5B,CAAC;gBACD,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAA;gBACtC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+EAA+E;QAE/E,YAAY,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,gBAAgB,GAAG;YAC1C,GAAG,iBAAiB;YACpB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC;SACtE,CAAC;QAEF,KAAK;QACL,2EAA2E;QAC3E,2BAA2B;QAC3B,sBAAsB;QACtB,IAAI;QAEJ,gBAAgB;QAChB,IAAI;QAEJ,eAAe;QACf,SAAS;QACT,sDAAsD;QACtD,8CAA8C;QAC9C,cAAc;QACd,sDAAsD;QACtD,mDAAmD;QACnD,aAAa;QACb,KAAK;IACP,CAAC;AACH,CAAC"
}

View file

@ -0,0 +1,397 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.looselyShuffle = exports.enforceSmoothing = exports.getRandomInArray = exports.setEscapeTimeOverrides = exports.getHealthBodyPartsByPercentage = exports.buildZombie = exports.buildBotWaves = exports.getRandomZombieType = exports.getRandomDifficulty = exports.zombieTypesCaps = exports.zombieTypes = exports.buildBossBasedWave = exports.shuffle = exports.getDifficulty = exports.waveBuilder = void 0;
const ILocationBase_1 = require("C:/snapshot/project/obj/models/eft/common/ILocationBase");
const mapConfig_json_1 = __importDefault(require("../../config/mapConfig.json"));
const constants_1 = require("./constants");
const waveBuilder = (totalWaves, timeLimit, waveDistribution, wildSpawnType, difficulty, isPlayer, maxSlots, combinedZones = [], specialZones = [], offset, starting, moreGroups) => {
if (totalWaves === 0)
return [];
const averageTime = timeLimit / totalWaves;
const firstHalf = Math.round(averageTime * (1 - waveDistribution));
const secondHalf = Math.round(averageTime * (1 + waveDistribution));
let timeStart = offset || 0;
const waves = [];
let maxSlotsReached = Math.round(1.3 * totalWaves);
while (totalWaves > 0 &&
(waves.length < totalWaves || specialZones.length > 0)) {
const accelerate = totalWaves > 5 && waves.length < totalWaves / 3;
const stage = Math.round(waves.length < Math.round(totalWaves * 0.5)
? accelerate
? firstHalf / 3
: firstHalf
: secondHalf);
const min = !offset && waves.length < 1 ? 0 : timeStart;
const max = !offset && waves.length < 1 ? 0 : timeStart + 60;
if (waves.length >= 1 || offset)
timeStart = timeStart + stage;
const BotPreset = (0, exports.getDifficulty)(difficulty);
// console.log(wildSpawnType, BotPreset);
// Math.round((1 - waves.length / totalWaves) * maxSlots) || 1;
let slotMax = Math.round((moreGroups ? Math.random() : Math.random() * Math.random()) * maxSlots);
if (slotMax < 1)
slotMax = 1;
let slotMin = (Math.round(Math.random() * slotMax) || 1) - 1;
if (wildSpawnType === "marksman" && slotMin < 1)
slotMin = 1;
waves.push({
BotPreset,
BotSide: getBotSide(wildSpawnType),
SpawnPoints: getZone(specialZones, combinedZones, waves.length >= totalWaves),
isPlayers: isPlayer,
slots_max: slotMax,
slots_min: slotMin,
time_min: min,
time_max: max,
WildSpawnType: wildSpawnType,
number: waves.length,
sptId: wildSpawnType + waves.length,
SpawnMode: ["regular", "pve"],
});
maxSlotsReached -= slotMax;
// if (wildSpawnType === "assault") console.log(slotMax, maxSlotsReached);
if (maxSlotsReached <= 0)
break;
}
// console.log(waves.map(({ slots_min }) => slots_min));
return waves;
};
exports.waveBuilder = waveBuilder;
const getZone = (specialZones, combinedZones, specialOnly) => {
if (!specialOnly && combinedZones.length)
return combinedZones[Math.round((combinedZones.length - 1) * Math.random())];
if (specialZones.length)
return specialZones.pop();
return "";
};
const getDifficulty = (diff) => {
const randomNumb = Math.random() + diff;
switch (true) {
case randomNumb < 0.55:
return "easy";
case randomNumb < 1.4:
return "normal";
case randomNumb < 1.85:
return "hard";
default:
return "impossible";
}
};
exports.getDifficulty = getDifficulty;
const shuffle = (array) => {
let currentIndex = array.length, randomIndex;
// While there remain elements to shuffle.
while (currentIndex != 0) {
// Pick a remaining element.
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
];
}
return array;
};
exports.shuffle = shuffle;
const getBotSide = (spawnType) => {
switch (spawnType) {
case "pmcBEAR":
return "Bear";
case "pmcUSEC":
return "Usec";
default:
return "Savage";
}
};
const buildBossBasedWave = (BossChance, BossEscortAmount, BossEscortType, BossName, BossZone, raidTime) => {
return {
BossChance,
BossDifficult: "normal",
BossEscortAmount,
BossEscortDifficult: "normal",
BossEscortType,
BossName,
BossPlayer: false,
BossZone,
Delay: 0,
ForceSpawn: false,
IgnoreMaxBots: true,
RandomTimeSpawn: false,
Time: raidTime ? Math.round(Math.random() * (raidTime * 5)) : -1,
Supports: null,
TriggerId: "",
TriggerName: "",
SpawnMode: ["regular", "pve"],
};
};
exports.buildBossBasedWave = buildBossBasedWave;
exports.zombieTypes = [
"infectedassault",
"infectedpmc",
"infectedlaborant",
"infectedcivil",
];
exports.zombieTypesCaps = [
"infectedAssault",
"infectedPmc",
"infectedLaborant",
"infectedCivil",
];
const getRandomDifficulty = (num = 1.5) => (0, exports.getDifficulty)(Math.round(Math.random() * num * 10) / 10);
exports.getRandomDifficulty = getRandomDifficulty;
const getRandomZombieType = () => exports.zombieTypesCaps[Math.round((exports.zombieTypesCaps.length - 1) * Math.random())];
exports.getRandomZombieType = getRandomZombieType;
const buildBotWaves = (botTotal, escapeTimeLimit, maxGroup, groupChance, bossZones, difficulty, botType, ForceSpawn, botDistribution, spawnDelay = 0) => {
if (!botTotal)
return [];
const pushToEnd = botDistribution > 1;
const pullFromEnd = botDistribution < 1;
const botToZoneTotal = bossZones.length / botTotal;
const isMarksman = botType === "marksman";
const isPMC = botType === "pmcUSEC" || botType === "pmcBEAR";
let startTime = pushToEnd
? Math.round((botDistribution - 1) * escapeTimeLimit)
: spawnDelay;
escapeTimeLimit = pullFromEnd
? Math.round(escapeTimeLimit * botDistribution)
: Math.round(escapeTimeLimit - startTime);
const averageTime = Math.round(escapeTimeLimit / botTotal);
const waves = [];
let maxSlotsReached = botTotal;
if (maxGroup < 1)
maxGroup = 1;
while (botTotal > 0) {
const allowGroup = groupChance > Math.random();
let bossEscortAmount = allowGroup
? Math.round(maxGroup * Math.random())
: 0;
if (bossEscortAmount < 0 ||
(bossEscortAmount > 0 && bossEscortAmount + 1 > maxSlotsReached)) {
bossEscortAmount = 0;
}
const totalCountThisWave = isMarksman ? 1 : bossEscortAmount + 1;
const totalCountThusFar = botTotal - maxSlotsReached;
const BossDifficult = (0, exports.getDifficulty)(difficulty);
waves.push({
BossChance: 100,
BossDifficult,
BossEscortAmount: bossEscortAmount.toString(),
BossEscortDifficult: BossDifficult,
BossEscortType: botType,
BossName: botType,
BossPlayer: false,
BossZone: bossZones[Math.floor(totalCountThusFar * botToZoneTotal)] || "",
ForceSpawn,
IgnoreMaxBots: ForceSpawn,
RandomTimeSpawn: false,
Time: startTime,
Supports: null,
TriggerId: "",
TriggerName: "",
SpawnMode: isPMC ? ["pve"] : ["regular", "pve"],
});
startTime += Math.round(totalCountThisWave * averageTime);
maxSlotsReached -= 1 + (isMarksman ? 0 : bossEscortAmount);
if (maxSlotsReached <= 0)
break;
}
// isMarksman &&
// console.log(
// // bossZones,
// botType,
// bossZones.length,
// waves.map(({ Time, BossZone }) => ({ Time, BossZone }))
// );
return waves;
};
exports.buildBotWaves = buildBotWaves;
const buildZombie = (botTotal, escapeTimeLimit, botDistribution, BossChance = 100) => {
if (!botTotal)
return [];
const pushToEnd = botDistribution > 1;
const pullFromEnd = botDistribution < 1;
let startTime = pushToEnd
? Math.round((botDistribution - 1) * escapeTimeLimit)
: 0;
escapeTimeLimit = pullFromEnd
? Math.round(escapeTimeLimit * botDistribution)
: Math.round(escapeTimeLimit - startTime);
const averageTime = Math.round(escapeTimeLimit / botTotal);
const waves = [];
let maxSlotsReached = botTotal;
while (botTotal > 0) {
const allowGroup = 0.2 > Math.random();
let bossEscortAmount = allowGroup ? Math.round(4 * Math.random()) : 0;
if (bossEscortAmount < 0)
bossEscortAmount = 0;
const totalCountThisWave = bossEscortAmount + 1;
const main = (0, exports.getRandomZombieType)();
waves.push({
BossChance,
BossDifficult: "normal",
BossEscortAmount: "0",
BossEscortDifficult: "normal",
BossEscortType: main,
BossName: main,
BossPlayer: false,
BossZone: "",
Delay: 0,
IgnoreMaxBots: false,
RandomTimeSpawn: false,
Time: startTime,
Supports: new Array(bossEscortAmount).fill("").map(() => ({
BossEscortType: (0, exports.getRandomZombieType)(),
BossEscortDifficult: ["normal"],
BossEscortAmount: "1",
})),
TriggerId: "",
TriggerName: "",
SpawnMode: ["regular", "pve"],
});
startTime += Math.round(totalCountThisWave * averageTime);
maxSlotsReached -= 1 + bossEscortAmount;
if (maxSlotsReached <= 0)
break;
}
// console.log(waves)
return waves;
};
exports.buildZombie = buildZombie;
const getHealthBodyPartsByPercentage = (num) => {
const num35 = Math.round(35 * num);
const num100 = Math.round(100 * num);
const num70 = Math.round(70 * num);
const num80 = Math.round(80 * num);
return {
Head: {
min: num35,
max: num35,
},
Chest: {
min: num100,
max: num100,
},
Stomach: {
min: num100,
max: num100,
},
LeftArm: {
min: num70,
max: num70,
},
RightArm: {
min: num70,
max: num70,
},
LeftLeg: {
min: num80,
max: num80,
},
RightLeg: {
min: num80,
max: num80,
},
};
};
exports.getHealthBodyPartsByPercentage = getHealthBodyPartsByPercentage;
const setEscapeTimeOverrides = (locationList, mapConfig, logger, config) => {
for (let index = 0; index < locationList.length; index++) {
const mapSettingsList = Object.keys(mapConfig);
const map = mapSettingsList[index];
const override = mapConfig[map].EscapeTimeLimitOverride;
const hardcodedEscapeLimitMax = 5;
if (!override &&
locationList[index].base.EscapeTimeLimit / constants_1.defaultEscapeTimes[map] >
hardcodedEscapeLimitMax) {
const maxLimit = constants_1.defaultEscapeTimes[map] * hardcodedEscapeLimitMax;
logger.warning(`[MOAR] EscapeTimeLimit set too high on ${map}\nEscapeTimeLimit changed from ${locationList[index].base.EscapeTimeLimit} => ${maxLimit}\n`);
locationList[index].base.EscapeTimeLimit = maxLimit;
}
if (override && locationList[index].base.EscapeTimeLimit !== override) {
console.log(`[Moar] Set ${map}'s Escape time limit to ${override} from ${locationList[index].base.EscapeTimeLimit}\n`);
locationList[index].base.EscapeTimeLimit = override;
locationList[index].base.EscapeTimeLimitCoop = override;
locationList[index].base.EscapeTimeLimitPVE = override;
}
if (config.startingPmcs &&
locationList[index].base.EscapeTimeLimit / constants_1.defaultEscapeTimes[map] > 2) {
logger.warning(`[MOAR] Average EscapeTimeLimit is too high (greater than 2x) to enable starting PMCS\nStarting PMCS has been turned off to prevent performance issues.\n`);
config.startingPmcs = false;
}
}
};
exports.setEscapeTimeOverrides = setEscapeTimeOverrides;
const getRandomInArray = (arr) => arr[Math.floor(Math.random() * arr.length)];
exports.getRandomInArray = getRandomInArray;
const enforceSmoothing = (locationList) => {
for (let index = 0; index < locationList.length; index++) {
const waves = locationList[index].base.BossLocationSpawn;
const Bosses = [];
let notBosses = [];
const notBossesSet = new Set([
"infectedLaborant",
"infectedAssault",
"infectedCivil",
ILocationBase_1.WildSpawnType.ASSAULT,
ILocationBase_1.WildSpawnType.MARKSMAN,
"pmcBEAR",
"pmcUSEC",
]);
for (const wave of waves) {
if (notBossesSet.has(wave.BossName)) {
notBosses.push(wave);
}
else {
Bosses.push(wave);
}
}
let first = Infinity, last = -Infinity;
notBosses.forEach((notBoss) => {
first = Math.min(notBoss.Time, first);
last = Math.max(notBoss.Time, last);
});
if (first < 15)
first = 15;
notBosses = notBosses.sort((a, b) => a.Time - b.Time);
// console.log(notBosses.map(({ Time }) => Time))
let start = first;
const smoothingDistribution = mapConfig_json_1.default[constants_1.configLocations[index]]
.smoothingDistribution;
const increment = (Math.round((last - first) / notBosses.length) * 2) * smoothingDistribution;
for (let index = 0; index < notBosses.length; index++) {
const ratio = (index + 1) / notBosses.length;
// console.log(ratio);
notBosses[index].Time = start;
let inc = Math.round(increment * ratio);
if (inc < 10)
inc = 5;
start += inc;
}
// console.log(
// configLocations[index],
// last,
// notBosses.map(({ Time, BossName }) => ({ BossName, Time }))
// );
locationList[index].base.BossLocationSpawn = [...Bosses, ...notBosses];
}
};
exports.enforceSmoothing = enforceSmoothing;
const looselyShuffle = (arr, shuffleStep = 3) => {
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;
};
exports.looselyShuffle = looselyShuffle;
//# sourceMappingURL=utils.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,26 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = checkPresetLogic;
const config_json_1 = __importDefault(require("../../config/config.json"));
const Presets_json_1 = __importDefault(require("../../config/Presets.json"));
const PresetWeightings_json_1 = __importDefault(require("../../config/PresetWeightings.json"));
function checkPresetLogic(container) {
const Logger = container.resolve("WinstonLogger");
for (const key in PresetWeightings_json_1.default) {
if (Presets_json_1.default[key] === undefined) {
Logger.error(`\n[MOAR]: No preset found in PresetWeightings.json for preset "${key}" in Presets.json`);
}
}
for (const key in Presets_json_1.default) {
const preset = Presets_json_1.default[key];
for (const id in preset) {
if (config_json_1.default[id] === undefined) {
Logger.error(`\n[MOAR]: No associated key found in config.json called "${id}" for preset "${key}" in Presets.json`);
}
}
}
}
//# sourceMappingURL=checkPresets.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "checkPresets.js",
"sourceRoot": "",
"sources": [
"checkPresets.ts"
],
"names": [],
"mappings": ";;;;;AAMA,mCAqBC;AAzBD,2EAA8C;AAC9C,6EAAgD;AAChD,+FAAkE;AAElE,SAAwB,gBAAgB,CAAC,SAA8B;IACrE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAU,eAAe,CAAC,CAAC;IAE3D,KAAK,MAAM,GAAG,IAAI,+BAAgB,EAAE,CAAC;QACnC,IAAI,sBAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC/B,MAAM,CAAC,KAAK,CACV,kEAAkE,GAAG,mBAAmB,CACzF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,sBAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,sBAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,IAAI,qBAAM,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,CAAC,KAAK,CACV,4DAA4D,EAAE,iBAAiB,GAAG,mBAAmB,CACtG,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"
}

View file

@ -0,0 +1,136 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setUpZombies = exports.resetCurrentEvents = exports.baseZombieSettings = void 0;
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const baseZombieSettings = (enabled, count) => ({
enabled,
name: "zombies",
type: "Zombies",
startDay: "1",
startMonth: "1",
endDay: "31",
endMonth: "12",
settings: {
enableSummoning: false,
removeEntryRequirement: [],
replaceBotHostility: true,
zombieSettings: {
enabled: true,
mapInfectionAmount: {
Interchange: count === -1 ? randomNumber100() : count,
Lighthouse: count === -1 ? randomNumber100() : count,
RezervBase: count === -1 ? randomNumber100() : count,
Sandbox: count === -1 ? randomNumber100() : count,
Shoreline: count === -1 ? randomNumber100() : count,
TarkovStreets: count === -1 ? randomNumber100() : count,
Woods: count === -1 ? randomNumber100() : count,
bigmap: count === -1 ? randomNumber100() : count,
factory4: count === -1 ? randomNumber100() : count,
laboratory: count === -1 ? randomNumber100() : count,
},
disableBosses: [],
disableWaves: [],
},
},
});
exports.baseZombieSettings = baseZombieSettings;
const randomNumber100 = () => Math.round(Math.random() * 100);
const resetCurrentEvents = (container, enabled, zombieWaveQuantity, random = false) => {
const configServer = container.resolve("ConfigServer");
const eventConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.SEASONAL_EVENT);
let percentToShow = random ? -1 : Math.round(zombieWaveQuantity * 100);
if (percentToShow > 100)
percentToShow = 100;
eventConfig.events = [(0, exports.baseZombieSettings)(enabled, percentToShow)];
const seasonalEventService = container.resolve("SeasonalEventService");
// First we need to clear any existing data
seasonalEventService.currentlyActiveEvents = [];
seasonalEventService.christmasEventActive = false;
seasonalEventService.halloweenEventActive = false;
// Then re-calculate the cached data
seasonalEventService.cacheActiveEvents();
// seasonalEventService.addEventBossesToMaps("halloweenzombies");
};
exports.resetCurrentEvents = resetCurrentEvents;
const setUpZombies = (container) => {
const configServer = container.resolve("ConfigServer");
const eventConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.SEASONAL_EVENT);
eventConfig.events = [(0, exports.baseZombieSettings)(false, 100)];
// eventConfig.eventBossSpawns = {
// zombies: eventConfig.eventBossSpawns.halloweenzombies,
// };
eventConfig.eventGear[eventConfig.events[0].name] = {};
eventConfig.hostilitySettingsForEvent.zombies.default =
eventConfig.hostilitySettingsForEvent.zombies.default
.filter(({ BotRole }) => !["pmcBEAR", "pmcUSEC"].includes(BotRole))
.map((host) => ({
...host,
AlwaysEnemies: [
"infectedAssault",
"infectedPmc",
"infectedCivil",
"infectedLaborant",
"infectedTagilla",
"pmcBEAR",
"pmcUSEC",
],
AlwaysNeutral: [
"marksman",
"assault",
"bossTest",
"bossBully",
"followerTest",
"bossKilla",
"bossKojaniy",
"followerKojaniy",
"pmcBot",
"cursedAssault",
"bossGluhar",
"followerGluharAssault",
"followerGluharSecurity",
"followerGluharScout",
"followerGluharSnipe",
"followerSanitar",
"bossSanitar",
"test",
"assaultGroup",
"sectantWarrior",
"sectantPriest",
"bossTagilla",
"followerTagilla",
"exUsec",
"gifter",
"bossKnight",
"followerBigPipe",
"followerBirdEye",
"bossZryachiy",
"followerZryachiy",
"bossBoar",
"followerBoar",
"arenaFighter",
"arenaFighterEvent",
"bossBoarSniper",
"crazyAssaultEvent",
"peacefullZryachiyEvent",
"sectactPriestEvent",
"ravangeZryachiyEvent",
"followerBoarClose1",
"followerBoarClose2",
"bossKolontay",
"followerKolontayAssault",
"followerKolontaySecurity",
"shooterBTR",
"bossPartisan",
"spiritWinter",
"spiritSpring",
"peacemaker",
"skier",
],
SavagePlayerBehaviour: "Neutral",
BearPlayerBehaviour: "AlwaysEnemies",
UsecPlayerBehaviour: "AlwaysEnemies",
}));
// console.log(eventConfig.hostilitySettingsForEvent.zombies.default);
};
exports.setUpZombies = setUpZombies;
//# sourceMappingURL=Zombies.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "Zombies.js",
"sourceRoot": "",
"sources": [
"Zombies.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,36 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const config_json_1 = require("../config/config.json");
const Spawning_1 = require("./Spawning/Spawning");
const config_json_2 = __importDefault(require("../config/config.json"));
const GlobalValues_1 = require("./GlobalValues");
const routes_1 = require("./Routes/routes");
const checkPresets_1 = __importDefault(require("./Tests/checkPresets"));
const setupSpawn_1 = require("./SpawnZoneChanges/setupSpawn");
class Moar {
preSptLoad(container) {
if (config_json_1.enableBotSpawning) {
(0, routes_1.setupRoutes)(container);
}
}
postDBLoad(container) {
if (config_json_1.enableBotSpawning) {
(0, setupSpawn_1.setupSpawns)(container);
}
}
postSptLoad(container) {
if (config_json_1.enableBotSpawning) {
(0, checkPresets_1.default)(container);
GlobalValues_1.globalValues.baseConfig = config_json_2.default;
GlobalValues_1.globalValues.overrideConfig = {};
const logger = container.resolve("WinstonLogger");
logger.info("\n[MOAR]: Starting up, may the bots ever be in your favour!");
(0, Spawning_1.buildWaves)(container);
}
}
}
module.exports = { mod: new Moar() };
//# sourceMappingURL=mod.js.map

View file

@ -0,0 +1,10 @@
{
"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,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"
}

View file

@ -0,0 +1,52 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.kebabToTitle = exports.getRandomPresetOrCurrentlySelectedPreset = exports.cloneDeep = exports.saveToFile = void 0;
const PresetWeightings_json_1 = __importDefault(require("../config/PresetWeightings.json"));
const Presets_json_1 = __importDefault(require("../config/Presets.json"));
const GlobalValues_1 = require("./GlobalValues");
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]}/`;
fs.writeFile(directory + filePath, JSON.stringify(data, null, 4), function (err) {
if (err)
throw err;
});
};
exports.saveToFile = saveToFile;
const cloneDeep = (objectToClone) => JSON.parse(JSON.stringify(objectToClone));
exports.cloneDeep = cloneDeep;
const getRandomPresetOrCurrentlySelectedPreset = () => {
switch (true) {
case GlobalValues_1.globalValues.forcedPreset.toLowerCase() === "custom":
return {};
case !GlobalValues_1.globalValues.forcedPreset:
GlobalValues_1.globalValues.forcedPreset = "random";
break;
case GlobalValues_1.globalValues.forcedPreset === "random":
break;
default:
return Presets_json_1.default[GlobalValues_1.globalValues.forcedPreset];
}
const all = [];
const itemKeys = Object.keys(PresetWeightings_json_1.default);
for (const key of itemKeys) {
for (let i = 0; i < PresetWeightings_json_1.default[key]; i++) {
all.push(key);
}
}
const preset = all[Math.round(Math.random() * (all.length - 1))];
GlobalValues_1.globalValues.currentPreset = preset;
return Presets_json_1.default[preset];
};
exports.getRandomPresetOrCurrentlySelectedPreset = getRandomPresetOrCurrentlySelectedPreset;
const kebabToTitle = (str) => str
.split("-")
.map((word) => word.slice(0, 1).toUpperCase() + word.slice(1))
.join(" ");
exports.kebabToTitle = kebabToTitle;
//# sourceMappingURL=utils.js.map

View file

@ -0,0 +1,10 @@
{
"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"
}

View file

@ -0,0 +1,127 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Calibers = exports.ParentClasses = void 0;
var ParentClasses;
(function (ParentClasses) {
ParentClasses["WEAPON"] = "5422acb9af1c889c16000029";
ParentClasses["ARMORVEST"] = "5448e54d4bdc2dcc718b4568";
ParentClasses["ARMOREDEQUIPMENT"] = "57bef4c42459772e8d35a53b";
ParentClasses["HEADWEAR"] = "5a341c4086f77401f2541505";
ParentClasses["FACECOVER"] = "5a341c4686f77469e155819e";
ParentClasses["CHESTRIG"] = "5448e5284bdc2dcb718b4567";
ParentClasses["BACKPACK"] = "5448e53e4bdc2d60728b4567";
ParentClasses["VISORS"] = "5448e5724bdc2ddf718b4568";
ParentClasses["FOOD"] = "5448e8d04bdc2ddf718b4569";
ParentClasses["DRINK"] = "5448e8d64bdc2dce718b4568";
ParentClasses["BARTER_ITEM"] = "5448eb774bdc2d0a728b4567";
ParentClasses["INFO"] = "5448ecbe4bdc2d60728b4568";
ParentClasses["MEDKIT"] = "5448f39d4bdc2d0a728b4568";
ParentClasses["DRUGS"] = "5448f3a14bdc2d27728b4569";
ParentClasses["STIMULATOR"] = "5448f3a64bdc2d60728b456a";
ParentClasses["MEDICAL"] = "5448f3ac4bdc2dce718b4569";
ParentClasses["MEDICAL_SUPPLIES"] = "57864c8c245977548867e7f1";
ParentClasses["MOD"] = "5448fe124bdc2da5018b4567";
ParentClasses["FUNCTIONAL_MOD"] = "550aa4154bdc2dd8348b456b";
ParentClasses["FUEL"] = "5d650c3e815116009f6201d2";
ParentClasses["GEAR_MOD"] = "55802f3e4bdc2de7118b4584";
ParentClasses["STOCK"] = "55818a594bdc2db9688b456a";
ParentClasses["FOREGRIP"] = "55818af64bdc2d5b648b4570";
ParentClasses["MASTER_MOD"] = "55802f4a4bdc2ddb688b4569";
ParentClasses["MOUNT"] = "55818b224bdc2dde698b456f";
ParentClasses["MUZZLE"] = "5448fe394bdc2d0d028b456c";
ParentClasses["SIGHTS"] = "5448fe7a4bdc2d6f028b456b";
ParentClasses["MEDS"] = "543be5664bdc2dd4348b4569";
ParentClasses["MONEY"] = "543be5dd4bdc2deb348b4569";
ParentClasses["NIGHTVISION"] = "5a2c3a9486f774688b05e574";
ParentClasses["THEMALVISION"] = "5d21f59b6dbe99052b54ef83";
ParentClasses["KEY"] = "543be5e94bdc2df1348b4568";
ParentClasses["KEY_MECHANICAL"] = "5c99f98d86f7745c314214b3";
ParentClasses["KEYCARD"] = "5c164d2286f774194c5e69fa";
ParentClasses["EQUIPMENT"] = "543be5f84bdc2dd4348b456a";
ParentClasses["THROW_WEAPON"] = "543be6564bdc2df4348b4568";
ParentClasses["FOOD_DRINK"] = "543be6674bdc2df1348b4569";
ParentClasses["PISTOL"] = "5447b5cf4bdc2d65278b4567";
ParentClasses["SMG"] = "5447b5e04bdc2d62278b4567";
ParentClasses["ASSAULT_RIFLE"] = "5447b5f14bdc2d61278b4567";
ParentClasses["ASSAULT_CARBINE"] = "5447b5fc4bdc2d87278b4567";
ParentClasses["SHOTGUN"] = "5447b6094bdc2dc3278b4567";
ParentClasses["MARKSMAN_RIFLE"] = "5447b6194bdc2d67278b4567";
ParentClasses["SNIPER_RIFLE"] = "5447b6254bdc2dc3278b4568";
ParentClasses["MACHINE_GUN"] = "5447bed64bdc2d97278b4568";
ParentClasses["GRENADE_LAUNCHER"] = "5447bedf4bdc2d87278b4568";
ParentClasses["SPECIAL_WEAPON"] = "5447bee84bdc2dc3278b4569";
ParentClasses["SPEC_ITEM"] = "5447e0e74bdc2d3c308b4567";
ParentClasses["KNIFE"] = "5447e1d04bdc2dff2f8b4567";
ParentClasses["AMMO"] = "5485a8684bdc2da71d8b4567";
ParentClasses["AMMO_BOX"] = "543be5cb4bdc2deb348b4568";
ParentClasses["LOOT_CONTAINER"] = "566965d44bdc2d814c8b4571";
ParentClasses["MOD_CONTAINER"] = "5448bf274bdc2dfc2f8b456a";
ParentClasses["SEARCHABLE_ITEM"] = "566168634bdc2d144c8b456c";
ParentClasses["STASH"] = "566abbb64bdc2d144c8b457d";
ParentClasses["SORTING_TABLE"] = "6050cac987d3f925bf016837";
ParentClasses["LOCKABLE_CONTAINER"] = "5671435f4bdc2d96058b4569";
ParentClasses["SIMPLE_CONTAINER"] = "5795f317245977243854e041";
ParentClasses["INVENTORY"] = "55d720f24bdc2d88028b456d";
ParentClasses["STATIONARY_CONTAINER"] = "567583764bdc2d98058b456e";
ParentClasses["POCKETS"] = "557596e64bdc2dc2118b4571";
ParentClasses["ARMBAND"] = "5b3f15d486f77432d0509248";
ParentClasses["DOG_TAG_USEC"] = "59f32c3b86f77472a31742f0";
ParentClasses["DOG_TAG_BEAR"] = "59f32bb586f774757e1e8442";
ParentClasses["JEWELRY"] = "57864a3d24597754843f8721";
ParentClasses["ELECTRONICS"] = "57864a66245977548f04a81f";
ParentClasses["BUILDING_MATERIAL"] = "57864ada245977548638de91";
ParentClasses["TOOL"] = "57864bb7245977548b3b66c2";
ParentClasses["HOUSEHOLD_GOODS"] = "57864c322459775490116fbf";
ParentClasses["LUBRICANT"] = "57864e4c24597754843f8723";
ParentClasses["BATTERY"] = "57864ee62459775490116fc1";
ParentClasses["ASSAULT_SCOPE"] = "55818add4bdc2d5b648b456f";
ParentClasses["TACTICAL_COMBO"] = "55818b164bdc2ddc698b456c";
ParentClasses["FLASHLIGHT"] = "55818b084bdc2d5b648b4571";
ParentClasses["MAGAZINE"] = "5448bc234bdc2d3c308b4569";
ParentClasses["LIGHT_LASER"] = "55818b0e4bdc2dde698b456e";
ParentClasses["FLASH_HIDER"] = "550aa4bf4bdc2dd6348b456b";
ParentClasses["COLLIMATOR"] = "55818ad54bdc2ddc698b4569";
ParentClasses["COMPACT_COLLIMATOR"] = "55818acf4bdc2dde698b456b";
ParentClasses["COMPENSATOR"] = "550aa4af4bdc2dd4348b456e";
ParentClasses["OPTIC_SCOPE"] = "55818ae44bdc2dde698b456c";
ParentClasses["SPECIAL_SCOPE"] = "55818aeb4bdc2ddc698b456a";
ParentClasses["OTHER"] = "590c745b86f7743cc433c5f2";
ParentClasses["SILENCER"] = "550aa4cd4bdc2dd8348b456c";
ParentClasses["PORTABLE_RANGE_FINDER"] = "61605ddea09d851a0a0c1bbc";
ParentClasses["ITEM"] = "54009119af1c881c07000029";
ParentClasses["CYLINDER_MAGAZINE"] = "610720f290b75a49ff2e5e25";
ParentClasses["MAP"] = "567849dd4bdc2d150f8b456e";
ParentClasses["REPAIRKITS"] = "616eb7aea207f41933308f46";
ParentClasses["COMPASS"] = "5f4fbaaca5573a5ac31db429";
ParentClasses["HEADSET"] = "5645bcb74bdc2ded0b8b4578";
ParentClasses["GASBLOCK"] = "56ea9461d2720b67698b456f";
})(ParentClasses || (exports.ParentClasses = ParentClasses = {}));
var Calibers;
(function (Calibers) {
Calibers["_9x19mm"] = "Caliber9x19PARA";
Calibers["_9x18mm"] = "Caliber9x18PM";
Calibers["_9x21mm"] = "Caliber9x21";
Calibers["_9x39mm"] = "Caliber9x39";
Calibers["_45ACP"] = "Caliber1143x23ACP";
Calibers["_46x30mm"] = "Caliber46x30";
Calibers["_57x28mm"] = "Caliber57x28";
Calibers["_762x25mm"] = "Caliber762x25TT";
Calibers["_366TKM"] = "Caliber366TKM";
Calibers["_762x39mm"] = "Caliber762x39";
Calibers["_762x51mm"] = "Caliber762x51";
Calibers["_762x54rmm"] = "Caliber762x54R";
Calibers["_300BLK"] = "Caliber762x35";
Calibers["_556x45mm"] = "Caliber556x45NATO";
Calibers["_545x39mm"] = "Caliber545x39";
Calibers["_127x55mm"] = "Caliber127x55";
Calibers["_338mag"] = "Caliber86x70";
Calibers["_357mag"] = "Caliber9x33R";
Calibers["_127x108mm"] = "Caliber127x108";
Calibers["_40x46mm"] = "Caliber40x46";
Calibers["_40x53mm"] = "Caliber40mmRU";
Calibers["_26x75mm"] = "Caliber26x75";
Calibers["_12ga"] = "Caliber12g";
Calibers["_20ga"] = "Caliber20g";
Calibers["_23x75mm"] = "Caliber23x75";
})(Calibers || (exports.Calibers = Calibers = {}));
//# sourceMappingURL=enums.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "enums.js",
"sourceRoot": "",
"sources": [
"enums.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,76 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
const config_json_1 = __importDefault(require("../config/config.json"));
class DisableDiscardLimits {
postDBLoad(container) {
const databaseServer = container.resolve("DatabaseServer");
const configServer = container.resolve("ConfigServer");
const pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
const botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const { logInfo } = useLogger(container);
const tables = databaseServer.getTables();
/**
* Set the item generation weights for backpackLoot, vestLoot, and pocketLoot to zero to prevent extra loot items from spawning on the specified bot type
* @param botTypes
*/
const emptyInventory = (botTypes) => {
botTypes.forEach((type) => {
logInfo(`Removing loot from ${type}`);
const backpackWeights = tables.bots.types[type].generation.items.backpackLoot.weights;
const vestWeights = tables.bots.types[type].generation.items.vestLoot.weights;
const pocketWeights = tables.bots.types[type].generation.items.pocketLoot.weights;
clearWeights(backpackWeights);
clearWeights(vestWeights);
clearWeights(pocketWeights);
});
};
if (!config_json_1.default.pmcSpawnWithLoot) {
emptyInventory(["usec", "bear"]);
// Do not allow weapons to spawn in PMC bags
pmcConfig.looseWeaponInBackpackLootMinMax.max = 0;
// Clear weights in pmc randomisation
botConfig.equipment?.pmc?.randomisation?.forEach(details => {
const generation = details?.generation;
clearWeights(generation?.backpackLoot?.weights);
clearWeights(generation?.pocketLoot?.weights);
clearWeights(generation?.vestLoot?.weights);
});
}
if (!config_json_1.default.scavSpawnWithLoot) {
emptyInventory(["assault"]);
}
logInfo("Marking items with DiscardLimits as InsuranceDisabled");
for (let itemId in tables.templates.items) {
const template = tables.templates.items[itemId];
/**
* When we set DiscardLimitsEnabled to false further down, this will cause some items to be able to be insured when they normally should not be.
* The DiscardLimit property is used by BSG for RMT protections and their code internally treats things with discard limits as not insurable.
* For items that have a DiscardLimit >= 0, we need to manually flag them as InsuranceDisabled to make sure they still cannot be insured by the player.
* Do not disable insurance if the item is marked as always available for insurance.
*/
if (template._props.DiscardLimit >= 0 &&
!template._props.IsAlwaysAvailableForInsurance) {
template._props.InsuranceDisabled = true;
}
}
tables.globals.config.DiscardLimitsEnabled = false;
logInfo("Global config DiscardLimitsEnabled set to false");
}
}
function clearWeights(weights = {}) {
Object.keys(weights).forEach(weight => weights[weight] = 0);
}
function useLogger(container) {
const logger = container.resolve("WinstonLogger");
return {
logInfo: (message) => {
logger.info(`[LootingBots-ServerMod] ${message}`);
},
};
}
module.exports = { mod: new DisableDiscardLimits() };
//# sourceMappingURL=mod.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "mod.js",
"sourceRoot": "",
"sources": [
"mod.ts"
],
"names": [],
"mappings": "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"
}

View file

@ -0,0 +1,66 @@
"use strict";
/* eslint-disable prefer-const */
/* eslint-disable @typescript-eslint/brace-style */
Object.defineProperty(exports, "__esModule", { value: true });
const ConfigTypes_1 = require("C:/snapshot/project/obj/models/enums/ConfigTypes");
let botConfig;
let pmcConfig;
let configServer;
class SAIN {
postDBLoad(container) {
configServer = container.resolve("ConfigServer");
pmcConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.PMC);
botConfig = configServer.getConfig(ConfigTypes_1.ConfigTypes.BOT);
const databaseServer = container.resolve("DatabaseServer");
const tables = databaseServer.getTables();
// Only allow `pmcBot` brains to spawn for PMCs
for (const pmcType in pmcConfig.pmcType) {
for (const map in pmcConfig.pmcType[pmcType]) {
const pmcBrains = pmcConfig.pmcType[pmcType][map];
for (const brain in pmcBrains) {
if (brain === "pmcBot") {
pmcBrains[brain] = 1;
}
else {
pmcBrains[brain] = 0;
}
}
}
}
// Only allow `assault` brains for scavs
for (const map in botConfig.assaultBrainType) {
const scavBrains = botConfig.assaultBrainType[map];
for (const brain in scavBrains) {
if (brain === "assault") {
scavBrains[brain] = 1;
}
else {
scavBrains[brain] = 0;
}
}
}
// Only allow `pmcBot` brains for player scavs
for (const map in botConfig.playerScavBrainType) {
const playerScavBrains = botConfig.playerScavBrainType[map];
for (const brain in playerScavBrains) {
if (brain === "pmcBot") {
playerScavBrains[brain] = 1;
}
else {
playerScavBrains[brain] = 0;
}
}
}
for (const locationName in tables.locations) {
const location = tables.locations[locationName].base;
if (location && location.BotLocationModifier) {
location.BotLocationModifier.AccuracySpeed = 1;
location.BotLocationModifier.GainSight = 1;
location.BotLocationModifier.Scattering = 1;
location.BotLocationModifier.VisibleDistance = 1;
}
}
}
}
module.exports = { mod: new SAIN() };
//# sourceMappingURL=mod.js.map

View file

@ -0,0 +1,10 @@
{
"version": 3,
"file": "mod.js",
"sourceRoot": "",
"sources": [
"mod.ts"
],
"names": [],
"mappings": ";AAAA,iCAAiC;AACjC,mDAAmD;;AAEnD,kFAA+E;AAQ/E,IAAI,SAAqB,CAAC;AAC1B,IAAI,SAAqB,CAAC;AAC1B,IAAI,YAA0B,CAAC;AAE/B,MAAM,IAAI;IACC,UAAU,CAAC,SAA8B;QAC5C,YAAY,GAAG,SAAS,CAAC,OAAO,CAAe,cAAc,CAAC,CAAC;QAC/D,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;QAChE,SAAS,GAAG,YAAY,CAAC,SAAS,CAAa,yBAAW,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAiB,gBAAgB,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC;QAE1C,+CAA+C;QAC/C,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAA;gBACjD,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;wBACrB,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACzB,CAAC;yBACI,CAAC;wBACF,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACzB,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,wCAAwC;QACxC,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;YAC3C,MAAM,UAAU,GAAG,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACnD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;gBAC7B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACtB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;qBACI,CAAC;oBACF,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACL,CAAC;QACL,CAAC;QAED,8CAA8C;QAC9C,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,mBAAmB,EAAE,CAAC;YAC9C,MAAM,gBAAgB,GAAG,SAAS,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;YAC5D,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;gBACnC,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACrB,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChC,CAAC;qBACI,CAAC;oBACF,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChC,CAAC;YACL,CAAC;QACL,CAAC;QAED,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC;YAErD,IAAI,QAAQ,IAAI,QAAQ,CAAC,mBAAmB,EAAE,CAAC;gBAC3C,QAAQ,CAAC,mBAAmB,CAAC,aAAa,GAAG,CAAC,CAAC;gBAC/C,QAAQ,CAAC,mBAAmB,CAAC,SAAS,GAAG,CAAC,CAAC;gBAC3C,QAAQ,CAAC,mBAAmB,CAAC,UAAU,GAAG,CAAC,CAAC;gBAC5C,QAAQ,CAAC,mBAAmB,CAAC,eAAe,GAAG,CAAC,CAAC;YACrD,CAAC;QACL,CAAC;IACL,CAAC;CACJ;AACD,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,CAAA"
}