Refactor equipment mod parameters
This commit is contained in:
parent
749fc75a25
commit
c6135802be
@ -23,6 +23,7 @@ import { LocalisationService } from "@spt-aki/services/LocalisationService";
|
||||
import { HashUtil } from "@spt-aki/utils/HashUtil";
|
||||
import { JsonUtil } from "@spt-aki/utils/JsonUtil";
|
||||
import { RandomUtil } from "@spt-aki/utils/RandomUtil";
|
||||
import { IGenerateEquipmentProperties } from "./BotInventoryGenerator";
|
||||
|
||||
@injectable()
|
||||
export class BotEquipmentModGenerator
|
||||
@ -65,18 +66,16 @@ export class BotEquipmentModGenerator
|
||||
*/
|
||||
public generateModsForEquipment(
|
||||
equipment: Item[],
|
||||
modPool: Mods,
|
||||
parentId: string,
|
||||
parentTemplate: ITemplateItem,
|
||||
modSpawnChances: ModsChances,
|
||||
botRole: string,
|
||||
settings: IGenerateEquipmentProperties,
|
||||
forceSpawn = false,
|
||||
): Item[]
|
||||
{
|
||||
const compatibleModsPool = modPool[parentTemplate._id];
|
||||
const compatibleModsPool = settings.modPool[parentTemplate._id];
|
||||
if (!compatibleModsPool)
|
||||
{
|
||||
this.logger.warning(`bot: ${botRole} lacks a mod slot pool for item: ${parentTemplate._id} ${parentTemplate._name}`);
|
||||
this.logger.warning(`bot: ${settings.botRole} lacks a mod slot pool for item: ${parentTemplate._id} ${parentTemplate._name}`);
|
||||
}
|
||||
|
||||
// Iterate over mod pool and choose mods to add to item
|
||||
@ -90,13 +89,13 @@ export class BotEquipmentModGenerator
|
||||
modSlot: modSlot,
|
||||
parentId: parentTemplate._id,
|
||||
parentName: parentTemplate._name,
|
||||
botRole: botRole
|
||||
botRole: settings.botRole
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(this.shouldModBeSpawned(itemSlot, modSlot, modSpawnChances) || forceSpawn))
|
||||
if (!(this.shouldModBeSpawned(itemSlot, modSlot, settings.spawnChances.mods) || forceSpawn))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -107,12 +106,14 @@ export class BotEquipmentModGenerator
|
||||
forceSpawn = true;
|
||||
}
|
||||
|
||||
const modPoolToChooseFrom = this.filterPlateModsForSlot(settings.botRole, modSlot, compatibleModsPool[modSlot]);
|
||||
|
||||
let modTpl: string;
|
||||
let found = false;
|
||||
|
||||
// Find random mod and check its compatible
|
||||
const exhaustableModPool = new ExhaustableArray(
|
||||
compatibleModsPool[modSlot],
|
||||
modPoolToChooseFrom,
|
||||
this.randomUtil,
|
||||
this.jsonUtil,
|
||||
);
|
||||
@ -144,24 +145,22 @@ export class BotEquipmentModGenerator
|
||||
}
|
||||
|
||||
const modTemplate = this.itemHelper.getItem(modTpl);
|
||||
if (!this.isModValidForSlot(modTemplate, itemSlot, modSlot, parentTemplate, botRole))
|
||||
if (!this.isModValidForSlot(modTemplate, itemSlot, modSlot, parentTemplate, settings.botRole))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const modId = this.hashUtil.generate();
|
||||
equipment.push(this.createModItem(modId, modTpl, parentId, modSlot, modTemplate[1], botRole));
|
||||
equipment.push(this.createModItem(modId, modTpl, parentId, modSlot, modTemplate[1], settings.botRole));
|
||||
|
||||
if (Object.keys(modPool).includes(modTpl))
|
||||
if (Object.keys(settings.modPool).includes(modTpl))
|
||||
{
|
||||
// Call self recursively
|
||||
this.generateModsForEquipment(
|
||||
equipment,
|
||||
modPool,
|
||||
modId,
|
||||
modTemplate[1],
|
||||
modSpawnChances,
|
||||
botRole,
|
||||
settings,
|
||||
forceSpawn,
|
||||
);
|
||||
}
|
||||
@ -170,6 +169,24 @@ export class BotEquipmentModGenerator
|
||||
return equipment;
|
||||
}
|
||||
|
||||
protected filterPlateModsForSlot(botRole: string, modSlot: string, modPool: string[]): string[]
|
||||
{
|
||||
// Not pmc or not a plate slot, return original mod pool array
|
||||
if (!this.botHelper.isBotPmc(botRole) || !this.slotIsPlate(modSlot))
|
||||
{
|
||||
return modPool;
|
||||
}
|
||||
|
||||
const filteredModPool = [];
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected slotIsPlate(modSlot: string): boolean
|
||||
{
|
||||
return ["front_plate", "back_plate", "side_plate"].includes(modSlot.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add mods to a weapon using the provided mod pool
|
||||
* @param sessionId session id
|
||||
|
@ -11,7 +11,7 @@ import { Inventory as PmcInventory } from "@spt-aki/models/eft/common/tables/IBo
|
||||
import { Chances, Generation, IBotType, Inventory, Mods } from "@spt-aki/models/eft/common/tables/IBotType";
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { EquipmentSlots } from "@spt-aki/models/enums/EquipmentSlots";
|
||||
import { EquipmentFilterDetails, IBotConfig, RandomisationDetails } from "@spt-aki/models/spt/config/IBotConfig";
|
||||
import { EquipmentFilterDetails, EquipmentFilters, IBotConfig, RandomisationDetails } from "@spt-aki/models/spt/config/IBotConfig";
|
||||
import { ILogger } from "@spt-aki/models/spt/utils/ILogger";
|
||||
import { ConfigServer } from "@spt-aki/servers/ConfigServer";
|
||||
import { DatabaseServer } from "@spt-aki/servers/DatabaseServer";
|
||||
@ -159,7 +159,6 @@ export class BotInventoryGenerator
|
||||
|
||||
const botEquipConfig = this.botConfig.equipment[this.botGeneratorHelper.getBotEquipmentRole(botRole)];
|
||||
const randomistionDetails = this.botHelper.getBotRandomizationDetails(botLevel, botEquipConfig);
|
||||
|
||||
for (const equipmentSlot in templateInventory.equipment)
|
||||
{
|
||||
// Weapons have special generation and will be generated separately; ArmorVest should be generated after TactivalVest
|
||||
@ -168,63 +167,75 @@ export class BotInventoryGenerator
|
||||
continue;
|
||||
}
|
||||
|
||||
this.generateEquipment(
|
||||
equipmentSlot,
|
||||
templateInventory.equipment[equipmentSlot],
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment({
|
||||
equipmentSlot: equipmentSlot,
|
||||
equipmentPool: templateInventory.equipment[equipmentSlot],
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
}
|
||||
|
||||
// Generate below in specific order
|
||||
this.generateEquipment(
|
||||
EquipmentSlots.FACE_COVER,
|
||||
templateInventory.equipment.FaceCover,
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment(
|
||||
EquipmentSlots.HEADWEAR,
|
||||
templateInventory.equipment.Headwear,
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment(
|
||||
EquipmentSlots.EARPIECE,
|
||||
templateInventory.equipment.Earpiece,
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment(
|
||||
EquipmentSlots.TACTICAL_VEST,
|
||||
templateInventory.equipment.TacticalVest,
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment(
|
||||
EquipmentSlots.ARMOR_VEST,
|
||||
templateInventory.equipment.ArmorVest,
|
||||
templateInventory.mods,
|
||||
equipmentChances,
|
||||
botRole,
|
||||
botInventory,
|
||||
randomistionDetails,
|
||||
);
|
||||
this.generateEquipment({
|
||||
equipmentSlot: EquipmentSlots.FACE_COVER,
|
||||
equipmentPool: templateInventory.equipment.FaceCover,
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
this.generateEquipment({
|
||||
equipmentSlot: EquipmentSlots.HEADWEAR,
|
||||
equipmentPool: templateInventory.equipment.Headwear,
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
this.generateEquipment({
|
||||
equipmentSlot: EquipmentSlots.EARPIECE,
|
||||
equipmentPool: templateInventory.equipment.Earpiece,
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
this.generateEquipment({
|
||||
equipmentSlot: EquipmentSlots.TACTICAL_VEST,
|
||||
equipmentPool: templateInventory.equipment.TacticalVest,
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
this.generateEquipment({
|
||||
equipmentSlot: EquipmentSlots.ARMOR_VEST,
|
||||
equipmentPool: templateInventory.equipment.ArmorVest,
|
||||
modPool: templateInventory.mods,
|
||||
spawnChances: equipmentChances,
|
||||
botRole: botRole,
|
||||
botLevel: botLevel,
|
||||
inventory: botInventory,
|
||||
botEquipmentConfig: botEquipConfig,
|
||||
randomisationDetails: randomistionDetails
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,49 +248,41 @@ export class BotInventoryGenerator
|
||||
* @param inventory Inventory to add item into
|
||||
* @param randomisationDetails settings from bot.json to adjust how item is generated
|
||||
*/
|
||||
protected generateEquipment(
|
||||
equipmentSlot: string,
|
||||
equipmentPool: Record<string, number>,
|
||||
modPool: Mods,
|
||||
spawnChances: Chances,
|
||||
botRole: string,
|
||||
inventory: PmcInventory,
|
||||
randomisationDetails: RandomisationDetails,
|
||||
): void
|
||||
protected generateEquipment(settings: IGenerateEquipmentProperties): void
|
||||
{
|
||||
const spawnChance =
|
||||
([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[]).includes(equipmentSlot)
|
||||
([EquipmentSlots.POCKETS, EquipmentSlots.SECURED_CONTAINER] as string[]).includes(settings.equipmentSlot)
|
||||
? 100
|
||||
: spawnChances.equipment[equipmentSlot];
|
||||
: settings.spawnChances.equipment[settings.equipmentSlot];
|
||||
if (typeof spawnChance === "undefined")
|
||||
{
|
||||
this.logger.warning(
|
||||
this.localisationService.getText("bot-no_spawn_chance_defined_for_equipment_slot", equipmentSlot),
|
||||
this.localisationService.getText("bot-no_spawn_chance_defined_for_equipment_slot", settings.equipmentSlot),
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const shouldSpawn = this.randomUtil.getChance100(spawnChance);
|
||||
if (Object.keys(equipmentPool).length && shouldSpawn)
|
||||
if (Object.keys(settings.equipmentPool).length && shouldSpawn)
|
||||
{
|
||||
const id = this.hashUtil.generate();
|
||||
const equipmentItemTpl = this.weightedRandomHelper.getWeightedValue<string>(equipmentPool);
|
||||
const equipmentItemTpl = this.weightedRandomHelper.getWeightedValue<string>(settings.equipmentPool);
|
||||
const itemTemplate = this.itemHelper.getItem(equipmentItemTpl);
|
||||
|
||||
if (!itemTemplate[0])
|
||||
{
|
||||
this.logger.error(this.localisationService.getText("bot-missing_item_template", equipmentItemTpl));
|
||||
this.logger.info(`EquipmentSlot -> ${equipmentSlot}`);
|
||||
this.logger.info(`EquipmentSlot -> ${settings.equipmentSlot}`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.botGeneratorHelper.isItemIncompatibleWithCurrentItems(
|
||||
inventory.items,
|
||||
settings.inventory.items,
|
||||
equipmentItemTpl,
|
||||
equipmentSlot,
|
||||
settings.equipmentSlot,
|
||||
).incompatible
|
||||
)
|
||||
{
|
||||
@ -290,19 +293,19 @@ export class BotInventoryGenerator
|
||||
const item = {
|
||||
_id: id,
|
||||
_tpl: equipmentItemTpl,
|
||||
parentId: inventory.equipment,
|
||||
slotId: equipmentSlot,
|
||||
...this.botGeneratorHelper.generateExtraPropertiesForItem(itemTemplate[1], botRole),
|
||||
parentId: settings.inventory.equipment,
|
||||
slotId: settings.equipmentSlot,
|
||||
...this.botGeneratorHelper.generateExtraPropertiesForItem(itemTemplate[1], settings.botRole),
|
||||
};
|
||||
|
||||
// use dynamic mod pool if enabled in config
|
||||
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(botRole);
|
||||
const botEquipmentRole = this.botGeneratorHelper.getBotEquipmentRole(settings.botRole);
|
||||
if (
|
||||
this.botConfig.equipment[botEquipmentRole]
|
||||
&& randomisationDetails?.randomisedArmorSlots?.includes(equipmentSlot)
|
||||
&& settings.randomisationDetails?.randomisedArmorSlots?.includes(settings.equipmentSlot)
|
||||
)
|
||||
{
|
||||
modPool[equipmentItemTpl] = this.getFilteredDynamicModsForItem(
|
||||
settings.modPool[equipmentItemTpl] = this.getFilteredDynamicModsForItem(
|
||||
equipmentItemTpl,
|
||||
this.botConfig.equipment[botEquipmentRole].blacklist,
|
||||
);
|
||||
@ -313,17 +316,16 @@ export class BotInventoryGenerator
|
||||
{
|
||||
const items = this.botEquipmentModGenerator.generateModsForEquipment(
|
||||
[item],
|
||||
modPool,
|
||||
settings.modPool,
|
||||
id,
|
||||
itemTemplate[1],
|
||||
spawnChances.mods,
|
||||
botRole,
|
||||
settings
|
||||
);
|
||||
inventory.items.push(...items);
|
||||
settings.inventory.items.push(...items);
|
||||
}
|
||||
else
|
||||
{
|
||||
inventory.items.push(item);
|
||||
settings.inventory.items.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -462,3 +464,16 @@ export class BotInventoryGenerator
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IGenerateEquipmentProperties
|
||||
{
|
||||
equipmentSlot: string,
|
||||
equipmentPool: Record<string, number>,
|
||||
modPool: Mods,
|
||||
spawnChances: Chances,
|
||||
botRole: string,
|
||||
botLevel: number,
|
||||
inventory: PmcInventory,
|
||||
botEquipmentConfig: EquipmentFilters,
|
||||
randomisationDetails: RandomisationDetails
|
||||
}
|
||||
|
@ -116,6 +116,7 @@ export interface EquipmentFilters
|
||||
weightingAdjustmentsByPlayerLevel?: WeightingAdjustmentDetails[];
|
||||
/** Should the stock mod be forced to spawn on bot */
|
||||
forceStock: boolean;
|
||||
armorPlateWeighting?: IArmorPlateWeights[]
|
||||
}
|
||||
|
||||
export interface ModLimits
|
||||
@ -156,19 +157,28 @@ export interface WeightingAdjustmentDetails
|
||||
/** Between what levels do these weight settings apply to */
|
||||
levelRange: MinMax;
|
||||
/** Key: ammo type e.g. Caliber556x45NATO, value: item tpl + weight */
|
||||
ammo?: AdjustmentDetails;
|
||||
ammo?: IAdjustmentDetails;
|
||||
/** Key: equipment slot e.g. TacticalVest, value: item tpl + weight */
|
||||
equipment?: AdjustmentDetails;
|
||||
equipment?: IAdjustmentDetails;
|
||||
/** Key: clothing slot e.g. feet, value: item tpl + weight */
|
||||
clothing?: AdjustmentDetails;
|
||||
clothing?: IAdjustmentDetails;
|
||||
|
||||
}
|
||||
|
||||
export interface AdjustmentDetails
|
||||
export interface IAdjustmentDetails
|
||||
{
|
||||
add: Record<string, Record<string, number>>;
|
||||
edit: Record<string, Record<string, number>>;
|
||||
}
|
||||
|
||||
export interface IArmorPlateWeights
|
||||
{
|
||||
levelRange: MinMax;
|
||||
frontPlateWeights: Record<string, number>;
|
||||
backPlateWeights: Record<string, number>;
|
||||
sidePlateWeights: Record<string, number>;
|
||||
}
|
||||
|
||||
export interface IRandomisedResourceDetails
|
||||
{
|
||||
food: IRandomisedResourceValues;
|
||||
|
@ -12,9 +12,9 @@ import {
|
||||
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
|
||||
import { BotGenerationDetails } from "@spt-aki/models/spt/bots/BotGenerationDetails";
|
||||
import {
|
||||
AdjustmentDetails,
|
||||
EquipmentFilterDetails,
|
||||
EquipmentFilters,
|
||||
IAdjustmentDetails,
|
||||
IBotConfig,
|
||||
WeightingAdjustmentDetails,
|
||||
} from "@spt-aki/models/spt/config/IBotConfig";
|
||||
@ -393,7 +393,7 @@ export class BotEquipmentFilterService
|
||||
* @param botItemPool Bot item dictionary to adjust
|
||||
*/
|
||||
protected adjustWeighting(
|
||||
weightingAdjustments: AdjustmentDetails,
|
||||
weightingAdjustments: IAdjustmentDetails,
|
||||
botItemPool: Record<string, any>,
|
||||
showEditWarnings = true,
|
||||
): void
|
||||
|
Loading…
x
Reference in New Issue
Block a user