Improve handleRecipe()

Better handling of item rewards that need to be split into root + child (ammo boxes)
Use `addItemsToStash()`
move `recipe.isEncoded` check to earlier in function

make use of `getItem()` inside `splitStack()` instead of direct db access
This commit is contained in:
Dev 2024-02-01 11:23:32 +00:00
parent 92d949b445
commit 44560991b0
2 changed files with 44 additions and 47 deletions

View File

@ -27,6 +27,7 @@ import { IHideoutUpgradeRequestData } from "@spt-aki/models/eft/hideout/IHideout
import { IQteData } from "@spt-aki/models/eft/hideout/IQteData"; import { IQteData } from "@spt-aki/models/eft/hideout/IQteData";
import { IRecordShootingRangePoints } from "@spt-aki/models/eft/hideout/IRecordShootingRangePoints"; import { IRecordShootingRangePoints } from "@spt-aki/models/eft/hideout/IRecordShootingRangePoints";
import { IAddItemDirectRequest } from "@spt-aki/models/eft/inventory/IAddItemDirectRequest"; import { IAddItemDirectRequest } from "@spt-aki/models/eft/inventory/IAddItemDirectRequest";
import { IAddItemsDirectRequest } from "@spt-aki/models/eft/inventory/IAddItemsDirectRequest";
import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse"; import { IItemEventRouterResponse } from "@spt-aki/models/eft/itemEvent/IItemEventRouterResponse";
import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes"; import { ConfigTypes } from "@spt-aki/models/enums/ConfigTypes";
import { HideoutAreas } from "@spt-aki/models/enums/HideoutAreas"; import { HideoutAreas } from "@spt-aki/models/enums/HideoutAreas";
@ -812,31 +813,23 @@ export class HideoutController
const rewardIsStackable = this.itemHelper.isItemTplStackable(recipe.endProduct); const rewardIsStackable = this.itemHelper.isItemTplStackable(recipe.endProduct);
if (rewardIsStackable) if (rewardIsStackable)
{ {
// Add raw item to array without checking stack size const rewardToAdd: Item[] = [];
itemAndChildrenToSendToPlayer.push([{ // Create root item
const rootItemToAdd: Item = {
_id: this.hashUtil.generate(), _id: this.hashUtil.generate(),
_tpl: recipe.endProduct, _tpl: recipe.endProduct,
upd: { upd: {
StackObjectsCount: recipe.count StackObjectsCount: recipe.count
} }
}]); };
// Split item into separate items with acceptable stack sizes // Split item into separate items with acceptable stack sizes
const splitReward = this.itemHelper.splitStack(itemAndChildrenToSendToPlayer[0][0]); const splitReward = this.itemHelper.splitStack(rewardToAdd[0]);
if (splitReward.length > 1) itemAndChildrenToSendToPlayer.push(splitReward);
{
// Empty out reward array and replace with split items
itemAndChildrenToSendToPlayer = [];
for (const item of splitReward)
{
itemAndChildrenToSendToPlayer.push([item]);
}
}
} }
else else
{ {
// Not stackable, send multiple single items // Not stackable, send multiple single items
// Add the initial item to array // Add the initial item to array
if (!rewardIsPreset) if (!rewardIsPreset)
{ {
@ -854,10 +847,26 @@ export class HideoutController
null, null,
this.jsonUtil.clone(itemAndChildrenToSendToPlayer[0]), this.jsonUtil.clone(itemAndChildrenToSendToPlayer[0]),
); );
itemAndChildrenToSendToPlayer.push(...[itemAndMods]); itemAndChildrenToSendToPlayer.push(...[itemAndMods]);
} }
} }
// Recipe has an `isEncoded` requirement for reward(s), Add `RecodableComponent` property
if (recipe.isEncoded)
{
for (const reward of itemAndChildrenToSendToPlayer)
{
if (!reward[0].upd)
{
reward[0].upd = {}
}
reward[0].upd.RecodableComponent = { IsEncoded: true };
}
}
// Loops over all current productions on profile // Loops over all current productions on profile
const entries = Object.entries(pmcData.Hideout.Production); const entries = Object.entries(pmcData.Hideout.Production);
let prodId: string; let prodId: string;
@ -908,31 +917,19 @@ export class HideoutController
hoursCrafting -= this.hideoutConfig.hoursForSkillCrafting * multiplierCrafting; hoursCrafting -= this.hideoutConfig.hoursForSkillCrafting * multiplierCrafting;
} }
// Loop over array of sub array (item+children) and add to stash // Create request for what we want to add to stash
for (const itemAndChildrenToSend of itemAndChildrenToSendToPlayer) const addItemsRequest: IAddItemsDirectRequest = {
itemsWithModsToAdd: itemAndChildrenToSendToPlayer,
foundInRaid: true,
useSortingTable: false,
callback: null
};
// Add FiR crafted items(s) to player inventory
this.inventoryHelper.addItemsToStash(sessionID, addItemsRequest, pmcData, output);
if (output.warnings.length > 0)
{ {
// Recipe has an `isEncoded` requirement on reward, make root item adjustment return output;
if (recipe.isEncoded)
{
if (!itemAndChildrenToSend[0].upd)
{
itemAndChildrenToSend[0].upd = {}
}
itemAndChildrenToSend[0].upd.RecodableComponent = { IsEncoded: true };
}
const additemRequest: IAddItemDirectRequest = {
itemWithModsToAdd: itemAndChildrenToSend,
foundInRaid: true,
callback: null,
useSortingTable: false
};
this.inventoryHelper.addItemToStash(sessionID, additemRequest,pmcData, output)
if (output.warnings.length > 0)
{
return output;
}
} }
// - increment skill point for crafting // - increment skill point for crafting

View File

@ -514,9 +514,9 @@ export class ItemHelper
} }
/** /**
* split item stack if it exceeds its items StackMaxSize property * Split item stack if it exceeds its items StackMaxSize property
* @param itemToSplit Item to split into smaller stacks * @param itemToSplit Item to split into smaller stacks
* @returns Array of split items * @returns Array of root item + children
*/ */
public splitStack(itemToSplit: Item): Item[] public splitStack(itemToSplit: Item): Item[]
{ {
@ -525,17 +525,17 @@ export class ItemHelper
return [itemToSplit]; return [itemToSplit];
} }
const maxStackSize = this.databaseServer.getTables().templates.items[itemToSplit._tpl]._props.StackMaxSize; const maxStackSize = this.getItem(itemToSplit._tpl)[1]._props.StackMaxSize;
let remainingCount = itemToSplit.upd.StackObjectsCount; let remainingCount = itemToSplit.upd.StackObjectsCount;
const stacks: Item[] = []; const rootAndChildren: Item[] = [];
// If the current count is already equal or less than the max // If the current count is already equal or less than the max
// then just return the item as is. // return the item as is.
if (remainingCount <= maxStackSize) if (remainingCount <= maxStackSize)
{ {
stacks.push(this.jsonUtil.clone(itemToSplit)); rootAndChildren.push(this.jsonUtil.clone(itemToSplit));
return stacks; return rootAndChildren;
} }
while (remainingCount) while (remainingCount)
@ -546,10 +546,10 @@ export class ItemHelper
newStack._id = this.hashUtil.generate(); newStack._id = this.hashUtil.generate();
newStack.upd.StackObjectsCount = amount; newStack.upd.StackObjectsCount = amount;
remainingCount -= amount; remainingCount -= amount;
stacks.push(newStack); rootAndChildren.push(newStack);
} }
return stacks; return rootAndChildren;
} }
/** /**