From c9e28e05bba906b943da6e6424f784cee1d45c91 Mon Sep 17 00:00:00 2001 From: Chomp Date: Wed, 21 May 2025 10:42:13 +0100 Subject: [PATCH] Moved in-game reward check even further up chain into `ApplyQuestReward()` Replaced magic strings with string consts inside `IngameTraders` collection Various comment improvements --- .../Helpers/QuestRewardHelper.cs | 63 ++++++++++++++----- .../Helpers/RewardHelper.cs | 49 +++------------ .../Services/CreateProfileService.cs | 2 +- 3 files changed, 56 insertions(+), 58 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Helpers/QuestRewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/QuestRewardHelper.cs index 6a5838fa..a6a6f9a4 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/QuestRewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/QuestRewardHelper.cs @@ -33,37 +33,61 @@ public class QuestRewardHelper( { protected QuestConfig _questConfig = _configServer.GetConfig(); - /** - * Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned - * @param profileData Player profile (scav or pmc) - * @param questId questId of quest to get rewards for - * @param state State of the quest to get rewards for - * @param sessionId Session id - * @param questResponse Response to send back to client - * @returns Array of reward objects - */ + /// + /// Value for in game reward traders to not duplicate quest rewards. + /// Value can be modified by modders by overriding this value with new traders. + /// Ensure to add Lightkeeper's ID (638f541a29ffd1183d187f57) and BTR Driver's ID (656f0f98d80a697f855d34b1) + /// + protected string[] InGameTraders = + [ + Traders.LIGHTHOUSEKEEPER, + Traders.BTR + ]; + + /// + /// Give player quest rewards - Skills/exp/trader standing/items/assort unlocks - Returns reward items player earned + /// SKIP quests completed in-game + /// + /// Player profile (scav or pmc) + /// questId of quest to get rewards for + /// State of the quest to get rewards for + /// Session id + /// Response to send back to client + /// Array of reward items player was given public IEnumerable ApplyQuestReward(PmcData profileData, string questId, QuestStatusEnum state, string sessionId, ItemEventRouterResponse questResponse) { // Repeatable quest base data is always in PMCProfile, `profileData` may be scav profile - // TODO: consider moving repeatable quest data to profile-agnostic location + // TODO: Move repeatable quest data to profile-agnostic location var fullProfile = _profileHelper.GetFullProfile(sessionId); var pmcProfile = fullProfile.CharacterData.PmcData; if (pmcProfile is null) { _logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given"); - return Enumerable.Empty(); + + return []; } var questDetails = GetQuestFromDb(questId, pmcProfile); if (questDetails is null) { _logger.Warning(_localisationService.GetText("quest-unable_to_find_quest_in_db_no_quest_rewards", questId)); - return Enumerable.Empty(); + + return []; + } + + if (IsInGameTrader(questDetails)) + { + // Assuming in-game traders give ALL rewards + _logger.Debug( + $"Skipping quest rewards for quest: {questDetails.Id}, trader: {questDetails.TraderId} in InGameRewardTrader list" + ); + + return []; } var questMoneyRewardBonusMultiplier = GetQuestMoneyRewardBonusMultiplier(pmcProfile); - if (questMoneyRewardBonusMultiplier > 0) // money = money + (money * intelCenterBonus / 100) + if (questMoneyRewardBonusMultiplier > 0) // money = money + (money * IntelCenterBonus / 100) { questDetails = ApplyMoneyBoost(questDetails, questMoneyRewardBonusMultiplier, state); } @@ -76,11 +100,20 @@ public class QuestRewardHelper( fullProfile, profileData, questId, - questResponse, - questDetails + questResponse ); } + /// + /// Determines if quest rewards are given in raid by the trader instead of through messaging system. + /// + /// The quest to check. + /// True if the quest's trader is in the in-game reward trader list; otherwise, false. + protected bool IsInGameTrader(Quest quest) + { + return InGameTraders.Contains(quest.TraderId); + } + /// /// Get quest by id from database (repeatable quests are stored in profile, check there if questId not found) /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs index e298e46a..c67c1e4c 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RewardHelper.cs @@ -37,7 +37,6 @@ public class RewardHelper( /// The profile data (could be the scav profile). /// The quest or achievement ID, used for finding production unlocks. /// Response to quest completion when a production is unlocked. - /// The quest that the reward is for. /// List of items that is the reward. public List ApplyRewards( List rewards, @@ -45,29 +44,20 @@ public class RewardHelper( SptProfile fullProfile, PmcData profileData, string rewardSourceId, - ItemEventRouterResponse? questResponse = null, - Quest? quest = null + ItemEventRouterResponse? questResponse = null ) { var sessionId = fullProfile?.ProfileInfo?.ProfileId; - var pmcProfile = fullProfile?.CharacterData.PmcData; + var pmcProfile = fullProfile?.CharacterData?.PmcData; if (pmcProfile is null) { - _logger.Error($"Unable to get pmc profile for: {sessionId}, no rewards given"); + _logger.Error($"Unable to get PMC profile for: {sessionId}, no rewards given"); + return []; } var gameVersion = pmcProfile.Info.GameVersion; - var isInGameRewardTrader = quest != null && IsInGameRewardTrader(quest); - if (isInGameRewardTrader) - { - _logger.Debug( - $"Skipping quest rewards for quest {quest.Id} as it is in the InGameRewardrTader list" - ); - return []; - } - foreach (var reward in rewards) { // Handle reward availability for different game versions, notAvailableInGameEditions currently not used @@ -142,30 +132,7 @@ public class RewardHelper( } } - return GetRewardItems(rewards, gameVersion, quest); - } - - /// - /// Value for in game reward traders to not duplicate quest rewards. - /// Value can be modified by modders by overriding this value with new traders. - /// Ensure to add Lightkeeper's ID (638f541a29ffd1183d187f57) and BTR Driver's ID (656f0f98d80a697f855d34b1) - /// - protected string[] noRewardTraders = - [ - // LightKeeper - "638f541a29ffd1183d187f57", - // BTR Driver - "656f0f98d80a697f855d34b1", - ]; - - /// - /// Determines if quest rewards are given in raid by the trader instead of through messaging system. - /// - /// The quest to check. - /// True if the quest's trader is in the in-game reward trader list; otherwise, false. - protected bool IsInGameRewardTrader(Quest quest) - { - return noRewardTraders.Contains(quest.TraderId); + return GetRewardItems(rewards, gameVersion); } /// @@ -285,12 +252,10 @@ public class RewardHelper( /// /// Array of rewards to get the items from. /// The game version of the profile. - /// The quest (optional). /// Array of items with the correct maxStack. protected List GetRewardItems( List rewards, - string gameVersion, - Quest? quest = null + string gameVersion ) { // Iterate over all rewards with the desired status, flatten out items that have a type of Item @@ -310,7 +275,7 @@ public class RewardHelper( /// Fixed rewards. protected List ProcessReward(Reward reward) { - /** item with mods to return */ + // item with mods to return List rewardItems = []; List targets = []; List mods = []; diff --git a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs index 875b00b0..ffd3279c 100644 --- a/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/CreateProfileService.cs @@ -135,7 +135,7 @@ public class CreateProfileService( var achievementsDb = _databaseService.GetTemplates().Achievements; var achievementRewardItemsToSend = new List(); - foreach (var (achievementId, achievement) in profileDetails.CharacterData.PmcData.Achievements) + foreach (var (achievementId, _) in profileDetails.CharacterData.PmcData.Achievements) { var rewards = achievementsDb.FirstOrDefault(achievementDb => achievementDb.Id == achievementId)?.Rewards;