private void GenerateItemPositions(bool spoiler) { do { try { if (spoiler) // Add a change between spoiler and non spoiler { random.Next(int.MaxValue); } var itemPool = advancementPool; bool logic = true; if (advancementPool.Count == 0) { itemPool = fillerPool; logic = false; } var currentLocations = romLocations.GetAvailableLocations(haveItems); var tempItems = new List <ItemType>(); var tempItems2 = new List <ItemType>(); tempItems.AddRange(itemPool); int randItem = random.Next(itemPool.Count < 50 ? itemPool.Count : 50); // Get a random Item to try and fill next var testItem = tempItems[randItem]; // Favoring for front of the List where Progression Items are at start. if (romLocations.isItemEarly(testItem, itemPool)) { continue; } tempItems.Remove(testItem); // and remove it from the current test pool if (logic) { while (tempItems.Count > tempItems2.Count) // Collect all Items reachable with test Item pool { if (spoiler) // Add a change between spoiler and non spoiler { random.Next(int.MaxValue); } tempItems2.Clear(); tempItems2.AddRange(tempItems); var x = romLocations.GetInLogicItems(tempItems); tempItems.Clear(); tempItems.AddRange(itemPool.ToList()); tempItems.Remove(testItem); tempItems.AddRange(x); } var locList = romLocations.GetAvailableLocations(tempItems); // See what Locations are available var lateUnique = romLocations.getEmptyLateLocation(testItem, tempItems); lateUnique.AddRange(romLocations.getEmptyUniqueLocation(testItem, tempItems)); if (locList.Count < 5) { random.Next(1); } if (lateUnique.Count > 0) { locList = lateUnique; } bool loc = true; while (loc) { if (spoiler) // Add a change between spoiler and non spoiler// Add a change between spoiler and non spoiler { random.Next(int.MaxValue); } int randLT = random.Next(locList.Count); // Find a Random Location we can throw our Item in if (romLocations.testLocation(testItem, locList[randLT])) { loc = false; romLocations.Locations[romLocations.Locations.IndexOf(locList[randLT])] .Item = new Item(testItem); itemPool.Remove(testItem); haveItems.Add(testItem); } } } else { var locList = romLocations.getEmptyLocation(); int randLT = random.Next(locList.Count); romLocations.Locations[romLocations.Locations.IndexOf(locList[randLT])] .Item = new Item(testItem); itemPool.Remove(testItem); haveItems.Add(testItem); } } catch (ArgumentOutOfRangeException) { if (RandomizerVersion.Debug) { using (var writer = new StreamWriter(string.Format("unavailableLocations - {0}.txt", string.Format(romLocations.SeedFileString, seed)))) { var unavailable = romLocations.GetUnavailableLocations(haveItems); writer.WriteLine("Unavailable Locations"); writer.WriteLine("---------------------"); foreach (var location in unavailable.OrderBy(x => x.Name)) { writer.WriteLine(location.Name); } writer.WriteLine(); writer.WriteLine("Have Items"); writer.WriteLine("----------"); foreach (var item in haveItems) { writer.WriteLine(item); } writer.WriteLine(); writer.WriteLine("Advancement Pool Pool"); writer.WriteLine("---------"); foreach (var item in advancementPool) { writer.WriteLine(item); } writer.WriteLine(); writer.WriteLine("Filler Pool Pool"); writer.WriteLine("---------"); foreach (var item in fillerPool) { writer.WriteLine(item); } } } throw; } } while ((advancementPool.Count > 0 || fillerPool.Count > 0) && romLocations.getEmptyLocation().Count > 0); foreach (var unavailableLocation in romLocations.getEmptyLocation()) { unavailableLocation.Item = new Item(ItemType.Nothing); } log?.AddOrderedItem(romLocations.GetOrderedItems()); log?.AddGeneratedItems(romLocations.Locations); }