Further implementation of gear/weapon generation
This commit is contained in:
@@ -860,7 +860,7 @@ public class BotEquipmentModGenerator(
|
||||
request.RandomisationSettings.MinimumMagazineSize is not null
|
||||
)
|
||||
{
|
||||
modPool = GetFilterdMagazinePoolByCapacity(request, modPool);
|
||||
modPool = GetFilterdMagazinePoolByCapacity(request, modPool).ToList();
|
||||
}
|
||||
|
||||
// Pick random mod that's compatible
|
||||
@@ -919,9 +919,24 @@ public class BotEquipmentModGenerator(
|
||||
/// <param name="modPool">Pool of magazine tpls to filter</param>
|
||||
/// <returns>Filtered pool of magazine tpls</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public List<string> GetFilterdMagazinePoolByCapacity(ModToSpawnRequest modSpawnRequest, List<string> modPool)
|
||||
public IEnumerable<string> GetFilterdMagazinePoolByCapacity(ModToSpawnRequest modSpawnRequest, List<string> modPool)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var weaponTpl = modSpawnRequest.Weapon[0].Template;
|
||||
modSpawnRequest.RandomisationSettings.MinimumMagazineSize.TryGetValue(weaponTpl, out var minMagSizeFromSettings);
|
||||
var minMagazineSize = minMagSizeFromSettings;
|
||||
var desiredMagazineTpls = modPool.Where((magTpl) => {
|
||||
var magazineDb = _itemHelper.GetItem(magTpl).Value;
|
||||
return magazineDb.Properties is not null && magazineDb.Properties.Cartridges.FirstOrDefault().MaxCount >= minMagazineSize;
|
||||
});
|
||||
|
||||
if (!desiredMagazineTpls.Any())
|
||||
{
|
||||
_logger.Warning("Magazine size filter for ${ weaponTpl} was too strict, ignoring filter");
|
||||
|
||||
return modPool;
|
||||
}
|
||||
|
||||
return desiredMagazineTpls;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1420,7 +1435,8 @@ public class BotEquipmentModGenerator(
|
||||
var result = new List<string>();
|
||||
|
||||
// Get item blacklist and mod equipment blacklist as one array
|
||||
var blacklist = _itemFilterService.GetBlacklistedItems().Concat(botEquipBlacklist.Equipment[modSlot]);
|
||||
botEquipBlacklist.Equipment.TryGetValue(modSlot, out var equipmentBlacklistValues);
|
||||
var blacklist = _itemFilterService.GetBlacklistedItems().Concat(equipmentBlacklistValues ?? []);
|
||||
result = allowedMods.Where((tpl) => !blacklist.Contains(tpl)).ToList();
|
||||
|
||||
return result;
|
||||
|
||||
@@ -668,8 +668,8 @@ public class BotGenerator(
|
||||
// Common skills have additional props
|
||||
if (isCommonSkills)
|
||||
{
|
||||
((Common)skillToAdd).PointsEarnedDuringSession = 0;
|
||||
((Common)skillToAdd).LastAccess = 0;
|
||||
skillToAdd.PointsEarnedDuringSession = 0;
|
||||
skillToAdd.LastAccess = 0;
|
||||
}
|
||||
|
||||
return skillToAdd;
|
||||
|
||||
@@ -2,6 +2,7 @@ using System.Text.Json.Serialization;
|
||||
using Core.Models.Common;
|
||||
using Core.Models.Enums;
|
||||
using Core.Utils.Json.Converters;
|
||||
using SptCommon.Extensions;
|
||||
|
||||
namespace Core.Models.Eft.Common.Tables;
|
||||
|
||||
@@ -57,6 +58,19 @@ public record Appearance
|
||||
[JsonPropertyName("voice")]
|
||||
[JsonConverter(typeof(ArrayToObjectFactoryConverter))]
|
||||
public Dictionary<string, double>? Voice { get; set; }
|
||||
|
||||
public Dictionary<string, double> this[string propName]
|
||||
{
|
||||
get
|
||||
{
|
||||
var matchingProp = GetType()
|
||||
.GetProperties()
|
||||
.SingleOrDefault(p => p.GetJsonName() == propName)
|
||||
?.GetValue(this);
|
||||
|
||||
return (Dictionary<string, double>)matchingProp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public record Chances
|
||||
|
||||
@@ -348,8 +348,45 @@ public class BotEquipmentFilterService
|
||||
bool showEditWarnings = true)
|
||||
{
|
||||
//TODO, bad typing by key with method below due to, EquipmentSlots
|
||||
// MAKE CONSISTENT BEFORE IMPLEMENTING
|
||||
throw new NotImplementedException();
|
||||
if (weightingAdjustments is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (weightingAdjustments.Add?.Count > 0)
|
||||
{
|
||||
foreach (var poolAdjustmentKvP in weightingAdjustments.Add)
|
||||
{
|
||||
var locationToUpdate = botItemPool[Enum.Parse<EquipmentSlots>(poolAdjustmentKvP.Key)];
|
||||
foreach (var itemToAddKvP in poolAdjustmentKvP.Value)
|
||||
{
|
||||
locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (weightingAdjustments.Edit?.Count > 0)
|
||||
{
|
||||
foreach (var poolAdjustmentKvP in weightingAdjustments.Edit)
|
||||
{
|
||||
var locationToUpdate = botItemPool[Enum.Parse<EquipmentSlots>(poolAdjustmentKvP.Key)];
|
||||
foreach (var itemToEditKvP in poolAdjustmentKvP.Value)
|
||||
{
|
||||
// Only make change if item exists as we're editing, not adding
|
||||
if (locationToUpdate[itemToEditKvP.Key] != null || locationToUpdate[itemToEditKvP.Key] == 0)
|
||||
{
|
||||
locationToUpdate[itemToEditKvP.Key] = itemToEditKvP.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (showEditWarnings)
|
||||
{
|
||||
_logger.Debug($"Tried to edit a non - existent item for slot: {poolAdjustmentKvP} {itemToEditKvP}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -414,6 +451,44 @@ public class BotEquipmentFilterService
|
||||
Appearance botItemPool,
|
||||
bool showEditWarnings = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (weightingAdjustments is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (weightingAdjustments.Add?.Count > 0)
|
||||
{
|
||||
foreach (var poolAdjustmentKvP in weightingAdjustments.Add)
|
||||
{
|
||||
var locationToUpdate = botItemPool[poolAdjustmentKvP.Key];
|
||||
foreach (var itemToAddKvP in poolAdjustmentKvP.Value)
|
||||
{
|
||||
locationToUpdate[itemToAddKvP.Key] = itemToAddKvP.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (weightingAdjustments.Edit?.Count > 0)
|
||||
{
|
||||
foreach (var poolAdjustmentKvP in weightingAdjustments.Edit)
|
||||
{
|
||||
var locationToUpdate = botItemPool[poolAdjustmentKvP.Key];
|
||||
foreach (var itemToEditKvP in poolAdjustmentKvP.Value)
|
||||
{
|
||||
// Only make change if item exists as we're editing, not adding
|
||||
if (locationToUpdate[itemToEditKvP.Key] != null || locationToUpdate[itemToEditKvP.Key] == 0)
|
||||
{
|
||||
locationToUpdate[itemToEditKvP.Key] = itemToEditKvP.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (showEditWarnings)
|
||||
{
|
||||
_logger.Debug($"Tried to edit a non - existent item for slot: {poolAdjustmentKvP} {itemToEditKvP}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,144 @@
|
||||
using SptCommon.Annotations;
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Utils;
|
||||
using Core.Helpers;
|
||||
using Core.Servers;
|
||||
using Core.Models.Enums;
|
||||
using Core.Models.Spt.Config;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class BotEquipmentModPoolService
|
||||
{
|
||||
protected ISptLogger<BotEquipmentModPoolService> _logger;
|
||||
protected ItemHelper _itemHelper;
|
||||
protected DatabaseService _databaseService;
|
||||
protected LocalisationService _localisationService;
|
||||
protected ConfigServer _configServer;
|
||||
|
||||
protected bool _weaponPoolGenerated = false;
|
||||
protected Dictionary<string, Dictionary<string, HashSet<string>>> _weaponModPool;
|
||||
protected Dictionary<string, Dictionary<string, HashSet<string>>> _gearModPool;
|
||||
protected BotConfig _botConfig;
|
||||
|
||||
public BotEquipmentModPoolService(
|
||||
ISptLogger<BotEquipmentModPoolService> logger,
|
||||
ItemHelper itemHelper,
|
||||
DatabaseService databaseService,
|
||||
LocalisationService localisationService,
|
||||
ConfigServer configServer
|
||||
)
|
||||
{
|
||||
_logger = logger;
|
||||
_itemHelper = itemHelper;
|
||||
_databaseService = databaseService;
|
||||
_localisationService = localisationService;
|
||||
_configServer = configServer;
|
||||
_botConfig = _configServer.GetConfig<BotConfig>();
|
||||
|
||||
_weaponModPool = new Dictionary<string, Dictionary<string, HashSet<string>>>();
|
||||
_gearModPool = new Dictionary<string, Dictionary<string, HashSet<string>>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Store dictionary of mods for each item passed in
|
||||
* @param items items to find related mods and store in modPool
|
||||
*/
|
||||
protected void GeneratePool(List<TemplateItem> items, string poolType)
|
||||
protected void GeneratePool(IEnumerable<TemplateItem>? items, string poolType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (items is null)
|
||||
{
|
||||
_logger.Error(_localisationService.GetText("bot-unable_to_generate_item_pool_no_items", poolType));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get weapon or gear pool
|
||||
var pool = poolType == "weapon" ? _weaponModPool : _gearModPool;
|
||||
foreach (var item in items) {
|
||||
if (item.Properties is null)
|
||||
{
|
||||
_logger.Error(_localisationService.GetText("bot-item_missing_props_property", new {
|
||||
itemTpl = item.Id,
|
||||
name = item.Name,
|
||||
}));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip item without slots
|
||||
if (item.Properties.Slots is null || item.Properties.Slots.Count == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add base item (weapon/armor) to pool
|
||||
if (!pool.ContainsKey(item.Id))
|
||||
{
|
||||
pool[item.Id] = new Dictionary<string, HashSet<string>>();
|
||||
}
|
||||
|
||||
// iterate over each items mod slots e.g. mod_muzzle
|
||||
foreach (var slot in item.Properties.Slots) {
|
||||
// Get mods that fit into the current mod slot
|
||||
var itemsThatFit = slot.Props.Filters.FirstOrDefault().Filter;
|
||||
|
||||
// Get weapon/armor pool to add mod slots + mod tpls to
|
||||
|
||||
foreach (var itemToAddTpl in itemsThatFit)
|
||||
{
|
||||
if (!pool[item.Id].ContainsKey(slot.Name))
|
||||
{
|
||||
// Ensure Mod slot key + blank dict value exist
|
||||
pool[item.Id][slot.Name] = new();
|
||||
}
|
||||
|
||||
if (!pool[item.Id][slot.Name].Contains(itemToAddTpl))
|
||||
{
|
||||
// Add tpl to list keyed by mod slot
|
||||
pool[item.Id][slot.Name].Add(itemToAddTpl);
|
||||
}
|
||||
|
||||
var subItemDetails = _itemHelper.GetItem(itemToAddTpl).Value;
|
||||
var hasSubItemsToAdd = (subItemDetails?.Properties?.Slots?.Count ?? 0) > 0;
|
||||
if (hasSubItemsToAdd && !pool.ContainsKey(subItemDetails.Id))
|
||||
{
|
||||
// Recursive call
|
||||
GeneratePool([subItemDetails], poolType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//foreach (var slot in item.Properties.Slots)
|
||||
//{
|
||||
// var itemsThatFit = slot.Props.Filters[0].Filter;
|
||||
// foreach (var itemToAddTpl in itemsThatFit)
|
||||
// {
|
||||
// // Ensure key/value exists
|
||||
// pool.TryAdd(slot.Name, new Dictionary<string, List<string>>());
|
||||
// pool.TryGetValue(item.Id, out var poolToAddTo);
|
||||
// poolToAddTo ??= new Dictionary<string, List<string>>();
|
||||
|
||||
// // only add item to pool if it doesn't already exist
|
||||
// poolToAddTo.TryAdd(slot.Name, []);
|
||||
// if (!poolToAddTo[slot.Name].Any(x => x == itemToAddTpl))
|
||||
// {
|
||||
// poolToAddTo[slot.Name].Add(itemToAddTpl);
|
||||
|
||||
// // Check item added into array for slots, need to iterate over those
|
||||
// var subItemDetails = _itemHelper.GetItem(itemToAddTpl).Value;
|
||||
// var hasSubItemsToAdd = (subItemDetails?.Properties?.Slots?.Count ?? 0) > 0;
|
||||
// if (hasSubItemsToAdd && !pool.ContainsKey(subItemDetails.Id))
|
||||
// {
|
||||
// // Recursive call
|
||||
// GeneratePool([subItemDetails], poolType);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +157,13 @@ public class BotEquipmentModPoolService
|
||||
*/
|
||||
public List<string> GetCompatibleModsForWeaponSlot(string itemTpl, string slotName)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (!_weaponPoolGenerated)
|
||||
{
|
||||
// Get every weapon in db and generate mod pool
|
||||
GenerateWeaponPool();
|
||||
}
|
||||
|
||||
return _weaponModPool[itemTpl][slotName].ToList();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +202,12 @@ public class BotEquipmentModPoolService
|
||||
*/
|
||||
protected void GenerateWeaponPool()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var weapons = _databaseService.GetItems().Values.Where(
|
||||
(item) => item.Type == "Item" && _itemHelper.IsOfBaseclass(item.Id, BaseClasses.WEAPON));
|
||||
GeneratePool(weapons, "weapon");
|
||||
|
||||
// Flag pool as being complete
|
||||
_weaponPoolGenerated = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -71,7 +71,7 @@ public class ItemFilterService(
|
||||
*/
|
||||
public List<string> GetBlacklistedItems()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _cloner.Clone(_itemConfig.Blacklist);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,29 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Text.Json.Serialization;
|
||||
using Core.Helpers;
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Eft.Common;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Models.Eft.ItemEvent;
|
||||
using Core.Models.Eft.Repair;
|
||||
using Core.Models.Enums;
|
||||
using Core.Utils;
|
||||
|
||||
namespace Core.Services;
|
||||
|
||||
[Injectable(InjectionType.Singleton)]
|
||||
public class RepairService
|
||||
{
|
||||
private readonly RandomUtil _randomUtil;
|
||||
private readonly WeightedRandomHelper _weightedRandomHelper;
|
||||
|
||||
public RepairService(
|
||||
RandomUtil randomUtil,
|
||||
WeightedRandomHelper weightedRandomHelper)
|
||||
{
|
||||
_randomUtil = randomUtil;
|
||||
_weightedRandomHelper = weightedRandomHelper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use trader to repair an items durability
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user