Improve handling of equipment mod generation

This commit is contained in:
Dev 2024-01-09 10:30:00 +00:00
parent 15d53a2d38
commit bac86262d4
3 changed files with 70 additions and 24 deletions

View File

@ -1100,9 +1100,13 @@
}, },
"equipmentLootSettings": { "equipmentLootSettings": {
"modSpawnChancePercent": { "modSpawnChancePercent": {
"mod_nvg": 20, "mod_nvg": 5,
"front_plate": 50, "front_plate": 50,
"back_plate": 50 "back_plate": 50,
"mod_equipment_000": 5,
"mod_equipment_001": 5,
"mod_equipment_002": 5,
"mod_mount": 5
} }
} }
} }

View File

@ -346,15 +346,7 @@ export class BotLootGenerator
// Must add soft inserts/plates // Must add soft inserts/plates
else if (this.itemHelper.isOfBaseclasses(itemToAddTemplate._id, [BaseClasses.ARMOR, BaseClasses.HEADWEAR, BaseClasses.VEST])) else if (this.itemHelper.isOfBaseclasses(itemToAddTemplate._id, [BaseClasses.ARMOR, BaseClasses.HEADWEAR, BaseClasses.VEST]))
{ {
// TODO - replace with config values itemsToAdd = this.itemHelper.addChildSlotItems(itemsToAdd, itemToAddTemplate, null, true);
const modIncludeedChances = {
mod_nvg: 10,
front_plate: 10,
back_plate: 10,
side_plate: 10
}
itemsToAdd = this.itemHelper.addChildSlotItems(itemsToAdd, itemToAddTemplate, modIncludeedChances);
} }
// Attempt to add item to container(s) // Attempt to add item to container(s)

View File

@ -1173,13 +1173,21 @@ export class ItemHelper
* @param itemToAdd array with single object (root item) * @param itemToAdd array with single object (root item)
* @param itemToAddTemplate Db tempalte for root item * @param itemToAddTemplate Db tempalte for root item
* @param modSpawnChanceDict Optional dictionary of mod name + % chance mod will be included in item (e.g. front_plate: 100) * @param modSpawnChanceDict Optional dictionary of mod name + % chance mod will be included in item (e.g. front_plate: 100)
* @returns * @param requiredOnly Only add required mods
* @returns Item with children
*/ */
public addChildSlotItems(itemToAdd: Item[], itemToAddTemplate: ITemplateItem, modSpawnChanceDict: Record<string, number> = null): Item[] public addChildSlotItems(itemToAdd: Item[], itemToAddTemplate: ITemplateItem, modSpawnChanceDict: Record<string, number> = null, requiredOnly = false): Item[]
{ {
const result = itemToAdd; const result = itemToAdd;
const incompatibleModTpls: Set<string> = new Set();
for (const slot of itemToAddTemplate._props.Slots) for (const slot of itemToAddTemplate._props.Slots)
{ {
// If only required mods is requested, skip non-essential
if (requiredOnly && !slot._required)
{
continue;
}
// Roll chance for non-required slot mods // Roll chance for non-required slot mods
if (modSpawnChanceDict && !slot._required) if (modSpawnChanceDict && !slot._required)
{ {
@ -1194,26 +1202,68 @@ export class ItemHelper
} }
} }
const possibleTplsForSlot = slot._props.filters[0].Filter ?? []; const itemPool = slot._props.filters[0].Filter ?? [];
if (possibleTplsForSlot.length === 0) const chosenTpl = this.getCompatibleTplFromArray(itemPool, incompatibleModTpls);
if (!chosenTpl)
{ {
this.logger.warning(`Unable to add mod to item: ${itemToAddTemplate._id} ${itemToAddTemplate._name} slot: ${slot._name} as the db pool is empty, skipping`); this.logger.debug(`Unable to add mod to item: ${itemToAddTemplate._id} ${itemToAddTemplate._name} slot: ${slot._name} as no compatible tpl could be found in pool of ${itemPool.length}, skipping`);
continue; continue;
} }
result.push( const moditemToAdd = {
{ _id: this.hashUtil.generate(),
_id: this.hashUtil.generate(), _tpl: chosenTpl,
_tpl: this.randomUtil.getArrayValue(possibleTplsForSlot), // Choose random tpl from array of compatible parentId: result[0]._id,
parentId: result[0]._id, slotId: slot._name
slotId: slot._name };
} result.push(moditemToAdd);
)
const modItemDbDetails = this.getItem(moditemToAdd._tpl)[1];
// Include conflicting items of newly added mod in pool to be used for next mod choice
// biome-ignore lint/complexity/noForEach: <explanation>
modItemDbDetails._props.ConflictingItems.forEach(incompatibleModTpls.add, incompatibleModTpls);
} }
return result; return result;
} }
/**
* Get a compatible tpl from the array provided where it is not found in the provided incompatible mod tpls parameter
* @param possibleTpls Tpls to randomply choose from
* @param incompatibleModTpls Incompatible tpls to not allow
* @returns Chosen tpl or null
*/
public getCompatibleTplFromArray(possibleTpls: string[], incompatibleModTpls: Set<string>): string
{
if (possibleTpls.length === 0)
{
return null;
}
let chosenTpl = null;
let count = 0;
while (!chosenTpl)
{
// Loop over choosing a random tpl until one is found or count varaible reaches the same size as the possible tpls array
const tpl = this.randomUtil.getArrayValue(possibleTpls);
if (incompatibleModTpls.has(tpl))
{
// Incompatible tpl was chosen, try again
count++
if (count >= possibleTpls.length)
{
return null;
}
continue;
}
chosenTpl = tpl;
}
return chosenTpl;
}
} }
namespace ItemHelper namespace ItemHelper