From db0feff1d8ba0455bf39918fbad4ba12a9b74e80 Mon Sep 17 00:00:00 2001 From: Chomp Date: Tue, 4 Feb 2025 19:38:59 +0000 Subject: [PATCH] Made `ProbabilityObjectArray` slightly less awful --- .../Core/Controllers/InsuranceController.cs | 2 +- .../Controllers/RepeatableQuestController.cs | 8 ++--- .../Core/Generators/LocationLootGenerator.cs | 17 +++++----- .../Generators/RepeatableQuestGenerator.cs | 33 +++++++------------ Libraries/Core/Helpers/ItemHelper.cs | 2 +- .../Core/Helpers/RepeatableQuestHelper.cs | 15 +-------- .../Core/Models/Spt/Config/QuestConfig.cs | 22 +++---------- .../Collections/ProbabilityObjectArray.cs | 20 +++++------ 8 files changed, 43 insertions(+), 76 deletions(-) diff --git a/Libraries/Core/Controllers/InsuranceController.cs b/Libraries/Core/Controllers/InsuranceController.cs index cc939be7..439c6c25 100644 --- a/Libraries/Core/Controllers/InsuranceController.cs +++ b/Libraries/Core/Controllers/InsuranceController.cs @@ -471,7 +471,7 @@ public class InsuranceController( var countOfAttachmentsToRemove = GetAttachmentCountToRemove(weightedAttachmentByPrice, traderId); // Create prob array and add all attachments with rouble price as the weight - var attachmentsProbabilityArray = new ProbabilityObjectArray, string, double?>(_mathUtil, _cloner); + var attachmentsProbabilityArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var attachmentTpl in weightedAttachmentByPrice) { attachmentsProbabilityArray.Add( diff --git a/Libraries/Core/Controllers/RepeatableQuestController.cs b/Libraries/Core/Controllers/RepeatableQuestController.cs index dcf7d56e..6d3d04b8 100644 --- a/Libraries/Core/Controllers/RepeatableQuestController.cs +++ b/Libraries/Core/Controllers/RepeatableQuestController.cs @@ -15,6 +15,7 @@ using Core.Servers; using Core.Services; using Core.Utils; using Core.Utils.Cloners; +using Core.Utils.Collections; using SptCommon.Annotations; using LogLevel = Core.Models.Spt.Logging.LogLevel; @@ -24,7 +25,7 @@ namespace Core.Controllers; public class RepeatableQuestController( ISptLogger _logger, TimeUtil _timeUtil, - HashUtil _hashUtil, + MathUtil _mathUtil, RandomUtil _randomUtil, HttpResponseUtil _httpResponseUtil, ProfileHelper _profileHelper, @@ -571,15 +572,14 @@ public class RepeatableQuestController( questPool.Pool.Pickup.Locations[ELocationName.any] = ["any"]; var eliminationConfig = _repeatableQuestHelper.GetEliminationConfigByPmcLevel(pmcLevel.Value, repeatableConfig); - var targetsConfig = - _repeatableQuestHelper.ProbabilityObjectArray(eliminationConfig.Targets); + var targetsConfig = new ProbabilityObjectArray(_mathUtil, _cloner, eliminationConfig.Targets); // Populate Elimination quest targets and their locations foreach (var targetKvP in targetsConfig) // Target is boss if (targetKvP.Data.IsBoss.GetValueOrDefault(false)) { - questPool.Pool.Elimination.Targets[targetKvP.Key] = new TargetLocation { Locations = ["any"] }; + questPool.Pool.Elimination.Targets.Add(targetKvP.Key, new TargetLocation { Locations = ["any"] }); } else { diff --git a/Libraries/Core/Generators/LocationLootGenerator.cs b/Libraries/Core/Generators/LocationLootGenerator.cs index 508ad82d..a2f41d69 100644 --- a/Libraries/Core/Generators/LocationLootGenerator.cs +++ b/Libraries/Core/Generators/LocationLootGenerator.cs @@ -307,7 +307,7 @@ public class LocationLootGenerator( // Create probability array with all possible container ids in this group and their relative probability of spawning var containerDistribution = - new ProbabilityObjectArray, string, double>(_mathUtil, _cloner); + new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var x in containerIds) { var value = containerData.ContainerIdsWithProbability[x]; @@ -556,7 +556,7 @@ public class LocationLootGenerator( { // Create probability array to calcualte the total count of lootable items inside container var itemCountArray = - new ProbabilityObjectArray, int, float?>(_mathUtil, _cloner); + new ProbabilityObjectArray(_mathUtil, _cloner); var countDistribution = staticLootDist[containerTypeId]?.ItemCountDistribution; if (countDistribution is null) { @@ -593,14 +593,15 @@ public class LocationLootGenerator( /// Container to get possible loot for /// staticLoot.json /// ProbabilityObjectArray of item tpls + probabilty - protected ProbabilityObjectArray, string, float?> GetPossibleLootItemsForContainer(string containerTypeId, - Dictionary staticLootDist) // TODO: Type Fuckery, return type was ProbabilityObjectArray + protected ProbabilityObjectArray GetPossibleLootItemsForContainer( + string containerTypeId, + Dictionary staticLootDist) { var seasonalEventActive = _seasonalEventService.SeasonalEventEnabled(); var seasonalItemTplBlacklist = _seasonalEventService.GetInactiveSeasonalEventItems(); var itemDistribution = - new ProbabilityObjectArray, string, float?>(_mathUtil, _cloner); + new ProbabilityObjectArray(_mathUtil, _cloner); var itemContainerDistribution = staticLootDist[containerTypeId]?.ItemDistribution; if (itemContainerDistribution is null) @@ -689,7 +690,7 @@ public class LocationLootGenerator( List guaranteedLoosePoints = []; var blacklistedSpawnpoints = _locationConfig.LooseLootBlacklist.GetValueOrDefault(locationName); - var spawnpointArray = new ProbabilityObjectArray, string, Spawnpoint>(_mathUtil, _cloner, []); + var spawnpointArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var spawnpoint in allDynamicSpawnpoints) { @@ -805,7 +806,7 @@ public class LocationLootGenerator( var validItemIds = spawnPoint.Template.Items.Select((item) => item.Id).ToList(); // Construct container to hold above filtered items, letting us pick an item for the spot - var itemArray = new ProbabilityObjectArray, string, double?>(_mathUtil, _cloner, []); + var itemArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var itemDist in spawnPoint.ItemDistribution) { if (!validItemIds.Contains(itemDist.ComposedKey.Key)) @@ -875,7 +876,7 @@ public class LocationLootGenerator( } // Create probability array of all spawn positions for this spawn id - var spawnpointArray = new ProbabilityObjectArray, string, Spawnpoint>(_mathUtil, _cloner, []); + var spawnpointArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var si in items) { // use locationId as template.Id is the same across all items diff --git a/Libraries/Core/Generators/RepeatableQuestGenerator.cs b/Libraries/Core/Generators/RepeatableQuestGenerator.cs index 102c0d40..51f8991c 100644 --- a/Libraries/Core/Generators/RepeatableQuestGenerator.cs +++ b/Libraries/Core/Generators/RepeatableQuestGenerator.cs @@ -13,7 +13,6 @@ using Core.Utils.Collections; using Core.Utils.Json; using SptCommon.Annotations; using SptCommon.Extensions; -using BodyPart = Core.Models.Spt.Config.BodyPart; namespace Core.Generators; @@ -100,18 +99,10 @@ public class RepeatableQuestGenerator( var eliminationConfig = _repeatableQuestHelper.GetEliminationConfigByPmcLevel(pmcLevel, repeatableConfig); var locationsConfig = repeatableConfig.Locations; - var targetsConfig = - _repeatableQuestHelper.ProbabilityObjectArray(eliminationConfig.Targets); - var bodyPartsConfig = - _repeatableQuestHelper.ProbabilityObjectArray>(eliminationConfig.BodyParts); - var weaponCategoryRequirementConfig = - _repeatableQuestHelper.ProbabilityObjectArray>( - eliminationConfig.WeaponCategoryRequirements - ); - var weaponRequirementConfig = - _repeatableQuestHelper.ProbabilityObjectArray>( - eliminationConfig.WeaponRequirements - ); + var targetsConfig = new ProbabilityObjectArray(_mathUtil, _cloner, eliminationConfig.Targets); + var bodyPartsConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.BodyParts); + var weaponCategoryRequirementConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.WeaponCategoryRequirements); + var weaponRequirementConfig = new ProbabilityObjectArray>(_mathUtil, _cloner, eliminationConfig.WeaponRequirements); // the difficulty of the quest varies in difficulty depending on the condition // possible conditions are @@ -209,11 +200,11 @@ public class RepeatableQuestGenerator( bodyPartsToClient = []; var bodyParts = bodyPartsConfig.Draw(_randomUtil.RandInt(1, 3), false); double probability = 0; - foreach (var bi in bodyParts) + foreach (var bodyPart in bodyParts) { // more than one part lead to an "OR" condition hence more parts reduce the difficulty - probability += bodyPartsConfig.Probability(bi).Value; - foreach (var biClient in bodyPartsConfig.Data(bi)) bodyPartsToClient.Add(biClient); + probability += bodyPartsConfig.Probability(bodyPart).Value; + bodyPartsToClient.Add(bodyPart); } bodyPartDifficulty = 1 / probability; @@ -268,7 +259,7 @@ public class RepeatableQuestGenerator( { List weaponTypes = ["Shotgun", "Pistol"]; weaponCategoryRequirementConfig = - (ProbabilityObjectArray>)weaponCategoryRequirementConfig + (ProbabilityObjectArray>)weaponCategoryRequirementConfig .Where( category => weaponTypes .Contains(category.Key) @@ -279,7 +270,7 @@ public class RepeatableQuestGenerator( List weaponTypes = ["MarksmanRifle", "DMR"]; // Filter out far range weapons from close distance requirement weaponCategoryRequirementConfig = - (ProbabilityObjectArray>)weaponCategoryRequirementConfig + (ProbabilityObjectArray>)weaponCategoryRequirementConfig .Where( category => weaponTypes .Contains(category.Key) @@ -298,8 +289,8 @@ public class RepeatableQuestGenerator( if (allowedWeaponsCategory is not null && eliminationConfig.WeaponRequirementProbability > rand.NextDouble()) { var weaponRequirement = weaponRequirementConfig.Draw(1, false); - var specificAllowedWeaponCategory = weaponRequirementConfig.Data(weaponRequirement[0])[0]; - var allowedWeapons = _itemHelper.GetItemTplsOfBaseType(specificAllowedWeaponCategory); + var specificAllowedWeaponCategory = weaponRequirementConfig.Data(weaponRequirement[0]); + var allowedWeapons = _itemHelper.GetItemTplsOfBaseType(specificAllowedWeaponCategory[0]); allowedWeapon = _randomUtil.GetArrayValue(allowedWeapons); } @@ -377,7 +368,7 @@ public class RepeatableQuestGenerator( */ protected int GetEliminationKillCount( string targetKey, - ProbabilityObjectArray targetsConfig, + ProbabilityObjectArray targetsConfig, EliminationConfig eliminationConfig) { if (targetsConfig.Data(targetKey).IsBoss.GetValueOrDefault(false)) diff --git a/Libraries/Core/Helpers/ItemHelper.cs b/Libraries/Core/Helpers/ItemHelper.cs index 72b74de3..21226147 100644 --- a/Libraries/Core/Helpers/ItemHelper.cs +++ b/Libraries/Core/Helpers/ItemHelper.cs @@ -1646,7 +1646,7 @@ public class ItemHelper( return null; } - var ammoArray = new ProbabilityObjectArray, string, float?>(_mathUtil, _cloner, []); + var ammoArray = new ProbabilityObjectArray(_mathUtil, _cloner); foreach (var icd in ammos) { // Whitelist exists and tpl not inside it, skip // Fixes 9x18mm kedr issues diff --git a/Libraries/Core/Helpers/RepeatableQuestHelper.cs b/Libraries/Core/Helpers/RepeatableQuestHelper.cs index b04f6f1b..c6b060fe 100644 --- a/Libraries/Core/Helpers/RepeatableQuestHelper.cs +++ b/Libraries/Core/Helpers/RepeatableQuestHelper.cs @@ -2,16 +2,13 @@ using Core.Models.Spt.Config; using Core.Models.Utils; using Core.Utils; using Core.Utils.Cloners; -using Core.Utils.Collections; using SptCommon.Annotations; namespace Core.Helpers; [Injectable] public class RepeatableQuestHelper( - ISptLogger _logger, - ICloner _cloner, - MathUtil _mathUtil + ISptLogger _logger ) { /// @@ -26,14 +23,4 @@ public class RepeatableQuestHelper( x => pmcLevel >= x.LevelRange.Min && pmcLevel <= x.LevelRange.Max ); } - - public ProbabilityObjectArray - ProbabilityObjectArray( - List? configArrayInput - ) where T : ProbabilityObject - { - var configArray = _cloner.Clone(configArrayInput); - var probabilityArray = new ProbabilityObjectArray(_mathUtil, _cloner, configArray); - return probabilityArray; - } } diff --git a/Libraries/Core/Models/Spt/Config/QuestConfig.cs b/Libraries/Core/Models/Spt/Config/QuestConfig.cs index bf7caab7..3817a44e 100644 --- a/Libraries/Core/Models/Spt/Config/QuestConfig.cs +++ b/Libraries/Core/Models/Spt/Config/QuestConfig.cs @@ -1,4 +1,4 @@ -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; using Core.Models.Common; using Core.Models.Enums; using Core.Utils.Collections; @@ -285,13 +285,13 @@ public record EliminationConfig : BaseQuestConfig public MinMax? LevelRange { get; set; } [JsonPropertyName("targets")] - public List? Targets { get; set; } + public List>? Targets { get; set; } [JsonPropertyName("bodyPartProb")] public double? BodyPartProbability { get; set; } [JsonPropertyName("bodyParts")] - public List? BodyParts { get; set; } + public List>>? BodyParts { get; set; } [JsonPropertyName("specificLocationProb")] public double? SpecificLocationProbability { get; set; } @@ -330,13 +330,13 @@ public record EliminationConfig : BaseQuestConfig public double? WeaponCategoryRequirementProbability { get; set; } [JsonPropertyName("weaponCategoryRequirements")] - public List? WeaponCategoryRequirements { get; set; } + public List>>? WeaponCategoryRequirements { get; set; } [JsonPropertyName("weaponRequirementProb")] public double? WeaponRequirementProbability { get; set; } [JsonPropertyName("weaponRequirements")] - public List? WeaponRequirements { get; set; } + public List>>? WeaponRequirements { get; set; } } public record BaseQuestConfig @@ -345,10 +345,6 @@ public record BaseQuestConfig public List? PossibleSkillRewards { get; set; } } -public class Target : ProbabilityObject -{ -} - public record BossInfo { [JsonPropertyName("isBoss")] @@ -357,11 +353,3 @@ public record BossInfo [JsonPropertyName("isPmc")] public bool? IsPmc { get; set; } } - -public class BodyPart : ProbabilityObject> -{ -} - -public class WeaponRequirement : ProbabilityObject> -{ -} diff --git a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs index 0d5630c2..4aeb7027 100644 --- a/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs +++ b/Libraries/Core/Utils/Collections/ProbabilityObjectArray.cs @@ -21,7 +21,7 @@ namespace Core.Utils.Collections; /// /// /// -public class ProbabilityObjectArray : List where T : ProbabilityObject +public class ProbabilityObjectArray : List> { private readonly MathUtil _mathUtil; private readonly ICloner _cloner; @@ -29,8 +29,8 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje public ProbabilityObjectArray( MathUtil mathUtil, ICloner cloner, - ICollection? items = null - ) : base(items ?? []) + ICollection>? items = null + ) : base(items) { _mathUtil = mathUtil; _cloner = cloner; @@ -55,9 +55,9 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje /// /// /// Filtered results - public ProbabilityObjectArray Filter(Predicate> predicate) + public ProbabilityObjectArray Filter(Predicate> predicate) { - var result = new ProbabilityObjectArray(_mathUtil, _cloner, new List()); + var result = new ProbabilityObjectArray(_mathUtil, _cloner, new List>()); foreach (var probabilityObject in this) if (predicate.Invoke(probabilityObject)) { @@ -71,13 +71,13 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje /// Deep clone this ProbabilityObjectArray /// /// Deep Copy of ProbabilityObjectArray - public ProbabilityObjectArray Clone() + public ProbabilityObjectArray Clone() { var clone = _cloner.Clone(this); - var probabilityObjects = new ProbabilityObjectArray( + var probabilityObjects = new ProbabilityObjectArray( _mathUtil, _cloner, - new List() + new List>() ); probabilityObjects.AddRange(clone); @@ -89,9 +89,9 @@ public class ProbabilityObjectArray : List where T : ProbabilityObje /// /// The key of the element to drop /// ProbabilityObjectArray without the dropped element - public ProbabilityObjectArray Drop(K key) + public ProbabilityObjectArray Drop(K key) { - return (ProbabilityObjectArray)this.Where((r) => !r.Key?.Equals(key) ?? false); + return (ProbabilityObjectArray)this.Where((r) => !r.Key?.Equals(key) ?? false); } ///