private void GenerateItemPositions() { do { var currentLocations = romLocations.GetAvailableLocations(haveItems); var candidateItemList = new List <ItemType>(); // Generate candidate item list foreach (var candidateItem in itemPool) { haveItems.Add(candidateItem); var newLocations = romLocations.GetAvailableLocations(haveItems); if (newLocations.Count > currentLocations.Count) { romLocations.TryInsertCandidateItem(currentLocations, candidateItemList, candidateItem); } haveItems.Remove(candidateItem); } // Grab an item from the candidate list if there are any, otherwise, grab a random item if (candidateItemList.Count > 0) { var insertedItem = candidateItemList[random.Next(candidateItemList.Count)]; itemPool.Remove(insertedItem); haveItems.Add(insertedItem); int insertedLocation = romLocations.GetInsertedLocation(currentLocations, insertedItem, random); currentLocations[insertedLocation].Item = new Item(insertedItem); if (log != null) { log.AddOrderedItem(currentLocations[insertedLocation]); } } else { ItemType insertedItem = romLocations.GetInsertedItem(currentLocations, itemPool, random); itemPool.Remove(insertedItem); haveItems.Add(insertedItem); int insertedLocation = romLocations.GetInsertedLocation(currentLocations, insertedItem, random); currentLocations[insertedLocation].Item = new Item(insertedItem); } } while (itemPool.Count > 0); var unavailableLocations = romLocations.GetUnavailableLocations(haveItems); foreach (var unavailableLocation in unavailableLocations) { unavailableLocation.Item = new Item(ItemType.Nothing); } if (log != null) { log.AddGeneratedItems(romLocations.Locations); } }
private void PlaceItems(List <Region> handledDungeons, List <InventoryItemType> insertedItemPool, Region region) { do { List <Location> currentLocations; if (region == Region.Progression) { currentLocations = romLocations.GetAvailableLocations(haveItems); if (romLocations.Locations.Count(x => x.Item == null) == 0) { throw new RandomizationException("Ran out of places to put items! (WTF?)"); } if (currentLocations.Count == 0) { throw new RandomizationException("Hit a roadblock in item generation..."); } } else { currentLocations = romLocations.GetAvailableLocations(haveItems, region); if (romLocations.Locations.Count(x => x.Item == null) == 0) { throw new RandomizationException("Ran out of places to put items! (WTF?)"); } if (currentLocations.Count == 0) { return; } } if (handledDungeons.Count == 1 || haveItems.Count == 0) { var itemsHandled = HandleForcedItems(currentLocations, insertedItemPool); if (itemsHandled) { continue; } } var candidateItemList = new List <InventoryItemType>(); // Generate candidate item list foreach (var candidateItem in insertedItemPool) { if (!Item.ommitAccessibleCheck(candidateItem)) // Can ommit the following logic for most items, as it doesn't do any thing { haveItems.Add(candidateItem); var newLocations = region == Region.Progression ? romLocations.GetAvailableLocations(haveItems) : romLocations.GetAvailableLocations(haveItems, region); if (newLocations.Count > currentLocations.Count) { romLocations.TryInsertCandidateItem(currentLocations, candidateItemList, candidateItem); } haveItems.Remove(candidateItem); } } if (region == Region.Progression) { AdjustCandidateItems(candidateItemList, haveItems, romLocations); } // Grab an item from the candidate list if there are any, otherwise, grab a random item if (candidateItemList.Count > 0) { var insertedItemList = random.RandomizeList(candidateItemList); foreach (var insertedItem in insertedItemList) { var itemPlaced = PlaceItem(handledDungeons, insertedItemPool, currentLocations, insertedItem, true); if (itemPlaced) { break; } } } else { var excludeLocations = currentLocations.Where(x => x.NeverItems.Any(insertedItemPool.Contains)).ToList(); if (excludeLocations.Count > 0) { var placeItems = new List <InventoryItemType>(); foreach (var location in excludeLocations) { currentLocations.Remove(location); foreach (var item in location.NeverItems) { if (!placeItems.Contains(item) && insertedItemPool.Contains(item)) { placeItems.Add(item); } } } if (currentLocations.Count == 0) { return; } var insertedItemList = random.RandomizeList(placeItems); foreach (var insertedItem in insertedItemList) { var itemPlaced = PlaceItem(handledDungeons, insertedItemPool, currentLocations, insertedItem); if (itemPlaced) { break; } } } else { try { bool itemPlaced; do { var insertedItem = romLocations.GetInsertedItem(currentLocations, insertedItemPool, random); itemPlaced = PlaceItem(handledDungeons, insertedItemPool, currentLocations, insertedItem); } while (!(itemPlaced || currentLocations.Count == 0)); } 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("Item Pool"); writer.WriteLine("---------"); foreach (var item in insertedItemPool) { writer.WriteLine(item); } } } throw; } } } } while (insertedItemPool.Count > 0); }
private void GenerateItemPositions() { do { var currentLocations = romLocations.GetAvailableLocations(haveItems); var candidateItemList = new List <ItemType>(); // Generate candidate item list foreach (var candidateItem in itemPool) { haveItems.Add(candidateItem); var newLocations = romLocations.GetAvailableLocations(haveItems); if (newLocations.Count > currentLocations.Count) { romLocations.TryInsertCandidateItem(currentLocations, candidateItemList, candidateItem); } haveItems.Remove(candidateItem); } AdjustCandidateItems(candidateItemList, haveItems, romLocations); // Grab an item from the candidate list if there are any, otherwise, grab a random item if (candidateItemList.Count > 0) { var insertedItem = candidateItemList[random.Next(candidateItemList.Count)]; itemPool.Remove(insertedItem); haveItems.Add(insertedItem); int insertedLocation = romLocations.GetInsertedLocation(currentLocations, insertedItem, random); currentLocations[insertedLocation].Item = new Item(insertedItem); log?.AddOrderedItem(currentLocations[insertedLocation]); } else { try { ItemType insertedItem = romLocations.GetInsertedItem(currentLocations, itemPool, random); itemPool.Remove(insertedItem); haveItems.Add(insertedItem); int insertedLocation = romLocations.GetInsertedLocation(currentLocations, insertedItem, random); currentLocations[insertedLocation].Item = new Item(insertedItem); } 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("Item Pool"); writer.WriteLine("---------"); foreach (var item in itemPool) { writer.WriteLine(item); } } } throw; } } } while (itemPool.Count > 0); var unavailableLocations = romLocations.GetUnavailableLocations(haveItems); foreach (var unavailableLocation in unavailableLocations) { unavailableLocation.Item = new Item(ItemType.Nothing); } log?.AddGeneratedItems(romLocations.Locations); log?.AddSpecialLocations(romLocations.SpecialLocations); }