diff --git a/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs b/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs index 11f4f921..bfcf12bc 100644 --- a/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs +++ b/Libraries/SPTarkov.Server.Core/Controllers/RagfairController.cs @@ -1145,7 +1145,7 @@ public class RagfairController }; } - _itemHelper.FixItemStackCount(rootItem); + rootItem.FixItemStackCount(); itemsToReturn.Add( _itemHelper.FindAndReturnChildrenAsItems(pmcData.Inventory.Items, itemId) diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs index 40f0ac31..484f916c 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ItemExtensions.cs @@ -223,5 +223,58 @@ namespace SPTarkov.Server.Core.Extensions return list; } + + /// Check if the passed in item has buy count restrictions + /// + /// Item to check + /// true if it has buy restrictions + public static bool HasBuyRestrictions(this Item itemToCheck) + { + return itemToCheck.Upd?.BuyRestrictionCurrent is not null + && itemToCheck.Upd?.BuyRestrictionMax is not null; + } + + /// + /// Gets the identifier for a child using slotId, locationX and locationY. + /// + /// Item. + /// SlotId OR slotid, locationX, locationY. + public static string GetChildId(this Item item) + { + if (item.Location is null) + { + return item.SlotId; + } + + var LocationTyped = (ItemLocation)item.Location; + + return $"{item.SlotId},{LocationTyped.X},{LocationTyped.Y}"; + } + + public static bool IsVertical(this ItemLocation itemLocation) + { + var castValue = itemLocation.R.ToString(); + return castValue == "1" + || string.Equals(castValue, "vertical", StringComparison.OrdinalIgnoreCase) + || string.Equals( + itemLocation.Rotation?.ToString(), + "vertical", + StringComparison.OrdinalIgnoreCase + ); + } + + /// + /// Update items upd.StackObjectsCount to be 1 if its upd is missing or StackObjectsCount is undefined + /// + /// Item to update + /// Fixed item + public static void FixItemStackCount(this Item item) + { + // Ensure item has 'Upd' object + item.Upd ??= new Upd { StackObjectsCount = 1 }; + + // Ensure item has 'StackObjectsCount' property + item.Upd.StackObjectsCount ??= 1; + } } } diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs new file mode 100644 index 00000000..9a1c960c --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Extensions/ProductionExtensions.cs @@ -0,0 +1,49 @@ +using SPTarkov.Server.Core.Helpers; +using SPTarkov.Server.Core.Models.Eft.Common.Tables; +using SPTarkov.Server.Core.Models.Enums; + +namespace SPTarkov.Server.Core.Extensions +{ + public static class ProductionExtensions + { + private static readonly HashSet _idCheck = + [ + HideoutHelper.BitcoinFarm, + HideoutHelper.CultistCircleCraftId, + ]; + + /// + /// Has the craft completed + /// Ignores bitcoin farm/cultist circle as they're continuous crafts + /// + /// Craft to check + /// True when craft is complete + public static bool IsCraftComplete(this Production craft) + { + return craft.Progress >= craft.ProductionTime && !_idCheck.Contains(craft.RecipeId); + } + + /// + /// Is a craft from a particular hideout area + /// + /// Craft to check + /// Type to check craft against + /// True if it is from that area + public static bool IsCraftOfType(this Production craft, HideoutAreas hideoutType) + { + switch (hideoutType) + { + case HideoutAreas.WaterCollector: + return craft.RecipeId == HideoutHelper.WaterCollector; + case HideoutAreas.BitcoinFarm: + return craft.RecipeId == HideoutHelper.BitcoinFarm; + case HideoutAreas.ScavCase: + return craft.SptIsScavCase ?? false; + case HideoutAreas.CircleOfCultists: + return craft.SptIsCultistCircle ?? false; + default: + return false; + } + } + } +} diff --git a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs index ca469ba7..e8144e79 100644 --- a/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs +++ b/Libraries/SPTarkov.Server.Core/Extensions/ProfileExtensions.cs @@ -110,5 +110,59 @@ namespace SPTarkov.Server.Core.Extensions Points = 0, }; } + + /// + /// Recursively checks if the given item is + /// inside the stash, that is it has the stash as + /// ancestor with slotId=hideout + /// + /// Player profile + /// Item to look for + /// True if item exists inside stash + public static bool IsItemInStash(this PmcData pmcData, Item itemToCheck) + { + // Start recursive check + return pmcData.IsParentInStash(itemToCheck.Id); + } + + public static bool IsParentInStash(this PmcData pmcData, string itemId) + { + // Item not found / has no parent + var item = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == itemId); + if (item?.ParentId is null) + { + return false; + } + + // Root level. Items parent is the stash with slotId "hideout" + if (item.ParentId == pmcData.Inventory.Stash && item.SlotId == "hideout") + { + return true; + } + + // Recursive case: Check the items parent + return IsParentInStash(pmcData, item.ParentId); + } + + /// + /// Iterate over all bonuses and sum up all bonuses of desired type in provided profile + /// + /// Player profile + /// Bonus to sum up + /// Summed bonus value or 0 if no bonus found + public static double GetBonusValueFromProfile( + this PmcData pmcProfile, + BonusType desiredBonus + ) + { + var bonuses = pmcProfile?.Bonuses?.Where(b => b.Type == desiredBonus); + if (!bonuses.Any()) + { + return 0; + } + + // Sum all bonuses found above + return bonuses?.Sum(bonus => bonus?.Value ?? 0) ?? 0; + } } } diff --git a/Libraries/SPTarkov.Server.Core/Extensions/TemplateItemExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/TemplateItemExtensions.cs new file mode 100644 index 00000000..a3c97a2f --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Extensions/TemplateItemExtensions.cs @@ -0,0 +1,41 @@ +using SPTarkov.Server.Core.Models.Eft.Common.Tables; + +namespace SPTarkov.Server.Core.Extensions +{ + public static class TemplateItemExtensions + { + public static IEnumerable OfClass( + this Dictionary templates, + params string[] baseClasses + ) + { + return templates.Where(x => baseClasses.Contains(x.Value.Parent)).Select(x => x.Value); + } + + public static IEnumerable OfClass( + this Dictionary templates, + Func pred, + params string[] baseClasses + ) + { + return templates + .Where(x => baseClasses.Contains(x.Value.Parent) && pred(x.Value)) + .Select(x => x.Value); + } + + /// + /// Check if item is quest item + /// + /// Items tpl to check quest status of + /// true if item is flagged as quest item + public static bool IsQuestItem(this TemplateItem templateItem) + { + if (templateItem.Properties.QuestItem.GetValueOrDefault(false)) + { + return true; + } + + return false; + } + } +} diff --git a/Libraries/SPTarkov.Server.Core/Extensions/UtilityExtensions.cs b/Libraries/SPTarkov.Server.Core/Extensions/UtilityExtensions.cs new file mode 100644 index 00000000..f70ec2be --- /dev/null +++ b/Libraries/SPTarkov.Server.Core/Extensions/UtilityExtensions.cs @@ -0,0 +1,13 @@ +namespace SPTarkov.Server.Core.Extensions +{ + public static class UtilityExtensions + { + public static List IntersectWith(this List first, List second) + { + //a.Intersect(x => b.Contains(x)).ToList(); + // gives error Delegate type could not be infered + + return first.Where(x => second.Contains(x)).ToList(); + } + } +} diff --git a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs index 7a135f7a..a2c4a9ef 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/BotEquipmentModGenerator.cs @@ -23,7 +23,6 @@ public class BotEquipmentModGenerator( ISptLogger _logger, HashUtil _hashUtil, RandomUtil _randomUtil, - ProbabilityHelper _probabilityHelper, DatabaseService _databaseService, ItemHelper _itemHelper, BotEquipmentFilterService _botEquipmentFilterService, @@ -1103,7 +1102,7 @@ public class BotEquipmentModGenerator( return ModSpawn.SPAWN; } - var spawnMod = _probabilityHelper.RollChance( + var spawnMod = _randomUtil.RollChance( modSpawnChances.GetValueOrDefault(modSlotName.ToLower()) ); if ( diff --git a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs index 9bab5cad..163a73fe 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/Dialogue/Commando/SptCommands/GiveCommand/GiveSptCommand.cs @@ -1,6 +1,7 @@ using System.Collections.Frozen; using System.Text.RegularExpressions; using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Helpers.Dialog.Commando.SptCommands; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Dialog; @@ -323,7 +324,7 @@ public class GiveSptCommand( protected bool IsItemAllowed(TemplateItem templateItem) { return templateItem.Type != "Node" - && !_itemHelper.IsQuestItem(templateItem.Id) + && !templateItem.IsQuestItem() && !_itemFilterService.IsItemBlacklisted(templateItem.Id) && (templateItem.Properties?.Prefab?.Path ?? "") != "" && !_itemHelper.IsOfBaseclasses( diff --git a/Libraries/SPTarkov.Server.Core/Helpers/GameEventHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/GameEventHelper.cs deleted file mode 100644 index 660ecfaa..00000000 --- a/Libraries/SPTarkov.Server.Core/Helpers/GameEventHelper.cs +++ /dev/null @@ -1,6 +0,0 @@ -using SPTarkov.DI.Annotations; - -namespace SPTarkov.Server.Core.Helpers; - -[Injectable] -public class GameEventHelper { } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs index 909ce837..ee857da4 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/HideoutHelper.cs @@ -35,7 +35,6 @@ public class HideoutHelper( public const string BitcoinProductionId = "5d5c205bd582a50d042a3c0e"; public const string WaterCollector = "5d5589c1f934db045e6c5492"; public const int MaxSkillPoint = 5000; - protected HashSet _idCheck = [BitcoinFarm, CultistCircleCraftId]; /// /// Add production to profiles' Hideout.Production array @@ -341,20 +340,20 @@ public class HideoutHelper( } // Skip processing (Don't skip continuous crafts like bitcoin farm or cultist circle) - if (IsCraftComplete(craft)) + if (craft.IsCraftComplete()) { continue; } // Special handling required - if (IsCraftOfType(craft, HideoutAreas.ScavCase)) + if (craft.IsCraftOfType(HideoutAreas.ScavCase)) { UpdateScavCaseProductionTimer(pmcData, prodId.Key); continue; } - if (IsCraftOfType(craft, HideoutAreas.WaterCollector)) + if (craft.IsCraftOfType(HideoutAreas.WaterCollector)) { UpdateWaterCollectorProductionTimer(pmcData, prodId.Key, hideoutProperties); @@ -362,7 +361,7 @@ public class HideoutHelper( } // Continuous craft - if (IsCraftOfType(craft, HideoutAreas.BitcoinFarm)) + if (craft.IsCraftOfType(HideoutAreas.BitcoinFarm)) { UpdateBitcoinFarm( pmcData, @@ -375,7 +374,7 @@ public class HideoutHelper( } // No recipe, needs special handling - if (IsCraftOfType(craft, HideoutAreas.CircleOfCultists)) + if (craft.IsCraftOfType(HideoutAreas.CircleOfCultists)) { UpdateCultistCircleCraftProgress(pmcData, prodId.Key); @@ -397,43 +396,6 @@ public class HideoutHelper( } } - /// - /// Is a craft from a particular hideout area - /// - /// Craft to check - /// Type to check craft against - /// True if it is from that area - protected bool IsCraftOfType(Production craft, HideoutAreas hideoutType) - { - switch (hideoutType) - { - case HideoutAreas.WaterCollector: - return craft.RecipeId == WaterCollector; - case HideoutAreas.BitcoinFarm: - return craft.RecipeId == BitcoinFarm; - case HideoutAreas.ScavCase: - return craft.SptIsScavCase ?? false; - case HideoutAreas.CircleOfCultists: - return craft.SptIsCultistCircle ?? false; - default: - _logger.Error( - $"Unhandled hideout area: {hideoutType}, assuming craft: {craft.RecipeId} is not of this type" - ); - return false; - } - } - - /// - /// Has the craft completed - /// Ignores bitcoin farm/cultist circle as they're continuous crafts - /// - /// Craft to check - /// True when craft is complete - protected bool IsCraftComplete(Production craft) - { - return craft.Progress >= craft.ProductionTime && !_idCheck.Contains(craft.RecipeId); - } - /// /// Update progress timer for water collector /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs index 0ae89c41..f9b8cf2f 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/InventoryHelper.cs @@ -512,7 +512,7 @@ public class InventoryHelper( profile.Inventory.Items, itemId ); - if (itemAndChildrenToRemove.Count == 0) + if (!itemAndChildrenToRemove.Any()) { if (_logger.IsLogEnabled(LogLevel.Debug)) { @@ -924,8 +924,8 @@ public class InventoryHelper( var tmpSize = GetSizeByInventoryItemHash(item.Template, item.Id, inventoryItemHash); var iW = tmpSize[0]; // x var iH = tmpSize[1]; // y - var fH = IsVertical(itemLocation) ? iW : iH; - var fW = IsVertical(itemLocation) ? iH : iW; + var fH = itemLocation.IsVertical() ? iW : iH; + var fW = itemLocation.IsVertical() ? iH : iW; for (var y = 0; y < fH; y++) { @@ -958,18 +958,6 @@ public class InventoryHelper( return containerYX; } - protected bool IsVertical(ItemLocation itemLocation) - { - var castValue = itemLocation.R.ToString(); - return castValue == "1" - || string.Equals(castValue, "vertical", StringComparison.OrdinalIgnoreCase) - || string.Equals( - itemLocation.Rotation?.ToString(), - "vertical", - StringComparison.OrdinalIgnoreCase - ); - } - protected InventoryItemHash GetInventoryItemHash(List inventoryItems) { var inventoryItemHash = new InventoryItemHash @@ -1370,39 +1358,6 @@ public class InventoryHelper( return _inventoryConfig; } - /// - /// Recursively checks if the given item is - /// inside the stash, that is it has the stash as - /// ancestor with slotId=hideout - /// - /// Player profile - /// Item to look for - /// True if item exists inside stash - public bool IsItemInStash(PmcData pmcData, Item itemToCheck) - { - // Start recursive check - return IsParentInStash(itemToCheck.Id, pmcData); - } - - protected static bool IsParentInStash(string itemId, PmcData pmcData) - { - // Item not found / has no parent - var item = pmcData.Inventory.Items.FirstOrDefault(item => item.Id == itemId); - if (item?.ParentId is null) - { - return false; - } - - // Root level. Items parent is the stash with slotId "hideout" - if (item.ParentId == pmcData.Inventory.Stash && item.SlotId == "hideout") - { - return true; - } - - // Recursive case: Check the items parent - return IsParentInStash(item.ParentId, pmcData); - } - public void ValidateInventoryUsesMongoIds(List itemsToValidate) { var errors = itemsToValidate diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs index 1c3c8ec2..f3eb037e 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/ItemHelper.cs @@ -499,22 +499,6 @@ public class ItemHelper( return null; } - /// - /// Update items upd.StackObjectsCount to be 1 if its upd is missing or StackObjectsCount is undefined - /// - /// Item to update - /// Fixed item - public Item FixItemStackCount(Item item) - { - // Ensure item has 'Upd' object - item.Upd ??= new Upd { StackObjectsCount = 1 }; - - // Ensure item has 'StackObjectsCount' property - item.Upd.StackObjectsCount ??= 1; - - return item; - } - /// /// Get cloned copy of all item data from items.json /// @@ -807,17 +791,6 @@ public class ItemHelper( return list; } - /// - /// Check if the passed in item has buy count restrictions - /// - /// Item to check - /// true if it has buy restrictions - public bool HasBuyRestrictions(Item itemToCheck) - { - return itemToCheck.Upd?.BuyRestrictionCurrent is not null - && itemToCheck.Upd?.BuyRestrictionMax is not null; - } - /// /// Checks if the passed template id is a dog tag. /// @@ -828,23 +801,6 @@ public class ItemHelper( return _dogTagTpls.Contains(tpl); } - /// - /// Gets the identifier for a child using slotId, locationX and locationY. - /// - /// Item. - /// SlotId OR slotid, locationX, locationY. - public string GetChildId(Item item) - { - if (item.Location is null) - { - return item.SlotId; - } - - var LocationTyped = (ItemLocation)item.Location; - - return $"{item.SlotId},{LocationTyped.X},{LocationTyped.Y}"; - } - /// /// Checks if the passed item can be stacked. /// @@ -1305,22 +1261,6 @@ public class ItemHelper( return DoesItemOrParentsIdMatch(item.Parent, tplsToCheck); } - /// - /// Check if item is quest item - /// - /// Items tpl to check quest status of - /// true if item is flagged as quest item - public bool IsQuestItem(string tpl) - { - var itemDetails = GetItem(tpl); - if (itemDetails.Key && itemDetails.Value.Properties.QuestItem.GetValueOrDefault(false)) - { - return true; - } - - return false; - } - /// /// Checks to see if the item is *actually* moddable in-raid. Checks include the items existence in the database, the /// parent items existence in the database, the existence (and value) of the items RaidModdable property, and that diff --git a/Libraries/SPTarkov.Server.Core/Helpers/ProbabilityHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/ProbabilityHelper.cs deleted file mode 100644 index cc24edeb..00000000 --- a/Libraries/SPTarkov.Server.Core/Helpers/ProbabilityHelper.cs +++ /dev/null @@ -1,20 +0,0 @@ -using SPTarkov.DI.Annotations; -using SPTarkov.Server.Core.Models.Utils; -using SPTarkov.Server.Core.Utils; - -namespace SPTarkov.Server.Core.Helpers; - -[Injectable] -public class ProbabilityHelper(ISptLogger _logger, RandomUtil _randomUtil) -{ - /// - /// Chance to roll a number out of 100 - /// - /// Percentage chance roll should success - /// scale of chance to allow support of numbers > 1-100 - /// true if success - public bool RollChance(double chance, double scale = 1) - { - return _randomUtil.GetInt(1, (int)(100 * scale)) / (1 * scale) <= chance; - } -} diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RagfairHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RagfairHelper.cs index 0d286122..c2ab2181 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RagfairHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RagfairHelper.cs @@ -1,4 +1,5 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Ragfair; using SPTarkov.Server.Core.Models.Enums; @@ -16,7 +17,6 @@ public class RagfairHelper( HandbookHelper handbookHelper, ItemHelper itemHelper, RagfairLinkedItemService ragfairLinkedItemService, - UtilityHelper utilityHelper, ConfigServer configServer, ICloner cloner ) @@ -86,7 +86,7 @@ public class RagfairHelper( if (!string.IsNullOrEmpty(request.HandbookId)) { var handbook = GetCategoryList(request.HandbookId); - result = result?.Count > 0 ? utilityHelper.ArrayIntersect(result, handbook) : handbook; + result = result?.Count > 0 ? result.IntersectWith(handbook) : handbook; } return result; @@ -157,25 +157,25 @@ public class RagfairHelper( foreach (var item in items) { - var itemFixed = itemHelper.FixItemStackCount(item); + item.FixItemStackCount(); - var isChild = items.Any(it => it.Id == itemFixed.ParentId); + var isChild = items.Any(it => it.Id == item.ParentId); if (!isChild) { if (rootItem == null) { - rootItem = cloner.Clone(itemFixed); + rootItem = cloner.Clone(item); rootItem.Upd.OriginalStackObjectsCount = rootItem.Upd.StackObjectsCount; } else { - rootItem.Upd.StackObjectsCount += itemFixed.Upd.StackObjectsCount; - list.Add(itemFixed); + rootItem.Upd.StackObjectsCount += item.Upd.StackObjectsCount; + list.Add(item); } } else { - list.Add(itemFixed); + list.Add(item); } } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs index 597eafac..b3225b5a 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs @@ -1,4 +1,5 @@ using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Enums; using SPTarkov.Server.Core.Models.Spt.Config; @@ -75,7 +76,7 @@ public class RagfairServerHelper( } // Skip quest items - if (blacklistConfig.EnableQuestList && itemHelper.IsQuestItem(itemDetails.Value.Id)) + if (blacklistConfig.EnableQuestList && itemDetails.Value.IsQuestItem()) { return false; } diff --git a/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs index 542fe3c2..6af675c1 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/TradeHelper.cs @@ -1,5 +1,6 @@ using System.Text.RegularExpressions; using SPTarkov.DI.Annotations; +using SPTarkov.Server.Core.Extensions; using SPTarkov.Server.Core.Models.Eft.Common; using SPTarkov.Server.Core.Models.Eft.Common.Tables; using SPTarkov.Server.Core.Models.Eft.Inventory; @@ -76,8 +77,7 @@ public class TradeHelper( var itemPurchased = offerWithItem.Items.FirstOrDefault(); // Ensure purchase does not exceed trader item limit - var assortHasBuyRestrictions = _itemHelper.HasBuyRestrictions(itemPurchased); - if (assortHasBuyRestrictions) + if (itemPurchased.HasBuyRestrictions()) { CheckPurchaseIsWithinTraderItemLimit( sessionID, @@ -170,8 +170,7 @@ public class TradeHelper( ); // Ensure purchase does not exceed trader item limit - var assortHasBuyRestrictions = _itemHelper.HasBuyRestrictions(itemPurchased); - if (assortHasBuyRestrictions) + if (itemPurchased.HasBuyRestrictions()) // Will throw error if check fails { CheckPurchaseIsWithinTraderItemLimit( @@ -195,7 +194,7 @@ public class TradeHelper( // Decrement trader item count itemPurchased.Upd.StackObjectsCount -= buyCount; - if (assortHasBuyRestrictions) + if (itemPurchased.HasBuyRestrictions()) { var itemPurchaseDat = new PurchaseDetails { diff --git a/Libraries/SPTarkov.Server.Core/Helpers/UtilityHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/UtilityHelper.cs deleted file mode 100644 index b5793fff..00000000 --- a/Libraries/SPTarkov.Server.Core/Helpers/UtilityHelper.cs +++ /dev/null @@ -1,15 +0,0 @@ -using SPTarkov.DI.Annotations; - -namespace SPTarkov.Server.Core.Helpers; - -[Injectable] -public class UtilityHelper -{ - public List ArrayIntersect(List a, List b) - { - //a.Intersect(x => b.Contains(x)).ToList(); - // gives error Delegate type could not be infered - - return a.Where(x => b.Contains(x)).ToList(); - } -} diff --git a/Libraries/SPTarkov.Server.Core/Models/Eft/Player/PlayerIncrementSkillLevelRequestData.cs b/Libraries/SPTarkov.Server.Core/Models/Eft/Player/PlayerIncrementSkillLevelRequestData.cs deleted file mode 100644 index 991d2751..00000000 --- a/Libraries/SPTarkov.Server.Core/Models/Eft/Player/PlayerIncrementSkillLevelRequestData.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Text.Json.Serialization; -using SPTarkov.Server.Core.Models.Eft.Common.Tables; - -namespace SPTarkov.Server.Core.Models.Eft.Player; - -public record PlayerIncrementSkillLevelRequestData -{ - [JsonExtensionData] - public Dictionary? ExtensionData { get; set; } - - [JsonPropertyName("_id")] - public string? Id { get; set; } - - [JsonPropertyName("experience")] - public int? Experience { get; set; } - - [JsonPropertyName("quests")] - public List? Quests { get; set; } - - [JsonPropertyName("ragFairOffers")] - public List? RagFairOffers { get; set; } - - [JsonPropertyName("builds")] - public List? Builds { get; set; } - - [JsonPropertyName("items")] - public Items? Items { get; set; } - - [JsonPropertyName("production")] - public Production? Production { get; set; } - - [JsonPropertyName("skills")] - public Skills? Skills { get; set; } - - [JsonPropertyName("traderRelations")] - public TraderRelations? TraderRelations { get; set; } -} - -// TODO: These are all lists of objects. -public record Items -{ - [JsonExtensionData] - public Dictionary? ExtensionData { get; set; } - - [JsonPropertyName("new")] - public List? NewItems { get; set; } - - [JsonPropertyName("change")] - public List? ChangedItems { get; set; } - - [JsonPropertyName("del")] - public List? DeletedItems { get; set; } -} - -public record Production -{ - [JsonExtensionData] - public Dictionary? ExtensionData { get; set; } -} - -public record TraderRelations -{ - [JsonExtensionData] - public Dictionary? ExtensionData { get; set; } -} diff --git a/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs b/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs index a0a1732c..05243a03 100644 --- a/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs +++ b/Libraries/SPTarkov.Server.Core/Services/PaymentService.cs @@ -238,7 +238,7 @@ public class PaymentService( } // Item is not in the stash - if (!_inventoryHelper.IsItemInStash(pmcData, item)) + if (!pmcData.IsItemInStash(item)) { continue; } diff --git a/Libraries/SPTarkov.Server.Core/Utils/RandomUtil.cs b/Libraries/SPTarkov.Server.Core/Utils/RandomUtil.cs index ca546f2f..cc9375df 100644 --- a/Libraries/SPTarkov.Server.Core/Utils/RandomUtil.cs +++ b/Libraries/SPTarkov.Server.Core/Utils/RandomUtil.cs @@ -461,4 +461,15 @@ public class RandomUtil(ISptLogger _logger, ICloner _cloner) { return GetCollectionValue(list); } + + /// + /// Chance to roll a number out of 100 + /// + /// Percentage chance roll should success + /// scale of chance to allow support of numbers > 1-100 + /// true if success + public bool RollChance(double chance, double scale = 1) + { + return GetInt(1, (int)(100 * scale)) / (1 * scale) <= chance; + } }