mirror of
https://github.com/sp-tarkov/server.git
synced 2025-02-13 09:50:43 -05:00
Added ability to filter out PMC loot items from pool based on its value, configured via pmc.json/lootItemLimitsRub
This commit is contained in:
parent
2d7fdc0dc2
commit
6a2afe2fa7
@ -1149,7 +1149,7 @@
|
|||||||
"backpackLoot": {
|
"backpackLoot": {
|
||||||
"weights": {
|
"weights": {
|
||||||
"0": 3,
|
"0": 3,
|
||||||
"1": 5,
|
"1": 7,
|
||||||
"2": 12,
|
"2": 12,
|
||||||
"3": 20,
|
"3": 20,
|
||||||
"4": 8,
|
"4": 8,
|
||||||
|
@ -717,6 +717,40 @@
|
|||||||
"value": 2500000
|
"value": 2500000
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"lootItemLimitsRub": [
|
||||||
|
{
|
||||||
|
"min": 46,
|
||||||
|
"max": 64,
|
||||||
|
"backpack": {
|
||||||
|
"min": 5000,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"pocket": {
|
||||||
|
"min": 5000,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"vest": {
|
||||||
|
"min": 5000,
|
||||||
|
"max": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"min": 65,
|
||||||
|
"max": 100,
|
||||||
|
"backpack": {
|
||||||
|
"min": 10000,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"pocket": {
|
||||||
|
"min": 10000,
|
||||||
|
"max": 0
|
||||||
|
},
|
||||||
|
"vest": {
|
||||||
|
"min": 10000,
|
||||||
|
"max": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"maxPocketLootTotalRub": 50000,
|
"maxPocketLootTotalRub": 50000,
|
||||||
"maxVestLootTotalRub": 50000,
|
"maxVestLootTotalRub": 50000,
|
||||||
"convertIntoPmcChance": {
|
"convertIntoPmcChance": {
|
||||||
|
@ -16,7 +16,7 @@ import { ItemAddedResult } from "@spt/models/enums/ItemAddedResult";
|
|||||||
import { LootCacheType } from "@spt/models/spt/bots/IBotLootCache";
|
import { LootCacheType } from "@spt/models/spt/bots/IBotLootCache";
|
||||||
import { IItemSpawnLimitSettings } from "@spt/models/spt/bots/IItemSpawnLimitSettings";
|
import { IItemSpawnLimitSettings } from "@spt/models/spt/bots/IItemSpawnLimitSettings";
|
||||||
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
import { IBotConfig } from "@spt/models/spt/config/IBotConfig";
|
||||||
import { IPmcConfig } from "@spt/models/spt/config/IPmcConfig";
|
import { IMinMaxLootItemValue, IPmcConfig } from "@spt/models/spt/config/IPmcConfig";
|
||||||
import type { ILogger } from "@spt/models/spt/utils/ILogger";
|
import type { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||||
import { BotLootCacheService } from "@spt/services/BotLootCacheService";
|
import { BotLootCacheService } from "@spt/services/BotLootCacheService";
|
||||||
@ -243,6 +243,8 @@ export class BotLootGenerator {
|
|||||||
containersIdFull,
|
containersIdFull,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const itemPriceLimits = this.getSingleItemLootPriceLimits(botLevel, isPmc);
|
||||||
|
|
||||||
// Backpack - generate loot if they have one
|
// Backpack - generate loot if they have one
|
||||||
if (containersBotHasAvailable.includes(EquipmentSlots.BACKPACK)) {
|
if (containersBotHasAvailable.includes(EquipmentSlots.BACKPACK)) {
|
||||||
// Add randomly generated weapon to PMC backpacks
|
// Add randomly generated weapon to PMC backpacks
|
||||||
@ -262,7 +264,13 @@ export class BotLootGenerator {
|
|||||||
|
|
||||||
const backpackLootRoubleTotal = this.getBackpackRoubleTotalByLevel(botLevel, isPmc);
|
const backpackLootRoubleTotal = this.getBackpackRoubleTotalByLevel(botLevel, isPmc);
|
||||||
this.addLootFromPool(
|
this.addLootFromPool(
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.BACKPACK, botJsonTemplate),
|
this.botLootCacheService.getLootFromCache(
|
||||||
|
botRole,
|
||||||
|
isPmc,
|
||||||
|
LootCacheType.BACKPACK,
|
||||||
|
botJsonTemplate,
|
||||||
|
itemPriceLimits?.backpack,
|
||||||
|
),
|
||||||
[EquipmentSlots.BACKPACK],
|
[EquipmentSlots.BACKPACK],
|
||||||
backpackLootCount,
|
backpackLootCount,
|
||||||
botInventory,
|
botInventory,
|
||||||
@ -278,7 +286,13 @@ export class BotLootGenerator {
|
|||||||
if (containersBotHasAvailable.includes(EquipmentSlots.TACTICAL_VEST)) {
|
if (containersBotHasAvailable.includes(EquipmentSlots.TACTICAL_VEST)) {
|
||||||
// Vest
|
// Vest
|
||||||
this.addLootFromPool(
|
this.addLootFromPool(
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.VEST, botJsonTemplate),
|
this.botLootCacheService.getLootFromCache(
|
||||||
|
botRole,
|
||||||
|
isPmc,
|
||||||
|
LootCacheType.VEST,
|
||||||
|
botJsonTemplate,
|
||||||
|
itemPriceLimits?.vest,
|
||||||
|
),
|
||||||
[EquipmentSlots.TACTICAL_VEST],
|
[EquipmentSlots.TACTICAL_VEST],
|
||||||
vestLootCount,
|
vestLootCount,
|
||||||
botInventory,
|
botInventory,
|
||||||
@ -292,7 +306,13 @@ export class BotLootGenerator {
|
|||||||
|
|
||||||
// Pockets
|
// Pockets
|
||||||
this.addLootFromPool(
|
this.addLootFromPool(
|
||||||
this.botLootCacheService.getLootFromCache(botRole, isPmc, LootCacheType.POCKET, botJsonTemplate),
|
this.botLootCacheService.getLootFromCache(
|
||||||
|
botRole,
|
||||||
|
isPmc,
|
||||||
|
LootCacheType.POCKET,
|
||||||
|
botJsonTemplate,
|
||||||
|
itemPriceLimits?.pocket,
|
||||||
|
),
|
||||||
[EquipmentSlots.POCKETS],
|
[EquipmentSlots.POCKETS],
|
||||||
pocketLootCount,
|
pocketLootCount,
|
||||||
botInventory,
|
botInventory,
|
||||||
@ -333,12 +353,23 @@ export class BotLootGenerator {
|
|||||||
const matchingValue = this.pmcConfig.maxBackpackLootTotalRub.find(
|
const matchingValue = this.pmcConfig.maxBackpackLootTotalRub.find(
|
||||||
(minMaxValue) => botLevel >= minMaxValue.min && botLevel <= minMaxValue.max,
|
(minMaxValue) => botLevel >= minMaxValue.min && botLevel <= minMaxValue.max,
|
||||||
);
|
);
|
||||||
return matchingValue.value;
|
return matchingValue?.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getSingleItemLootPriceLimits(botLevel: number, isPmc: boolean): IMinMaxLootItemValue | undefined {
|
||||||
|
if (isPmc) {
|
||||||
|
const matchingValue = this.pmcConfig.lootItemLimitsRub.find(
|
||||||
|
(minMaxValue) => botLevel >= minMaxValue.min && botLevel <= minMaxValue.max,
|
||||||
|
);
|
||||||
|
return matchingValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an array of the containers a bot has on them (pockets/backpack/vest)
|
* Get an array of the containers a bot has on them (pockets/backpack/vest)
|
||||||
* @param botInventory Bot to check
|
* @param botInventory Bot to check
|
||||||
|
@ -35,6 +35,7 @@ export interface IPmcConfig extends IBaseConfig {
|
|||||||
/** What 'brain' does a PMC use, keyed by map and side (USEC/BEAR) key: map location, value: type for usec/bear */
|
/** What 'brain' does a PMC use, keyed by map and side (USEC/BEAR) key: map location, value: type for usec/bear */
|
||||||
pmcType: Record<string, Record<string, Record<string, number>>>;
|
pmcType: Record<string, Record<string, Record<string, number>>>;
|
||||||
maxBackpackLootTotalRub: IMinMaxLootValue[];
|
maxBackpackLootTotalRub: IMinMaxLootValue[];
|
||||||
|
lootItemLimitsRub: IMinMaxLootItemValue[];
|
||||||
maxPocketLootTotalRub: number;
|
maxPocketLootTotalRub: number;
|
||||||
maxVestLootTotalRub: number;
|
maxVestLootTotalRub: number;
|
||||||
/** Percentage chance a bot from a wave is converted into a PMC, first key = map, second key = bot wildspawn type (assault/exusec), value: min+max chance to be converted */
|
/** Percentage chance a bot from a wave is converted into a PMC, first key = map, second key = bot wildspawn type (assault/exusec), value: min+max chance to be converted */
|
||||||
@ -80,3 +81,9 @@ export interface ISlotLootSettings {
|
|||||||
export interface IMinMaxLootValue extends MinMax {
|
export interface IMinMaxLootValue extends MinMax {
|
||||||
value: number;
|
value: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IMinMaxLootItemValue extends MinMax {
|
||||||
|
backpack: MinMax;
|
||||||
|
pocket: MinMax;
|
||||||
|
vest: MinMax;
|
||||||
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { PMCLootGenerator } from "@spt/generators/PMCLootGenerator";
|
import { PMCLootGenerator } from "@spt/generators/PMCLootGenerator";
|
||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||||
|
import { MinMax } from "@spt/models/common/MinMax";
|
||||||
import { IBotType } from "@spt/models/eft/common/tables/IBotType";
|
import { IBotType } from "@spt/models/eft/common/tables/IBotType";
|
||||||
import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
import { IProps, ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
||||||
@ -40,6 +41,7 @@ export class BotLootCacheService {
|
|||||||
* @param isPmc is the bot a pmc
|
* @param isPmc is the bot a pmc
|
||||||
* @param lootType what type of loot is needed (backpack/pocket/stim/vest etc)
|
* @param lootType what type of loot is needed (backpack/pocket/stim/vest etc)
|
||||||
* @param botJsonTemplate Base json db file for the bot having its loot generated
|
* @param botJsonTemplate Base json db file for the bot having its loot generated
|
||||||
|
* @param itemPriceMinMax OPTIONAL - min max limit of loot item price
|
||||||
* @returns ITemplateItem array
|
* @returns ITemplateItem array
|
||||||
*/
|
*/
|
||||||
public getLootFromCache(
|
public getLootFromCache(
|
||||||
@ -47,6 +49,7 @@ export class BotLootCacheService {
|
|||||||
isPmc: boolean,
|
isPmc: boolean,
|
||||||
lootType: LootCacheType,
|
lootType: LootCacheType,
|
||||||
botJsonTemplate: IBotType,
|
botJsonTemplate: IBotType,
|
||||||
|
itemPriceMinMax?: MinMax,
|
||||||
): Record<string, number> {
|
): Record<string, number> {
|
||||||
if (!this.botRoleExistsInCache(botRole)) {
|
if (!this.botRoleExistsInCache(botRole)) {
|
||||||
this.initCacheForBotRole(botRole);
|
this.initCacheForBotRole(botRole);
|
||||||
@ -105,6 +108,27 @@ export class BotLootCacheService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (itemPriceMinMax) {
|
||||||
|
const filteredResult = Object.entries(result).filter(([key, val]) => {
|
||||||
|
const itemPrice = this.itemHelper.getItemPrice(key);
|
||||||
|
if (itemPriceMinMax?.min && itemPriceMinMax?.max) {
|
||||||
|
return itemPrice >= itemPriceMinMax?.min && itemPrice <= itemPriceMinMax?.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itemPriceMinMax?.min && !itemPriceMinMax?.max) {
|
||||||
|
return itemPrice >= itemPriceMinMax?.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!itemPriceMinMax?.min && itemPriceMinMax?.max) {
|
||||||
|
return itemPrice <= itemPriceMinMax?.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.cloner.clone(Object.fromEntries(filteredResult));
|
||||||
|
}
|
||||||
|
|
||||||
return this.cloner.clone(result);
|
return this.cloner.clone(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user