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); //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) { var containerDict = new Dictionary>(); foreach (var bot in rawBotsOfSameType) { var backpack = bot.Inventory.items.FirstOrDefault(x => x.slotId == "Backpack"); if (backpack != null) { containerDict.Add(backpack._id, new List()); } var pocket = bot.Inventory.items.FirstOrDefault(x => x.slotId == "Pockets"); if (pocket != null) { containerDict.Add(pocket._id, new List()); } var secure = bot.Inventory.items.FirstOrDefault(x => x.slotId == "SecuredContainer"); if (secure != null) { containerDict.Add(secure._id, new List()); } var tacVest = bot.Inventory.items.FirstOrDefault(x => x.slotId == "TacticalVest"); if (tacVest != null) { containerDict.Add(tacVest._id, new List()); } foreach (var item in bot.Inventory.items) { // Filter out root items and equipment mod items if (item.parentId == null || item.location == null) { continue; } // Container (backpack etc) exists in dict if (containerDict.ContainsKey(item.parentId)) { containerDict[item.parentId].AddUnique(item._tpl); } } var forcedLoot = ForcedLootHelper.GetForcedLoot(); forcedLoot.TryGetValue(botType, out var lootToAdd); if (backpack != null) { if (lootToAdd?.Backpack != null) { botToUpdate.inventory.items.Backpack.AddUniqueRange(lootToAdd.Backpack); } botToUpdate.inventory.items.Backpack.AddUniqueRange(containerDict[backpack._id]); } if (pocket != null) { if (lootToAdd?.Pockets != null) { botToUpdate.inventory.items.Pockets.AddUniqueRange(lootToAdd.Pockets); } botToUpdate.inventory.items.Pockets.AddUniqueRange(containerDict[pocket._id]); } if (secure != null) { botToUpdate.inventory.items.SecuredContainer.AddUniqueRange(containerDict[secure._id]); } if (tacVest != null) { if (lootToAdd?.TacticalVest != null) { botToUpdate.inventory.items.TacticalVest.AddUniqueRange(lootToAdd.TacticalVest); } botToUpdate.inventory.items.TacticalVest.AddUniqueRange(containerDict[tacVest._id]); } 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) { botToUpdate.inventory.items.SpecialLoot.AddRange(SpecialLootHelper.GetSpecialLootForBotType(botToUpdate.botType)); } private static IEnumerable GetItemsStoredInEquipmentItem(IEnumerable rawBots, string containerName) { var itemsStoredInContainer = new List(); var containers = new List(); foreach (var bot in rawBots) { // find the container type we want on this bot (backpack etc) // Add to list var botContainers = bot.Inventory.items.Where(x => x.slotId == containerName); foreach (var container in botContainers) { containers.AddUnique(container._id); } foreach (var item in bot.Inventory.items) { if (containers.Contains(item.parentId)) { itemsStoredInContainer.AddUnique(item._tpl); } } } return itemsStoredInContainer; } } }