private void removeFromLocation(RandoItem chosenItem, RandoLocation chosenLocation)
        {
            if (chosenLocation.Locked == true)
            {
                throw new RandoException("The attempt on a Locked Location has left the program scarred and deformed.");
            }

            //Clear the item
            chosenLocation.ClearItem();

            //Add back into pools
            unusedLocations.Add(chosenLocation);
            unusedItems.Add(chosenItem);

            // Mark as unobtained
            obtainedItems.Remove(chosenItem);
            obtainedLocations.Remove(chosenLocation);
        }
        private void placeAtLocation(RandoItem chosenItem, RandoLocation chosenLocation)
        {
            //Place the item
            chosenLocation.PlaceItem(chosenItem);

            //Remove from the pools
            unusedLocations.Remove(chosenLocation);
            unusedItems.Remove(chosenItem);

            // Mark as obtained
            obtainedItems.Add(chosenItem);
            if (countAvailableLocations(obtainedItems, out _) > availCount)
            {
                //This item opened up progression; lock it in place.
                chosenLocation.Locked = true;
            }
            obtainedLocations.Add(chosenLocation);
        }
예제 #3
0
 public static bool Eval(RandoLocation location, List <RandoItem> obtained)
 {
     return(Eval(location.LogicBase, obtained));
 }
        public List <RandoLocation> Randomize()
        {
            IO.Log("Get Stuff");
            unusedItems     = RandoData.GetAllItems();
            unusedLocations = RandoData.GetAllLocations();

            obtainedLocations = new List <RandoLocation>();
            obtainedItems     = new List <RandoItem>();

            IO.Log("Main Rando Loop");
            while (unusedLocations.Count > 0)
            {
                IO.Log($"Top of Loop: {unusedLocations.Count} locs left");
                availCount = countAvailableLocations(obtainedItems, out List <RandoLocation> allAvailLocations);
                RandoItem     chosenItem;
                RandoLocation chosenLocation;

                if (unusedLocations.Count == 1 && unusedItems.Count == 1)
                {
                    IO.Log("Almost done! Last location.");
                    // The last metroid is in captivity. The galaxy is almost complete.
                    chosenItem     = unusedItems[0];
                    chosenLocation = unusedLocations[0];
                }
                else
                {
                    bool canCompleteGame = Logic.Eval(RandoData.Macros["CAN_COMPLETE_GAME"].LogicBase, obtainedItems);

                    if (availCount == 1 && !canCompleteGame)
                    {
                        IO.Log("Must force!", IO.LogType.Warn);
                        // Force Progression
                        List <RandoItem> candItems = getItemCandidates(obtainedItems, availCount);
                        if (candItems.Count == 0)
                        {
                            if (unusedItems.Count == 2)
                            {
                                int vhsCount = unusedItems.Where(v => v.Name == "vhs").Count();

                                if (vhsCount == 2)
                                {
                                    IO.Log("A wild Panic Swap appeared!", IO.LogType.Warn);
                                    logCurrentItems(null, unusedLocations, unusedItems);

                                    // Last Loc VHS Problem
                                    RandoItem     panicItem     = unusedItems[0];
                                    RandoLocation panicLocation = chooseLocation(obtainedLocations.Where(v => v.Locked == false && v.Item.Name != "vhs"));

                                    RandoItem swapItem = panicLocation.Item;

                                    removeFromLocation(swapItem, panicLocation);
                                    placeAtLocation(panicItem, panicLocation);
                                    vhsCount--;

                                    IO.Log($"Okay, panic resolved.");
                                    IO.Log($"I put {panicItem} at {panicLocation.ID} and will find a new home for {swapItem}", IO.LogType.Debug);

                                    logCurrentItems(null, unusedLocations, unusedItems);
                                    continue;
                                }

                                IO.Log($"I am reasonably certain something has gone wrong... I know you're upset, but please refrain from turning people into animals JUST yet.");
                                logCurrentItems(obtainedLocations, unusedLocations, unusedItems);
                                throw new RandoException("No Candidate Items Left!");
                            }
                        }

                        // Pick an item
                        chosenItem = candItems[rnd.Next(candItems.Count - 1)];
                    }
                    else
                    {
                        // Choose a totes random item.
                        chosenItem = unusedItems[rnd.Next(unusedItems.Count - 1)];
                    }
                    // Choose the spot
                    chosenLocation = chooseLocation(allAvailLocations.Except(obtainedLocations));
                }

                // Place the item; remove from pools
                placeAtLocation(chosenItem, chosenLocation);

                IO.Log($"{chosenLocation.ID}: I got put a {chosenItem.Name} on me.", IO.LogType.Debug);
            }

            IO.Log("Rando Finish");
            logCurrentItems(obtainedLocations, null, null);

            return(obtainedLocations);
        }