Merge branch 'main' of https://github.com/sp-tarkov/server-csharp
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user