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,
|
modSlotName: string,
|
||||||
): IChooseRandomCompatibleModResult {
|
): IChooseRandomCompatibleModResult {
|
||||||
let chosenTpl: string;
|
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" };
|
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
|
// 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;
|
let blockedAttemptCount = 0;
|
||||||
while (exhaustableModPool.hasValues()) {
|
while (exhaustableModPool.hasValues()) {
|
||||||
chosenTpl = exhaustableModPool.getRandomValue();
|
chosenTpl = exhaustableModPool.getRandomValue();
|
||||||
@ -865,13 +882,6 @@ export class BotEquipmentModGenerator {
|
|||||||
break;
|
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(
|
chosenModResult = this.botGeneratorHelper.isWeaponModIncompatibleWithCurrentMods(
|
||||||
weapon,
|
weapon,
|
||||||
chosenTpl,
|
chosenTpl,
|
||||||
@ -905,6 +915,19 @@ export class BotEquipmentModGenerator {
|
|||||||
return chosenModResult;
|
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:
|
* Filter mod pool down based on various criteria:
|
||||||
* Is slot flagged as randomisable
|
* Is slot flagged as randomisable
|
||||||
|
@ -250,13 +250,18 @@ export class BotGeneratorHelper {
|
|||||||
return { Durability: currentDurability, MaxDurability: maxDurability };
|
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(
|
public isWeaponModIncompatibleWithCurrentMods(
|
||||||
itemsEquipped: Item[],
|
weapon: Item[],
|
||||||
tplToCheck: string,
|
tplToCheck: string,
|
||||||
modSlot: string,
|
modSlot: string,
|
||||||
): IChooseRandomCompatibleModResult {
|
): 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 itemToEquipDb = this.itemHelper.getItem(tplToCheck);
|
||||||
const itemToEquip = itemToEquipDb[1];
|
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` };
|
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
|
// Check for existing weapon mods being incompatable with new item
|
||||||
const blockingItem = equippedItemsDb.find((x) => x._props.ConflictingItems?.includes(tplToCheck));
|
const blockingModItem = weapon.find((item) => itemToEquip._props.ConflictingItems?.includes(item._tpl));
|
||||||
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));
|
|
||||||
if (blockingModItem) {
|
if (blockingModItem) {
|
||||||
return {
|
return {
|
||||||
incompatible: true,
|
incompatible: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user