Made ProbabilityObjectArray slightly less awful

This commit is contained in:
Chomp
2025-02-04 19:38:59 +00:00
parent 621dd27323
commit db0feff1d8
8 changed files with 43 additions and 76 deletions
@@ -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<ProbabilityObject<string, double?>, string, double?>(_mathUtil, _cloner);
var attachmentsProbabilityArray = new ProbabilityObjectArray<string, double?>(_mathUtil, _cloner);
foreach (var attachmentTpl in weightedAttachmentByPrice)
{
attachmentsProbabilityArray.Add(
@@ -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<RepeatableQuestChangeRequest> _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<Target, string, BossInfo>(eliminationConfig.Targets);
var targetsConfig = new ProbabilityObjectArray<string, BossInfo>(_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
{
@@ -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<ProbabilityObject<string, double>, string, double>(_mathUtil, _cloner);
new ProbabilityObjectArray<string, double>(_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<ProbabilityObject<int, float?>, int, float?>(_mathUtil, _cloner);
new ProbabilityObjectArray<int, float?>(_mathUtil, _cloner);
var countDistribution = staticLootDist[containerTypeId]?.ItemCountDistribution;
if (countDistribution is null)
{
@@ -593,14 +593,15 @@ public class LocationLootGenerator(
/// <param name="containerTypeId">Container to get possible loot for</param>
/// <param name="staticLootDist">staticLoot.json</param>
/// <returns>ProbabilityObjectArray of item tpls + probabilty</returns>
protected ProbabilityObjectArray<ProbabilityObject<string, float?>, string, float?> GetPossibleLootItemsForContainer(string containerTypeId,
Dictionary<string, StaticLootDetails> staticLootDist) // TODO: Type Fuckery, return type was ProbabilityObjectArray<string, number>
protected ProbabilityObjectArray<string, float?> GetPossibleLootItemsForContainer(
string containerTypeId,
Dictionary<string, StaticLootDetails> staticLootDist)
{
var seasonalEventActive = _seasonalEventService.SeasonalEventEnabled();
var seasonalItemTplBlacklist = _seasonalEventService.GetInactiveSeasonalEventItems();
var itemDistribution =
new ProbabilityObjectArray<ProbabilityObject<string, float?>, string, float?>(_mathUtil, _cloner);
new ProbabilityObjectArray<string, float?>(_mathUtil, _cloner);
var itemContainerDistribution = staticLootDist[containerTypeId]?.ItemDistribution;
if (itemContainerDistribution is null)
@@ -689,7 +690,7 @@ public class LocationLootGenerator(
List<Spawnpoint> guaranteedLoosePoints = [];
var blacklistedSpawnpoints = _locationConfig.LooseLootBlacklist.GetValueOrDefault(locationName);
var spawnpointArray = new ProbabilityObjectArray<ProbabilityObject<string, Spawnpoint>, string, Spawnpoint>(_mathUtil, _cloner, []);
var spawnpointArray = new ProbabilityObjectArray<string, Spawnpoint>(_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<ProbabilityObject<string, double?>, string, double?>(_mathUtil, _cloner, []);
var itemArray = new ProbabilityObjectArray<string, double?>(_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<ProbabilityObject<string, Spawnpoint>, string, Spawnpoint>(_mathUtil, _cloner, []);
var spawnpointArray = new ProbabilityObjectArray<string, Spawnpoint>(_mathUtil, _cloner);
foreach (var si in items)
{
// use locationId as template.Id is the same across all items
@@ -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<Target, string, BossInfo>(eliminationConfig.Targets);
var bodyPartsConfig =
_repeatableQuestHelper.ProbabilityObjectArray<BodyPart, string, List<string>>(eliminationConfig.BodyParts);
var weaponCategoryRequirementConfig =
_repeatableQuestHelper.ProbabilityObjectArray<WeaponRequirement, string, List<string>>(
eliminationConfig.WeaponCategoryRequirements
);
var weaponRequirementConfig =
_repeatableQuestHelper.ProbabilityObjectArray<WeaponRequirement, string, List<string>>(
eliminationConfig.WeaponRequirements
);
var targetsConfig = new ProbabilityObjectArray<string, BossInfo>(_mathUtil, _cloner, eliminationConfig.Targets);
var bodyPartsConfig = new ProbabilityObjectArray<string, List<string>>(_mathUtil, _cloner, eliminationConfig.BodyParts);
var weaponCategoryRequirementConfig = new ProbabilityObjectArray<string, List<string>>(_mathUtil, _cloner, eliminationConfig.WeaponCategoryRequirements);
var weaponRequirementConfig = new ProbabilityObjectArray<string, List<string>>(_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<string> weaponTypes = ["Shotgun", "Pistol"];
weaponCategoryRequirementConfig =
(ProbabilityObjectArray<WeaponRequirement, string, List<string>>)weaponCategoryRequirementConfig
(ProbabilityObjectArray<string, List<string>>)weaponCategoryRequirementConfig
.Where(
category => weaponTypes
.Contains(category.Key)
@@ -279,7 +270,7 @@ public class RepeatableQuestGenerator(
List<string> weaponTypes = ["MarksmanRifle", "DMR"];
// Filter out far range weapons from close distance requirement
weaponCategoryRequirementConfig =
(ProbabilityObjectArray<WeaponRequirement, string, List<string>>)weaponCategoryRequirementConfig
(ProbabilityObjectArray<string, List<string>>)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<Target, string, BossInfo> targetsConfig,
ProbabilityObjectArray<string, BossInfo> targetsConfig,
EliminationConfig eliminationConfig)
{
if (targetsConfig.Data(targetKey).IsBoss.GetValueOrDefault(false))
+1 -1
View File
@@ -1646,7 +1646,7 @@ public class ItemHelper(
return null;
}
var ammoArray = new ProbabilityObjectArray<ProbabilityObject<string, float?>, string, float?>(_mathUtil, _cloner, []);
var ammoArray = new ProbabilityObjectArray<string, float?>(_mathUtil, _cloner);
foreach (var icd in ammos) {
// Whitelist exists and tpl not inside it, skip
// Fixes 9x18mm kedr issues
@@ -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<RepeatableQuestHelper> _logger,
ICloner _cloner,
MathUtil _mathUtil
ISptLogger<RepeatableQuestHelper> _logger
)
{
/// <summary>
@@ -26,14 +23,4 @@ public class RepeatableQuestHelper(
x => pmcLevel >= x.LevelRange.Min && pmcLevel <= x.LevelRange.Max
);
}
public ProbabilityObjectArray<T, K, V>
ProbabilityObjectArray<T, K, V>(
List<T>? configArrayInput
) where T : ProbabilityObject<K, V>
{
var configArray = _cloner.Clone(configArrayInput);
var probabilityArray = new ProbabilityObjectArray<T, K, V>(_mathUtil, _cloner, configArray);
return probabilityArray;
}
}
@@ -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<Target>? Targets { get; set; }
public List<ProbabilityObject<string, BossInfo>>? Targets { get; set; }
[JsonPropertyName("bodyPartProb")]
public double? BodyPartProbability { get; set; }
[JsonPropertyName("bodyParts")]
public List<BodyPart>? BodyParts { get; set; }
public List<ProbabilityObject<string, List<string>>>? 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<WeaponRequirement>? WeaponCategoryRequirements { get; set; }
public List<ProbabilityObject<string, List<string>>>? WeaponCategoryRequirements { get; set; }
[JsonPropertyName("weaponRequirementProb")]
public double? WeaponRequirementProbability { get; set; }
[JsonPropertyName("weaponRequirements")]
public List<WeaponRequirement>? WeaponRequirements { get; set; }
public List<ProbabilityObject<string, List<string>>>? WeaponRequirements { get; set; }
}
public record BaseQuestConfig
@@ -345,10 +345,6 @@ public record BaseQuestConfig
public List<string>? PossibleSkillRewards { get; set; }
}
public class Target : ProbabilityObject<string, BossInfo>
{
}
public record BossInfo
{
[JsonPropertyName("isBoss")]
@@ -357,11 +353,3 @@ public record BossInfo
[JsonPropertyName("isPmc")]
public bool? IsPmc { get; set; }
}
public class BodyPart : ProbabilityObject<string, List<string>>
{
}
public class WeaponRequirement : ProbabilityObject<string, List<string>>
{
}
@@ -21,7 +21,7 @@ namespace Core.Utils.Collections;
/// <typeparam name="T"></typeparam>
/// <typeparam name="K"></typeparam>
/// <typeparam name="V"></typeparam>
public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObject<K, V>
public class ProbabilityObjectArray<K, V> : List<ProbabilityObject<K, V>>
{
private readonly MathUtil _mathUtil;
private readonly ICloner _cloner;
@@ -29,8 +29,8 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
public ProbabilityObjectArray(
MathUtil mathUtil,
ICloner cloner,
ICollection<T>? items = null
) : base(items ?? [])
ICollection<ProbabilityObject<K, V>>? items = null
) : base(items)
{
_mathUtil = mathUtil;
_cloner = cloner;
@@ -55,9 +55,9 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
/// </summary>
/// <param name="predicate"></param>
/// <returns>Filtered results</returns>
public ProbabilityObjectArray<T, K, V> Filter(Predicate<ProbabilityObject<K, V>> predicate)
public ProbabilityObjectArray<K, V> Filter(Predicate<ProbabilityObject<K, V>> predicate)
{
var result = new ProbabilityObjectArray<T, K, V>(_mathUtil, _cloner, new List<T>());
var result = new ProbabilityObjectArray<K, V>(_mathUtil, _cloner, new List<ProbabilityObject<K, V>>());
foreach (var probabilityObject in this)
if (predicate.Invoke(probabilityObject))
{
@@ -71,13 +71,13 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
/// Deep clone this ProbabilityObjectArray
/// </summary>
/// <returns>Deep Copy of ProbabilityObjectArray</returns>
public ProbabilityObjectArray<T, K, V> Clone()
public ProbabilityObjectArray<K, V> Clone()
{
var clone = _cloner.Clone(this);
var probabilityObjects = new ProbabilityObjectArray<T, K, V>(
var probabilityObjects = new ProbabilityObjectArray<K, V>(
_mathUtil,
_cloner,
new List<T>()
new List<ProbabilityObject<K, V>>()
);
probabilityObjects.AddRange(clone);
@@ -89,9 +89,9 @@ public class ProbabilityObjectArray<T, K, V> : List<T> where T : ProbabilityObje
/// </summary>
/// <param name="key">The key of the element to drop</param>
/// <returns>ProbabilityObjectArray without the dropped element</returns>
public ProbabilityObjectArray<T, K, V> Drop(K key)
public ProbabilityObjectArray<K, V> Drop(K key)
{
return (ProbabilityObjectArray<T, K, V>)this.Where((r) => !r.Key?.Equals(key) ?? false);
return (ProbabilityObjectArray<K, V>)this.Where((r) => !r.Key?.Equals(key) ?? false);
}
/// <summary>