From 85a562d1e5f2958dbc7e5541b7dc0d5587869085 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 6 Aug 2025 12:27:50 +0100 Subject: [PATCH] Improved `GetRewardProductionMatch` logic to make use of saved `QuestId` property we generate for crafts --- .../Helpers/RewardHelper.cs | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs index b60511ec..afd7d427 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs @@ -223,22 +223,12 @@ public class RewardHelper( /// List of matching HideoutProduction objects. public List GetRewardProductionMatch(Reward craftUnlockReward, MongoId questId) { - // Get hideout crafts and find those that match by areatype/required level/end product tpl - hope for just one match - var craftingRecipes = databaseService.GetHideout().Production.Recipes; + // Get hideout crafts and find those that match by areaType/required level/end product tpl - hope for just one match - // Area that will be used to craft unlocked item + // "TraderId" holds area ID that will be used to craft unlocked item var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString()); - var matchingProductions = craftingRecipes - .Where(prod => - prod.AreaType == desiredHideoutAreaType - && - //prod.requirements.some((requirement) => requirement.questId == questId) && // BSG don't store the quest id in requirement any more! - prod.Requirements.Any(requirement => requirement.Type == "QuestComplete") - && prod.Requirements.Any(requirement => requirement.RequiredLevel == craftUnlockReward.LoyaltyLevel) - && prod.EndProduct == craftUnlockReward.Items.FirstOrDefault().Template - ) - .ToList(); + var matchingProductions = GetMatchingProductions(desiredHideoutAreaType, questId, craftUnlockReward); // More/less than single match, above filtering wasn't strict enough if (matchingProductions.Count != 1) @@ -252,6 +242,47 @@ public class RewardHelper( return matchingProductions; } + /// + /// Find a hideout craft (production) based on input parameter data + /// + /// Hideout area craft is for + /// Id of quest with production unlock + /// Reward given by quest + /// Hideout crafts that match input parameters + protected List GetMatchingProductions(HideoutAreas desiredHideoutAreaType, MongoId questId, Reward craftUnlockReward) + { + var craftingRecipes = databaseService.GetHideout().Production.Recipes; + + // Some crafts have the quest id stored in their requirements, check for that first + var matchingCraft = craftingRecipes.FirstOrDefault(craft => craft.Requirements.Any(requirement => requirement.QuestId == questId)); + if (matchingCraft is not null) + { + return [matchingCraft]; + } + + var rewardItemTpl = craftUnlockReward.Items.FirstOrDefault()?.Template; + if (rewardItemTpl is null) + { + return []; + } + + return craftingRecipes + .Where(production => + // Primary condition: A requirement explicitly references the quest ID. + production.Requirements.Any(req => req.QuestId == questId) + || + // Fallback condition: Infer the match from reward and area details. + // This part only runs if the primary condition is false and a reward item exists. + ( + production.AreaType == desiredHideoutAreaType + && production.EndProduct == rewardItemTpl.Value + && production.Requirements.Any(req => req.Type is "QuestComplete") + && production.Requirements.Any(req => req.RequiredLevel == craftUnlockReward.LoyaltyLevel) + ) + ) + .ToList(); + } + /// /// Gets a flat list of reward items from the given rewards for the specified game version. ///