Converted FindAndReturnChildrenAsItems into extension method
This commit is contained in:
@@ -407,13 +407,12 @@ public class InsuranceController(
|
||||
if (itemRoll ?? false)
|
||||
{
|
||||
// Check to see if this item is a parent in the parentAttachmentsMap. If so, do a look-up for *all* of
|
||||
// its children and mark them for deletion as well. Additionally remove the parent (and its children)
|
||||
// its children and mark them for deletion as well. Also remove parent (and its children)
|
||||
// from the parentAttachmentsMap so that it's children are not rolled for later in the process.
|
||||
if (parentAttachmentsMap.ContainsKey(insuredItem.Id))
|
||||
{
|
||||
// This call will also return the parent item itself, queueing it for deletion as well.
|
||||
var itemAndChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
insured.Items,
|
||||
var itemAndChildren = insured.Items.FindAndReturnChildrenAsItems(
|
||||
insuredItem.Id
|
||||
);
|
||||
foreach (var item in itemAndChildren)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Generators;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
@@ -310,8 +311,7 @@ public class ProfileController(
|
||||
foreach (var rootItems in hideoutRootItems)
|
||||
{
|
||||
// Check each root items for children and add
|
||||
var itemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
profileToViewPmc.Inventory.Items,
|
||||
var itemWithChildren = profileToViewPmc.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
rootItems.Id
|
||||
);
|
||||
itemsToReturn.AddRange(itemWithChildren);
|
||||
|
||||
@@ -335,8 +335,7 @@ public class QuestController(
|
||||
// element `location` properties of the parent so they are sequential, while retaining order
|
||||
if (removedItem.Location?.GetType() == typeof(int))
|
||||
{
|
||||
var childItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
var childItems = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
removedItem.ParentId
|
||||
);
|
||||
childItems.RemoveAt(0); // Remove the parent
|
||||
|
||||
@@ -649,8 +649,7 @@ public class RagfairController
|
||||
|
||||
// multi-offers are all the same item,
|
||||
// Get first item and its children and use as template
|
||||
var inventoryItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
var inventoryItems = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
firstOfferItemId // Choose first item as they're all the same item
|
||||
);
|
||||
|
||||
@@ -766,9 +765,8 @@ public class RagfairController
|
||||
|
||||
// multi-offers are all the same item,
|
||||
// Get first item and its children and use as template
|
||||
var firstInventoryItemAndChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
offerRequest.Items[0]
|
||||
var firstInventoryItemAndChildren = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
offerRequest.Items.FirstOrDefault()
|
||||
);
|
||||
|
||||
// Find items to be listed on flea (+ children) from player inventory
|
||||
@@ -1147,9 +1145,7 @@ public class RagfairController
|
||||
|
||||
rootItem.FixItemStackCount();
|
||||
|
||||
itemsToReturn.Add(
|
||||
_itemHelper.FindAndReturnChildrenAsItems(pmcData.Inventory.Items, itemId)
|
||||
);
|
||||
itemsToReturn.Add(pmcData.Inventory.Items.FindAndReturnChildrenAsItems(itemId));
|
||||
}
|
||||
|
||||
if (itemsToReturn?.Count == 0)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
@@ -367,7 +368,7 @@ public class TradeController(
|
||||
TraderBase traderDetails
|
||||
)
|
||||
{
|
||||
var itemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(items, parentItemId);
|
||||
var itemWithChildren = items.FindAndReturnChildrenAsItems(parentItemId);
|
||||
|
||||
var totalPrice = 0;
|
||||
foreach (var itemToSell in itemWithChildren)
|
||||
|
||||
@@ -276,5 +276,52 @@ namespace SPTarkov.Server.Core.Extensions
|
||||
// Ensure item has 'StackObjectsCount' property
|
||||
item.Upd.StackObjectsCount ??= 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A variant of FindAndReturnChildren where the output is list of item objects instead of their ids.
|
||||
/// </summary>
|
||||
/// <param name="items">List of items (item + possible children)</param>
|
||||
/// <param name="baseItemId">Parent item's id</param>
|
||||
/// <param name="modsOnly">OPTIONAL - Include only mod items, exclude items stored inside root item</param>
|
||||
/// <returns>list of Item objects</returns>
|
||||
public static List<Item> FindAndReturnChildrenAsItems(
|
||||
this IEnumerable<Item> items,
|
||||
string baseItemId,
|
||||
bool modsOnly = false
|
||||
)
|
||||
{
|
||||
// Use dictionary to make key lookup faster, convert to list before being returned
|
||||
OrderedDictionary<string, Item> result = [];
|
||||
foreach (var childItem in items)
|
||||
{
|
||||
// Include itself
|
||||
if (string.Equals(childItem.Id, baseItemId, StringComparison.Ordinal))
|
||||
{
|
||||
// Root item MUST be at 0 index for things like flea market offers
|
||||
result.Insert(0, childItem.Id, childItem);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is stored in parent and disallowed
|
||||
if (modsOnly && childItem.Location is not null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Items parentId matches root item AND returned items doesn't contain current child
|
||||
if (
|
||||
!result.ContainsKey(childItem.Id)
|
||||
&& string.Equals(childItem.ParentId, baseItemId, StringComparison.Ordinal)
|
||||
)
|
||||
{
|
||||
foreach (var item in FindAndReturnChildrenAsItems(items, childItem.Id))
|
||||
{
|
||||
result.Add(item.Id, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.Values.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
@@ -1145,7 +1146,7 @@ public class LocationLootGenerator(
|
||||
{
|
||||
// Also used by armors to get child mods
|
||||
// Get item + children and add into array we return
|
||||
var itemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(items, chosenItem.Id);
|
||||
var itemWithChildren = items.FindAndReturnChildrenAsItems(chosenItem.Id);
|
||||
|
||||
// Ensure all IDs are unique
|
||||
itemWithChildren = _itemHelper.ReplaceIDs(_cloner.Clone(itemWithChildren));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Frozen;
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Constants;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
using SPTarkov.Server.Core.Models.Enums;
|
||||
using SPTarkov.Server.Core.Models.Spt.Bots;
|
||||
@@ -800,10 +801,7 @@ public class BotGeneratorHelper(
|
||||
{
|
||||
// Check item in container for children, store for later insertion into `containerItemsToCheck`
|
||||
// (used later when figuring out how much space weapon takes up)
|
||||
var itemWithChildItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
itemsWithoutLocation,
|
||||
rootItem.Id
|
||||
);
|
||||
var itemWithChildItems = itemsWithoutLocation.FindAndReturnChildrenAsItems(rootItem.Id);
|
||||
|
||||
// Item had children, replace existing data with item + its children
|
||||
result.Add(rootItem);
|
||||
|
||||
@@ -75,14 +75,12 @@ public class InRaidHelper(
|
||||
);
|
||||
|
||||
// Get all items that have a parent of `serverProfile.Inventory.equipment` (All items player had on them at end of raid)
|
||||
var postRaidInventoryItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
postRaidProfile.Inventory.Items,
|
||||
var postRaidInventoryItems = postRaidProfile.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
postRaidProfile.Inventory.Equipment
|
||||
);
|
||||
|
||||
// Get all items that have a parent of `serverProfile.Inventory.questRaidItems` (Quest items player had on them at end of raid)
|
||||
var postRaidQuestItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
postRaidProfile.Inventory.Items,
|
||||
var postRaidQuestItems = postRaidProfile.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
postRaidProfile.Inventory.QuestRaidItems
|
||||
);
|
||||
|
||||
|
||||
@@ -508,10 +508,7 @@ public class InventoryHelper(
|
||||
}
|
||||
|
||||
// Get children of item, they get deleted too
|
||||
var itemAndChildrenToRemove = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
profile.Inventory.Items,
|
||||
itemId
|
||||
);
|
||||
var itemAndChildrenToRemove = profile.Inventory.Items.FindAndReturnChildrenAsItems(itemId);
|
||||
if (!itemAndChildrenToRemove.Any())
|
||||
{
|
||||
if (_logger.IsLogEnabled(LogLevel.Debug))
|
||||
@@ -591,11 +588,10 @@ public class InventoryHelper(
|
||||
if (messageWithReward is not null)
|
||||
{
|
||||
// Find item + any possible children and remove them from mails items array
|
||||
var itemWithChildern = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
messageWithReward.Items.Data,
|
||||
var itemWithChildren = messageWithReward.Items.Data.FindAndReturnChildrenAsItems(
|
||||
removeRequest.Item
|
||||
);
|
||||
foreach (var itemToDelete in itemWithChildern)
|
||||
foreach (var itemToDelete in itemWithChildren)
|
||||
{
|
||||
// Get index of item to remove from reward array + remove it
|
||||
var indexOfItemToRemove = messageWithReward.Items.Data.IndexOf(itemToDelete);
|
||||
@@ -649,10 +645,7 @@ public class InventoryHelper(
|
||||
}
|
||||
|
||||
// Goal is to keep removing items until we can remove part of an items stack
|
||||
var itemsToReduce = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
itemId
|
||||
);
|
||||
var itemsToReduce = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(itemId);
|
||||
var remainingCount = countToRemove;
|
||||
foreach (var itemToReduce in itemsToReduce)
|
||||
{
|
||||
|
||||
@@ -712,53 +712,6 @@ public class ItemHelper(
|
||||
return Math.Sqrt(durability ?? 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A variant of FindAndReturnChildren where the output is list of item objects instead of their ids.
|
||||
/// </summary>
|
||||
/// <param name="items">List of items (item + possible children)</param>
|
||||
/// <param name="baseItemId">Parent item's id</param>
|
||||
/// <param name="modsOnly">OPTIONAL - Include only mod items, exclude items stored inside root item</param>
|
||||
/// <returns>list of Item objects</returns>
|
||||
public List<Item> FindAndReturnChildrenAsItems(
|
||||
IEnumerable<Item> items,
|
||||
string baseItemId,
|
||||
bool modsOnly = false
|
||||
)
|
||||
{
|
||||
// Use dictionary to make key lookup faster, convert to list before being returned
|
||||
OrderedDictionary<string, Item> result = [];
|
||||
foreach (var childItem in items)
|
||||
{
|
||||
// Include itself
|
||||
if (string.Equals(childItem.Id, baseItemId, StringComparison.Ordinal))
|
||||
{
|
||||
// Root item MUST be at 0 index for things like flea market offers
|
||||
result.Insert(0, childItem.Id, childItem);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Is stored in parent and disallowed
|
||||
if (modsOnly && childItem.Location is not null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Items parentId matches root item AND returned items doesn't contain current child
|
||||
if (
|
||||
!result.ContainsKey(childItem.Id)
|
||||
&& string.Equals(childItem.ParentId, baseItemId, StringComparison.Ordinal)
|
||||
)
|
||||
{
|
||||
foreach (var item in FindAndReturnChildrenAsItems(items, childItem.Id))
|
||||
{
|
||||
result.Add(item.Id, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find children of the item in a given assort (weapons parts for example, need recursive loop function)
|
||||
/// </summary>
|
||||
@@ -1402,7 +1355,7 @@ public class ItemHelper(
|
||||
var forcedLeft = 0;
|
||||
var forcedRight = 0;
|
||||
|
||||
var children = FindAndReturnChildrenAsItems(items, rootItemId);
|
||||
var children = items.FindAndReturnChildrenAsItems(rootItemId);
|
||||
foreach (var ci in children)
|
||||
{
|
||||
var itemTemplate = GetItem(ci.Template).Value;
|
||||
|
||||
@@ -678,10 +678,7 @@ public class ProfileHelper(
|
||||
foreach (var itemId in profile.Inventory?.FavoriteItems ?? [])
|
||||
{
|
||||
// When viewing another users profile, the client expects a full item with children, so get that
|
||||
var itemAndChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
profile.Inventory.Items,
|
||||
itemId
|
||||
);
|
||||
var itemAndChildren = profile.Inventory.Items.FindAndReturnChildrenAsItems(itemId);
|
||||
if (itemAndChildren?.Count > 0)
|
||||
{
|
||||
// To get the client to actually see the items, we set the main item's parent to null, so it's treated as a root item
|
||||
|
||||
@@ -152,10 +152,7 @@ public class TradeHelper(
|
||||
return;
|
||||
}
|
||||
|
||||
offerItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
fenceItems,
|
||||
buyRequestData.ItemId
|
||||
);
|
||||
offerItems = fenceItems.FindAndReturnChildrenAsItems(buyRequestData.ItemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -223,10 +220,7 @@ public class TradeHelper(
|
||||
.Items;
|
||||
|
||||
// Get item + children for purchase
|
||||
var relevantItems = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
traderItems,
|
||||
buyRequestData.ItemId
|
||||
);
|
||||
var relevantItems = traderItems.FindAndReturnChildrenAsItems(buyRequestData.ItemId);
|
||||
if (relevantItems.Count == 0)
|
||||
{
|
||||
_logger.Error(
|
||||
|
||||
@@ -332,8 +332,7 @@ public class CircleOfCultistService(
|
||||
List<Item> sacrificedItems = [];
|
||||
foreach (var rootItem in inventoryRootItemsInCultistGrid)
|
||||
{
|
||||
var rootItemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
var rootItemWithChildren = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(
|
||||
rootItem.Id
|
||||
);
|
||||
sacrificedItems.AddRange(rootItemWithChildren);
|
||||
|
||||
@@ -145,9 +145,7 @@ public class FenceService(
|
||||
{
|
||||
// HUGE THANKS TO LACYWAY AND LEAVES FOR PROVIDING THIS SOLUTION FOR SPT TO IMPLEMENT!!
|
||||
// Copy the item and its children
|
||||
var clonedItems = _cloner.Clone(
|
||||
itemHelper.FindAndReturnChildrenAsItems(items, mainItem.Id)
|
||||
);
|
||||
var clonedItems = _cloner.Clone(items.FindAndReturnChildrenAsItems(mainItem.Id));
|
||||
// I BLAME LACY FOR THIS ISSUE, I SPENT HOURS FIXING IT /s
|
||||
// i think on node the one with hideout usually came first
|
||||
var root = clonedItems.FirstOrDefault(x => x.SlotId == "hideout");
|
||||
@@ -423,8 +421,7 @@ public class FenceService(
|
||||
// Check if same type of item exists + its on list of item types to always stack
|
||||
if (existingRootItem != null && ItemInPreventDupeCategoryList(newRootItem.Template))
|
||||
{
|
||||
var existingFullItemTree = itemHelper.FindAndReturnChildrenAsItems(
|
||||
existingFenceAssorts.Items,
|
||||
var existingFullItemTree = existingFenceAssorts.Items.FindAndReturnChildrenAsItems(
|
||||
existingRootItem.Id
|
||||
);
|
||||
if (
|
||||
@@ -580,10 +577,7 @@ public class FenceService(
|
||||
}
|
||||
|
||||
// Remove item + child mods (if any)
|
||||
var itemWithChildren = itemHelper.FindAndReturnChildrenAsItems(
|
||||
assort.Items,
|
||||
rootItemToAdjust.Id
|
||||
);
|
||||
var itemWithChildren = assort.Items.FindAndReturnChildrenAsItems(rootItemToAdjust.Id);
|
||||
foreach (var itemToDelete in itemWithChildren)
|
||||
// Delete item from assort items array
|
||||
{
|
||||
@@ -824,10 +818,7 @@ public class FenceService(
|
||||
.ToList();
|
||||
|
||||
var desiredAssortItemAndChildrenClone = _cloner.Clone(
|
||||
itemHelper.FindAndReturnChildrenAsItems(
|
||||
childItemsAndSingleRoot,
|
||||
chosenBaseAssortRoot.Id
|
||||
)
|
||||
childItemsAndSingleRoot.FindAndReturnChildrenAsItems(chosenBaseAssortRoot.Id)
|
||||
);
|
||||
|
||||
var itemDbDetails = itemHelper.GetItem(chosenBaseAssortRoot.Template).Value;
|
||||
@@ -1121,10 +1112,7 @@ public class FenceService(
|
||||
var rootItemDb = itemHelper.GetItem(randomPresetRoot.Template).Value;
|
||||
|
||||
var presetWithChildrenClone = _cloner.Clone(
|
||||
itemHelper.FindAndReturnChildrenAsItems(
|
||||
baseFenceAssort.Items,
|
||||
randomPresetRoot.Id
|
||||
)
|
||||
baseFenceAssort.Items.FindAndReturnChildrenAsItems(randomPresetRoot.Id)
|
||||
);
|
||||
|
||||
RandomiseItemUpdProperties(rootItemDb, presetWithChildrenClone[0]);
|
||||
@@ -1204,7 +1192,7 @@ public class FenceService(
|
||||
var rootItemDb = itemHelper.GetItem(randomPresetRoot.Template).Value;
|
||||
|
||||
var presetWithChildrenClone = _cloner.Clone(
|
||||
itemHelper.FindAndReturnChildrenAsItems(baseFenceAssort.Items, randomPresetRoot.Id)
|
||||
baseFenceAssort.Items.FindAndReturnChildrenAsItems(randomPresetRoot.Id)
|
||||
);
|
||||
|
||||
// Need to add mods to armors so they don't show as red in the trade screen
|
||||
@@ -1799,7 +1787,7 @@ public class FenceService(
|
||||
protected void DeleteOffer(string assortId, List<Item> assorts)
|
||||
{
|
||||
// Assort could have child items, remove those too
|
||||
var itemWithChildrenToRemove = itemHelper.FindAndReturnChildrenAsItems(assorts, assortId);
|
||||
var itemWithChildrenToRemove = assorts.FindAndReturnChildrenAsItems(assortId);
|
||||
foreach (var itemToRemove in itemWithChildrenToRemove)
|
||||
{
|
||||
var indexToRemove = assorts.FindIndex(item => item.Id == itemToRemove.Id);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using SPTarkov.DI.Annotations;
|
||||
using SPTarkov.Server.Core.Extensions;
|
||||
using SPTarkov.Server.Core.Helpers;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common;
|
||||
using SPTarkov.Server.Core.Models.Eft.Common.Tables;
|
||||
@@ -168,10 +169,7 @@ public class RagfairTaxService(
|
||||
if (isRootItem)
|
||||
{
|
||||
// Since we get a flat list of all child items, we only want to recurse from parent item
|
||||
var itemChildren = _itemHelper.FindAndReturnChildrenAsItems(
|
||||
pmcData.Inventory.Items,
|
||||
item.Id
|
||||
);
|
||||
var itemChildren = pmcData.Inventory.Items.FindAndReturnChildrenAsItems(item.Id);
|
||||
if (itemChildren.Count > 1)
|
||||
{
|
||||
var itemChildrenClone = _cloner.Clone(itemChildren); // Clone is expensive, only run if necessary
|
||||
|
||||
Reference in New Issue
Block a user