BotGeneraorHelper cleared of warnings, other changes needed for that too
This commit is contained in:
+149
-150
@@ -31,8 +31,8 @@ public class BotLootGenerator
|
||||
private readonly ConfigServer _configServer;
|
||||
private readonly ICloner _cloner;
|
||||
|
||||
private BotConfig _botConfig;
|
||||
private PmcConfig _pmcConfig;
|
||||
private readonly BotConfig _botConfig;
|
||||
private readonly PmcConfig _pmcConfig;
|
||||
|
||||
public BotLootGenerator(
|
||||
ISptLogger<BotLootGenerator> logger,
|
||||
@@ -77,13 +77,13 @@ public class BotLootGenerator
|
||||
/// <param name="botRole"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public ItemSpawnLimitSettings GetItemSpawnLimitsForBot(string botRole)
|
||||
private ItemSpawnLimitSettings GetItemSpawnLimitsForBot(string botRole)
|
||||
{
|
||||
// Init item limits
|
||||
Dictionary<string, double> limitsForBotDict = new();
|
||||
InitItemLimitArray(botRole, limitsForBotDict);
|
||||
|
||||
return new() { CurrentLimits = limitsForBotDict, GlobalLimits = GetItemSpawnLimitsForBotType(botRole) };
|
||||
return new ItemSpawnLimitSettings { CurrentLimits = limitsForBotDict, GlobalLimits = GetItemSpawnLimitsForBotType(botRole) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -98,10 +98,10 @@ public class BotLootGenerator
|
||||
public void GenerateLoot(string sessionId, BotType botJsonTemplate, bool isPmc, string botRole, BotBaseInventory botInventory, int botLevel)
|
||||
{
|
||||
// Limits on item types to be added as loot
|
||||
var itemCounts = botJsonTemplate.BotGeneration.Items;
|
||||
var itemCounts = botJsonTemplate.BotGeneration?.Items;
|
||||
|
||||
if (
|
||||
itemCounts.BackpackLoot.Weights is null ||
|
||||
itemCounts?.BackpackLoot.Weights is null ||
|
||||
itemCounts.PocketLoot.Weights is null ||
|
||||
itemCounts.VestLoot.Weights is null ||
|
||||
itemCounts.SpecialItems.Weights is null ||
|
||||
@@ -268,7 +268,7 @@ public class BotLootGenerator
|
||||
botInventory,
|
||||
EquipmentSlots.Backpack,
|
||||
botJsonTemplate.BotInventory,
|
||||
botJsonTemplate.BotChances.WeaponModsChances,
|
||||
botJsonTemplate.BotChances?.WeaponModsChances,
|
||||
botRole,
|
||||
isPmc,
|
||||
botLevel,
|
||||
@@ -360,16 +360,14 @@ public class BotLootGenerator
|
||||
private MinMaxLootItemValue? GetSingleItemLootPriceLimits(int botLevel, bool isPmc)
|
||||
{
|
||||
// TODO - extend to other bot types
|
||||
if (isPmc)
|
||||
{
|
||||
var matchingValue = _pmcConfig.LootItemLimitsRub.FirstOrDefault(
|
||||
(minMaxValue) => botLevel >= minMaxValue.Min && botLevel <= minMaxValue.Max
|
||||
);
|
||||
if (!isPmc) return null;
|
||||
|
||||
var matchingValue = _pmcConfig?.LootItemLimitsRub?.FirstOrDefault(
|
||||
minMaxValue => botLevel >= minMaxValue.Min && botLevel <= minMaxValue.Max
|
||||
);
|
||||
|
||||
return matchingValue;
|
||||
}
|
||||
return matchingValue;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -379,17 +377,15 @@ public class BotLootGenerator
|
||||
/// <param name="botLevel">Bots level</param>
|
||||
/// <param name="isPmc">Is the bot a PMC</param>
|
||||
/// <returns>int</returns>
|
||||
public double? GetBackpackRoubleTotalByLevel(int botLevel, bool isPmc)
|
||||
private double? GetBackpackRoubleTotalByLevel(int botLevel, bool isPmc)
|
||||
{
|
||||
if (isPmc)
|
||||
{
|
||||
var matchingValue = _pmcConfig.MaxBackpackLootTotalRub.FirstOrDefault(
|
||||
(minMaxValue) => botLevel >= minMaxValue.Min && botLevel <= minMaxValue.Max
|
||||
);
|
||||
return matchingValue?.Value;
|
||||
}
|
||||
if (!isPmc) return 0;
|
||||
|
||||
var matchingValue = _pmcConfig.MaxBackpackLootTotalRub.FirstOrDefault(
|
||||
(minMaxValue) => botLevel >= minMaxValue.Min && botLevel <= minMaxValue.Max
|
||||
);
|
||||
return matchingValue?.Value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -398,16 +394,16 @@ public class BotLootGenerator
|
||||
/// <param name="botInventory"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public List<EquipmentSlots> GetAvailableContainersBotCanStoreItemsIn(BotBaseInventory botInventory)
|
||||
private List<EquipmentSlots> GetAvailableContainersBotCanStoreItemsIn(BotBaseInventory botInventory)
|
||||
{
|
||||
List<EquipmentSlots> result = [EquipmentSlots.Pockets];
|
||||
|
||||
if (botInventory.Items.Any((item) => item.SlotId == EquipmentSlots.TacticalVest.ToString()))
|
||||
if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.TacticalVest.ToString()))
|
||||
{
|
||||
result.Add(EquipmentSlots.TacticalVest);
|
||||
}
|
||||
|
||||
if (botInventory.Items.Any((item) => item.SlotId == EquipmentSlots.Backpack.ToString()))
|
||||
if ((botInventory.Items ?? []).Any((item) => item.SlotId == EquipmentSlots.Backpack.ToString()))
|
||||
{
|
||||
result.Add(EquipmentSlots.Backpack);
|
||||
}
|
||||
@@ -420,11 +416,11 @@ public class BotLootGenerator
|
||||
/// </summary>
|
||||
/// <param name="botInventory">Inventory to add items to</param>
|
||||
/// <param name="botRole">Role of bot (pmcBEAR/pmcUSEC)</param>
|
||||
public void AddForcedMedicalItemsToPmcSecure(BotBaseInventory botInventory, string botRole)
|
||||
private void AddForcedMedicalItemsToPmcSecure(BotBaseInventory botInventory, string botRole)
|
||||
{
|
||||
// surv12
|
||||
AddLootFromPool(
|
||||
new() { { "5d02797c86f774203f38e30a", 1 } },
|
||||
new Dictionary<string, double> { { "5d02797c86f774203f38e30a", 1 } },
|
||||
[EquipmentSlots.SecuredContainer],
|
||||
1,
|
||||
botInventory,
|
||||
@@ -436,7 +432,7 @@ public class BotLootGenerator
|
||||
|
||||
// AFAK
|
||||
AddLootFromPool(
|
||||
new() { { "60098ad7c2240c0fe85c570a", 1 } },
|
||||
new Dictionary<string, double> { { "60098ad7c2240c0fe85c570a", 1 } },
|
||||
[EquipmentSlots.SecuredContainer],
|
||||
10,
|
||||
botInventory,
|
||||
@@ -460,152 +456,152 @@ public class BotLootGenerator
|
||||
/// <param name="totalValueLimitRub">Total value of loot allowed in roubles</param>
|
||||
/// <param name="isPmc">Is bot being generated for a pmc</param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public void AddLootFromPool
|
||||
private void AddLootFromPool
|
||||
(
|
||||
Dictionary<string, double> pool,
|
||||
List<EquipmentSlots> equipmentSlots,
|
||||
double totalItemCount,
|
||||
BotBaseInventory inventoryToAddItemsTo, // TODO: type for containersIdFull was Set<string>
|
||||
BotBaseInventory inventoryToAddItemsTo,
|
||||
string botRole,
|
||||
ItemSpawnLimitSettings itemSpawnLimits,
|
||||
ItemSpawnLimitSettings? itemSpawnLimits,
|
||||
double totalValueLimitRub = 0,
|
||||
bool isPmc = false,
|
||||
List<string> containersIdFull = null
|
||||
List<string>? containersIdFull = null
|
||||
)
|
||||
{
|
||||
// Loot pool has items
|
||||
var poolSize = pool.Count;
|
||||
if (poolSize > 0)
|
||||
|
||||
if (poolSize <= 0) return;
|
||||
|
||||
double currentTotalRub = 0;
|
||||
|
||||
var fitItemIntoContainerAttempts = 0;
|
||||
for (var i = 0; i < totalItemCount; i++)
|
||||
{
|
||||
double currentTotalRub = 0;
|
||||
|
||||
var fitItemIntoContainerAttempts = 0;
|
||||
for (var i = 0; i < totalItemCount; i++)
|
||||
// Pool can become empty if item spawn limits keep removing items
|
||||
if (pool.Count == 0)
|
||||
{
|
||||
// Pool can become empty if item spawn limits keep removing items
|
||||
if (pool.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var weightedItemTpl = _weightedRandomHelper.GetWeightedValue<string>(pool);
|
||||
var itemResult = _itemHelper.GetItem(weightedItemTpl);
|
||||
var itemToAddTemplate = itemResult.Value;
|
||||
if (!itemResult.Key)
|
||||
{
|
||||
_logger.Warning($"Unable to process item tpl: {weightedItemTpl} for slots: {equipmentSlots} on bot: {botRole}");
|
||||
var weightedItemTpl = _weightedRandomHelper.GetWeightedValue<string>(pool);
|
||||
var (key, itemToAddTemplate) = _itemHelper.GetItem(weightedItemTpl);
|
||||
|
||||
if (!key)
|
||||
{
|
||||
_logger.Warning($"Unable to process item tpl: {weightedItemTpl} for slots: {equipmentSlots} on bot: {botRole}");
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (itemSpawnLimits is not null)
|
||||
{
|
||||
if (ItemHasReachedSpawnLimit(itemToAddTemplate, botRole, itemSpawnLimits))
|
||||
{
|
||||
// Remove item from pool to prevent it being picked again
|
||||
pool.Remove(weightedItemTpl);
|
||||
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemSpawnLimits is not null)
|
||||
var newRootItemId = _hashUtil.Generate();
|
||||
List<Item> itemWithChildrenToAdd =
|
||||
[
|
||||
new()
|
||||
{
|
||||
if (ItemHasReachedSpawnLimit(itemToAddTemplate, botRole, itemSpawnLimits))
|
||||
{
|
||||
// Remove item from pool to prevent it being picked again
|
||||
pool.Remove(weightedItemTpl);
|
||||
Id = newRootItemId,
|
||||
Template = itemToAddTemplate?.Id ?? string.Empty,
|
||||
Upd = _botGeneratorHelper.GenerateExtraPropertiesForItem(itemToAddTemplate, botRole)
|
||||
},
|
||||
];
|
||||
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var newRootItemId = _hashUtil.Generate();
|
||||
List<Item> itemWithChildrenToAdd =
|
||||
[
|
||||
new()
|
||||
{
|
||||
Id = newRootItemId,
|
||||
Template = itemToAddTemplate.Id,
|
||||
Upd = _botGeneratorHelper.GenerateExtraPropertiesForItem(itemToAddTemplate, botRole)
|
||||
},
|
||||
];
|
||||
|
||||
// Is Simple-Wallet / WZ wallet
|
||||
if (_botConfig.WalletLoot.WalletTplPool.Contains(weightedItemTpl))
|
||||
// Is Simple-Wallet / WZ wallet
|
||||
if (_botConfig.WalletLoot.WalletTplPool.Contains(weightedItemTpl))
|
||||
{
|
||||
var addCurrencyToWallet = _randomUtil.GetChance100(_botConfig.WalletLoot.ChancePercent);
|
||||
if (addCurrencyToWallet)
|
||||
{
|
||||
var addCurrencyToWallet = _randomUtil.GetChance100(_botConfig.WalletLoot.ChancePercent);
|
||||
if (addCurrencyToWallet)
|
||||
// Create the currency items we want to add to wallet
|
||||
var itemsToAdd = CreateWalletLoot(newRootItemId);
|
||||
|
||||
// Get the container grid for the wallet
|
||||
var containerGrid = _inventoryHelper.GetContainerSlotMap(weightedItemTpl);
|
||||
|
||||
// Check if all the chosen currency items fit into wallet
|
||||
var canAddToContainer = _inventoryHelper.CanPlaceItemsInContainer(
|
||||
_cloner.Clone(containerGrid), // MUST clone grid before passing in as function modifies grid
|
||||
itemsToAdd
|
||||
);
|
||||
if (canAddToContainer)
|
||||
{
|
||||
// Create the currency items we want to add to wallet
|
||||
var itemsToAdd = CreateWalletLoot(newRootItemId);
|
||||
|
||||
// Get the container grid for the wallet
|
||||
var containerGrid = _inventoryHelper.GetContainerSlotMap(weightedItemTpl);
|
||||
|
||||
// Check if all the chosen currency items fit into wallet
|
||||
var canAddToContainer = _inventoryHelper.CanPlaceItemsInContainer(
|
||||
_cloner.Clone(containerGrid), // MUST clone grid before passing in as function modifies grid
|
||||
itemsToAdd
|
||||
);
|
||||
if (canAddToContainer)
|
||||
// Add each currency to wallet
|
||||
foreach (var itemToAdd in itemsToAdd)
|
||||
{
|
||||
// Add each currency to wallet
|
||||
foreach (var itemToAdd in itemsToAdd)
|
||||
{
|
||||
_inventoryHelper.PlaceItemInContainer(
|
||||
containerGrid,
|
||||
itemToAdd,
|
||||
itemWithChildrenToAdd[0].Id,
|
||||
"main"
|
||||
);
|
||||
}
|
||||
|
||||
itemWithChildrenToAdd.AddRange(itemsToAdd.SelectMany(x => x));
|
||||
_inventoryHelper.PlaceItemInContainer(
|
||||
containerGrid,
|
||||
itemToAdd,
|
||||
itemWithChildrenToAdd[0].Id,
|
||||
"main"
|
||||
);
|
||||
}
|
||||
|
||||
itemWithChildrenToAdd.AddRange(itemsToAdd.SelectMany(x => x));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some items (ammoBox/ammo) need extra changes
|
||||
AddRequiredChildItemsToParent(itemToAddTemplate, itemWithChildrenToAdd, isPmc, botRole);
|
||||
// Some items (ammoBox/ammo) need extra changes
|
||||
AddRequiredChildItemsToParent(itemToAddTemplate, itemWithChildrenToAdd, isPmc, botRole);
|
||||
|
||||
// Attempt to add item to container(s)
|
||||
var itemAddedResult = _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
|
||||
equipmentSlots,
|
||||
newRootItemId,
|
||||
itemToAddTemplate.Id,
|
||||
itemWithChildrenToAdd,
|
||||
inventoryToAddItemsTo,
|
||||
containersIdFull
|
||||
);
|
||||
// Attempt to add item to container(s)
|
||||
var itemAddedResult = _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot(
|
||||
equipmentSlots,
|
||||
newRootItemId,
|
||||
itemToAddTemplate?.Id,
|
||||
itemWithChildrenToAdd,
|
||||
inventoryToAddItemsTo,
|
||||
containersIdFull
|
||||
);
|
||||
|
||||
// Handle when item cannot be added
|
||||
if (itemAddedResult != ItemAddedResult.SUCCESS)
|
||||
// Handle when item cannot be added
|
||||
if (itemAddedResult != ItemAddedResult.SUCCESS)
|
||||
{
|
||||
if (itemAddedResult == ItemAddedResult.NO_CONTAINERS)
|
||||
{
|
||||
if (itemAddedResult == ItemAddedResult.NO_CONTAINERS)
|
||||
{
|
||||
// Bot has no container to put item in, exit
|
||||
_logger.Debug($"Unable to add: {totalItemCount} items to bot as it lacks a container to include them");
|
||||
break;
|
||||
}
|
||||
|
||||
fitItemIntoContainerAttempts++;
|
||||
if (fitItemIntoContainerAttempts >= 4)
|
||||
{
|
||||
_logger.Debug(
|
||||
$"Failed placing item: {i} of: {totalItemCount} items into: {botRole} " +
|
||||
$"containers: {string.Join(",", equipmentSlots)}. Tried: {fitItemIntoContainerAttempts} " +
|
||||
$"times, reason: {itemAddedResult.ToString()}, skipping"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Try again, failed but still under attempt limit
|
||||
continue;
|
||||
// Bot has no container to put item in, exit
|
||||
_logger.Debug($"Unable to add: {totalItemCount} items to bot as it lacks a container to include them");
|
||||
break;
|
||||
}
|
||||
|
||||
// Item added okay, reset counter for next item
|
||||
fitItemIntoContainerAttempts = 0;
|
||||
|
||||
// Stop adding items to bots pool if rolling total is over total limit
|
||||
if (totalValueLimitRub > 0)
|
||||
fitItemIntoContainerAttempts++;
|
||||
if (fitItemIntoContainerAttempts >= 4)
|
||||
{
|
||||
currentTotalRub += _handbookHelper.GetTemplatePrice(itemToAddTemplate.Id);
|
||||
if (currentTotalRub > totalValueLimitRub)
|
||||
{
|
||||
break;
|
||||
}
|
||||
_logger.Debug(
|
||||
$"Failed placing item: {i} of: {totalItemCount} items into: {botRole} " +
|
||||
$"containers: {string.Join(",", equipmentSlots)}. Tried: {fitItemIntoContainerAttempts} " +
|
||||
$"times, reason: {itemAddedResult.ToString()}, skipping"
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Try again, failed but still under attempt limit
|
||||
continue;
|
||||
}
|
||||
|
||||
// Item added okay, reset counter for next item
|
||||
fitItemIntoContainerAttempts = 0;
|
||||
|
||||
// Stop adding items to bots pool if rolling total is over total limit
|
||||
if (totalValueLimitRub > 0)
|
||||
{
|
||||
currentTotalRub += _handbookHelper.GetTemplatePrice(itemToAddTemplate.Id);
|
||||
if (currentTotalRub > totalValueLimitRub)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,8 +626,9 @@ public class BotLootGenerator
|
||||
{
|
||||
// Choose the size of the currency stack - default is 5k, 10k, 15k, 20k, 25k
|
||||
var chosenStackCount = _weightedRandomHelper.GetWeightedValue<string>(_botConfig.WalletLoot.StackSizeWeight);
|
||||
List<Item> items = new List<Item>();
|
||||
items.Add(
|
||||
List<Item> items =
|
||||
[
|
||||
|
||||
new Item
|
||||
{
|
||||
Id = _hashUtil.Generate(),
|
||||
@@ -642,7 +639,9 @@ public class BotLootGenerator
|
||||
StackObjectsCount = double.Parse(chosenStackCount)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
];
|
||||
result.Add(items);
|
||||
}
|
||||
|
||||
@@ -656,7 +655,7 @@ public class BotLootGenerator
|
||||
/// <param name="itemToAddChildrenTo">Item to add children to</param>
|
||||
/// <param name="isPmc">Is the item being generated for a pmc (affects money/ammo stack sizes)</param>
|
||||
/// <param name="botRole">role bot has that owns item</param>
|
||||
public void AddRequiredChildItemsToParent(TemplateItem itemToAddTemplate, List<Item> itemToAddChildrenTo, bool isPmc, string botRole)
|
||||
public void AddRequiredChildItemsToParent(TemplateItem? itemToAddTemplate, List<Item> itemToAddChildrenTo, bool isPmc, string botRole)
|
||||
{
|
||||
// Fill ammo box
|
||||
if (_itemHelper.IsOfBaseclass(itemToAddTemplate.Id, BaseClasses.AMMO_BOX))
|
||||
@@ -695,8 +694,8 @@ public class BotLootGenerator
|
||||
public void AddLooseWeaponsToInventorySlot(string sessionId,
|
||||
BotBaseInventory botInventory,
|
||||
EquipmentSlots equipmentSlot,
|
||||
BotTypeInventory templateInventory,
|
||||
Dictionary<string, double> modChances,
|
||||
BotTypeInventory? templateInventory,
|
||||
Dictionary<string, double>? modChances,
|
||||
string botRole,
|
||||
bool isPmc,
|
||||
int botLevel,
|
||||
@@ -771,7 +770,7 @@ public class BotLootGenerator
|
||||
/// <param name="botRole">Bot type</param>
|
||||
/// <param name="itemSpawnLimits"></param>
|
||||
/// <returns>true if item has reached spawn limit</returns>
|
||||
public bool ItemHasReachedSpawnLimit(TemplateItem itemTemplate, string botRole, ItemSpawnLimitSettings? itemSpawnLimits)
|
||||
private bool ItemHasReachedSpawnLimit(TemplateItem? itemTemplate, string botRole, ItemSpawnLimitSettings? itemSpawnLimits)
|
||||
{
|
||||
// PMCs and scavs have different sections of bot config for spawn limits
|
||||
if (itemSpawnLimits is not null && itemSpawnLimits.GlobalLimits?.Count == 0) {
|
||||
|
||||
+154
-174
@@ -17,7 +17,6 @@ public class BotGeneratorHelper
|
||||
{
|
||||
private readonly ISptLogger<BotGeneratorHelper> _logger;
|
||||
private readonly RandomUtil _randomUtil;
|
||||
private readonly DatabaseService _databaseService;
|
||||
private readonly DurabilityLimitsHelper _durabilityLimitsHelper;
|
||||
private readonly ItemHelper _itemHelper;
|
||||
private readonly InventoryHelper _inventoryHelper;
|
||||
@@ -33,7 +32,6 @@ public class BotGeneratorHelper
|
||||
(
|
||||
ISptLogger<BotGeneratorHelper> logger,
|
||||
RandomUtil randomUtil,
|
||||
DatabaseService databaseService,
|
||||
DurabilityLimitsHelper durabilityLimitsHelper,
|
||||
ItemHelper itemHelper,
|
||||
InventoryHelper inventoryHelper,
|
||||
@@ -45,7 +43,6 @@ public class BotGeneratorHelper
|
||||
{
|
||||
_logger = logger;
|
||||
_randomUtil = randomUtil;
|
||||
_databaseService = databaseService;
|
||||
_durabilityLimitsHelper = durabilityLimitsHelper;
|
||||
_itemHelper = itemHelper;
|
||||
_inventoryHelper = inventoryHelper;
|
||||
@@ -65,7 +62,7 @@ public class BotGeneratorHelper
|
||||
/// <param name="itemTemplate">Item extra properties are being generated for</param>
|
||||
/// <param name="botRole">Used by weapons to randomize the durability values. Null for non-equipped items</param>
|
||||
/// <returns>Item Upd object with extra properties</returns>
|
||||
public Upd GenerateExtraPropertiesForItem(TemplateItem itemTemplate, string botRole = null)
|
||||
public Upd GenerateExtraPropertiesForItem(TemplateItem? itemTemplate, string? botRole = null)
|
||||
{
|
||||
// Get raid settings, if no raid, default to day
|
||||
var raidSettings = _applicationContext
|
||||
@@ -75,7 +72,7 @@ public class BotGeneratorHelper
|
||||
|
||||
Upd itemProperties = new();
|
||||
|
||||
if (itemTemplate.Properties.MaxDurability is not null)
|
||||
if (itemTemplate?.Properties?.MaxDurability is not null)
|
||||
{
|
||||
if (itemTemplate.Properties.WeapClass is not null)
|
||||
{
|
||||
@@ -89,63 +86,54 @@ public class BotGeneratorHelper
|
||||
}
|
||||
}
|
||||
|
||||
if (itemTemplate.Properties.HasHinge ?? false)
|
||||
if (itemTemplate?.Properties?.HasHinge ?? false)
|
||||
{
|
||||
itemProperties.Togglable = new() { On = true };
|
||||
itemProperties.Togglable = new UpdTogglable { On = true };
|
||||
}
|
||||
|
||||
if (itemTemplate.Properties.Foldable ?? false)
|
||||
if (itemTemplate?.Properties?.Foldable ?? false)
|
||||
{
|
||||
itemProperties.Foldable = new() { Folded = false };
|
||||
itemProperties.Foldable = new UpdFoldable { Folded = false };
|
||||
}
|
||||
|
||||
if (itemTemplate.Properties.WeapFireType?.Any() ?? false)
|
||||
if (itemTemplate?.Properties?.WeapFireType?.Count == 0)
|
||||
{
|
||||
if (itemTemplate.Properties.WeapFireType.Contains("fullauto"))
|
||||
{
|
||||
itemProperties.FireMode = new() { FireMode = "fullauto" };
|
||||
}
|
||||
else
|
||||
{
|
||||
itemProperties.FireMode = new() { FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType) };
|
||||
}
|
||||
itemProperties.FireMode = itemTemplate.Properties.WeapFireType.Contains("fullauto")
|
||||
? new UpdFireMode { FireMode = "fullauto" }
|
||||
: new UpdFireMode { FireMode = _randomUtil.GetArrayValue(itemTemplate.Properties.WeapFireType) };
|
||||
}
|
||||
|
||||
if (itemTemplate.Properties.MaxHpResource is not null)
|
||||
if (itemTemplate?.Properties?.MaxHpResource is not null)
|
||||
{
|
||||
itemProperties.MedKit = new()
|
||||
itemProperties.MedKit = new UpdMedKit
|
||||
{
|
||||
HpResource = (int)GetRandomizedResourceValue(
|
||||
HpResource = GetRandomizedResourceValue(
|
||||
itemTemplate.Properties.MaxHpResource ?? 0,
|
||||
_botConfig.LootItemResourceRandomization[botRole]?.Meds
|
||||
_botConfig.LootItemResourceRandomization[botRole ?? string.Empty].Meds
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
if (itemTemplate.Properties.MaxResource is not null && itemTemplate.Properties.FoodUseTime is not null)
|
||||
if (itemTemplate?.Properties?.MaxResource is not null && itemTemplate.Properties?.FoodUseTime is not null)
|
||||
{
|
||||
itemProperties.FoodDrink = new()
|
||||
itemProperties.FoodDrink = new UpdFoodDrink
|
||||
{
|
||||
HpPercent = (int)GetRandomizedResourceValue(
|
||||
HpPercent = GetRandomizedResourceValue(
|
||||
itemTemplate.Properties.MaxResource ?? 0,
|
||||
_botConfig.LootItemResourceRandomization[botRole]?.Food
|
||||
_botConfig.LootItemResourceRandomization[botRole ?? string.Empty].Food
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
if (itemTemplate.Parent == BaseClasses.FLASHLIGHT)
|
||||
if (itemTemplate?.Parent == BaseClasses.FLASHLIGHT)
|
||||
{
|
||||
// Get chance from botconfig for bot type
|
||||
var lightLaserActiveChance = raidIsNight
|
||||
? GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveNightChancePercent", 50)
|
||||
: GetBotEquipmentSettingFromConfig(botRole, "lightIsActiveDayChancePercent", 25);
|
||||
itemProperties.Light = new()
|
||||
{
|
||||
IsActive = _randomUtil.GetChance100(lightLaserActiveChance),
|
||||
SelectedMode = 0,
|
||||
};
|
||||
itemProperties.Light = new UpdLight { IsActive = _randomUtil.GetChance100(lightLaserActiveChance), SelectedMode = 0, };
|
||||
}
|
||||
else if (itemTemplate.Parent == BaseClasses.TACTICAL_COMBO)
|
||||
else if (itemTemplate?.Parent == BaseClasses.TACTICAL_COMBO)
|
||||
{
|
||||
// Get chance from botconfig for bot type, use 50% if no value found
|
||||
var lightLaserActiveChance = GetBotEquipmentSettingFromConfig(
|
||||
@@ -153,40 +141,32 @@ public class BotGeneratorHelper
|
||||
"laserIsActiveChancePercent",
|
||||
50
|
||||
);
|
||||
itemProperties.Light = new()
|
||||
itemProperties.Light = new UpdLight
|
||||
{
|
||||
IsActive = _randomUtil.GetChance100(lightLaserActiveChance),
|
||||
SelectedMode = 0,
|
||||
};
|
||||
}
|
||||
|
||||
if (itemTemplate.Parent == BaseClasses.NIGHTVISION)
|
||||
if (itemTemplate?.Parent == BaseClasses.NIGHTVISION)
|
||||
{
|
||||
// Get chance from botconfig for bot type
|
||||
var nvgActiveChance = raidIsNight
|
||||
? GetBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceNightPercent", 90)
|
||||
: GetBotEquipmentSettingFromConfig(botRole, "nvgIsActiveChanceDayPercent", 15);
|
||||
itemProperties.Togglable = new()
|
||||
{
|
||||
On = _randomUtil.GetChance100(nvgActiveChance)
|
||||
};
|
||||
itemProperties.Togglable = new UpdTogglable { On = _randomUtil.GetChance100(nvgActiveChance) };
|
||||
}
|
||||
|
||||
// Togglable face shield
|
||||
if ((itemTemplate.Properties.HasHinge ?? false) && (itemTemplate.Properties.FaceShieldComponent ?? false))
|
||||
{
|
||||
// Get chance from botconfig for bot type, use 75% if no value found
|
||||
var faceShieldActiveChance = GetBotEquipmentSettingFromConfig(
|
||||
botRole,
|
||||
"faceShieldIsActiveChancePercent",
|
||||
75
|
||||
);
|
||||
itemProperties.Togglable = new()
|
||||
{
|
||||
On = _randomUtil.GetChance100(faceShieldActiveChance)
|
||||
}
|
||||
;
|
||||
}
|
||||
if (!(itemTemplate?.Properties?.HasHinge ?? false) || !(itemTemplate.Properties.FaceShieldComponent ?? false)) return itemProperties;
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -197,7 +177,7 @@ public class BotGeneratorHelper
|
||||
/// <param name="maxResource">Max resource value of medical items</param>
|
||||
/// <param name="randomizationValues">Value provided from config</param>
|
||||
/// <returns>Randomized value from maxHpResource</returns>
|
||||
protected double GetRandomizedResourceValue(double maxResource, RandomisedResourceValues randomizationValues)
|
||||
private double GetRandomizedResourceValue(double maxResource, RandomisedResourceValues? randomizationValues)
|
||||
{
|
||||
if (randomizationValues is null)
|
||||
{
|
||||
@@ -222,7 +202,7 @@ public class BotGeneratorHelper
|
||||
/// <param name="setting">the setting of the weapon attachment/helmet equipment to be activated</param>
|
||||
/// <param name="defaultValue">default value for the chance of activation if the botrole or bot equipment role is undefined</param>
|
||||
/// <returns>Percent chance to be active</returns>
|
||||
protected double GetBotEquipmentSettingFromConfig(string botRole, string setting, double defaultValue)
|
||||
private double? GetBotEquipmentSettingFromConfig(string? botRole, string setting, double defaultValue)
|
||||
{
|
||||
if (botRole is null)
|
||||
{
|
||||
@@ -237,9 +217,9 @@ public class BotGeneratorHelper
|
||||
"bot-missing_equipment_settings",
|
||||
new
|
||||
{
|
||||
botRole = botRole,
|
||||
setting = setting,
|
||||
defaultValue = defaultValue
|
||||
botRole,
|
||||
setting,
|
||||
defaultValue
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -248,26 +228,24 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
var props = botEquipmentSettings.GetType().GetProperties();
|
||||
var propValue = (double?)props.FirstOrDefault(x => x.Name.ToLower() == setting.ToLower()).GetValue(botEquipmentSettings);
|
||||
var propValue = (double?)props.FirstOrDefault(x => string.Equals(x.Name, setting, StringComparison.CurrentCultureIgnoreCase))
|
||||
?.GetValue(botEquipmentSettings);
|
||||
|
||||
if (propValue is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_localisationService.GetText(
|
||||
"bot-missing_equipment_settings_property",
|
||||
new
|
||||
{
|
||||
botRole = botRole,
|
||||
setting = setting,
|
||||
defaultValue = defaultValue
|
||||
}
|
||||
)
|
||||
);
|
||||
if (propValue is not null) return propValue;
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
_logger.Warning(
|
||||
_localisationService.GetText(
|
||||
"bot-missing_equipment_settings_property",
|
||||
new
|
||||
{
|
||||
botRole,
|
||||
setting,
|
||||
defaultValue
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return propValue ?? 0;
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -276,7 +254,7 @@ public class BotGeneratorHelper
|
||||
/// <param name="itemTemplate">weapon object being generated for</param>
|
||||
/// <param name="botRole">type of bot being generated for</param>
|
||||
/// <returns>Repairable object</returns>
|
||||
protected UpdRepairable GenerateWeaponRepairableProperties(TemplateItem itemTemplate, string botRole = null)
|
||||
private UpdRepairable GenerateWeaponRepairableProperties(TemplateItem itemTemplate, string? botRole = null)
|
||||
{
|
||||
var maxDurability = _durabilityLimitsHelper.GetRandomizedMaxWeaponDurability(itemTemplate, botRole);
|
||||
var currentDurability = _durabilityLimitsHelper.GetRandomizedWeaponDurability(
|
||||
@@ -285,7 +263,7 @@ public class BotGeneratorHelper
|
||||
maxDurability
|
||||
);
|
||||
|
||||
return new() { Durability = (int)currentDurability, MaxDurability = (int)maxDurability };
|
||||
return new UpdRepairable { Durability = (int)currentDurability, MaxDurability = (int)maxDurability };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -294,11 +272,11 @@ public class BotGeneratorHelper
|
||||
/// <param name="itemTemplate">weapon object being generated for</param>
|
||||
/// <param name="botRole">type of bot being generated for</param>
|
||||
/// <returns>Repairable object</returns>
|
||||
protected UpdRepairable GenerateArmorRepairableProperties(TemplateItem itemTemplate, string botRole = null)
|
||||
private UpdRepairable GenerateArmorRepairableProperties(TemplateItem itemTemplate, string? botRole = null)
|
||||
{
|
||||
double? maxDurability = null;
|
||||
double? currentDurability = null;
|
||||
if (itemTemplate.Properties.ArmorClass == 0)
|
||||
double? maxDurability;
|
||||
double? currentDurability;
|
||||
if (itemTemplate.Properties?.ArmorClass == 0)
|
||||
{
|
||||
maxDurability = itemTemplate.Properties.MaxDurability;
|
||||
currentDurability = itemTemplate.Properties.MaxDurability;
|
||||
@@ -309,11 +287,11 @@ public class BotGeneratorHelper
|
||||
currentDurability = _durabilityLimitsHelper.GetRandomizedArmorDurability(
|
||||
itemTemplate,
|
||||
botRole,
|
||||
maxDurability ?? 0
|
||||
maxDurability
|
||||
);
|
||||
}
|
||||
|
||||
return new() { Durability = (int)currentDurability, MaxDurability = (int)maxDurability };
|
||||
return new UpdRepairable { Durability = (int)currentDurability!, MaxDurability = (int)maxDurability! };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -329,15 +307,14 @@ public class BotGeneratorHelper
|
||||
List<string> slotsToCheck = ["Scabbard", "Backpack", "SecureContainer", "Holster", "ArmBand"];
|
||||
if (slotsToCheck.Contains(equipmentSlot))
|
||||
{
|
||||
return new() { Incompatible = false, Found = false, Reason = "" };
|
||||
return new ChooseRandomCompatibleModResult { Incompatible = false, Found = false, Reason = "" };
|
||||
}
|
||||
|
||||
// TODO: Can probably be optimized to cache itemTemplates as items are added to inventory
|
||||
var equippedItemsDb = itemsEquipped.Select((equippedItem) => _itemHelper.GetItem(equippedItem.Template).Value);
|
||||
var itemToEquipDb = _itemHelper.GetItem(tplToCheck);
|
||||
var itemToEquip = itemToEquipDb.Value;
|
||||
var equippedItemsDb = itemsEquipped.Select(equippedItem => _itemHelper.GetItem(equippedItem.Template).Value).ToList();
|
||||
var (key, itemToEquip) = _itemHelper.GetItem(tplToCheck);
|
||||
|
||||
if (!itemToEquipDb.Key)
|
||||
if (!key)
|
||||
{
|
||||
_logger.Warning(
|
||||
_localisationService.GetText(
|
||||
@@ -350,29 +327,30 @@ public class BotGeneratorHelper
|
||||
)
|
||||
);
|
||||
|
||||
return new() { Incompatible = true, Found = false, Reason = $"item: {tplToCheck} does not exist in the database" };
|
||||
return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"item: {tplToCheck} does not exist in the database" };
|
||||
}
|
||||
|
||||
if (itemToEquip.Properties is null)
|
||||
if (itemToEquip?.Properties is null)
|
||||
{
|
||||
_logger.Warning(
|
||||
_localisationService.GetText(
|
||||
"bot-compatibility_check_missing_props",
|
||||
new
|
||||
{
|
||||
id = itemToEquip.Id,
|
||||
name = itemToEquip.Name,
|
||||
id = itemToEquip?.Id,
|
||||
name = itemToEquip?.Name,
|
||||
slot = equipmentSlot,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return new() { Incompatible = true, Found = false, Reason = $"item: {tplToCheck} does not have a _props field" };
|
||||
return new ChooseRandomCompatibleModResult { Incompatible = true, Found = false, Reason = $"item: {tplToCheck} does not have a _props field" };
|
||||
}
|
||||
|
||||
// Does an equipped item have a property that blocks the desired item - check for prop "BlocksX" .e.g BlocksEarpiece / BlocksFaceCover
|
||||
var blockingItem = equippedItemsDb.FirstOrDefault(
|
||||
(item) => item.Properties.GetType().GetProperties().FirstOrDefault(x => x.Name.ToLower() == $"blocks{equipmentSlot}").GetValue(item) is not null
|
||||
var templateItems = equippedItemsDb.ToList();
|
||||
var blockingItem = templateItems.FirstOrDefault(
|
||||
item => item?.Properties?.GetType().GetProperties().FirstOrDefault(x => x.Name.ToLower() == $"blocks{equipmentSlot}")?.GetValue(item) is not null
|
||||
);
|
||||
if (blockingItem is not null)
|
||||
{
|
||||
@@ -386,11 +364,11 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// Check if any of the current inventory templates have the incoming item defined as incompatible
|
||||
blockingItem = equippedItemsDb.FirstOrDefault((x) => x.Properties.ConflictingItems?.Contains(tplToCheck) ?? false);
|
||||
blockingItem = templateItems.FirstOrDefault(x => x?.Properties?.ConflictingItems?.Contains(tplToCheck) ?? false);
|
||||
if (blockingItem is not null)
|
||||
{
|
||||
// this.logger.warning(`2 incompatibility found between - ${itemToEquip[1]._name} and ${blockingItem._props.Name} - ${equipmentSlot}`);
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -405,7 +383,7 @@ public class BotGeneratorHelper
|
||||
var existingHeadwear = itemsEquipped.FirstOrDefault((x) => x.SlotId == "Headwear");
|
||||
if (existingHeadwear is not null)
|
||||
{
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -421,7 +399,7 @@ public class BotGeneratorHelper
|
||||
var existingFaceCover = itemsEquipped.FirstOrDefault((item) => item.SlotId == "FaceCover");
|
||||
if (existingFaceCover is not null)
|
||||
{
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -437,7 +415,7 @@ public class BotGeneratorHelper
|
||||
var existingEarpiece = itemsEquipped.FirstOrDefault((item) => item.SlotId == "Earpiece");
|
||||
if (existingEarpiece is not null)
|
||||
{
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -453,7 +431,7 @@ public class BotGeneratorHelper
|
||||
var existingArmorVest = itemsEquipped.FirstOrDefault((item) => item.SlotId == "ArmorVest");
|
||||
if (existingArmorVest is not null)
|
||||
{
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -468,7 +446,7 @@ public class BotGeneratorHelper
|
||||
if (blockingInventoryItem is not null)
|
||||
{
|
||||
// this.logger.warning(`3 incompatibility found between - ${itemToEquip[1]._name} and ${blockingInventoryItem._tpl} - ${equipmentSlot}`)
|
||||
return new()
|
||||
return new ChooseRandomCompatibleModResult
|
||||
{
|
||||
Incompatible = true,
|
||||
Found = false,
|
||||
@@ -476,7 +454,7 @@ public class BotGeneratorHelper
|
||||
};
|
||||
}
|
||||
|
||||
return new() { Incompatible = false, Reason = "" };
|
||||
return new ChooseRandomCompatibleModResult { Incompatible = false, Reason = "" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -502,16 +480,17 @@ public class BotGeneratorHelper
|
||||
/// <param name="rootItemTplId">Root itms tpl id</param>
|
||||
/// <param name="itemWithChildren">Item to add</param>
|
||||
/// <param name="inventory">Inventory to add item+children into</param>
|
||||
/// <param name="containersIdFull"></param>
|
||||
/// <returns>ItemAddedResult result object</returns>
|
||||
public ItemAddedResult AddItemWithChildrenToEquipmentSlot(
|
||||
List<EquipmentSlots> equipmentSlots,
|
||||
string rootItemId,
|
||||
string rootItemTplId,
|
||||
string? rootItemTplId,
|
||||
List<Item> itemWithChildren,
|
||||
BotBaseInventory inventory,
|
||||
List<string> containersIdFull = null)
|
||||
List<string>? containersIdFull = null)
|
||||
{
|
||||
/** Track how many containers are unable to be found */
|
||||
// Track how many containers are unable to be found
|
||||
var missingContainerCount = 0;
|
||||
foreach (var equipmentSlotId in equipmentSlots)
|
||||
{
|
||||
@@ -521,7 +500,7 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// Get container to put item into
|
||||
var container = inventory.Items.FirstOrDefault((item) => item.SlotId == equipmentSlotId.ToString());
|
||||
var container = (inventory.Items ?? []).FirstOrDefault(item => item.SlotId == equipmentSlotId.ToString());
|
||||
if (container is null)
|
||||
{
|
||||
missingContainerCount++;
|
||||
@@ -529,7 +508,7 @@ public class BotGeneratorHelper
|
||||
{
|
||||
// Bot doesnt have any containers we want to add item to
|
||||
_logger.Debug(
|
||||
$"Unable to add item: {itemWithChildren[0].Template} to bot as it lacks the following containers: {string.Join(",", equipmentSlots)}"
|
||||
$"Unable to add item: {itemWithChildren.FirstOrDefault()?.Template} to bot as it lacks the following containers: {string.Join(",", equipmentSlots)}"
|
||||
);
|
||||
|
||||
return ItemAddedResult.NO_CONTAINERS;
|
||||
@@ -540,8 +519,8 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// Get container details from db
|
||||
var containerTemplate = _itemHelper.GetItem(container.Template);
|
||||
if (!containerTemplate.Key)
|
||||
var (key, value) = _itemHelper.GetItem(container.Template);
|
||||
if (!key)
|
||||
{
|
||||
_logger.Warning(_localisationService.GetText("bot-missing_container_with_tpl", container.Template));
|
||||
|
||||
@@ -549,7 +528,7 @@ public class BotGeneratorHelper
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!containerTemplate.Value.Properties.Grids?.Any() ?? false)
|
||||
if (value?.Properties?.Grids?.Count == 0)
|
||||
{
|
||||
// Container has no slots to hold items
|
||||
continue;
|
||||
@@ -560,11 +539,11 @@ public class BotGeneratorHelper
|
||||
|
||||
// Iterate over each grid in the container and look for a big enough space for the item to be placed in
|
||||
var currentGridCount = 1;
|
||||
var totalSlotGridCount = containerTemplate.Value.Properties.Grids.Count;
|
||||
foreach (var slotGrid in containerTemplate.Value.Properties.Grids)
|
||||
var totalSlotGridCount = value?.Properties?.Grids?.Count;
|
||||
foreach (var slotGrid in value?.Properties?.Grids ?? [])
|
||||
{
|
||||
// Grid is empty, skip or item size is bigger than grid
|
||||
if (slotGrid.Props.CellsH == 0 || slotGrid.Props.CellsV == 0 || itemSize[0] * itemSize[1] > slotGrid.Props.CellsV * slotGrid.Props.CellsH)
|
||||
if (slotGrid.Props?.CellsH == 0 || slotGrid.Props?.CellsV == 0 || itemSize[0] * itemSize[1] > slotGrid.Props?.CellsV * slotGrid.Props?.CellsH)
|
||||
continue;
|
||||
|
||||
// Can't put item type in grid, skip all grids as we're assuming they have the same rules
|
||||
@@ -575,55 +554,60 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// Get all root items in found container
|
||||
var existingContainerItems = inventory.Items.Where(
|
||||
(item) => item.ParentId == container.Id && item.SlotId == slotGrid.Name
|
||||
var existingContainerItems = (inventory.Items ?? []).Where(
|
||||
item => item.ParentId == container.Id && item.SlotId == slotGrid.Name
|
||||
)
|
||||
.ToList();
|
||||
|
||||
// Get root items in container we can iterate over to find out what space is free
|
||||
var containerItemsToCheck = existingContainerItems.Where((x) => x.SlotId == slotGrid.Name);
|
||||
var containerItemsToCheck = existingContainerItems.Where(x => x.SlotId == slotGrid.Name);
|
||||
foreach (var item in containerItemsToCheck)
|
||||
{
|
||||
// Look for children on items, insert into array if found
|
||||
// (used later when figuring out how much space weapon takes up)
|
||||
var itemWithChildrens = _itemHelper.FindAndReturnChildrenAsItems(inventory.Items, item.Id);
|
||||
if (itemWithChildrens.Count > 1)
|
||||
{
|
||||
existingContainerItems.Remove(item);
|
||||
existingContainerItems.AddRange(itemWithChildrens);
|
||||
}
|
||||
if (itemWithChildrens.Count <= 1) continue;
|
||||
|
||||
existingContainerItems.Remove(item);
|
||||
existingContainerItems.AddRange(itemWithChildrens);
|
||||
}
|
||||
|
||||
// Get rid of items free/used spots in current grid
|
||||
var slotGridMap = _inventoryHelper.GetContainerMap(
|
||||
slotGrid.Props.CellsH.GetValueOrDefault(),
|
||||
slotGrid.Props.CellsV.GetValueOrDefault(),
|
||||
existingContainerItems,
|
||||
container.Id
|
||||
);
|
||||
|
||||
// Try to fit item into grid
|
||||
var findSlotResult = _containerHelper.FindSlotForItem(slotGridMap, itemSize[0], itemSize[1]);
|
||||
|
||||
// Open slot found, add item to inventory
|
||||
if (findSlotResult.Success ?? false)
|
||||
if (slotGrid.Props is not null)
|
||||
{
|
||||
var parentItem = itemWithChildren.FirstOrDefault((i) => i.Id == rootItemId);
|
||||
var slotGridMap = _inventoryHelper.GetContainerMap(
|
||||
slotGrid.Props.CellsH.GetValueOrDefault(),
|
||||
slotGrid.Props.CellsV.GetValueOrDefault(),
|
||||
existingContainerItems,
|
||||
container.Id
|
||||
);
|
||||
|
||||
// Set items parent to container id
|
||||
parentItem.ParentId = container.Id;
|
||||
parentItem.SlotId = slotGrid.Name;
|
||||
parentItem.Location = new ItemLocation()
|
||||
// Try to fit item into grid
|
||||
var findSlotResult = _containerHelper.FindSlotForItem(slotGridMap, itemSize[0], itemSize[1]);
|
||||
|
||||
// Open slot found, add item to inventory
|
||||
if (findSlotResult.Success ?? false)
|
||||
{
|
||||
var parentItem = itemWithChildren.FirstOrDefault((i) => i.Id == rootItemId);
|
||||
|
||||
// Set items parent to container id
|
||||
if (parentItem is not null)
|
||||
{
|
||||
X = findSlotResult.X,
|
||||
Y = findSlotResult.Y,
|
||||
R = (findSlotResult.Rotation ?? false) ? 1 : 0,
|
||||
parentItem.ParentId = container.Id;
|
||||
parentItem.SlotId = slotGrid.Name;
|
||||
parentItem.Location = new ItemLocation()
|
||||
{
|
||||
X = findSlotResult.X,
|
||||
Y = findSlotResult.Y,
|
||||
R = (findSlotResult.Rotation ?? false) ? 1 : 0,
|
||||
}
|
||||
;
|
||||
}
|
||||
;
|
||||
|
||||
inventory.Items.AddRange(itemWithChildren);
|
||||
(inventory.Items ?? []).AddRange(itemWithChildren);
|
||||
|
||||
return ItemAddedResult.SUCCESS;
|
||||
return ItemAddedResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've checked all grids in container and reached this point, there's no space for item
|
||||
@@ -637,13 +621,12 @@ public class BotGeneratorHelper
|
||||
}
|
||||
|
||||
// if we got to this point, the item couldnt be placed on the container
|
||||
if (containersIdFull is not null)
|
||||
if (containersIdFull is null) continue;
|
||||
|
||||
// if the item was a one by one, we know it must be full. Or if the maps cant find a slot for a one by one
|
||||
if (itemSize[0] == 1 && itemSize[1] == 1)
|
||||
{
|
||||
// if the item was a one by one, we know it must be full. Or if the maps cant find a slot for a one by one
|
||||
if (itemSize[0] == 1 && itemSize[1] == 1)
|
||||
{
|
||||
containersIdFull.Add(equipmentSlotId.ToString());
|
||||
}
|
||||
containersIdFull.Add(equipmentSlotId.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,40 +639,37 @@ public class BotGeneratorHelper
|
||||
/// <param name="slotGrid">Items sub-grid we want to place item inside</param>
|
||||
/// <param name="itemTpl">Item tpl being placed</param>
|
||||
/// <returns>True if allowed</returns>
|
||||
protected bool ItemAllowedInContainer(Grid slotGrid, string itemTpl)
|
||||
private bool ItemAllowedInContainer(Grid? slotGrid, string? itemTpl)
|
||||
{
|
||||
var propFilters = slotGrid.Props.Filters;
|
||||
var excludedFilter = propFilters[0]?.ExcludedFilter ?? [];
|
||||
var filter = propFilters[0]?.Filter ?? [];
|
||||
var propFilters = slotGrid?.Props?.Filters;
|
||||
var excludedFilter = propFilters?.FirstOrDefault()?.ExcludedFilter ?? [];
|
||||
var filter = propFilters?.FirstOrDefault()?.Filter ?? [];
|
||||
|
||||
if (propFilters.Count == 0)
|
||||
if (propFilters?.Count == 0)
|
||||
{
|
||||
// no filters, item is fine to add
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if item base type is excluded
|
||||
if (excludedFilter is not null || filter is not null)
|
||||
var itemDetails = _itemHelper.GetItem(itemTpl).Value;
|
||||
|
||||
// if item to add is found in exclude filter, not allowed
|
||||
if (excludedFilter.Contains(itemDetails?.Parent ?? string.Empty))
|
||||
{
|
||||
var itemDetails = _itemHelper.GetItem(itemTpl).Value;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if item to add is found in exclude filter, not allowed
|
||||
if (excludedFilter?.Contains(itemDetails.Parent) ?? false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// If Filter array only contains 1 filter and its for basetype 'item', allow it
|
||||
if (filter.Count == 1 && filter.Contains(BaseClasses.ITEM))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If Filter array only contains 1 filter and its for basetype 'item', allow it
|
||||
if (filter?.Count == 1 && filter.Contains(BaseClasses.ITEM))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If allowed filter has something in it + filter doesnt have basetype 'item', not allowed
|
||||
if (filter?.Count > 0 && !filter.Contains(itemDetails.Parent))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// If allowed filter has something in it + filter doesnt have basetype 'item', not allowed
|
||||
if (filter.Count > 0 && !filter.Contains(itemDetails?.Parent ?? string.Empty))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class DurabilityLimitsHelper
|
||||
/// <param name="itemTemplate">Item to get max durability for</param>
|
||||
/// <param name="botRole">Role of bot to get max durability for</param>
|
||||
/// <returns>max durability</returns>
|
||||
public double GetRandomizedMaxArmorDurability(TemplateItem itemTemplate, string? botRole = null)
|
||||
public double GetRandomizedMaxArmorDurability(TemplateItem? itemTemplate, string? botRole = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -47,7 +47,7 @@ public class DurabilityLimitsHelper
|
||||
/// <param name="botRole">Role of bot to get current durability for</param>
|
||||
/// <param name="maxDurability">Max durability of armor</param>
|
||||
/// <returns>Current armor durability</returns>
|
||||
public double GetRandomizedArmorDurability(TemplateItem itemTemplate, string? botRole, double maxDurability)
|
||||
public double GetRandomizedArmorDurability(TemplateItem? itemTemplate, string? botRole, double? maxDurability)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public class InventoryHelper
|
||||
/// <param name="containerFS2D">Container grid to fit items into</param>
|
||||
/// <param name="itemsWithChildren">Items to try and fit into grid</param>
|
||||
/// <returns>True all fit</returns>
|
||||
public bool CanPlaceItemsInContainer(List<List<double>> containerFS2D, List<List<Item>> itemsWithChildren)
|
||||
public bool CanPlaceItemsInContainer(List<List<double>>? containerFS2D, List<List<Item>> itemsWithChildren)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -91,7 +91,7 @@ public class InventoryHelper
|
||||
/// <param name="containerFS2D">Container grid</param>
|
||||
/// <param name="itemWithChildren">Item to check fits</param>
|
||||
/// <returns>True it fits</returns>
|
||||
public bool CanPlaceItemInContainer(List<List<int>> containerFS2D, List<Item> itemWithChildren)
|
||||
public bool CanPlaceItemInContainer(List<List<int>>? containerFS2D, List<Item> itemWithChildren)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public class InventoryHelper
|
||||
/// <param name="itemId">Items id to get size of</param>
|
||||
/// <param name="inventoryItems"></param>
|
||||
/// <returns>[width, height]</returns>
|
||||
public List<int> GetItemSize(string itemTpl, string itemId, List<Item> inventoryItems)
|
||||
public List<int> GetItemSize(string? itemTpl, string itemId, List<Item> inventoryItems)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -502,7 +502,7 @@ public class ItemHelper
|
||||
* @param tpl items template id to look up
|
||||
* @returns bool - is valid + template item object as array
|
||||
*/
|
||||
public KeyValuePair<bool, TemplateItem?> GetItem(string tpl)
|
||||
public KeyValuePair<bool, TemplateItem?> GetItem(string? tpl)
|
||||
{
|
||||
// -> Gets item from <input: _tpl>
|
||||
if (_databaseService.GetItems().Keys.Contains(tpl))
|
||||
@@ -710,7 +710,7 @@ public class ItemHelper
|
||||
* @param modsOnly Include only mod items, exclude items stored inside root item
|
||||
* @returns A list of Item objects
|
||||
*/
|
||||
public List<Item> FindAndReturnChildrenAsItems(List<Item> items, string baseItemId, bool modsOnly = false)
|
||||
public List<Item> FindAndReturnChildrenAsItems(List<Item>? items, string baseItemId, bool modsOnly = false)
|
||||
{
|
||||
List<Item> list = [];
|
||||
foreach (var childItem in items)
|
||||
|
||||
@@ -42,7 +42,7 @@ public record BotConfig : BaseConfig
|
||||
|
||||
/** Blacklist/whitelist items on a bot */
|
||||
[JsonPropertyName("equipment")]
|
||||
public Dictionary<string, EquipmentFilters> Equipment { get; set; }
|
||||
public Dictionary<string, EquipmentFilters?> Equipment { get; set; }
|
||||
|
||||
/** Show a bots botType value after their name */
|
||||
[JsonPropertyName("showTypeInNickname")]
|
||||
|
||||
@@ -115,9 +115,9 @@ public class RandomUtil
|
||||
/// </summary>
|
||||
/// <param name="chancePercent">The percentage chance (0-100) that the event will occur.</param>
|
||||
/// <returns>`true` if the event occurs, `false` otherwise.</returns>
|
||||
public bool GetChance100(double chancePercent)
|
||||
public bool GetChance100(double? chancePercent)
|
||||
{
|
||||
chancePercent = Math.Clamp(chancePercent, 0f, 100f);
|
||||
chancePercent = Math.Clamp(chancePercent ?? 0, 0f, 100f);
|
||||
|
||||
return GetIntEx(100) <= chancePercent;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user