Reworked how items are chosen to be force-stacked
Fixes medical items not stacking correctly when there was multiple of the same item with different resource values Added additional item types to be force-stacked Added backpack item limit Sligfhtly reduce item limit to account for items now stacking
This commit is contained in:
parent
d4ee8f64d4
commit
92c5dc7f6b
@ -61,7 +61,7 @@
|
||||
},
|
||||
"partialRefreshTimeSeconds": 240,
|
||||
"partialRefreshChangePercent": 15,
|
||||
"assortSize": 140,
|
||||
"assortSize": 120,
|
||||
"weaponPresetMinMax": {
|
||||
"min": 12,
|
||||
"max": 19
|
||||
@ -116,12 +116,13 @@
|
||||
"5485a8684bdc2da71d8b4567": 23,
|
||||
"5f4fbaaca5573a5ac31db429": 0,
|
||||
"5447e0e74bdc2d3c308b4567": 4,
|
||||
"57bef4c42459772e8d35a53b": 1,
|
||||
"57bef4c42459772e8d35a53b": 2,
|
||||
"5b3f15d486f77432d0509248": 3,
|
||||
"543be6564bdc2df4348b4568": 0,
|
||||
"5448ecbe4bdc2d60728b4568": 0,
|
||||
"5671435f4bdc2d96058b4569": 0,
|
||||
"543be5cb4bdc2deb348b4568": 3
|
||||
"543be5cb4bdc2deb348b4568": 3,
|
||||
"5448e53e4bdc2d60728b4567": 7
|
||||
},
|
||||
"preventDuplicateOffersOfCategory": [
|
||||
"543be5cb4bdc2deb348b4568",
|
||||
@ -134,9 +135,17 @@
|
||||
"543be5e94bdc2df1348b4568",
|
||||
"5448eb774bdc2d0a728b4567",
|
||||
"5447e1d04bdc2dff2f8b4567",
|
||||
"5448e53e4bdc2d60728b4567",
|
||||
"5448ecbe4bdc2d60728b4568",
|
||||
"543be6674bdc2df1348b4569",
|
||||
"5448fe124bdc2da5018b4567"
|
||||
"5448fe124bdc2da5018b4567",
|
||||
"567849dd4bdc2d150f8b456e",
|
||||
"5a341c4686f77469e155819e",
|
||||
"5448e5284bdc2dcb718b4567",
|
||||
"5447e0e74bdc2d3c308b4567",
|
||||
"5b3f15d486f77432d0509248",
|
||||
"5645bcb74bdc2ded0b8b4578",
|
||||
"5795f317245977243854e041"
|
||||
],
|
||||
"weaponDurabilityPercentMinMax": {
|
||||
"current": {
|
||||
|
@ -6,7 +6,7 @@ import { PresetHelper } from "@spt-aki/helpers/PresetHelper";
|
||||
import { MinMax } from "@spt-aki/models/common/MinMax";
|
||||
import { IFenceLevel } from "@spt-aki/models/eft/common/IGlobals";
|
||||
import { IPmcData } from "@spt-aki/models/eft/common/IPmcData";
|
||||
import { Item, Repairable } from "@spt-aki/models/eft/common/tables/IItem";
|
||||
import { Item, Repairable, Upd } from "@spt-aki/models/eft/common/tables/IItem";
|
||||
import { ITemplateItem } from "@spt-aki/models/eft/common/tables/ITemplateItem";
|
||||
import { IBarterScheme, ITraderAssort } from "@spt-aki/models/eft/common/tables/ITrader";
|
||||
import { BaseClasses } from "@spt-aki/models/enums/BaseClasses";
|
||||
@ -602,24 +602,28 @@ export class FenceService
|
||||
this.itemHelper.remapRootItemId(desiredAssortItemAndChildrenClone);
|
||||
|
||||
const rootItemBeingAdded = desiredAssortItemAndChildrenClone[0];
|
||||
|
||||
// Set stack size based on possible overrides, e.g. ammos, otherwise set to 1
|
||||
rootItemBeingAdded.upd.StackObjectsCount = this.getSingleItemStackCount(itemDbDetails);
|
||||
|
||||
// Skip items already in the assort if it exists in the prevent duplicate list
|
||||
const existingItem = assorts.items.find((item) => item._tpl === rootItemBeingAdded._tpl);
|
||||
if (this.itemShouldBeForceStacked(existingItem, itemDbDetails))
|
||||
{
|
||||
i--;
|
||||
existingItem.upd.StackObjectsCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Only randomise single items
|
||||
// Only randomise upd values for single
|
||||
const isSingleStack = rootItemBeingAdded.upd.StackObjectsCount === 1;
|
||||
if (isSingleStack)
|
||||
{
|
||||
this.randomiseItemUpdProperties(itemDbDetails, rootItemBeingAdded);
|
||||
}
|
||||
|
||||
// Skip items already in the assort if it exists in the prevent duplicate list
|
||||
const existingItemThatMatches = this.getMatchingItem(rootItemBeingAdded, itemDbDetails, assorts.items);
|
||||
const shouldBeStacked = this.itemShouldBeForceStacked(existingItemThatMatches, itemDbDetails);
|
||||
if (shouldBeStacked && existingItemThatMatches)
|
||||
{ // Decrement loop counter so another items gets added
|
||||
i--;
|
||||
existingItemThatMatches.upd.StackObjectsCount++;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add mods to armors so they dont show as red in the trade screen
|
||||
if (this.itemHelper.itemRequiresSoftInserts(rootItemBeingAdded._tpl))
|
||||
{
|
||||
@ -642,6 +646,63 @@ export class FenceService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an assort item that matches the first parameter, also matches based on upd properties
|
||||
* e.g. salewa hp resource units left
|
||||
* @param rootItemBeingAdded item to look for a match against
|
||||
* @param itemDbDetails Db details of matching item
|
||||
* @param fenceItemAssorts Items to search through
|
||||
* @returns Matching assort item
|
||||
*/
|
||||
protected getMatchingItem(rootItemBeingAdded: Item, itemDbDetails: ITemplateItem, fenceItemAssorts: Item[]): Item
|
||||
{
|
||||
const matchingItems = fenceItemAssorts.filter((item) => item._tpl === rootItemBeingAdded._tpl);
|
||||
if (matchingItems.length === 0)
|
||||
{
|
||||
// Nothing matches by tpl, exit early
|
||||
return null;
|
||||
}
|
||||
|
||||
const isMedical = this.itemHelper.isOfBaseclasses(rootItemBeingAdded._tpl, [
|
||||
BaseClasses.MEDICAL,
|
||||
BaseClasses.MEDKIT,
|
||||
]);
|
||||
const isGearAndHasSlots =
|
||||
this.itemHelper.isOfBaseclasses(rootItemBeingAdded._tpl, [
|
||||
BaseClasses.ARMORED_EQUIPMENT,
|
||||
BaseClasses.SEARCHABLE_ITEM,
|
||||
]) && itemDbDetails._props.Slots.length > 0;
|
||||
|
||||
// Only one match and its not medical or armored gear
|
||||
if (matchingItems.length === 1 && (!(isMedical || isGearAndHasSlots)))
|
||||
{
|
||||
return matchingItems[0];
|
||||
}
|
||||
|
||||
// Items have sub properties that need to be checked against
|
||||
for (const item of matchingItems)
|
||||
{
|
||||
if (isMedical && rootItemBeingAdded.upd.MedKit?.HpResource === item.upd.MedKit?.HpResource)
|
||||
{
|
||||
// e.g. bandages with multiple use
|
||||
// Both null === both max resoruce left
|
||||
return item;
|
||||
}
|
||||
|
||||
// Armors/helmets etc
|
||||
if (
|
||||
isGearAndHasSlots
|
||||
&& rootItemBeingAdded.upd.Repairable?.Durability === item.upd.Repairable?.Durability
|
||||
&& rootItemBeingAdded.upd.Repairable?.MaxDurability === item.upd.Repairable?.MaxDurability
|
||||
)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should this item be forced into only 1 stack on fence
|
||||
* @param existingItem Existing item from fence assort
|
||||
@ -656,39 +717,11 @@ export class FenceService
|
||||
return false;
|
||||
}
|
||||
|
||||
// Item type not in config list
|
||||
if (
|
||||
!this.itemHelper.isOfBaseclasses(
|
||||
itemDbDetails._id,
|
||||
this.traderConfig.fence.preventDuplicateOffersOfCategory,
|
||||
)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't stack armor with slots (plates/inserts etc)
|
||||
if (
|
||||
this.itemHelper.isOfBaseclass(itemDbDetails._id, BaseClasses.ARMORED_EQUIPMENT)
|
||||
&& itemDbDetails._props.Slots.length > 0
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't stack meds (e.g. bandages) with unequal usages remaining
|
||||
// TODO - Doesnt look beyond the first matching fence item, e.g. bandage A has 1 usage left = not a match, but bandage B has 2 uses, would have matched
|
||||
if (
|
||||
this.itemHelper.isOfBaseclasses(itemDbDetails._id, [BaseClasses.MEDICAL, BaseClasses.MEDKIT])
|
||||
&& existingItem.upd.MedKit?.HpResource // null medkit object means its brand new/max resource
|
||||
&& (itemDbDetails._props.MaxHpResource !== existingItem.upd.MedKit.HpResource)
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Passed all checks, will be forced stacked
|
||||
return true;
|
||||
// Item type in config list
|
||||
return this.itemHelper.isOfBaseclasses(
|
||||
itemDbDetails._id,
|
||||
this.traderConfig.fence.preventDuplicateOffersOfCategory,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user