Improved loot generator code comments
This commit is contained in:
parent
b6b527df2a
commit
e15ed9b7eb
@ -2,12 +2,13 @@ import { InventoryHelper } from "@spt/helpers/InventoryHelper";
|
|||||||
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
import { ItemHelper } from "@spt/helpers/ItemHelper";
|
||||||
import { PresetHelper } from "@spt/helpers/PresetHelper";
|
import { PresetHelper } from "@spt/helpers/PresetHelper";
|
||||||
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper";
|
||||||
|
import { MinMax } from "@spt/models/common/MinMax";
|
||||||
import { IPreset } from "@spt/models/eft/common/IGlobals";
|
import { IPreset } from "@spt/models/eft/common/IGlobals";
|
||||||
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
import { IItem } from "@spt/models/eft/common/tables/IItem";
|
||||||
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
import { ITemplateItem } from "@spt/models/eft/common/tables/ITemplateItem";
|
||||||
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
import { BaseClasses } from "@spt/models/enums/BaseClasses";
|
||||||
import { ISealedAirdropContainerSettings, RewardDetails } from "@spt/models/spt/config/IInventoryConfig";
|
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 { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||||
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
import { ItemFilterService } from "@spt/services/ItemFilterService";
|
||||||
@ -40,7 +41,7 @@ export class LootGenerator {
|
|||||||
* @param options parameters to adjust how loot is generated
|
* @param options parameters to adjust how loot is generated
|
||||||
* @returns An array of loot items
|
* @returns An array of loot items
|
||||||
*/
|
*/
|
||||||
public createRandomLoot(options: LootRequest): IItem[] {
|
public createRandomLoot(options: ILootRequest): IItem[] {
|
||||||
const result: IItem[] = [];
|
const result: IItem[] = [];
|
||||||
const itemTypeCounts = this.initItemLimitCounter(options.itemLimits);
|
const itemTypeCounts = this.initItemLimitCounter(options.itemLimits);
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ export class LootGenerator {
|
|||||||
const { itemPool, blacklist } = this.getItemRewardPool(
|
const { itemPool, blacklist } = this.getItemRewardPool(
|
||||||
options.itemBlacklist,
|
options.itemBlacklist,
|
||||||
options.itemTypeWhitelist,
|
options.itemTypeWhitelist,
|
||||||
options.useRewarditemBlacklist,
|
options.useRewardItemBlacklist,
|
||||||
options.allowBossItems,
|
options.allowBossItems,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -153,13 +154,19 @@ export class LootGenerator {
|
|||||||
return result;
|
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 result: IItem[] = [];
|
||||||
|
|
||||||
const forcedItems = Object.keys(airdropConfig.forcedLoot);
|
const forcedItems = Object.keys(forcedLootDict);
|
||||||
|
|
||||||
for (const tpl of forcedItems) {
|
for (const tpl of forcedItems) {
|
||||||
const details = airdropConfig.forcedLoot[tpl];
|
const details = forcedLootDict[tpl];
|
||||||
const randomisedItemCount = this.randomUtil.getInt(details.min, details.max);
|
const randomisedItemCount = this.randomUtil.getInt(details.min, details.max);
|
||||||
|
|
||||||
// Add forced loot item to result
|
// Add forced loot item to result
|
||||||
@ -179,6 +186,14 @@ export class LootGenerator {
|
|||||||
return result;
|
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(
|
protected getItemRewardPool(
|
||||||
itemTplBlacklist: string[],
|
itemTplBlacklist: string[],
|
||||||
itemTypeWhitelist: string[],
|
itemTypeWhitelist: string[],
|
||||||
@ -216,7 +231,7 @@ export class LootGenerator {
|
|||||||
* @param options Loot request options - armor level etc
|
* @param options Loot request options - armor level etc
|
||||||
* @returns True if item has desired armor level
|
* @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"];
|
const relevantSlots = ["front_plate", "helmet_top", "soft_armor_front"];
|
||||||
for (const slotId of relevantSlots) {
|
for (const slotId of relevantSlots) {
|
||||||
const armorItem = armor._items.find((item) => item?.slotId?.toLowerCase() === slotId);
|
const armorItem = armor._items.find((item) => item?.slotId?.toLowerCase() === slotId);
|
||||||
@ -258,7 +273,7 @@ export class LootGenerator {
|
|||||||
protected findAndAddRandomItemToLoot(
|
protected findAndAddRandomItemToLoot(
|
||||||
items: [string, ITemplateItem][],
|
items: [string, ITemplateItem][],
|
||||||
itemTypeCounts: Record<string, { current: number; max: number }>,
|
itemTypeCounts: Record<string, { current: number; max: number }>,
|
||||||
options: LootRequest,
|
options: ILootRequest,
|
||||||
result: IItem[],
|
result: IItem[],
|
||||||
): boolean {
|
): boolean {
|
||||||
const randomItem = this.randomUtil.getArrayValue(items)[1];
|
const randomItem = this.randomUtil.getArrayValue(items)[1];
|
||||||
@ -305,7 +320,7 @@ export class LootGenerator {
|
|||||||
* @param options loot options
|
* @param options loot options
|
||||||
* @returns stack count
|
* @returns stack count
|
||||||
*/
|
*/
|
||||||
protected getRandomisedStackCount(item: ITemplateItem, options: LootRequest): number {
|
protected getRandomisedStackCount(item: ITemplateItem, options: ILootRequest): number {
|
||||||
let min = item._props.StackMinRandom;
|
let min = item._props.StackMinRandom;
|
||||||
let max = item._props.StackMaxSize;
|
let max = item._props.StackMaxSize;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { MinMax } from "@spt/models/common/MinMax";
|
import { MinMax } from "@spt/models/common/MinMax";
|
||||||
import { IBaseConfig } from "@spt/models/spt/config/IBaseConfig";
|
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 {
|
export interface ITraderConfig extends IBaseConfig {
|
||||||
kind: "spt-trader";
|
kind: "spt-trader";
|
||||||
@ -57,7 +57,7 @@ export interface IItemDurabilityCurrentMax {
|
|||||||
max: MinMax;
|
max: MinMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CoopExtractReward extends LootRequest {
|
export interface CoopExtractReward extends ILootRequest {
|
||||||
sendGift: boolean;
|
sendGift: boolean;
|
||||||
messageLocaleIds: string[];
|
messageLocaleIds: string[];
|
||||||
giftExpiryHours: number;
|
giftExpiryHours: number;
|
||||||
|
35
project/src/models/spt/services/ILootRequest.ts
Normal file
35
project/src/models/spt/services/ILootRequest.ts
Normal 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;
|
||||||
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ import { AirdropTypeEnum, SptAirdropTypeEnum } from "@spt/models/enums/AirdropTy
|
|||||||
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||||
import { ItemTpl } from "@spt/models/enums/ItemTpl";
|
import { ItemTpl } from "@spt/models/enums/ItemTpl";
|
||||||
import { IAirdropConfig, IAirdropLoot } from "@spt/models/spt/config/IAirdropConfig";
|
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 { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||||
import { DatabaseService } from "@spt/services/DatabaseService";
|
import { DatabaseService } from "@spt/services/DatabaseService";
|
||||||
@ -54,18 +54,19 @@ export class AirdropService {
|
|||||||
* Handle client/location/getAirdropLoot
|
* Handle client/location/getAirdropLoot
|
||||||
* Get loot for an airdrop container
|
* Get loot for an airdrop container
|
||||||
* Generates it randomly based on config/airdrop.json values
|
* Generates it randomly based on config/airdrop.json values
|
||||||
|
* @param forcedAirdropType OPTIONAL - Desired airdrop type, randomised when not provided
|
||||||
* @returns Array of LootItem objects
|
* @returns Array of LootItem objects
|
||||||
*/
|
*/
|
||||||
public generateAirdropLoot(forcedAirdropType = null): IGetAirdropLootResponse {
|
public generateAirdropLoot(forcedAirdropType = null): IGetAirdropLootResponse {
|
||||||
const airdropType = forcedAirdropType ? forcedAirdropType : this.chooseAirdropType();
|
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
|
// Common/weapon/etc
|
||||||
const airdropConfig = this.getAirdropLootConfigByType(airdropType);
|
const airdropConfig = this.getAirdropLootConfigByType(airdropType);
|
||||||
|
|
||||||
// generate loot to put into airdrop crate
|
// generate loot to put into airdrop crate
|
||||||
const crateLoot = airdropConfig.useForcedLoot
|
const crateLoot = airdropConfig.useForcedLoot
|
||||||
? this.lootGenerator.createForcedLoot(airdropConfig)
|
? this.lootGenerator.createForcedLoot(airdropConfig.forcedLoot)
|
||||||
: this.lootGenerator.createRandomLoot(airdropConfig);
|
: this.lootGenerator.createRandomLoot(airdropConfig);
|
||||||
|
|
||||||
// Create airdrop crate and add to result in first spot
|
// Create airdrop crate and add to result in first spot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user