From e1fb90644a082033dd4e45f373da9ff40d36b0ba Mon Sep 17 00:00:00 2001 From: Chomp Date: Fri, 14 Nov 2025 16:41:29 +0000 Subject: [PATCH] Optimised `PrioritiseStashSort` to reduce iterating over list, reduces time taken to purchase items when player has a LOT of money stacks in stash --- .../Services/PaymentService.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs b/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs index f45cefa9..29633cef 100644 --- a/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs @@ -370,8 +370,9 @@ public class PaymentService( moneyItemsInInventory = noLocked.ToList(); } - // Prioritise items in stash to top of array - moneyItemsInInventory.Sort((a, b) => PrioritiseStashSort(a, b, pmcData.Inventory.Items, itemsInStashCache)); + // Sort money stacks to prioritise items in stash and not in secure to top of array + var inventoryParent = pmcData.Inventory.Items.ToDictionary(item => item.Id.ToString(), item => item.Template); + moneyItemsInInventory.Sort((a, b) => PrioritiseStashSort(a, b, inventoryParent, itemsInStashCache)); return moneyItemsInInventory; } @@ -401,13 +402,13 @@ public class PaymentService( /// /// First money stack item /// Second money stack item - /// Players inventory items + /// item id (as string) and template id KvP /// Cache of item IDs and if they're in stash /// Sort order, -1 if A has priority, 1 if B has priority, 0 if they match protected int PrioritiseStashSort( Item a, Item b, - List inventoryItems, + Dictionary itemIdToTplCache, IReadOnlyDictionary itemInStashCache ) { @@ -441,11 +442,14 @@ public class PaymentService( if (aInContainer && bInContainer) { // Containers where taking money from would inconvenience player - var aImmediateParent = inventoryItems.FirstOrDefault(item => item.Id == a.ParentId); - var bImmediateParent = inventoryItems.FirstOrDefault(item => item.Id == b.ParentId); - var aInDeprioContainer = InventoryConfig.DeprioritisedMoneyContainers.Contains(aImmediateParent.Template); - var bInDeprioContainer = InventoryConfig.DeprioritisedMoneyContainers.Contains(bImmediateParent.Template); + // Get template Id of items' parent so we can see if items in a container we want to de prioritise + var aImmediateParentTemplate = itemIdToTplCache.FirstOrDefault(item => string.Equals(item.Key, a.ParentId, StringComparison.OrdinalIgnoreCase)); + var bImmediateParentTemplate = itemIdToTplCache.FirstOrDefault(item => string.Equals(item.Key, b.ParentId, StringComparison.OrdinalIgnoreCase)); + + // e.g. secure container + var aInDeprioContainer = InventoryConfig.DeprioritisedMoneyContainers.Contains(aImmediateParentTemplate.Value); + var bInDeprioContainer = InventoryConfig.DeprioritisedMoneyContainers.Contains(bImmediateParentTemplate.Value); // Prioritize B if (!aInDeprioContainer && bInDeprioContainer)