Example #1
0
        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);
        }
Example #2
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);
        }
        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 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);
        }