Fix armor in bot backpacks having no soft inserts
centralise code that adds mods to equipment into one location
This commit is contained in:
parent
0efd2861c7
commit
15d53a2d38
@ -295,7 +295,7 @@ export class BotLootGenerator
|
||||
{
|
||||
const itemToAddTemplate = this.getRandomItemFromPoolByRole(pool, botRole);
|
||||
const id = this.hashUtil.generate();
|
||||
const itemsToAdd: Item[] = [{
|
||||
let itemsToAdd: Item[] = [{
|
||||
_id: id,
|
||||
_tpl: itemToAddTemplate._id,
|
||||
...this.botGeneratorHelper.generateExtraPropertiesForItem(itemToAddTemplate, botRole),
|
||||
@ -343,6 +343,19 @@ export class BotLootGenerator
|
||||
{
|
||||
this.randomiseAmmoStackSize(isPmc, itemToAddTemplate, itemsToAdd[0]);
|
||||
}
|
||||
// Must add soft inserts/plates
|
||||
else if (this.itemHelper.isOfBaseclasses(itemToAddTemplate._id, [BaseClasses.ARMOR, BaseClasses.HEADWEAR, BaseClasses.VEST]))
|
||||
{
|
||||
// TODO - replace with config values
|
||||
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)
|
||||
const itemAddedResult = this.botWeaponGeneratorHelper.addItemWithChildrenToEquipmentSlot(
|
||||
@ -376,11 +389,9 @@ export class BotLootGenerator
|
||||
// Reset loop, try again
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Item added okay, reset counter for next item
|
||||
fitItemIntoContainerAttempts = 0;
|
||||
}
|
||||
|
||||
// Item added okay, reset counter for next item
|
||||
fitItemIntoContainerAttempts = 0;
|
||||
|
||||
// Stop adding items to bots pool if rolling total is over total limit
|
||||
if (totalValueLimitRub > 0)
|
||||
|
@ -826,7 +826,7 @@ export class LocationGenerator
|
||||
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
|
||||
|
||||
// Item array to return
|
||||
const itemWithMods: Item[] = [];
|
||||
let itemWithMods: Item[] = [];
|
||||
|
||||
// Money/Ammo - don't rely on items in spawnPoint.template.Items so we can randomise it ourselves
|
||||
if (this.itemHelper.isOfBaseclasses(chosenTpl, [BaseClasses.MONEY, BaseClasses.AMMO]))
|
||||
@ -869,7 +869,7 @@ export class LocationGenerator
|
||||
});
|
||||
if (itemTemplate._props.Slots?.length > 0)
|
||||
{
|
||||
this.addModsToEquipmentItem(itemWithMods, itemTemplate)
|
||||
itemWithMods = this.itemHelper.addChildSlotItems(itemWithMods, itemTemplate, this.locationConfig.equipmentLootSettings.modSpawnChancePercent);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1075,7 +1075,7 @@ export class LocationGenerator
|
||||
{
|
||||
if (itemTemplate._props.Slots?.length > 0)
|
||||
{
|
||||
this.addModsToEquipmentItem(items, itemTemplate)
|
||||
items = this.itemHelper.addChildSlotItems(items, itemTemplate, this.locationConfig.equipmentLootSettings.modSpawnChancePercent);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1085,44 +1085,4 @@ export class LocationGenerator
|
||||
height: height
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add mod componenets to an equipment item (head/rig/armor)
|
||||
* @param modItem
|
||||
* @param itemTemplate
|
||||
*/
|
||||
protected addModsToEquipmentItem(modItem: Item[], itemTemplate: ITemplateItem): void
|
||||
{
|
||||
// Add armor plates
|
||||
for (const slot of itemTemplate._props.Slots)
|
||||
{
|
||||
// Check if mod has % chance to be added
|
||||
const modSpawnChance = this.locationConfig.equipmentLootSettings.modSpawnChancePercent[slot._name.toLowerCase()];
|
||||
if (modSpawnChance && !slot._required)
|
||||
{
|
||||
// only run chance to not add item if its not a required mod
|
||||
if (this.randomUtil.getChance100(modSpawnChance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const possibleTplsForSlot = slot._props.filters[0].Filter ?? [];
|
||||
if (possibleTplsForSlot.length === 0)
|
||||
{
|
||||
this.logger.warning(`Unable to add mod to item: ${itemTemplate._id} ${itemTemplate._name} slot: ${slot._name} as the db pool is empty, skipping`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
modItem.push(
|
||||
{
|
||||
_id: this.hashUtil.generate(),
|
||||
_tpl: this.randomUtil.getArrayValue(possibleTplsForSlot), // Choose random tpl from array of compatible
|
||||
parentId: modItem[0]._id,
|
||||
slotId: slot._name
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -392,30 +392,30 @@ export class ItemHelper
|
||||
/**
|
||||
* Recursive function that looks at every item from parameter and gets their childrens Ids + includes parent item in results
|
||||
* @param items Array of items (item + possible children)
|
||||
* @param itemId Parent items id
|
||||
* @param baseItemId Parent items id
|
||||
* @returns an array of strings
|
||||
*/
|
||||
public findAndReturnChildrenByItems(items: Item[], itemId: string): string[]
|
||||
public findAndReturnChildrenByItems(items: Item[], baseItemId: string): string[]
|
||||
{
|
||||
const list: string[] = [];
|
||||
|
||||
for (const childitem of items)
|
||||
{
|
||||
if (childitem.parentId === itemId)
|
||||
if (childitem.parentId === baseItemId)
|
||||
{
|
||||
list.push(...this.findAndReturnChildrenByItems(items, childitem._id));
|
||||
}
|
||||
}
|
||||
|
||||
list.push(itemId); // Required, push original item id onto array
|
||||
list.push(baseItemId); // Required, push original item id onto array
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of findAndReturnChildren where the output is list of item objects instead of their ids.
|
||||
* @param items
|
||||
* @param baseItemId
|
||||
* @param items Array of items (item + possible children)
|
||||
* @param baseItemId Parent items id
|
||||
* @returns An array of Item objects
|
||||
*/
|
||||
public findAndReturnChildrenAsItems(items: Item[], baseItemId: string): Item[]
|
||||
@ -974,10 +974,8 @@ export class ItemHelper
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this.itemIsInsideContainer(parent, desiredContainerSlotId, items);
|
||||
}
|
||||
|
||||
return this.itemIsInsideContainer(parent, desiredContainerSlotId, items);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1169,6 +1167,53 @@ export class ItemHelper
|
||||
x._parent === desiredBaseType
|
||||
).map((x) => x._id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add child slot items to an item, chooses random child item if multiple choices exist
|
||||
* @param itemToAdd array with single object (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)
|
||||
* @returns
|
||||
*/
|
||||
public addChildSlotItems(itemToAdd: Item[], itemToAddTemplate: ITemplateItem, modSpawnChanceDict: Record<string, number> = null): Item[]
|
||||
{
|
||||
const result = itemToAdd;
|
||||
for (const slot of itemToAddTemplate._props.Slots)
|
||||
{
|
||||
// Roll chance for non-required slot mods
|
||||
if (modSpawnChanceDict && !slot._required)
|
||||
{
|
||||
// only roll chance to not include mod if dict exists and has value for this mod type (e.g. front_plate)
|
||||
const modSpawnChance = modSpawnChanceDict[slot._name.toLowerCase()];
|
||||
if (modSpawnChance)
|
||||
{
|
||||
if (!this.randomUtil.getChance100(modSpawnChanceDict[slot._name]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const possibleTplsForSlot = slot._props.filters[0].Filter ?? [];
|
||||
if (possibleTplsForSlot.length === 0)
|
||||
{
|
||||
this.logger.warning(`Unable to add mod to item: ${itemToAddTemplate._id} ${itemToAddTemplate._name} slot: ${slot._name} as the db pool is empty, skipping`);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push(
|
||||
{
|
||||
_id: this.hashUtil.generate(),
|
||||
_tpl: this.randomUtil.getArrayValue(possibleTplsForSlot), // Choose random tpl from array of compatible
|
||||
parentId: result[0]._id,
|
||||
slotId: slot._name
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ItemHelper
|
||||
|
Loading…
Reference in New Issue
Block a user