This commit is contained in:
Valens
2025-01-25 16:23:02 -05:00
9 changed files with 55 additions and 34 deletions
@@ -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<Item> presetAndMods = _itemHelper.ReplaceIDs(defaultPreset.Items);
List<Item> 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<Item> itemAndMods = _itemHelper.ReplaceIDs(itemAndChildrenToSendToPlayer.FirstOrDefault());
List<Item> itemAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(itemAndChildrenToSendToPlayer.FirstOrDefault()));
itemAndChildrenToSendToPlayer.AddRange([itemAndMods]);
}
}
@@ -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<TraderConfig>();
@@ -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++)
@@ -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<Item> presetAndMods = _itemHelper.ReplaceIDs(defaultPreset.Items);
List<Item> presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(defaultPreset.Items));
_itemHelper.RemapRootItemId(presetAndMods);
// Use original items parentId otherwise item doesnt get added to container correctly
@@ -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<List<Item>> 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
@@ -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<ScavCaseConfig>();
@@ -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<Item> presetAndMods = _itemHelper.ReplaceIDs(preset.Items);
List<Item> presetAndMods = _itemHelper.ReplaceIDs(_cloner.Clone(preset.Items));
_itemHelper.RemapRootItemId(presetAndMods);
resultItem = presetAndMods;
+22 -9
View File
@@ -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;
}
/// <summary>
+2 -2
View File
@@ -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) =>
@@ -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;
+11 -11
View File
@@ -25,7 +25,7 @@ public class FenceService(
PresetHelper presetHelper,
LocalisationService localisationService,
ConfigServer configServer,
ICloner cloner
ICloner _cloner
)
{
protected TraderConfig traderConfig = configServer.GetConfig<TraderConfig>();
@@ -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)
);
+4 -2
View File
@@ -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)