From fa307a29a393e69553d8874fbbc046420c637c03 Mon Sep 17 00:00:00 2001 From: CWX Date: Thu, 16 Jan 2025 13:01:03 +0000 Subject: [PATCH] finish BotWeaponGenHelper --- Core/Helpers/BotWeaponGeneratorHelper.cs | 110 +++++++++++++++++++++-- Core/Models/Eft/Common/Tables/BotType.cs | 2 +- 2 files changed, 103 insertions(+), 9 deletions(-) diff --git a/Core/Helpers/BotWeaponGeneratorHelper.cs b/Core/Helpers/BotWeaponGeneratorHelper.cs index 2ef93210..d9a81053 100644 --- a/Core/Helpers/BotWeaponGeneratorHelper.cs +++ b/Core/Helpers/BotWeaponGeneratorHelper.cs @@ -1,21 +1,82 @@ using Core.Annotations; using Core.Models.Eft.Common.Tables; using Core.Models.Enums; +using Core.Models.Spt.Bots; +using Core.Models.Utils; +using Core.Servers; +using Core.Services; +using Core.Utils; namespace Core.Helpers; [Injectable] public class BotWeaponGeneratorHelper { + private readonly ISptLogger _logger; + private readonly DatabaseServer _databaseServer; + private readonly ItemHelper _itemHelper; + private readonly RandomUtil _randomUtil; + private readonly HashUtil _hashUtil; + private readonly WeightedRandomHelper _weightedRandomHelper; + private readonly BotGeneratorHelper _botGeneratorHelper; + private readonly LocalisationService _localisationService; + + private readonly List _magCheck = ["CylinderMagazine", "SpringDrivenCylinder"]; + + public BotWeaponGeneratorHelper + ( + ISptLogger logger, + DatabaseServer databaseServer, + ItemHelper itemHelper, + RandomUtil randomUtil, + HashUtil hashUtil, + WeightedRandomHelper weightedRandomHelper, + BotGeneratorHelper botGeneratorHelper, + LocalisationService localisationService + ) + { + _logger = logger; + _databaseServer = databaseServer; + _itemHelper = itemHelper; + _randomUtil = randomUtil; + _hashUtil = hashUtil; + _weightedRandomHelper = weightedRandomHelper; + _botGeneratorHelper = botGeneratorHelper; + _localisationService = localisationService; + } + /// /// Get a randomized number of bullets for a specific magazine /// /// Weights of magazines /// Magazine to generate bullet count for /// Bullet count number - public int GetRandomizedBulletCount(GenerationData magCounts, TemplateItem magTemplate) + public double? GetRandomizedBulletCount(GenerationData magCounts, TemplateItem magTemplate) { - throw new NotImplementedException(); + var randomizedMagazineCount = GetRandomizedMagazineCount(magCounts); + var parentItem = _itemHelper.GetItem(magTemplate.Parent).Value; + double? chamberBulletCount = 0; + if (MagazineIsCylinderRelated(parentItem.Name)) + { + var firstSlotAmmoTpl = magTemplate.Properties.Cartridges[0].Props.Filters[0].Filter[0]; + var ammoMaxStackSize = _itemHelper.GetItem(firstSlotAmmoTpl).Value?.Properties?.StackMaxSize ?? 1; + chamberBulletCount = ammoMaxStackSize == 1 + ? 1 // Rotating grenade launcher + : magTemplate.Properties.Slots.Count; // Shotguns/revolvers. We count the number of camoras as the _max_count of the magazine is 0 + } + else if (parentItem.Id == BaseClasses.UBGL) + { + // Underbarrel launchers can only have 1 chambered grenade + chamberBulletCount = 1; + } + else + { + chamberBulletCount = magTemplate.Properties.Cartridges[0].MaxCount; + } + + // Get the amount of bullets that would fit in the internal magazine + // and multiply by how many magazines were supposed to be created + return chamberBulletCount * randomizedMagazineCount; } /// @@ -25,7 +86,7 @@ public class BotWeaponGeneratorHelper /// Numerical value of magazine count public int GetRandomizedMagazineCount(GenerationData magCounts) { - throw new NotImplementedException(); + return (int)_weightedRandomHelper.GetWeightedValue(magCounts.Weights); } /// @@ -35,7 +96,7 @@ public class BotWeaponGeneratorHelper /// True if it is cylinder related public bool MagazineIsCylinderRelated(string magazineParentName) { - throw new NotImplementedException(); + return _magCheck.Contains(magazineParentName); } /// @@ -47,7 +108,14 @@ public class BotWeaponGeneratorHelper /// Item array public List CreateMagazineWithAmmo(string magazineTpl, string ammoTpl, TemplateItem magTemplate) { - throw new NotImplementedException(); + List magazine = + [ + new() { Id = _hashUtil.Generate(), Template = magazineTpl } + ]; + + _itemHelper.FillMagazineWithCartridge(magazine, magTemplate, ammoTpl, 1); + + return magazine; } /// @@ -61,10 +129,36 @@ public class BotWeaponGeneratorHelper string ammoTpl, int cartridgeCount, BotBaseInventory inventory, - object equipmentSlotsToAddTo // TODO: EquipmentSlots[] equipmentSlotsToAddTo = new EquipmentSlots[] { EquipmentSlots.TACTICAL_VEST, EquipmentSlots.POCKETS } + List equipmentSlotsToAddTo ) { - throw new NotImplementedException(); + if (equipmentSlotsToAddTo is null) + equipmentSlotsToAddTo = [EquipmentSlots.TacticalVest.ToString(), EquipmentSlots.Pockets.ToString()]; + + var ammoItems = _itemHelper.SplitStack(new () { + Id = _hashUtil.Generate(), + Template = ammoTpl, + Upd = new () { StackObjectsCount = cartridgeCount }, + }); + + foreach (var ammoItem in ammoItems) { + var result = _botGeneratorHelper.AddItemWithChildrenToEquipmentSlot( + equipmentSlotsToAddTo, + ammoItem.Id, + ammoItem.Template, + [ammoItem], + inventory + ); + + if (result != ItemAddedResult.SUCCESS) { + _logger.Debug($"Unable to add ammo: {ammoItem.Template} to bot inventory, {result.ToString()}"); + + if (result == ItemAddedResult.NO_SPACE || result == ItemAddedResult.NO_CONTAINERS) { + // If there's no space for 1 stack or no containers to hold item, there's no space for the others + break; + } + } + } } /// @@ -74,6 +168,6 @@ public class BotWeaponGeneratorHelper /// Tpl of magazine public string GetWeaponsDefaultMagazineTpl(TemplateItem weaponTemplate) { - throw new NotImplementedException(); + return weaponTemplate.Properties.DefMagType; } } diff --git a/Core/Models/Eft/Common/Tables/BotType.cs b/Core/Models/Eft/Common/Tables/BotType.cs index ccc92bd2..17ab603c 100644 --- a/Core/Models/Eft/Common/Tables/BotType.cs +++ b/Core/Models/Eft/Common/Tables/BotType.cs @@ -303,7 +303,7 @@ public class GenerationData { /** key: number of items, value: weighting */ [JsonPropertyName("weights")] - public Dictionary? Weights { get; set; } + public Dictionary? Weights { get; set; } /** Array of item tpls */ [JsonPropertyName("whitelist")]