Improved pickWeaponModTplForSlotFromPool()
, now pre-sorts mod pool prior to adding it to exhaustableModPool
and processing
This commit is contained in:
parent
0c42a38306
commit
af33625a5c
@ -847,12 +847,29 @@ export class BotEquipmentModGenerator {
|
||||
modSlotName: string,
|
||||
): IChooseRandomCompatibleModResult {
|
||||
let chosenTpl: string;
|
||||
const exhaustableModPool = new ExhaustableArray(modPool, this.randomUtil, this.cloner);
|
||||
|
||||
// Filter out incompatable mods from pool
|
||||
let preFilteredModPool = this.getFilteredModPool(modPool, weapon);
|
||||
if (preFilteredModPool.length === 0) {
|
||||
return {
|
||||
incompatible: true,
|
||||
found: false,
|
||||
reason: `Unable to add mod to ${ModSpawn[choiceTypeEnum]} slot: ${modSlotName}. All: ${modPool.length} had conflicts`,
|
||||
};
|
||||
}
|
||||
|
||||
// Filter mod pool to only items that appear in parents allowed list
|
||||
preFilteredModPool = preFilteredModPool.filter((tpl) => parentSlot._props.filters[0].Filter.includes(tpl));
|
||||
if (preFilteredModPool.length === 0) {
|
||||
return { incompatible: true, found: false, reason: "No mods found in parents allowed list" };
|
||||
}
|
||||
|
||||
// Create pool to pick mod item from
|
||||
const exhaustableModPool = new ExhaustableArray(preFilteredModPool, this.randomUtil, this.cloner);
|
||||
let chosenModResult: IChooseRandomCompatibleModResult = { incompatible: true, found: false, reason: "unknown" };
|
||||
const modParentFilterList = parentSlot._props.filters[0].Filter;
|
||||
|
||||
// How many times can a mod for the slot be blocked before we stop trying
|
||||
const maxBlockedAttempts = Math.round(modPool.length * 0.75); // Roughly 75% of pool size
|
||||
const maxBlockedAttempts = Math.round(modPool.length * 0.75); // 75% of pool size
|
||||
let blockedAttemptCount = 0;
|
||||
while (exhaustableModPool.hasValues()) {
|
||||
chosenTpl = exhaustableModPool.getRandomValue();
|
||||
@ -865,13 +882,6 @@ export class BotEquipmentModGenerator {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check chosen item is on the allowed list of the parent
|
||||
const isOnModParentFilterList = modParentFilterList.includes(chosenTpl);
|
||||
if (!isOnModParentFilterList) {
|
||||
// Try again
|
||||
continue;
|
||||
}
|
||||
|
||||
chosenModResult = this.botGeneratorHelper.isWeaponModIncompatibleWithCurrentMods(
|
||||
weapon,
|
||||
chosenTpl,
|
||||
@ -905,6 +915,19 @@ export class BotEquipmentModGenerator {
|
||||
return chosenModResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of mod tpls that are compatible with the current weapon
|
||||
* @param initialModPool
|
||||
* @param weapon
|
||||
* @returns string array of compatible mod tpls with weapon
|
||||
*/
|
||||
protected getFilteredModPool(initialModPool: string[], weapon: Item[]): string[] {
|
||||
const equippedItemsDb = weapon.map((item) => this.itemHelper.getItem(item._tpl)[1]);
|
||||
const conflicingItemsList = equippedItemsDb.flatMap((item) => item._props.ConflictingItems);
|
||||
|
||||
return initialModPool.filter((tpl) => !conflicingItemsList.includes(tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter mod pool down based on various criteria:
|
||||
* Is slot flagged as randomisable
|
||||
|
@ -250,13 +250,18 @@ export class BotGeneratorHelper {
|
||||
return { Durability: currentDurability, MaxDurability: maxDurability };
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform validation checks on mod tpl against rest of weapon child items
|
||||
* @param weapon all items in weapon
|
||||
* @param tplToCheck Chosen tpl
|
||||
* @param modSlot Slot mod will be placed in
|
||||
* @returns IChooseRandomCompatibleModResult
|
||||
*/
|
||||
public isWeaponModIncompatibleWithCurrentMods(
|
||||
itemsEquipped: Item[],
|
||||
weapon: Item[],
|
||||
tplToCheck: string,
|
||||
modSlot: string,
|
||||
): IChooseRandomCompatibleModResult {
|
||||
// TODO: Can probably be optimized to cache itemTemplates as items are added to inventory
|
||||
const equippedItemsDb = itemsEquipped.map((item) => this.itemHelper.getItem(item._tpl)[1]);
|
||||
const itemToEquipDb = this.itemHelper.getItem(tplToCheck);
|
||||
const itemToEquip = itemToEquipDb[1];
|
||||
|
||||
@ -284,19 +289,8 @@ export class BotGeneratorHelper {
|
||||
return { incompatible: true, found: false, reason: `item: ${tplToCheck} does not have a _props field` };
|
||||
}
|
||||
|
||||
// Check if any of the current weapon mod templates have the incoming item defined as incompatible
|
||||
const blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck));
|
||||
if (blockingItem) {
|
||||
return {
|
||||
incompatible: true,
|
||||
found: false,
|
||||
reason: `Cannot add: ${tplToCheck} ${itemToEquip._name} to slot: ${modSlot}. Blocked by: ${blockingItem._id} ${blockingItem._name}`,
|
||||
slotBlocked: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Check inverse to above, if the incoming item has any existing mods in its conflicting items array
|
||||
const blockingModItem = itemsEquipped.find((item) => itemToEquip._props.ConflictingItems?.includes(item._tpl));
|
||||
// Check for existing weapon mods being incompatable with new item
|
||||
const blockingModItem = weapon.find((item) => itemToEquip._props.ConflictingItems?.includes(item._tpl));
|
||||
if (blockingModItem) {
|
||||
return {
|
||||
incompatible: true,
|
||||
|
Loading…
Reference in New Issue
Block a user