Improved loot generator code comments

This commit is contained in:
Dev 2024-10-19 11:21:02 +01:00
parent b6b527df2a
commit e15ed9b7eb
5 changed files with 65 additions and 37 deletions

View File

@ -2,12 +2,13 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper";
import { ItemHelper } from "@spt/helpers/ItemHelper";
import { PresetHelper } from "@spt/helpers/PresetHelper";
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
import { MinMax } from "@spt/models/common/MinMax";
import { IPreset } from "@spt/models/eft/common/IGlobals";
import { IItem } from "@spt/models/eft/common/tables/IItem";
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
import { BaseClasses } from "@spt/models/enums/BaseClasses";
import { ISealedAirdropContainerSettings, RewardDetails } from "@spt/models/spt/config/IInventoryConfig";
import { LootRequest } from "@spt/models/spt/services/LootRequest";
import { ILootRequest } from "@spt/models/spt/services/ILootRequest";
import { ILogger } from "@spt/models/spt/utils/ILogger";
import { DatabaseService } from "@spt/services/DatabaseService";
import { ItemFilterService } from "@spt/services/ItemFilterService";
@ -40,7 +41,7 @@ export class LootGenerator {
* @param options parameters to adjust how loot is generated
* @returns An array of loot items
*/
public createRandomLoot(options: LootRequest): IItem[] {
public createRandomLoot(options: ILootRequest): IItem[] {
const result: IItem[] = [];
const itemTypeCounts = this.initItemLimitCounter(options.itemLimits);
@ -74,7 +75,7 @@ export class LootGenerator {
const { itemPool, blacklist } = this.getItemRewardPool(
options.itemBlacklist,
options.itemTypeWhitelist,
options.useRewarditemBlacklist,
options.useRewardItemBlacklist,
options.allowBossItems,
);
@ -153,13 +154,19 @@ export class LootGenerator {
return result;
}
public createForcedLoot(airdropConfig: LootRequest) {
/**
* Generate An array of items
* TODO - handle weapon presets/ammo packs
* @param forcedLootDict Dictionary of item tpls with minmax values
* @returns Array of IItem
*/
public createForcedLoot(forcedLootDict: Record<string, MinMax>): IItem[] {
const result: IItem[] = [];
const forcedItems = Object.keys(airdropConfig.forcedLoot);
const forcedItems = Object.keys(forcedLootDict);
for (const tpl of forcedItems) {
const details = airdropConfig.forcedLoot[tpl];
const details = forcedLootDict[tpl];
const randomisedItemCount = this.randomUtil.getInt(details.min, details.max);
// Add forced loot item to result
@ -179,6 +186,14 @@ export class LootGenerator {
return result;
}
/**
* Get pool of items from item db that fit passed in param criteria
* @param itemTplBlacklist Prevent these items
* @param itemTypeWhitelist Only allow these items
* @param useRewardItemBlacklist Should item.json reward item config be used
* @param allowBossItems Should boss items be allowed in result
* @returns results of filtering + blacklist used
*/
protected getItemRewardPool(
itemTplBlacklist: string[],
itemTypeWhitelist: string[],
@ -216,7 +231,7 @@ export class LootGenerator {
* @param options Loot request options - armor level etc
* @returns True if item has desired armor level
*/
protected isArmorOfDesiredProtectionLevel(armor: IPreset, options: LootRequest): boolean {
protected isArmorOfDesiredProtectionLevel(armor: IPreset, options: ILootRequest): boolean {
const relevantSlots = ["front_plate", "helmet_top", "soft_armor_front"];
for (const slotId of relevantSlots) {
const armorItem = armor._items.find((item) => item?.slotId?.toLowerCase() === slotId);
@ -258,7 +273,7 @@ export class LootGenerator {
protected findAndAddRandomItemToLoot(
items: [string, ITemplateItem][],
itemTypeCounts: Record<string, { current: number; max: number }>,
options: LootRequest,
options: ILootRequest,
result: IItem[],
): boolean {
const randomItem = this.randomUtil.getArrayValue(items)[1];
@ -305,7 +320,7 @@ export class LootGenerator {
* @param options loot options
* @returns stack count
*/
protected getRandomisedStackCount(item: ITemplateItem, options: LootRequest): number {
protected getRandomisedStackCount(item: ITemplateItem, options: ILootRequest): number {
let min = item._props.StackMinRandom;
let max = item._props.StackMaxSize;

View File

@ -1,6 +1,6 @@
import { MinMax } from "@spt/models/common/MinMax";
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
import { LootRequest } from "@spt/models/spt/services/LootRequest";
import { ILootRequest } from "@spt/models/spt/services/ILootRequest";
export interface ITraderConfig extends IBaseConfig {
kind: "spt-trader";
@ -57,7 +57,7 @@ export interface IItemDurabilityCurrentMax {
max: MinMax;
}
export interface CoopExtractReward extends LootRequest {
export interface CoopExtractReward extends ILootRequest {
sendGift: boolean;
messageLocaleIds: string[];
giftExpiryHours: number;

View File

@ -0,0 +1,35 @@
import { MinMax } from "@spt/models/common/MinMax";
import { AirdropTypeEnum } from "@spt/models/enums/AirdropType";
export interface ILootRequest {
/** Count of weapons to generate */
weaponPresetCount: MinMax;
/** Count of armor to generate */
armorPresetCount: MinMax;
/** Count of items to generate */
itemCount: MinMax;
/** Count of sealed weapon crates to generate */
weaponCrateCount: MinMax;
/** Item tpl blacklist to exclude */
itemBlacklist: string[];
/** Item tpl whitelist to pick from */
itemTypeWhitelist: string[];
/** key: item base type: value: max count */
itemLimits: Record<string, number>;
itemStackLimits: Record<string, MinMax>;
/** Allowed armor plate levels 2/3/4/5/6 for armor generated */
armorLevelWhitelist: number[];
/** Should boss items be included in allowed items */
allowBossItems: boolean;
/** Should item.json item reward blacklist be used */
useRewardItemBlacklist?: boolean;
/** Should forced loot be used instead of randomised loot */
useForcedLoot?: boolean;
/** Item tpls + count of items to force include */
forcedLoot?: Record<string, MinMax>;
}
export interface IAirdropLootRequest extends ILootRequest {
/** Airdrop icon used by client to show crate type */
icon?: AirdropTypeEnum;
}

View File

@ -1,23 +0,0 @@
import { MinMax } from "@spt/models/common/MinMax";
import { AirdropTypeEnum } from "@spt/models/enums/AirdropType";
export interface LootRequest {
weaponPresetCount: MinMax;
armorPresetCount: MinMax;
itemCount: MinMax;
weaponCrateCount: MinMax;
itemBlacklist: string[];
itemTypeWhitelist: string[];
/** key: item base type: value: max count */
itemLimits: Record<string, number>;
itemStackLimits: Record<string, MinMax>;
armorLevelWhitelist: number[];
allowBossItems: boolean;
useRewarditemBlacklist?: boolean;
useForcedLoot?: boolean;
forcedLoot?: Record<string, MinMax>;
}
export interface IAirdropLootRequest extends LootRequest {
icon?: AirdropTypeEnum;
}

View File

@ -8,7 +8,7 @@ import { AirdropTypeEnum, SptAirdropTypeEnum } from "@spt/models/enums/AirdropTy
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
import { ItemTpl } from "@spt/models/enums/ItemTpl";
import { IAirdropConfig, IAirdropLoot } from "@spt/models/spt/config/IAirdropConfig";
import { IAirdropLootRequest, LootRequest } from "@spt/models/spt/services/LootRequest";
import { IAirdropLootRequest, ILootRequest } from "@spt/models/spt/services/ILootRequest";
import { ILogger } from "@spt/models/spt/utils/ILogger";
import { ConfigServer } from "@spt/servers/ConfigServer";
import { DatabaseService } from "@spt/services/DatabaseService";
@ -54,18 +54,19 @@ export class AirdropService {
* Handle client/location/getAirdropLoot
* Get loot for an airdrop container
* Generates it randomly based on config/airdrop.json values
* @param forcedAirdropType OPTIONAL - Desired airdrop type, randomised when not provided
* @returns Array of LootItem objects
*/
public generateAirdropLoot(forcedAirdropType = null): IGetAirdropLootResponse {
const airdropType = forcedAirdropType ? forcedAirdropType : this.chooseAirdropType();
this.logger.debug(`Chose ${airdropType} for airdrop loot`);
this.logger.debug(`Chose: ${airdropType} for airdrop loot`);
// Common/weapon/etc
const airdropConfig = this.getAirdropLootConfigByType(airdropType);
// generate loot to put into airdrop crate
const crateLoot = airdropConfig.useForcedLoot
? this.lootGenerator.createForcedLoot(airdropConfig)
? this.lootGenerator.createForcedLoot(airdropConfig.forcedLoot)
: this.lootGenerator.createRandomLoot(airdropConfig);
// Create airdrop crate and add to result in first spot