Update inventoryHelper.addItem() to account for items with children that have a upd object

This whole function is in dire need of a rewrite, its awful
This commit is contained in:
Dev 2024-01-08 12:41:52 +00:00
parent aff5c69c80
commit 6dc4604a77

View File

@ -87,7 +87,10 @@ export class InventoryHelper
useSortingTable = false, useSortingTable = false,
): IItemEventRouterResponse ): IItemEventRouterResponse
{ {
const itemLib: Item[] = []; // TODO: what is the purpose of this property /** All items to add + their children */
const itemsToAddPool: Item[] = [];
/** Root items to add to inventory */
const itemsToAdd: IAddItemTempObject[] = []; const itemsToAdd: IAddItemTempObject[] = [];
for (const requestItem of request.items) for (const requestItem of request.items)
@ -97,13 +100,13 @@ export class InventoryHelper
const presetItems = this.jsonUtil.clone( const presetItems = this.jsonUtil.clone(
this.databaseServer.getTables().globals.ItemPresets[requestItem.item_id]._items, this.databaseServer.getTables().globals.ItemPresets[requestItem.item_id]._items,
); );
itemLib.push(...presetItems); itemsToAddPool.push(...presetItems);
requestItem.isPreset = true; requestItem.isPreset = true;
requestItem.item_id = presetItems[0]._id; requestItem.item_id = presetItems[0]._id;
} }
else if (this.paymentHelper.isMoneyTpl(requestItem.item_id)) else if (this.paymentHelper.isMoneyTpl(requestItem.item_id))
{ {
itemLib.push({ _id: requestItem.item_id, _tpl: requestItem.item_id }); itemsToAddPool.push({ _id: requestItem.item_id, _tpl: requestItem.item_id });
} }
else if (request.tid === Traders.FENCE) else if (request.tid === Traders.FENCE)
{ {
@ -121,11 +124,11 @@ export class InventoryHelper
requestItem.item_id, requestItem.item_id,
); );
addUpd = purchasedItemWithChildren[0].upd; // Must persist the fence upd properties (e.g. durability/currentHp) addUpd = purchasedItemWithChildren[0].upd; // Must persist the fence upd properties (e.g. durability/currentHp)
itemLib.push(...purchasedItemWithChildren); itemsToAddPool.push(...purchasedItemWithChildren);
} }
else if (request.tid === "RandomLootContainer") else if (request.tid === "RandomLootContainer")
{ {
itemLib.push({ _id: requestItem.item_id, _tpl: requestItem.item_id }); itemsToAddPool.push({ _id: requestItem.item_id, _tpl: requestItem.item_id });
} }
else else
{ {
@ -133,14 +136,14 @@ export class InventoryHelper
const traderItems = this.traderAssortHelper.getAssort(sessionID, request.tid).items; const traderItems = this.traderAssortHelper.getAssort(sessionID, request.tid).items;
const relevantItems = this.itemHelper.findAndReturnChildrenAsItems(traderItems, requestItem.item_id); const relevantItems = this.itemHelper.findAndReturnChildrenAsItems(traderItems, requestItem.item_id);
const toAdd = relevantItems.filter((traderItem) => const toAdd = relevantItems.filter((traderItem) =>
!itemLib.some((item) => traderItem._id === item._id) !itemsToAddPool.some((item) => traderItem._id === item._id)
); // what's this ); // what's this
itemLib.push(...toAdd); itemsToAddPool.push(...toAdd);
} }
// Split stacks into allowed sizes if needed // Split stacks into allowed sizes if needed
// e.g. when buying 300 ammo from flea but max stack size is 50 // e.g. when buying 300 ammo from flea but max stack size is 50
this.splitStackIntoSmallerStacks(itemLib, requestItem, itemsToAdd); this.splitStackIntoSmallerStacks(itemsToAddPool, requestItem, itemsToAdd);
} }
// Find an empty slot in stash for each of the items being added // Find an empty slot in stash for each of the items being added
@ -150,11 +153,12 @@ export class InventoryHelper
for (const itemToAdd of itemsToAdd) for (const itemToAdd of itemsToAdd)
{ {
// Update Items `location` properties // Update Items `location` properties
const itemWithChildren = this.itemHelper.findAndReturnChildrenAsItems(itemsToAddPool, itemToAdd.itemRef._id);
const errorOutput = this.placeItemInInventory( const errorOutput = this.placeItemInInventory(
itemToAdd, itemToAdd,
stashFS2D, stashFS2D,
sortingTableFS2D, sortingTableFS2D,
itemLib, itemWithChildren,
pmcData.Inventory, pmcData.Inventory,
useSortingTable, useSortingTable,
output, output,
@ -165,7 +169,7 @@ export class InventoryHelper
} }
} }
// Successfully found slot for every item (stash or sorting table), run callback, catch if it fails (e.g. payMoney() might fail) // Found slot for every item (stash or sorting table), run callback and catch failure (e.g. payMoney() as player doesnt have enough)
try try
{ {
if (typeof callback === "function") if (typeof callback === "function")
@ -181,16 +185,23 @@ export class InventoryHelper
return this.httpResponse.appendErrorToOutput(output, message); return this.httpResponse.appendErrorToOutput(output, message);
} }
for (const itemToAdd of itemsToAdd)
{
const itemWithChildren = this.itemHelper.findAndReturnChildrenAsItems(itemsToAddPool, itemToAdd.itemRef._id);
}
// Update UPD properties and add to output.profileChanges/pmcData.Inventory.items arrays // Update UPD properties and add to output.profileChanges/pmcData.Inventory.items arrays
for (const itemToAdd of itemsToAdd) for (const itemToAdd of itemsToAdd)
{ {
const itemWithChildren = this.itemHelper.findAndReturnChildrenAsItems(itemsToAddPool, itemToAdd.itemRef._id);
let idForItemToAdd = this.hashUtil.generate(); let idForItemToAdd = this.hashUtil.generate();
const toDo: string[][] = [[itemToAdd.itemRef._id, idForItemToAdd]]; // WHAT IS THIS?! const originalKeyToNewKeyMap: string[][] = [[itemToAdd.itemRef._id, idForItemToAdd]]; // Every item id + randomly generated id
let upd: Upd = { StackObjectsCount: itemToAdd.count }; let upd: Upd = { StackObjectsCount: itemToAdd.count };
// If item being added is preset, load preset's upd data too. // If item being added is preset, load preset's upd data too.
if (itemToAdd.isPreset) if (itemToAdd.isPreset)
{ {
// Iterate over properties in upd and add them
for (const updID in itemToAdd.itemRef.upd) for (const updID in itemToAdd.itemRef.upd)
{ {
upd[updID] = itemToAdd.itemRef.upd[updID]; upd[updID] = itemToAdd.itemRef.upd[updID];
@ -198,6 +209,7 @@ export class InventoryHelper
if (addUpd) if (addUpd)
{ {
// Iterate over properties in addUpd and add them
for (const updID in addUpd) for (const updID in addUpd)
{ {
upd[updID] = addUpd[updID]; upd[updID] = addUpd[updID];
@ -260,29 +272,33 @@ export class InventoryHelper
if (this.itemHelper.isOfBaseclass(itemToAdd.itemRef._tpl, BaseClasses.AMMO_BOX)) if (this.itemHelper.isOfBaseclass(itemToAdd.itemRef._tpl, BaseClasses.AMMO_BOX))
{ {
this.hydrateAmmoBoxWithAmmo(pmcData, itemToAdd, toDo[0][1], sessionID, output, foundInRaid); this.hydrateAmmoBoxWithAmmo(pmcData, itemToAdd, originalKeyToNewKeyMap[0][1], sessionID, output, foundInRaid);
} }
while (toDo.length > 0) // Loop over item + children
{ while (originalKeyToNewKeyMap.length > 0)
for (const tmpKey in itemLib) {// Iterate item + children being added
for (const arrayIndex in itemsToAddPool)
{ {
if (itemLib[tmpKey]?.parentId !== toDo[0][0]) // Does parent match original key
if (itemsToAddPool[arrayIndex]?.parentId !== originalKeyToNewKeyMap[0][0])
{ {
// Skip when items parent isnt on remap
continue; continue;
} }
// Create new id for item
idForItemToAdd = this.hashUtil.generate(); idForItemToAdd = this.hashUtil.generate();
const slotID = itemLib[tmpKey].slotId; const slotID = itemsToAddPool[arrayIndex].slotId;
// If its from ItemPreset, load preset's upd data too. // If its from ItemPreset, load prese's upd data too.
if (itemToAdd.isPreset) if (itemToAdd.isPreset)
{ {
upd = { StackObjectsCount: itemToAdd.count }; upd = { StackObjectsCount: itemToAdd.count };
for (const updID in itemLib[tmpKey].upd) for (const updID in itemsToAddPool[arrayIndex].upd)
{ {
upd[updID] = itemLib[tmpKey].upd[updID]; upd[updID] = itemsToAddPool[arrayIndex].upd[updID];
} }
if (foundInRaid || this.inventoryConfig.newItemsMarkedFound) if (foundInRaid || this.inventoryConfig.newItemsMarkedFound)
@ -290,13 +306,13 @@ export class InventoryHelper
upd.SpawnedInSession = true; upd.SpawnedInSession = true;
} }
} }
// Is root item
if (slotID === "hideout") if (slotID === "hideout")
{ {
output.profileChanges[sessionID].items.new.push({ output.profileChanges[sessionID].items.new.push({
_id: idForItemToAdd, _id: idForItemToAdd,
_tpl: itemLib[tmpKey]._tpl, _tpl: itemsToAddPool[arrayIndex]._tpl,
parentId: toDo[0][1], parentId: originalKeyToNewKeyMap[0][1],
slotId: slotID, slotId: slotID,
location: { x: itemToAdd.location.x, y: itemToAdd.location.y, r: "Horizontal" }, location: { x: itemToAdd.location.x, y: itemToAdd.location.y, r: "Horizontal" },
upd: this.jsonUtil.clone(upd), upd: this.jsonUtil.clone(upd),
@ -304,47 +320,51 @@ export class InventoryHelper
pmcData.Inventory.items.push({ pmcData.Inventory.items.push({
_id: idForItemToAdd, _id: idForItemToAdd,
_tpl: itemLib[tmpKey]._tpl, _tpl: itemsToAddPool[arrayIndex]._tpl,
parentId: toDo[0][1], parentId: originalKeyToNewKeyMap[0][1],
slotId: itemLib[tmpKey].slotId, slotId: itemsToAddPool[arrayIndex].slotId,
location: { x: itemToAdd.location.x, y: itemToAdd.location.y, r: "Horizontal" }, location: { x: itemToAdd.location.x, y: itemToAdd.location.y, r: "Horizontal" },
upd: this.jsonUtil.clone(upd), upd: this.jsonUtil.clone(upd),
}); });
} }
else else
{ {
const itemLocation = {}; // Child of item being added
// Item already has location property, use it // Item already has location property, use it
if (itemLib[tmpKey]["location"] !== undefined) const itemLocation = {};
if (itemsToAddPool[arrayIndex].location !== undefined)
{ {
itemLocation["location"] = itemLib[tmpKey]["location"]; itemLocation["location"] = itemsToAddPool[arrayIndex].location;
} }
const upd = this.jsonUtil.clone(itemsToAddPool[arrayIndex].upd);
output.profileChanges[sessionID].items.new.push({ output.profileChanges[sessionID].items.new.push({
_id: idForItemToAdd, _id: idForItemToAdd,
_tpl: itemLib[tmpKey]._tpl, _tpl: itemsToAddPool[arrayIndex]._tpl,
parentId: toDo[0][1], parentId: originalKeyToNewKeyMap[0][1],
slotId: slotID, slotId: slotID,
...itemLocation, ...itemLocation,
upd: this.jsonUtil.clone(upd), upd: upd,
}); });
pmcData.Inventory.items.push({ pmcData.Inventory.items.push({
_id: idForItemToAdd, _id: idForItemToAdd,
_tpl: itemLib[tmpKey]._tpl, _tpl: itemsToAddPool[arrayIndex]._tpl,
parentId: toDo[0][1], parentId: originalKeyToNewKeyMap[0][1],
slotId: itemLib[tmpKey].slotId, slotId: itemsToAddPool[arrayIndex].slotId,
...itemLocation, ...itemLocation,
upd: this.jsonUtil.clone(upd), upd: upd,
}); });
this.logger.debug(`Added ${itemLib[tmpKey]._tpl} with id: ${idForItemToAdd} to inventory`); this.logger.debug(`Added ${itemsToAddPool[arrayIndex]._tpl} with id: ${idForItemToAdd} to inventory`);
} }
toDo.push([itemLib[tmpKey]._id, idForItemToAdd]); // Add mapping of child item to new id
originalKeyToNewKeyMap.push([itemsToAddPool[arrayIndex]._id, idForItemToAdd]);
} }
toDo.splice(0, 1); // Remove mapping now we're done with it
originalKeyToNewKeyMap.splice(0, 1);
} }
} }
@ -536,7 +556,7 @@ export class InventoryHelper
protected splitStackIntoSmallerStacks(assortItems: Item[], requestItem: AddItem, result: IAddItemTempObject[]): void protected splitStackIntoSmallerStacks(assortItems: Item[], requestItem: AddItem, result: IAddItemTempObject[]): void
{ {
for (const item of assortItems) for (const item of assortItems)
{ {// Iterated item matches root item
if (item._id === requestItem.item_id) if (item._id === requestItem.item_id)
{ {
// Get item details from db // Get item details from db
@ -544,7 +564,7 @@ export class InventoryHelper
const itemToAdd: IAddItemTempObject = { const itemToAdd: IAddItemTempObject = {
itemRef: item, itemRef: item,
count: requestItem.count, count: requestItem.count,
isPreset: requestItem.isPreset, isPreset: !!requestItem.isPreset,
}; };
// Split stacks if the size is higher than allowed by items StackMaxSize property // Split stacks if the size is higher than allowed by items StackMaxSize property
@ -566,19 +586,19 @@ export class InventoryHelper
// Keep splitting items into stacks until none left // Keep splitting items into stacks until none left
if (remainingCountOfItemToAdd > 0) if (remainingCountOfItemToAdd > 0)
{ {
const newItemToAdd = this.jsonUtil.clone(itemToAdd); const newChildItemToAdd = this.jsonUtil.clone(itemToAdd);
if (remainingCountOfItemToAdd > itemDetails._props.StackMaxSize) if (remainingCountOfItemToAdd > itemDetails._props.StackMaxSize)
{ {
// Reduce total count of item purchased by stack size we're going to add to inventory // Reduce total count of item purchased by stack size we're going to add to inventory
remainingCountOfItemToAdd -= itemDetails._props.StackMaxSize; remainingCountOfItemToAdd -= itemDetails._props.StackMaxSize;
newItemToAdd.count = itemDetails._props.StackMaxSize; newChildItemToAdd.count = itemDetails._props.StackMaxSize;
} }
else else
{ {
newItemToAdd.count = remainingCountOfItemToAdd; newChildItemToAdd.count = remainingCountOfItemToAdd;
} }
result.push(newItemToAdd); result.push(newChildItemToAdd);
} }
} }
} }