From 8276e7bef8a88caaf4864983a6a9e922463f1a1e Mon Sep 17 00:00:00 2001 From: Chomp Date: Thu, 19 Jun 2025 12:10:08 +0100 Subject: [PATCH] Added rootItem to `CreateOffersFromAssort` and skip `RemoveBannedPlatesFromPreset` when creating replacement expired offer Added `isExpiredOffer` `CreateSingleOfferForItem`, Only remove armor plates on non-expired offers + added helper method `RemoveArmorPlates` --- .../Generators/RagfairOfferGenerator.cs | 105 ++++++++++-------- .../Helpers/RagfairServerHelper.cs | 4 +- 2 files changed, 63 insertions(+), 46 deletions(-) diff --git a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs index eedd37bc..c0705724 100644 --- a/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs +++ b/Libraries/SPTarkov.Server.Core/Generators/RagfairOfferGenerator.cs @@ -431,9 +431,9 @@ public class RagfairOfferGenerator( Dynamic config ) { - var itemToSellDetails = itemHelper.GetItem(assortItemWithChildren[0].Template); - var isPreset = presetHelper.IsPreset(assortItemWithChildren[0].Upd.SptPresetId); - + var rootItem = assortItemWithChildren.FirstOrDefault(); + var itemToSellDetails = itemHelper.GetItem(rootItem.Template); + // Only perform checks on newly generated items, skip expired items being refreshed if (!(isExpiredOffer || ragfairServerHelper.IsItemValidRagfairItem(itemToSellDetails))) { @@ -441,7 +441,8 @@ public class RagfairOfferGenerator( } // Armor presets can hold plates above the allowed flea level, remove if necessary - if (isPreset && ragfairConfig.Dynamic.Blacklist.EnableBsgList) + var isPreset = presetHelper.IsPreset(rootItem.Upd.SptPresetId); + if (!isExpiredOffer && isPreset && ragfairConfig.Dynamic.Blacklist.EnableBsgList) { RemoveBannedPlatesFromPreset( assortItemWithChildren, @@ -469,7 +470,8 @@ public class RagfairOfferGenerator( hashUtil.Generate(), clonedAssort, isPreset, - itemToSellDetails.Value + itemToSellDetails.Value, + isExpiredOffer ); } } @@ -524,63 +526,45 @@ public class RagfairOfferGenerator( /// Create one flea offer for a specific item /// /// ID of seller - /// Item to create offer for + /// Item to create offer for /// Is item a weapon preset /// Raw DB item details + /// Offer being created is to replace an expired, existing offer protected void CreateSingleOfferForItem( string sellerId, List itemWithChildren, bool isPreset, - TemplateItem itemToSellDetails + TemplateItem itemToSellDetails, + bool isExpiredOffer ) { + var rootItem = itemWithChildren.FirstOrDefault(); + // Get randomised amount to list on flea var desiredStackSize = ragfairServerHelper.CalculateDynamicStackCount( - itemWithChildren[0].Template, + rootItem.Template, isPreset ); - + // Reset stack count to 1 from whatever it was prior - itemWithChildren[0].Upd.StackObjectsCount = 1; + rootItem.Upd.StackObjectsCount = 1; + + if (!isExpiredOffer && itemHelper.ArmorItemCanHoldMods(rootItem.Template)) + { + // Run randomised chance to remove removable plates from new offers(not expired) + RemoveArmorPlates(itemWithChildren, rootItem); + } var isBarterOffer = randomUtil.GetChance100(ragfairConfig.Dynamic.Barter.ChancePercent); var isPackOffer = - randomUtil.GetChance100(ragfairConfig.Dynamic.Pack.ChancePercent) - && !isBarterOffer + !isBarterOffer + && randomUtil.GetChance100(ragfairConfig.Dynamic.Pack.ChancePercent) && itemWithChildren.Count == 1 && itemHelper.IsOfBaseclasses( - itemWithChildren[0].Template, + rootItem.Template, ragfairConfig.Dynamic.Pack.ItemTypeWhitelist ); - // Remove removable plates if % check passes - if (itemHelper.ArmorItemCanHoldMods(itemWithChildren[0].Template)) - { - var armorConfig = ragfairConfig.Dynamic.Armor; - - var shouldRemovePlates = randomUtil.GetChance100( - armorConfig.RemoveRemovablePlateChance - ); - if ( - shouldRemovePlates - && itemHelper.ArmorItemHasRemovablePlateSlots(itemWithChildren[0].Template) - ) - { - var offerItemPlatesToRemove = itemWithChildren.Where(item => - armorConfig.PlateSlotIdToRemovePool.Contains(item.SlotId?.ToLower()) - ); - - // Latest first, to ensure we don't move later items off by 1 each time we remove an item below it - var indexesToRemove = offerItemPlatesToRemove - .Select(plateItem => itemWithChildren.IndexOf(plateItem)) - .ToHashSet(); - foreach (var index in indexesToRemove.OrderByDescending(x => x)) - { - itemWithChildren.RemoveAt(index); - } - } - } - List barterScheme; if (isPackOffer) { @@ -604,15 +588,16 @@ public class RagfairOfferGenerator( barterScheme = CreateBarterBarterScheme(itemWithChildren, ragfairConfig.Dynamic.Barter); if (ragfairConfig.Dynamic.Barter.MakeSingleStackOnly) { - var rootItem = itemWithChildren.FirstOrDefault(); - if (rootItem?.Upd != null) + var rootBarterItem = itemWithChildren.FirstOrDefault(); + if (rootBarterItem?.Upd != null) { - rootItem.Upd.StackObjectsCount = 1; + rootBarterItem.Upd.StackObjectsCount = 1; } } } else { + // Not barter or pack offer // Apply randomised properties RandomiseOfferItemUpdProperties(sellerId, itemWithChildren, itemToSellDetails); barterScheme = CreateCurrencyBarterScheme(itemWithChildren, isPackOffer); @@ -629,6 +614,38 @@ public class RagfairOfferGenerator( ); } + /// + /// Run % check to remove removable armor plates from item + /// + /// Armor item + /// Root armor item + protected void RemoveArmorPlates(List itemWithChildren, Item rootItem) + { + var armorConfig = ragfairConfig.Dynamic.Armor; + + var shouldRemovePlates = randomUtil.GetChance100( + armorConfig.RemoveRemovablePlateChance + ); + if (!shouldRemovePlates || !itemHelper.ArmorItemHasRemovablePlateSlots(rootItem.Template) + ) + { + return; + } + + var offerItemPlatesToRemove = itemWithChildren.Where(item => + armorConfig.PlateSlotIdToRemovePool.Contains(item.SlotId?.ToLower()) + ); + + // Latest first, to ensure we don't move later items off by 1 each time we remove an item below it + var indexesToRemove = offerItemPlatesToRemove + .Select(plateItem => itemWithChildren.IndexOf(plateItem)) + .ToHashSet(); + foreach (var index in indexesToRemove.OrderByDescending(x => x)) + { + itemWithChildren.RemoveAt(index); + } + } + /// /// Generate trader offers on flea using the traders assort data /// diff --git a/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs b/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs index 962b6304..597eafac 100644 --- a/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs +++ b/Libraries/SPTarkov.Server.Core/Helpers/RagfairServerHelper.cs @@ -145,7 +145,7 @@ public class RagfairServerHelper( ); } - public int CalculateDynamicStackCount(string tplId, bool isWeaponPreset) + public int CalculateDynamicStackCount(string tplId, bool isPreset) { var config = ragfairConfig.Dynamic; @@ -163,7 +163,7 @@ public class RagfairServerHelper( // Item Types to return one of if ( - isWeaponPreset + isPreset || itemHelper.IsOfBaseclasses( itemDetails.Value.Id, ragfairConfig.Dynamic.ShowAsSingleStack