using System.Diagnostics; using System.Linq; using Common.Extensions; using Common.Models.Input; using Common.Models.Output; using Generator.Helpers.Gear; namespace Generator { public static class BotLootGenerator { internal static IEnumerable AddLoot(this IEnumerable botsWithGear, Dictionary> rawBots) { var stopwatch = Stopwatch.StartNew(); LoggingHelpers.LogToConsole("Started processing bot loot"); var dictionaryLock = new object(); var tasks = new List(50); foreach (var botToUpdate in botsWithGear) { tasks.Add(Task.Factory.StartNew(() => { var botType = botToUpdate.botType.ToString().ToLower(); List rawBotsOfSameType; lock (dictionaryLock) { if (!rawBots.TryGetValue(botType, out rawBotsOfSameType)) { Console.WriteLine($"(loot) Unable to find {botType} on rawBots data"); return; } } if (rawBotsOfSameType.Count == 0) { return; } AddLootToContainers(botType, botToUpdate, rawBotsOfSameType); GearHelpers.ReduceWeightValues(botToUpdate.inventory.equipment.Backpack); GearHelpers.ReduceWeightValues(botToUpdate.inventory.equipment.Pockets); GearHelpers.ReduceWeightValues(botToUpdate.inventory.equipment.TacticalVest); GearHelpers.ReduceWeightValues(botToUpdate.inventory.equipment.SecuredContainer); //foreach (var rawParsedBot in rawBotsOfSameType) //{ // AddPocketLoot(botToUpdate, rawParsedBot); //} //AddTacticalVestLoot(botToUpdate, rawBotsOfSameType); //AddBackpackLoot(botToUpdate, rawBotsOfSameType); //AddSecureContainerLoot(botToUpdate, rawBotsOfSameType); //AddSpecialLoot(botToUpdate); })); } Task.WaitAll(tasks.ToArray()); stopwatch.Stop(); LoggingHelpers.LogToConsole($"Finished processing bot loot. Took: {LoggingHelpers.LogTimeTaken(stopwatch.Elapsed.TotalSeconds)} seconds"); return botsWithGear; } private static void AddLootToContainers(string botType, Bot botToUpdate, List rawBotsOfSameType) { // Process each bot foreach (var rawBot in rawBotsOfSameType) { // Filter out base inventory items and equipment mod items var rawBotItems = rawBot.Inventory.items.Where(item => item.location != null).ToList(); var botBackpack = rawBot.Inventory.items.FirstOrDefault(item => item.slotId == "Backpack"); if (botBackpack != null) { AddLootItemsToContainerDictionary(rawBotItems, botBackpack._id, botToUpdate.inventory.items.Backpack); } var botPockets = rawBot.Inventory.items.FirstOrDefault(item => item.slotId == "Pockets"); if (botPockets != null) { AddLootItemsToContainerDictionary(rawBotItems, botPockets._id, botToUpdate.inventory.items.Pockets); } var botVest = rawBot.Inventory.items.FirstOrDefault(item => item.slotId == "TacticalVest"); if (botVest != null) { AddLootItemsToContainerDictionary(rawBotItems, botVest._id, botToUpdate.inventory.items.TacticalVest); } var botSecure = rawBot.Inventory.items.FirstOrDefault(item => item.slotId == "SecuredContainer"); if (botSecure != null) { AddLootItemsToContainerDictionary(rawBotItems, botSecure._id, botToUpdate.inventory.items.SecuredContainer); } // Add generic keys to bosses if (botToUpdate.botType.IsBoss()) { var keys = SpecialLootHelper.GetGenericBossKeysDictionary(); foreach (var bosskey in keys) { if (!botToUpdate.inventory.items.Backpack.ContainsKey(bosskey.Key)) { botToUpdate.inventory.items.Backpack.Add(bosskey.Key, bosskey.Value); } } } AddSpecialLoot(botToUpdate); } } /// /// Look for items inside itemsToFilter that have the parentid of `containerId` and add them to dictToAddTo /// Keep track of how many items are added in the dictToAddTo value /// /// Bots inventory items /// /// private static void AddLootItemsToContainerDictionary(List itemsToFilter, string containerId, Dictionary dictToAddTo) { var lootItems = itemsToFilter.Where(item => item.parentId == containerId); foreach (var itemToAdd in lootItems) { if (!dictToAddTo.ContainsKey(itemToAdd._tpl)) { dictToAddTo[itemToAdd._tpl] = 1; return; } dictToAddTo[itemToAdd._tpl]++; } } private static void AddSpecialLoot(Bot botToUpdate) { var itemsToAdd = SpecialLootHelper.GetSpecialLootForBotType(botToUpdate.botType); foreach (var item in itemsToAdd) { if (!botToUpdate.inventory.items.SpecialLoot.ContainsKey(item.Key)) { botToUpdate.inventory.items.SpecialLoot.Add(item.Key, item.Value); } } } } }