From badb12830d3e664d953d49593587c35621aeaa60 Mon Sep 17 00:00:00 2001 From: CWX Date: Sat, 25 Jan 2025 20:31:05 +0000 Subject: [PATCH 1/3] fix jsonelement --- Libraries/Core/Helpers/RewardHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Libraries/Core/Helpers/RewardHelper.cs b/Libraries/Core/Helpers/RewardHelper.cs index 2eac3e89..eae04bfc 100644 --- a/Libraries/Core/Helpers/RewardHelper.cs +++ b/Libraries/Core/Helpers/RewardHelper.cs @@ -213,7 +213,7 @@ namespace Core.Helpers var craftingRecipes = _databaseService.GetHideout().Production.Recipes; // Area that will be used to craft unlocked item - var desiredHideoutAreaType = (HideoutAreas)craftUnlockReward.TraderId; + var desiredHideoutAreaType = (HideoutAreas)int.Parse(craftUnlockReward.TraderId.ToString()); var matchingProductions = craftingRecipes.Where( (prod) => From 0327f998059ccabb206e5bac50bf1533d57322c7 Mon Sep 17 00:00:00 2001 From: Chomp Date: Sat, 25 Jan 2025 21:21:27 +0000 Subject: [PATCH 2/3] Fixed bots spawning with empty upd objects --- Libraries/Core/Helpers/BotGeneratorHelper.cs | 31 ++++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/Libraries/Core/Helpers/BotGeneratorHelper.cs b/Libraries/Core/Helpers/BotGeneratorHelper.cs index 4631c44b..be4fa009 100644 --- a/Libraries/Core/Helpers/BotGeneratorHelper.cs +++ b/Libraries/Core/Helpers/BotGeneratorHelper.cs @@ -45,6 +45,7 @@ public class BotGeneratorHelper( _botConfig.LootItemResourceRandomization.TryGetValue(botRole, out var randomisationSettings); Upd itemProperties = new(); + var hasProperties = false; if (itemTemplate?.Properties?.MaxDurability is not null) { @@ -52,22 +53,26 @@ public class BotGeneratorHelper( { // Is weapon itemProperties.Repairable = GenerateWeaponRepairableProperties(itemTemplate, botRole); + hasProperties = true; } else if (itemTemplate.Properties.ArmorClass is not null) { // Is armor itemProperties.Repairable = GenerateArmorRepairableProperties(itemTemplate, botRole); + hasProperties = true; } } if (itemTemplate?.Properties?.HasHinge ?? false) { itemProperties.Togglable = new UpdTogglable { On = true }; + hasProperties = true; } if (itemTemplate?.Properties?.Foldable ?? false) { itemProperties.Foldable = new UpdFoldable { Folded = false }; + hasProperties = true; } if (itemTemplate?.Properties?.WeapFireType?.Count == 0) @@ -75,6 +80,7 @@ public class BotGeneratorHelper( itemProperties.FireMode = itemTemplate.Properties.WeapFireType.Contains("fullauto") ? new UpdFireMode { FireMode = "fullauto" } : new UpdFireMode { FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType) }; + hasProperties = true; } if (itemTemplate?.Properties?.MaxHpResource is not null) @@ -86,6 +92,7 @@ public class BotGeneratorHelper( randomisationSettings?.Meds ) }; + hasProperties = true; } if (itemTemplate?.Properties?.MaxResource is not null && itemTemplate.Properties?.FoodUseTime is not null) @@ -97,6 +104,7 @@ public class BotGeneratorHelper( randomisationSettings?.Food ), }; + hasProperties = true; } if (itemTemplate?.Parent == BaseClasses.FLASHLIGHT) @@ -106,6 +114,7 @@ public class BotGeneratorHelper( ? GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50) : GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25); itemProperties.Light = new UpdLight { IsActive = _randomUtil.GetChance100(lightLaserActiveChance), SelectedMode = 0, }; + hasProperties = true; } else if (itemTemplate?.Parent == BaseClasses.TACTICAL_COMBO) { @@ -120,6 +129,7 @@ public class BotGeneratorHelper( IsActive = _randomUtil.GetChance100(lightLaserActiveChance), SelectedMode = 0, }; + hasProperties = true; } if (itemTemplate?.Parent == BaseClasses.NIGHTVISION) @@ -129,20 +139,23 @@ public class BotGeneratorHelper( ? GetBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceNightPercent", 90) : GetBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15); itemProperties.Togglable = new UpdTogglable { On = _randomUtil.GetChance100(nvgActiveChance) }; + hasProperties = true; } // Togglable face shield - if (!(itemTemplate?.Properties?.HasHinge ?? false) || !(itemTemplate.Properties.FaceShieldComponent ?? false)) return itemProperties; + if ((itemTemplate?.Properties?.HasHinge ?? false) && (itemTemplate.Properties.FaceShieldComponent ?? false)) + { + var faceShieldActiveChance = GetBotEquipmentSettingFromConfig( + botRole, + "faceShieldIsActiveChancePercent", + 75 + ); + itemProperties.Togglable = new UpdTogglable { On = _randomUtil.GetChance100(faceShieldActiveChance) }; + hasProperties = true; + } // Get chance from botconfig for bot type, use 75% if no value found - var faceShieldActiveChance = GetBotEquipmentSettingFromConfig( - botRole, - "faceShieldIsActiveChancePercent", - 75 - ); - itemProperties.Togglable = new UpdTogglable { On = _randomUtil.GetChance100(faceShieldActiveChance) }; - - return itemProperties; + return hasProperties ? itemProperties : null; } /// From e16a08489a1db34ae5b80abc22a2bb979bc2d881 Mon Sep 17 00:00:00 2001 From: CWX Date: Sat, 25 Jan 2025 21:20:32 +0000 Subject: [PATCH 3/3] Fix profiles not creating, along with chomps replaceID changes --- .../Core/Controllers/HideoutController.cs | 4 ++-- .../Generators/FenceBaseAssortGenerator.cs | 6 +++-- .../Core/Generators/LocationLootGenerator.cs | 4 ++-- .../Core/Generators/RagfairAssortGenerator.cs | 6 +++-- .../Generators/ScavCaseRewardGenerator.cs | 6 +++-- Libraries/Core/Helpers/RewardHelper.cs | 2 +- Libraries/Core/Services/FenceService.cs | 22 +++++++++---------- Libraries/Core/Services/MailSendService.cs | 6 +++-- 8 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Libraries/Core/Controllers/HideoutController.cs b/Libraries/Core/Controllers/HideoutController.cs index 5a377d01..f2f4f604 100644 --- a/Libraries/Core/Controllers/HideoutController.cs +++ b/Libraries/Core/Controllers/HideoutController.cs @@ -714,7 +714,7 @@ public class HideoutController( var defaultPreset = _presetHelper.GetDefaultPreset(recipe.EndProduct); // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory - List presetAndMods = _itemHelper.ReplaceIDs(defaultPreset.Items); + List presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); _itemHelper.RemapRootItemId(presetAndMods); @@ -752,7 +752,7 @@ public class HideoutController( var countOfItemsToReward = recipe.Count; for (var index = 1; index < countOfItemsToReward; index++) { - List itemAndMods = _itemHelper.ReplaceIDs(itemAndChildrenToSendToPlayer.FirstOrDefault()); + List itemAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault())); itemAndChildrenToSendToPlayer.AddRange([itemAndMods]); } } diff --git a/Libraries/Core/Generators/FenceBaseAssortGenerator.cs b/Libraries/Core/Generators/FenceBaseAssortGenerator.cs index 9bf1a7e4..d1c9980f 100644 --- a/Libraries/Core/Generators/FenceBaseAssortGenerator.cs +++ b/Libraries/Core/Generators/FenceBaseAssortGenerator.cs @@ -7,6 +7,7 @@ using Core.Models.Utils; using Core.Servers; using Core.Services; using Core.Utils; +using Core.Utils.Cloners; namespace Core.Generators; @@ -22,7 +23,8 @@ public class FenceBaseAssortGenerator( SeasonalEventService seasonalEventService, LocalisationService localisationService, ConfigServer configServer, - FenceService fenceService + FenceService fenceService, + ICloner _cloner ) { protected TraderConfig traderConfig = configServer.GetConfig(); @@ -147,7 +149,7 @@ public class FenceBaseAssortGenerator( } // Construct preset + mods - var itemAndChildren = itemHelper.ReplaceIDs(defaultPreset.Items); + var itemAndChildren = itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); // Find root item and add some properties to it for (var i = 0; i < itemAndChildren.Count; i++) diff --git a/Libraries/Core/Generators/LocationLootGenerator.cs b/Libraries/Core/Generators/LocationLootGenerator.cs index 72b41328..be5f9019 100644 --- a/Libraries/Core/Generators/LocationLootGenerator.cs +++ b/Libraries/Core/Generators/LocationLootGenerator.cs @@ -945,7 +945,7 @@ public class LocationLootGenerator( var itemWithChildren = _itemHelper.FindAndReturnChildrenAsItems(items, chosenItem.Id); // Ensure all IDs are unique - itemWithChildren = _itemHelper.ReplaceIDs(itemWithChildren); + itemWithChildren = _itemHelper.ReplaceIDs(_cloner.Clone(itemWithChildren)); if (_locationConfig.TplsToStripChildItemsFrom.Contains(chosenItem.Template)) { // Strip children from parent before adding @@ -1148,7 +1148,7 @@ public class LocationLootGenerator( var defaultPreset = _presetHelper.GetDefaultPreset(chosenTpl); if (defaultPreset is not null) { - List presetAndMods = _itemHelper.ReplaceIDs(defaultPreset.Items); + List presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); _itemHelper.RemapRootItemId(presetAndMods); // Use original items parentId otherwise item doesnt get added to container correctly diff --git a/Libraries/Core/Generators/RagfairAssortGenerator.cs b/Libraries/Core/Generators/RagfairAssortGenerator.cs index 30da3261..ceb019e8 100644 --- a/Libraries/Core/Generators/RagfairAssortGenerator.cs +++ b/Libraries/Core/Generators/RagfairAssortGenerator.cs @@ -7,6 +7,7 @@ using Core.Models.Spt.Config; using Core.Servers; using Core.Services; using Core.Utils; +using Core.Utils.Cloners; namespace Core.Generators; @@ -16,7 +17,8 @@ public class RagfairAssortGenerator( ItemHelper itemHelper, PresetHelper presetHelper, SeasonalEventService seasonalEventService, - ConfigServer configServer + ConfigServer configServer, + ICloner _cloner ) { protected List> generatedAssortItems = []; @@ -77,7 +79,7 @@ public class RagfairAssortGenerator( foreach (var preset in presets) { // Update Ids and clone - var presetAndMods = itemHelper.ReplaceIDs(preset.Items); + var presetAndMods = itemHelper.ReplaceIDs(_cloner.Clone(preset.Items)); itemHelper.RemapRootItemId(presetAndMods); // Add presets base item tpl to the processed list so its skipped later on when processing items diff --git a/Libraries/Core/Generators/ScavCaseRewardGenerator.cs b/Libraries/Core/Generators/ScavCaseRewardGenerator.cs index 624f1062..9cc71f1a 100644 --- a/Libraries/Core/Generators/ScavCaseRewardGenerator.cs +++ b/Libraries/Core/Generators/ScavCaseRewardGenerator.cs @@ -11,6 +11,7 @@ using Core.Models.Utils; using Core.Servers; using Core.Services; using Core.Utils; +using Core.Utils.Cloners; using SptCommon.Extensions; namespace Core.Generators; @@ -26,7 +27,8 @@ public class ScavCaseRewardGenerator( RagfairPriceService _ragfairPriceService, SeasonalEventService _seasonalEventService, ItemFilterService _itemFilterService, - ConfigServer _configServer + ConfigServer _configServer, + ICloner _cloner ) { protected ScavCaseConfig _scavCaseConfig = _configServer.GetConfig(); @@ -312,7 +314,7 @@ public class ScavCaseRewardGenerator( } // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory - List presetAndMods = _itemHelper.ReplaceIDs(preset.Items); + List presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(preset.Items)); _itemHelper.RemapRootItemId(presetAndMods); resultItem = presetAndMods; diff --git a/Libraries/Core/Helpers/RewardHelper.cs b/Libraries/Core/Helpers/RewardHelper.cs index eae04bfc..51fa07d4 100644 --- a/Libraries/Core/Helpers/RewardHelper.cs +++ b/Libraries/Core/Helpers/RewardHelper.cs @@ -361,7 +361,7 @@ namespace Core.Helpers if (defaultPreset is not null) { // Found preset, use mods to hydrate reward item - var presetAndMods = _itemHelper.ReplaceIDs(defaultPreset.Items); + var presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items)); var newRootId = _itemHelper.RemapRootItemId(presetAndMods); reward.Items = presetAndMods; diff --git a/Libraries/Core/Services/FenceService.cs b/Libraries/Core/Services/FenceService.cs index 9151dd06..e287e0c8 100644 --- a/Libraries/Core/Services/FenceService.cs +++ b/Libraries/Core/Services/FenceService.cs @@ -25,7 +25,7 @@ public class FenceService( PresetHelper presetHelper, LocalisationService localisationService, ConfigServer configServer, - ICloner cloner + ICloner _cloner ) { protected TraderConfig traderConfig = configServer.GetConfig(); @@ -116,13 +116,13 @@ public class FenceService( } // Clone assorts so we can adjust prices before sending to client - var assort = cloner.Clone(fenceAssort); + var assort = _cloner.Clone(fenceAssort); AdjustAssortItemPricesByConfigMultiplier(assort, 1, traderConfig.Fence.PresetPriceMult); // merge normal fence assorts + discount assorts if player standing is large enough if (pmcProfile.TradersInfo[Traders.FENCE].Standing >= 6) { - var discountAssort = cloner.Clone(fenceDiscountAssort); + var discountAssort = _cloner.Clone(fenceDiscountAssort); AdjustAssortItemPricesByConfigMultiplier( discountAssort, traderConfig.Fence.DiscountOptions.ItemPriceMult, @@ -145,7 +145,7 @@ public class FenceService( { // HUGE THANKS TO LACYWAY AND LEAVES FOR PROVIDING THIS SOLUTION FOR SPT TO IMPLEMENT!! // Copy the item and its children - var clonedItems = cloner.Clone(itemHelper.FindAndReturnChildrenAsItems(items, mainItem.Id)); + var clonedItems = _cloner.Clone(itemHelper.FindAndReturnChildrenAsItems(items, mainItem.Id)); var root = clonedItems[0]; var cost = GetItemPrice(root.Template, clonedItems); @@ -292,7 +292,7 @@ public class FenceService( */ public TraderAssort GetRawFenceAssorts() { - return MergeAssorts(cloner.Clone(fenceAssort), cloner.Clone(fenceDiscountAssort)); + return MergeAssorts(_cloner.Clone(fenceAssort), _cloner.Clone(fenceDiscountAssort)); } /** @@ -675,7 +675,7 @@ public class FenceService( { var result = new CreateFenceAssortsResult() { SptItems = [], BarterScheme = new(), LoyalLevelItems = new() }; - var baseFenceAssortClone = cloner.Clone(databaseService.GetTrader(Traders.FENCE).Assort); + var baseFenceAssortClone = _cloner.Clone(databaseService.GetTrader(Traders.FENCE).Assort); var itemTypeLimitCounts = InitItemLimitCounter(traderConfig.Fence.ItemTypeLimits); if (itemCounts.Item > 0) @@ -733,7 +733,7 @@ public class FenceService( continue; } - var desiredAssortItemAndChildrenClone = cloner.Clone( + var desiredAssortItemAndChildrenClone = _cloner.Clone( itemHelper.FindAndReturnChildrenAsItems(baseFenceAssortClone.Items, chosenBaseAssortRoot.Id) ); @@ -771,7 +771,7 @@ public class FenceService( } // MUST randomise Ids as its possible to add the same base fence assort twice = duplicate IDs = dead client - desiredAssortItemAndChildrenClone = itemHelper.ReplaceIDs(desiredAssortItemAndChildrenClone); + desiredAssortItemAndChildrenClone = itemHelper.ReplaceIDs(_cloner.Clone(desiredAssortItemAndChildrenClone)); itemHelper.RemapRootItemId(desiredAssortItemAndChildrenClone); var rootItemBeingAdded = desiredAssortItemAndChildrenClone[0]; @@ -807,7 +807,7 @@ public class FenceService( assorts.SptItems.Add(desiredAssortItemAndChildrenClone); assorts.BarterScheme[rootItemBeingAdded.Id] = - cloner.Clone(baseFenceAssortClone.BarterScheme[chosenBaseAssortRoot.Id]); + _cloner.Clone(baseFenceAssortClone.BarterScheme[chosenBaseAssortRoot.Id]); // Only adjust item price by quality for solo items, never multi-stack if (isSingleStack) @@ -1015,7 +1015,7 @@ public class FenceService( var rootItemDb = itemHelper.GetItem(randomPresetRoot.Template).Value; - var presetWithChildrenClone = cloner.Clone( + var presetWithChildrenClone = _cloner.Clone( itemHelper.FindAndReturnChildrenAsItems(baseFenceAssort.Items, randomPresetRoot.Id) ); @@ -1076,7 +1076,7 @@ public class FenceService( var randomPresetRoot = randomUtil.GetArrayValue(equipmentPresetRootItems); var rootItemDb = itemHelper.GetItem(randomPresetRoot.Template).Value; - var presetWithChildrenClone = cloner.Clone( + var presetWithChildrenClone = _cloner.Clone( itemHelper.FindAndReturnChildrenAsItems(baseFenceAssort.Items, randomPresetRoot.Id) ); diff --git a/Libraries/Core/Services/MailSendService.cs b/Libraries/Core/Services/MailSendService.cs index dedc4a0f..46f6230a 100644 --- a/Libraries/Core/Services/MailSendService.cs +++ b/Libraries/Core/Services/MailSendService.cs @@ -7,6 +7,7 @@ using Core.Models.Spt.Dialog; using Core.Models.Utils; using Core.Servers; using Core.Utils; +using Core.Utils.Cloners; namespace Core.Services; @@ -22,7 +23,8 @@ public class MailSendService( NotificationSendHelper _notificationSendHelper, LocalisationService _localisationService, ItemHelper _itemHelper, - TraderHelper _traderHelper + TraderHelper _traderHelper, + ICloner _cloner ) { private const string _systemSenderId = "59e7125688a45068a6249071"; @@ -453,7 +455,7 @@ public class MailSendService( }; // Ensure Ids are unique and cont collide with items in player inventory later - messageDetails.Items = _itemHelper.ReplaceIDs(messageDetails.Items); + messageDetails.Items = _itemHelper.ReplaceIDs(_cloner.Clone(messageDetails.Items)); // Ensure item exits in items db foreach (var reward in messageDetails.Items)