From 7c2d455b7b076320ea070df40510d332b3377825 Mon Sep 17 00:00:00 2001 From: Dev Date: Tue, 31 Oct 2023 19:35:32 +0000 Subject: [PATCH] Calculate weights for all bot equipment/ammo/appearance --- Common/Extensions/EnumExtensions.cs | 5 +- Generator/BaseBotGenerator.cs | 11 +- Generator/BotGearGenerator.cs | 3 + Generator/BotLootGenerator.cs | 15 +- Generator/Generator.csproj | 45 ++++++ Generator/Helpers/Gear/GearHelpers.cs | 178 ++++++++++++++++++------ Generator/Program.cs | 29 ++-- Generator/Weighting/WeightingService.cs | 2 +- 8 files changed, 222 insertions(+), 66 deletions(-) diff --git a/Common/Extensions/EnumExtensions.cs b/Common/Extensions/EnumExtensions.cs index 74400fb..f37673a 100644 --- a/Common/Extensions/EnumExtensions.cs +++ b/Common/Extensions/EnumExtensions.cs @@ -4,13 +4,14 @@ using System.Collections.Generic; namespace Common.Extensions; public static class EnumExtensions { - private static readonly List bossTypes = new List(){ + private static readonly List bossTypes = new(){ BotType.bossbully, BotType.bossgluhar, BotType.bosskilla, BotType.bosskojaniy, BotType.bosssanitar, - BotType.bosstagilla + BotType.bosstagilla, + BotType.bossboar }; public static bool IsBoss(this BotType self) diff --git a/Generator/BaseBotGenerator.cs b/Generator/BaseBotGenerator.cs index 887961a..539b634 100644 --- a/Generator/BaseBotGenerator.cs +++ b/Generator/BaseBotGenerator.cs @@ -3,6 +3,7 @@ using Common.Models; using Common.Models.Input; using Common.Models.Output; using Generator.Helpers; +using Generator.Helpers.Gear; using System.Diagnostics; namespace Generator @@ -53,7 +54,6 @@ namespace Generator } } - stopwatch.Stop(); LoggingHelpers.LogToConsole($"Finished processing bot base. Took {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); @@ -155,10 +155,15 @@ namespace Generator private static void AddVisualAppearanceItems(Bot botToUpdate, Datum rawBot) { + GearHelpers.IncrementDictionaryValue(botToUpdate.appearance.feet, rawBot.Customization.Feet); + //botToUpdate.appearance.feet.AddUnique(rawBot.Customization.Feet, 1); + GearHelpers.ReduceWeightValues(botToUpdate.appearance.feet); + + GearHelpers.IncrementDictionaryValue(botToUpdate.appearance.body, rawBot.Customization.Body); + GearHelpers.ReduceWeightValues(botToUpdate.appearance.body); + botToUpdate.appearance.head.AddUnique(rawBot.Customization.Head); - botToUpdate.appearance.body.AddUnique(rawBot.Customization.Body, 1); botToUpdate.appearance.hands.AddUnique(rawBot.Customization.Hands); - botToUpdate.appearance.feet.AddUnique(rawBot.Customization.Feet, 1); } private static void AddName(Bot botToUpdate, Datum rawBot) diff --git a/Generator/BotGearGenerator.cs b/Generator/BotGearGenerator.cs index 3a9505f..0ad6b30 100644 --- a/Generator/BotGearGenerator.cs +++ b/Generator/BotGearGenerator.cs @@ -42,6 +42,9 @@ namespace Generator GearHelpers.AddEquippedMods(botToUpdate, rawParsedBot); //GearHelpers.AddCartridges(botToUpdate, rawParsedBot); } + + GearHelpers.ReduceAmmoWeightValues(botToUpdate); + GearHelpers.ReduceEquipmentWeightValues(botToUpdate.inventory.equipment); })); } diff --git a/Generator/BotLootGenerator.cs b/Generator/BotLootGenerator.cs index 256aa77..7428976 100644 --- a/Generator/BotLootGenerator.cs +++ b/Generator/BotLootGenerator.cs @@ -136,12 +136,6 @@ namespace Generator if (backpack != null) { botToUpdate.inventory.items.Backpack.AddUniqueRange(containerDict[backpack._id]); - - // Add generic keys to bosses - if (botToUpdate.botType.IsBoss()) - { - botToUpdate.inventory.items.Backpack.AddUniqueRange(SpecialLootHelper.GetGenericBossKeys().ToList()); - } } if (pocket != null) @@ -161,6 +155,15 @@ namespace Generator containerDict.Clear(); } + + // Add generic keys to bosses + if (botToUpdate.botType.IsBoss()) + { + var keys = SpecialLootHelper.GetGenericBossKeys().ToList(); + botToUpdate.inventory.items.Backpack.AddUniqueRange(keys); + } + + AddSpecialLoot(botToUpdate); } private static void AddSpecialLoot(Bot botToUpdate) diff --git a/Generator/Generator.csproj b/Generator/Generator.csproj index 52f62a0..5316150 100644 --- a/Generator/Generator.csproj +++ b/Generator/Generator.csproj @@ -180,18 +180,63 @@ + + Always + Always + + Always + + + Always + + + Always + + + Always + Always Always + + Always + + + Always + + + Always + + + Always + + + Always + Always + + Always + + + Always + + + Always + + + Always + + + Always + diff --git a/Generator/Helpers/Gear/GearHelpers.cs b/Generator/Helpers/Gear/GearHelpers.cs index c35d211..61d5034 100644 --- a/Generator/Helpers/Gear/GearHelpers.cs +++ b/Generator/Helpers/Gear/GearHelpers.cs @@ -12,30 +12,10 @@ namespace Generator.Helpers.Gear var modItemsInRawBot = new List(); var itemsWithModsInRawBot = new List(); - - //foreach (var inv in rawParsedBot.Inventory.items.Where(x => x.slotId == "mod_magazine")) - //{ - //var count = rawParsedBot.Inventory.items.Where(x => x.slotId == "mod_magazine").Count(); - // if (inv._tpl == "60dc519adf4c47305f6d410d") - // { - // var y = 1; - // } - //} - modItemsInRawBot = rawParsedBot.Inventory.items .Where(x => x.slotId != null && (x.slotId.StartsWith("mod_") || x.slotId.StartsWith("patron_in_weapon"))).ToList(); - //var x = new List(); - //foreach (var item in rawParsedBot.Inventory.items.Where(x=>x.slotId == "mod_magazine")) - //{ - // if (item._tpl == "60dc519adf4c47305f6d410d") - // { - // var wow = 1; - // } - // x.Add(item); - //} - - // get items with Mods by iterating over mod items and getting the parent item + // Get items with Mods by iterating over mod items and getting the parent item itemsWithModsInRawBot.AddRange(modItemsInRawBot .Select(modItem => rawParsedBot.Inventory.items .Find(x => x._id == modItem.parentId))); @@ -45,6 +25,16 @@ namespace Generator.Helpers.Gear { var modsToAdd = modItemsInRawBot.Where(x => x.parentId == itemToAdd._id).ToList(); + // fix pistolgrip that changes slot id name + if (itemToAdd._tpl == "56e0598dd2720bb5668b45a6") + { + var badMod = modsToAdd.FirstOrDefault(x => x.slotId == "mod_pistol_grip" && x._tpl == "56e05a6ed2720bd0748b4567"); + if (badMod != null) + { + badMod.slotId = "mod_pistolgrip"; + } + } + AddItemToDictionary(itemToAdd, modsToAdd, itemsWithModsDictionary); // check if these mods have sub-mods and add those @@ -64,14 +54,17 @@ namespace Generator.Helpers.Gear internal static void AddAmmo(Bot botToUpdate, Datum bot) { - var weightService = new WeightingService(); - foreach (var inventoryItem in bot.Inventory.items.Where(x => x.slotId != null && (x.slotId == "patron_in_weapon" || x.slotId == "cartridges" || x.slotId.StartsWith("camora")))) + //var weightService = new WeightingService(); + foreach (var ammo in bot.Inventory.items.Where( + x => x.slotId != null + && (x.slotId == "patron_in_weapon" + || (x.slotId == "cartridges" && bot.Inventory.items.FirstOrDefault(parent => parent._id == x.parentId)?.slotId != "main") // Ignore cartridges in ammo boxes for ammo usage calc + || x.slotId.StartsWith("camora")))) { - var caliber = ItemTemplateHelper.GetTemplateById(inventoryItem._tpl)._props.ammoCaliber; - + var caliber = ItemTemplateHelper.GetTemplateById(ammo._tpl)._props.ammoCaliber; if (caliber == null) { - caliber = ItemTemplateHelper.GetTemplateById(inventoryItem._tpl)._props.Caliber; + caliber = ItemTemplateHelper.GetTemplateById(ammo._tpl)._props.Caliber; } // Create key if caliber doesnt exist @@ -80,10 +73,36 @@ namespace Generator.Helpers.Gear botToUpdate.inventory.Ammo[caliber] = new Dictionary(); } - botToUpdate.inventory.Ammo[caliber].AddUnique(inventoryItem._tpl, weightService.GetAmmoWeight(inventoryItem._tpl, botToUpdate.botType, caliber)); + if (!botToUpdate.inventory.Ammo[caliber].ContainsKey(ammo._tpl)) + { + botToUpdate.inventory.Ammo[caliber][ammo._tpl] = 0; + } + + botToUpdate.inventory.Ammo[caliber][ammo._tpl] ++; } } + public static int CommonDivisor(List numbers) + { + int result = numbers[0]; + for (int i = 1; i < numbers.Count; i++) + { + result = GCD(result, numbers[i]); + } + return result; + } + + private static int GCD(int a, int b) + { + while (b != 0) + { + int temp = b; + b = a % b; + a = temp; + } + return a; + } + public static void AddEquippedGear(Bot botToUpdate, Datum bot) { // add equipped gear @@ -93,46 +112,46 @@ namespace Generator.Helpers.Gear switch (inventoryItem.slotId?.ToLower()) { case "headwear": - botToUpdate.inventory.equipment.Headwear.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "headwear")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Headwear, inventoryItem._tpl); break; case "earpiece": - botToUpdate.inventory.equipment.Earpiece.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "earpiece")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Earpiece, inventoryItem._tpl); break; case "facecover": - botToUpdate.inventory.equipment.FaceCover.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "facecover")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.FaceCover, inventoryItem._tpl); break; case "armorvest": - botToUpdate.inventory.equipment.ArmorVest.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "armorvest")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.ArmorVest, inventoryItem._tpl); break; case "eyewear": - botToUpdate.inventory.equipment.Eyewear.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "eyewear")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Eyewear, inventoryItem._tpl); break; case "armband": - botToUpdate.inventory.equipment.ArmBand.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "armband")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.ArmBand, inventoryItem._tpl); break; case "tacticalvest": - botToUpdate.inventory.equipment.TacticalVest.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "tacticalvest")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.TacticalVest, inventoryItem._tpl); break; case "backpack": - botToUpdate.inventory.equipment.Backpack.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "backpack")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Backpack, inventoryItem._tpl); break; case "firstprimaryweapon": - botToUpdate.inventory.equipment.FirstPrimaryWeapon.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "firstprimaryweapon")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.FirstPrimaryWeapon, inventoryItem._tpl); break; case "secondprimaryweapon": - botToUpdate.inventory.equipment.SecondPrimaryWeapon.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "secondprimaryweapon")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.SecondPrimaryWeapon, inventoryItem._tpl); break; case "holster": - botToUpdate.inventory.equipment.Holster.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "holster")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Holster, inventoryItem._tpl); break; case "scabbard": - botToUpdate.inventory.equipment.Scabbard.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "scabbard")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Scabbard, inventoryItem._tpl); break; case "pockets": - botToUpdate.inventory.equipment.Pockets.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "pockets")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.Pockets, inventoryItem._tpl); break; case "securedcontainer": - botToUpdate.inventory.equipment.SecuredContainer.AddUnique(inventoryItem._tpl, weightService.GetItemWeight(inventoryItem._tpl, botToUpdate.botType, "securedcontainer")); + IncrementDictionaryValue(botToUpdate.inventory.equipment.SecuredContainer, inventoryItem._tpl); break; default: break; @@ -140,6 +159,16 @@ namespace Generator.Helpers.Gear } } + public static void IncrementDictionaryValue(Dictionary dictToIncrement, string key) + { + if (!dictToIncrement.ContainsKey(key)) + { + dictToIncrement[key] = 0; + } + + dictToIncrement[key]++; + } + public static void AddCartridges(Bot botToUpdate, Datum rawParsedBot) { var cartridgesInRawBot = rawParsedBot.Inventory.items @@ -250,5 +279,72 @@ namespace Generator.Helpers.Gear return itemsThatTakeCartridgesDict; } + + internal static void ReduceAmmoWeightValues(Bot botToUpdate) + { + foreach (var caliber in botToUpdate.inventory.Ammo) + { + foreach (var cartridge in botToUpdate.inventory.Ammo.Keys) + { + var cartridgeWithWeights = botToUpdate.inventory.Ammo[cartridge]; + var weights = cartridgeWithWeights.Values.Select(x => x).ToList(); + var commonAmmoDivisor = CommonDivisor(weights); + + foreach (var cartridgeWeightKvP in cartridgeWithWeights) + { + botToUpdate.inventory.Ammo[cartridge][cartridgeWeightKvP.Key] /= commonAmmoDivisor; + } + } + } + } + + public static void ReduceEquipmentWeightValues(Equipment equipment) + { + ReduceWeightValues(equipment.Headwear); + ReduceWeightValues(equipment.Earpiece); + ReduceWeightValues(equipment.FaceCover); + ReduceWeightValues(equipment.ArmorVest); + ReduceWeightValues(equipment.Eyewear); + ReduceWeightValues(equipment.ArmBand); + ReduceWeightValues(equipment.TacticalVest); + ReduceWeightValues(equipment.Backpack); + ReduceWeightValues(equipment.FirstPrimaryWeapon); + ReduceWeightValues(equipment.SecondPrimaryWeapon); + ReduceWeightValues(equipment.Scabbard); + ReduceWeightValues(equipment.Holster); + ReduceWeightValues(equipment.Pockets); + ReduceWeightValues(equipment.SecuredContainer); + } + + public static void ReduceWeightValues(Dictionary equipmentDict) + { + // No values, nothing to reduce + if (equipmentDict.Count == 0) + { + return; + } + + // Only one value, quickly set to 1 and exit + if (equipmentDict.Count == 1) + { + equipmentDict[equipmentDict.First().Key] = 1; + + return; + } + + var weights = equipmentDict.Values.Select(x => x).ToList(); + var commonAmmoDivisor = CommonDivisor(weights); + + // No point in dividing by 1 + if (commonAmmoDivisor == 1) + { + return; + } + + foreach (var itemTplWithWeight in equipmentDict) + { + equipmentDict[itemTplWithWeight.Key] /= commonAmmoDivisor; + } + } } } diff --git a/Generator/Program.cs b/Generator/Program.cs index f753df3..4a64ebd 100644 --- a/Generator/Program.cs +++ b/Generator/Program.cs @@ -24,8 +24,7 @@ internal static class Program "bosszryachiy", "bossboar", "bossboarsniper", - - + "followerbully", "followergluharassault", "followergluharscout", @@ -38,43 +37,47 @@ internal static class Program "followerbigpipe", "followerzryachiy", "followerboar", - // // + "cursedassault", - // // "sectantpriest", "sectantwarrior", "gifter", "arenafighterevent", "crazyassaultevent" - }; + }; // Read raw bot dumps and turn into c# objects var workingPath = Directory.GetCurrentDirectory(); var dumpPath = $"{workingPath}//dumps"; var parsedBots = BotParser.ParseAsync(dumpPath, botTypes.ToHashSet()); - // put in dictionary for better use later on + // Put in dictionary for better use later on var rawBotsCache = new Dictionary>(40); foreach (var rawBot in parsedBots) { if (rawBotsCache.TryGetValue(rawBot.Info.Settings.Role.ToLower(), out var botList)) + { botList.Add(rawBot); - else - rawBotsCache.Add(rawBot.Info.Settings.Role.ToLower(), new List {rawBot}); + + continue; + } + + // Doesnt exist, add key and bot + rawBotsCache.Add(rawBot.Info.Settings.Role.ToLower(), new List { rawBot }); } - + if (parsedBots.Count == 0) { - LoggingHelpers.LogToConsole("no bots found, unable to continue"); + LoggingHelpers.LogToConsole("No bots found, unable to continue"); LoggingHelpers.LogToConsole("Check your dumps are in 'Generator\\bin\\Debug\\net6.0\\dumps' and start with 'resp.' NOT 'req.'"); return; } // Generate the base bot class with basic details (health/body part hp etc) and then append everything else var bots = BaseBotGenerator.GenerateBaseDetails(parsedBots, workingPath, botTypes) - .AddGear(rawBotsCache) // Add weapons/armor - .AddLoot(rawBotsCache) - .AddChances(rawBotsCache); // Add mod/equipment chances + .AddGear(rawBotsCache) // Add weapons/armor + .AddLoot(rawBotsCache) + .AddChances(rawBotsCache); // Add mod/equipment chances // Output bot to json file var jsonWriter = new JsonWriter(workingPath, "output"); diff --git a/Generator/Weighting/WeightingService.cs b/Generator/Weighting/WeightingService.cs index d739c79..115c498 100644 --- a/Generator/Weighting/WeightingService.cs +++ b/Generator/Weighting/WeightingService.cs @@ -15,8 +15,8 @@ namespace Generator.Weighting public class WeightingService { private readonly Dictionary _weights; - private readonly Dictionary> _generationWeights; + public WeightingService() { var assetsPath = $"{Directory.GetCurrentDirectory()}\\Assets";