diff --git a/Libraries/Core/Generators/RepeatableQuestGenerator.cs b/Libraries/Core/Generators/RepeatableQuestGenerator.cs index 43da0cd1..f163e9fe 100644 --- a/Libraries/Core/Generators/RepeatableQuestGenerator.cs +++ b/Libraries/Core/Generators/RepeatableQuestGenerator.cs @@ -148,13 +148,13 @@ public class RepeatableQuestGenerator( var targetKey = targetsConfig.Draw()[0]; var targetDifficulty = 1 / targetsConfig.Probability(targetKey); - var locations = questTypePool.Pool.Elimination.Targets.GetByJsonProp(targetKey).Locations; + questTypePool.Pool.Elimination.Targets.TryGetValue(targetKey, out var targetLocationPool); + var locations = targetLocationPool.Locations; // we use any as location if "any" is in the pool and we do not hit the specific location random // we use any also if the random condition is not met in case only "any" was in the pool var locationKey = "any"; - if (locations.Contains("any") && - (eliminationConfig.SpecificLocationProbability < rand.Next() || locations.Count <= 1) + if (locations.Contains("any") && (eliminationConfig.SpecificLocationProbability < rand.Next() || locations.Count <= 1) ) { locationKey = "any"; @@ -634,6 +634,7 @@ public class RepeatableQuestGenerator( /// object of "Completion"-condition protected QuestCondition GenerateCompletionAvailableForFinish(string itemTpl, double value) { + _logger.Error("NOT IMPLEMENTED - GenerateCompletionAvailableForFinish"); throw new NotImplementedException(); } diff --git a/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs b/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs index b3f764e3..f31b76c4 100644 --- a/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs +++ b/Libraries/Core/Generators/RepeatableQuestRewardGenerator.cs @@ -1,7 +1,6 @@ using SptCommon.Annotations; using Core.Helpers; using Core.Models.Eft.Common.Tables; -using Core.Models.Eft.Player; using Core.Models.Enums; using Core.Models.Spt.Config; using Core.Models.Spt.Repeatable; @@ -10,7 +9,8 @@ using Core.Servers; using Core.Services; using Core.Utils; using Core.Utils.Cloners; -using System.Linq; +using Core.Models.Eft.Common; +using Core.Models.Spt.Server; namespace Core.Generators; @@ -110,7 +110,7 @@ public class RepeatableQuestRewardGenerator( if (traderWhitelistDetails?.RewardCanBeWeapon ?? false && _randomUtil.GetChance100(traderWhitelistDetails.WeaponRewardChancePercent ?? 0) ) { - var chosenWeapon = GetRandomWeaponPresetWithinBudget(itemRewardBudget, rewardIndex); + var chosenWeapon = GetRandomWeaponPresetWithinBudget(itemRewardBudget.Value, rewardIndex); if (chosenWeapon is not null) { rewards.Success.Add(chosenWeapon.Value.Key); @@ -319,9 +319,81 @@ public class RepeatableQuestRewardGenerator( }).ToList(); } - private KeyValuePair? GetRandomWeaponPresetWithinBudget(double? itemRewardBudget, double rewardIndex) + private KeyValuePair? GetRandomWeaponPresetWithinBudget(double roublesBudget, int rewardIndex) { - throw new NotImplementedException(); + // Add a random default preset weapon as reward + var defaultPresetPool = new ExhaustableArray( + _presetHelper.GetDefaultWeaponPresets().Values.ToList(), + _randomUtil, + _cloner); + + while (defaultPresetPool.HasValues()) + { + var randomPreset = defaultPresetPool.GetRandomValue(); + if (randomPreset is null) + { + continue; + } + + // Gather all tpls so we can get prices of them + var tpls = randomPreset.Items.Select((item) => item.Template).ToList(); + + // Does preset items fit our budget + var presetPrice = _itemHelper.GetItemAndChildrenPrice(tpls); + if (presetPrice <= roublesBudget) + { + _logger.Debug("Added weapon: ${ tpls[0]}with price: ${ presetPrice}"); + var chosenPreset = _cloner.Clone(randomPreset); + + return new KeyValuePair(GeneratePresetReward(chosenPreset.Encyclopedia, 1, rewardIndex, chosenPreset.Items), presetPrice); + } + } + + return null; + } + + /** + * Helper to create a reward item structured as required by the client + * + * @param {string} tpl ItemId of the rewarded item + * @param {integer} count Amount of items to give + * @param {integer} index All rewards will be appended to a list, for unknown reasons the client wants the index + * @param preset Optional array of preset items + * @returns {object} Object of "Reward"-item-type + */ + protected Reward GeneratePresetReward(string tpl, int count, int index, List? preset, bool foundInRaid = true) + { + var id = _hashUtil.Generate(); + var questRewardItem = new Reward{ + Id = _hashUtil.Generate(), + Unknown = false, + GameMode =[], + AvailableInGameEditions =[], + Index = index, + Target =id, + Value = count, + IsEncoded = false, + FindInRaid =foundInRaid, + Type =RewardType.Item, + Items =[], + }; + + // Get presets root item + var rootItem = preset.FirstOrDefault((item) => item.Template == tpl); + if (rootItem is null) + { + _logger.Warning($"Root item of preset: ${ tpl} not found"); + } + + if (rootItem.Upd is not null) + { + rootItem.Upd.SpawnedInSession = foundInRaid; + } + + questRewardItem.Items = _itemHelper.ReparentItemAndChildren(rootItem, preset); + questRewardItem.Target = rootItem.Id; // Target property and root items id must match + + return questRewardItem; } private Reward GenerateItemReward(string tpl, double count, int index, bool foundInRaid = true) diff --git a/Libraries/Core/Helpers/ItemHelper.cs b/Libraries/Core/Helpers/ItemHelper.cs index 57bb05d6..fcce0289 100644 --- a/Libraries/Core/Helpers/ItemHelper.cs +++ b/Libraries/Core/Helpers/ItemHelper.cs @@ -376,7 +376,7 @@ public class ItemHelper( public double GetItemAndChildrenPrice(List tpls) { // Run getItemPrice for each tpl in tpls array, return sum - return tpls.Aggregate(0, (total, tpl) => total + (int)GetItemPrice(tpl)); + return tpls.Aggregate(0, (total, tpl) => total + (int)GetItemPrice(tpl).GetValueOrDefault(0)); } /// @@ -762,7 +762,11 @@ public class ItemHelper( ItemTpl.BARTER_DOGTAG_BEAR_TUE, ItemTpl.BARTER_DOGTAG_USEC, ItemTpl.BARTER_DOGTAG_USEC_EOD, - ItemTpl.BARTER_DOGTAG_USEC_TUE + ItemTpl.BARTER_DOGTAG_USEC_TUE, + ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_1, + ItemTpl.BARTER_DOGTAG_BEAR_PRESTIGE_2, + ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_1, + ItemTpl.BARTER_DOGTAG_USEC_PRESTIGE_2 ]; return dogTagTpls.Contains(tpl);