Пример #1
0
        private static void PlaceOneWayTransitions()
        {
            if (randomizationError)
            {
                return;
            }
            List <string> oneWayEntrances   = LogicManager.TransitionNames().Where(transition => LogicManager.GetTransitionDef(transition).oneWay == 1).ToList();
            List <string> oneWayExits       = LogicManager.TransitionNames().Where(transition => LogicManager.GetTransitionDef(transition).oneWay == 2).ToList();
            List <string> horizontalOneWays = oneWayEntrances.Where(t => !LogicManager.GetTransitionDef(t).doorName.StartsWith("b")).ToList();

            while (horizontalOneWays.Any())
            {
                string horizontalEntrance = horizontalOneWays.First();
                string downExit           = oneWayExits[rand.Next(oneWayExits.Count)];

                tm.PlaceOneWayPair(horizontalEntrance, downExit);
                oneWayEntrances.Remove(horizontalEntrance);
                horizontalOneWays.Remove(horizontalEntrance);
                oneWayExits.Remove(downExit);
            }

            DirectedTransitions directed = new DirectedTransitions(rand);

            directed.Add(oneWayExits);
            while (oneWayEntrances.Any())
            {
                string entrance = oneWayEntrances[rand.Next(oneWayEntrances.Count)];
                string exit     = directed.GetNextTransition(entrance);

                tm.PlaceOneWayPair(entrance, exit);
                oneWayEntrances.Remove(entrance);
                oneWayExits.Remove(exit);
                directed.Remove(exit);
            }
        }
        public void Add(params string[] newTransitions)
        {
            foreach (string t in newTransitions)
            {
                string doorName = LogicManager.GetTransitionDef(t).doorName;
                switch (doorName.Substring(0, 3))
                {
                case "doo":
                case "rig":
                    rightTransitions.Add(t);
                    break;

                case "lef":
                    leftTransitions.Add(t);
                    break;

                case "top":
                    topTransitions.Add(t);
                    break;

                case "bot":
                    botTransitions.Add(t);
                    break;
                }
            }
        }
 public void Add(List <string> newTransitions)
 {
     leftTransitions.AddRange(newTransitions.Where(transition => LogicManager.GetTransitionDef(transition).doorName.StartsWith("left")));
     rightTransitions.AddRange(newTransitions.Where(transition => LogicManager.GetTransitionDef(transition).doorName.StartsWith("right") || LogicManager.GetTransitionDef(transition).doorName.StartsWith("door")));
     topTransitions.AddRange(newTransitions.Where(transition => LogicManager.GetTransitionDef(transition).doorName.StartsWith("top")));
     botTransitions.AddRange(newTransitions.Where(transition => LogicManager.GetTransitionDef(transition).doorName.StartsWith("bot")));
 }
        public void LogCounts()
        {
            int left1  = leftTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay != 0).Count();
            int right1 = rightTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay != 0).Count();
            int top1   = topTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay != 0).Count();
            int bot1   = botTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay != 0).Count();

            int left2  = leftTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay == 0).Count();
            int right2 = rightTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay == 0).Count();
            int top2   = topTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay == 0).Count();
            int bot2   = botTransitions.Where(t => LogicManager.GetTransitionDef(t).oneWay == 0).Count();

            if (0 != left1 || 0 != right1 || 0 != top1 || bot1 != 0)
            {
                LogHelper.Log("One-way counts:");
                LogHelper.Log("Left: " + left1);
                LogHelper.Log("Right: " + right1);
                LogHelper.Log("Top: " + top1);
                LogHelper.Log("Bottom: " + bot1);
            }
            LogHelper.Log("Two-way counts:");
            LogHelper.Log("Left: " + left2);
            LogHelper.Log("Right: " + right2);
            LogHelper.Log("Top: " + top2);
            LogHelper.Log("Bottom: " + bot2);
        }
        public static void BuildRoomSpanningTree()
        {
            List <string> rooms = new List <string>();
            Dictionary <string, List <string> > roomTransitions = new Dictionary <string, List <string> >();

            foreach (string transition in LogicManager.TransitionNames())
            {
                if (transition == startTransition)
                {
                    continue;
                }
                TransitionDef def      = LogicManager.GetTransitionDef(transition);
                string        roomName = def.sceneName;
                if (new List <string> {
                    "Crossroads_46", "Crossroads_46b"
                }.Contains(roomName))
                {
                    roomName = "Crossroads_46";
                }
                if (new List <string> {
                    "Abyss_03", "Abyss_03_b", "Abyss_03_c"
                }.Contains(roomName))
                {
                    roomName = "Abyss_03";
                }
                if (new List <string> {
                    "Ruins2_10", "Ruins2_10b"
                }.Contains(roomName))
                {
                    roomName = "Ruins2_10";
                }

                if (!rooms.Contains(roomName) && !def.deadEnd && !def.isolated)
                {
                    rooms.Add(roomName);
                    roomTransitions.Add(roomName, new List <string>());
                }
            }

            foreach (string transition in LogicManager.TransitionNames())
            {
                if (transition == startTransition)
                {
                    continue;
                }
                TransitionDef def      = LogicManager.GetTransitionDef(transition);
                string        roomName = def.sceneName;
                if (def.oneWay == 0 && rooms.Contains(roomName))
                {
                    roomTransitions[roomName].Add(transition);
                }
            }

            BuildSpanningTree(roomTransitions);
        }
Пример #6
0
        private List <string> GetReachableTransitions(ProgressionManager _pm = null) // essentially the same as the method in transitionManager, using that class's static placement dictionary
        {
            if (_pm != null)
            {
                pm = _pm;
            }
            bool          done    = false;
            bool          updated = false;
            List <string> reachableTransitions   = new List <string>();
            List <string> unreachableTransitions = LogicManager.TransitionNames().ToList();

            while (!done)
            {
                foreach (string transition in unreachableTransitions)
                {
                    if (pm.Has(transition))
                    {
                        reachableTransitions.Add(transition);
                    }
                    else if (LogicManager.GetTransitionDef(transition).oneWay == 2)
                    {
                        string entrance = TransitionManager.transitionPlacements.FirstOrDefault(exit => exit.Value == transition).Key;

                        if (entrance != null && pm.CanGet(entrance))
                        {
                            reachableTransitions.Add(transition);
                            updated = true;
                        }
                    }
                    else if (!LogicManager.GetTransitionDef(transition).isolated&& pm.CanGet(transition))
                    {
                        reachableTransitions.Add(transition);
                        updated = true;
                    }

                    else if (TransitionManager.transitionPlacements.TryGetValue(transition, out string altTransition) && LogicManager.GetTransitionDef(altTransition).oneWay != 2 &&
                             !LogicManager.GetTransitionDef(altTransition).isolated&& pm.CanGet(altTransition))
                    {
                        reachableTransitions.Add(transition);
                        updated = true;
                    }
                }
                foreach (string transition in reachableTransitions)
                {
                    unreachableTransitions.Remove(transition);
                    pm.Add(transition);
                }
                done    = !updated;
                updated = false;
            }
            return(reachableTransitions);
        }
        public static void BuildAreaSpanningTree()
        {
            List <string> areas = new List <string>();
            Dictionary <string, List <string> > areaTransitions = new Dictionary <string, List <string> >();

            foreach (string transition in LogicManager.TransitionNames())
            {
                if (transition == startTransition)
                {
                    continue;
                }
                TransitionDef def      = LogicManager.GetTransitionDef(transition);
                string        areaName = def.areaName;
                if (new List <string> {
                    "City_of_Tears", "Forgotten_Crossroads", "Resting_Grounds"
                }.Contains(areaName))
                {
                    areaName = "Kings_Station";
                }
                if (new List <string> {
                    "Ancient_Basin", "Kingdoms_Edge"
                }.Contains(areaName))
                {
                    areaName = "Deepnest";
                }

                if (!areas.Contains(areaName) && !def.deadEnd && !def.isolated)
                {
                    areas.Add(areaName);
                    areaTransitions.Add(areaName, new List <string>());
                }
            }

            foreach (string transition in LogicManager.TransitionNames())
            {
                if (transition == startTransition)
                {
                    continue;
                }
                TransitionDef def      = LogicManager.GetTransitionDef(transition);
                string        areaName = def.areaName;
                if (def.oneWay == 0 && areas.Contains(areaName))
                {
                    areaTransitions[areaName].Add(transition);
                }
            }

            BuildSpanningTree(areaTransitions);
        }
        public bool Test(string transitionTarget)
        {
            if (SinglyCompatible())
            {
                return(true);
            }
            string doorName = LogicManager.GetTransitionDef(transitionTarget).doorName;

            switch (doorName.Substring(0, 3))
            {
            case "doo":
            case "rig":
                if (left)
                {
                    return(true);
                }
                break;

            case "lef":
                if (right)
                {
                    return(true);
                }
                break;

            case "top":
                if (bot)
                {
                    return(true);
                }
                break;

            case "bot":
                if (top)
                {
                    return(true);
                }
                break;
            }
            return(false);
        }
        public string GetNextTransition(string input)
        {
            string doorName = LogicManager.GetTransitionDef(input).doorName;
            string output   = null;

            switch (doorName.Substring(0, 3))
            {
            case "doo":
            case "rig":
                if (leftTransitions.Any())
                {
                    output = leftTransitions[rand.Next(leftTransitions.Count)];
                }
                break;

            case "lef":
                if (rightTransitions.Any())
                {
                    output = rightTransitions[rand.Next(rightTransitions.Count)];
                }
                break;

            case "top":
                if (botTransitions.Any())
                {
                    output = botTransitions[rand.Next(botTransitions.Count)];
                }
                break;

            case "bot":
                if (topTransitions.Any())
                {
                    output = topTransitions[rand.Next(topTransitions.Count)];
                }
                break;
            }
            return(output);
        }
Пример #10
0
        private static void CompleteTransitionGraph()
        {
            if (randomizationError)
            {
                return;
            }

            // IDK if this is the right fix but the line is correct and the algo is being rewritten so w/e
            foreach (string item in startProgression)
            {
                im.UpdateReachableLocations(item);
            }

            int failsafe = 0;

            Log("Beginning full placement of transitions...");

            while (tm.unplacedTransitions.Any())
            {
                failsafe++;
                if (failsafe > 120)
                {
                    Log("Aborted randomization on too many passes. At the time, there were:");
                    Log("Unplaced transitions: " + tm.unplacedTransitions.Count);
                    Log("Reachable transitions: " + tm.reachableTransitions.Count);
                    Log("Reachable unplaced transitions, directionally compatible: " + tm.placeableCount);
                    Log("Reachable item locations: " + im.availableCount);
                    foreach (string t in tm.unplacedTransitions)
                    {
                        Log(t + ", in reachable: " + tm.reachableTransitions.Contains(t) + ", is reachable: " + tm.pm.CanGet(t));
                    }
                    randomizationError = true;
                    return;
                }

                if (im.canGuess && im.availableCount > 1) // give randomized progression as locations are available
                {
                    if (im.FindNextLocation(tm.pm) is string placeLocation)
                    {
                        string placeItem = im.GuessItem();
                        im.PlaceItem(placeItem, placeLocation);
                        tm.UpdateReachableTransitions(placeItem, true);
                    }
                }

                int placeableCount = tm.placeableCount;
                if (placeableCount < 4)
                {
                    tm.UpdateReachableTransitions();
                }
                if (placeableCount == 0 && im.availableCount == 0)
                {
                    Log("Ran out of locations?!?");
                    randomizationError = true;
                    return;
                }
                else if (placeableCount > 2)
                {
                    tm.UnloadReachableStandby();
                    string transition1 = tm.NextTransition();
                    string transition2 = tm.dt.GetNextTransition(transition1);
                    tm.PlaceTransitionPair(transition1, transition2);
                    //Log($">2 place: {transition1}, {transition2}");
                    continue;
                }
                else if (tm.unplacedTransitions.Count == 2)
                {
                    string transition1 = tm.unplacedTransitions[0];
                    string transition2 = tm.unplacedTransitions[1];
                    tm.PlaceTransitionPair(transition1, transition2);
                    //Log($"last place: {transition1}, {transition2}");
                    continue;
                }
                else if (placeableCount != 0)
                {
                    if (tm.ForceTransition() is string transition1)
                    {
                        string transition2 = tm.dt.GetNextTransition(transition1);
                        tm.PlaceTransitionPair(transition1, transition2);
                        //Log($"force place: {transition1}, {transition2}");
                        continue;
                    }
                }
                // Last ditch effort to save the seed. The list is ordered by which items are heuristically likely to unlock transitions at this point.
                if (im.FindNextLocation(tm.pm) is string lastLocation)
                {
                    IEnumerable <string> progressionCandidates = new List <string> {
                        "Mantis_Claw", "Monarch_Wings", "Left_Mantis_Claw", "Right_Mantis_Claw",
                        "Desolate_Dive", "Isma's_Tear", "Crystal_Heart",
                        "Mothwing_Cloak", "Shade_Cloak", "Right_Mothwing_Cloak", "Right_Shade_Cloak", "Left_Mothwing_Cloak", "Left_Shade_Cloak"
                    }
                    .Where(item => im.randomizedItems.Contains(item));

                    foreach (string item in progressionCandidates)
                    {
                        if (!tm.pm.Has(item))
                        {
                            im.PlaceItem(item, lastLocation);
                            tm.UpdateReachableTransitions(item, true);
                            break;
                        }
                    }
                    continue;
                }
            }
            Log("Placing last reserved transitions...");
            tm.UnloadStandby();
            Log("All transitions placed? " + (TransitionManager.transitionPlacements.Count == LogicManager.TransitionNames().Count(t => LogicManager.GetTransitionDef(t).oneWay != 2)));
        }
Пример #11
0
        private static void PlaceIsolatedTransitions()
        {
            if (randomizationError)
            {
                return;
            }

            List <string>       isolatedTransitions    = tm.unplacedTransitions.Where(transition => LogicManager.GetTransitionDef(transition).isolated).ToList();
            List <string>       nonisolatedTransitions = tm.unplacedTransitions.Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList();
            DirectedTransitions directed = new DirectedTransitions(rand);

            isolatedTransitions.Remove(startTransition);
            nonisolatedTransitions.Remove(startTransition);
            directed.Add(nonisolatedTransitions);

            bool connectAreas = RandomizerMod.Instance.Settings.ConnectAreas;

            while (isolatedTransitions.Any())
            {
                string transition1 = isolatedTransitions[rand.Next(isolatedTransitions.Count)];
                string transition2 = directed.GetNextTransition(transition1, favorSameArea: connectAreas);
                if (transition2 is null)
                {
                    Log("Ran out of nonisolated transitions during preplacement!");
                    randomizationError = true;
                    return;
                }
                tm.PlaceStandbyPair(transition1, transition2);
                isolatedTransitions.Remove(transition1);
                directed.Remove(transition2);
            }
        }
        public static void BuildSpanningTree(Dictionary <string, List <string> > sortedTransitions, string first = null)
        {
            List <string> remaining = sortedTransitions.Keys.ToList();

            while (first == null)
            {
                first = remaining[rand.Next(remaining.Count)];
                if (!sortedTransitions[first].Any(t => !LogicManager.GetTransitionDef(t).isolated))
                {
                    first = null;
                }
            }
            remaining.Remove(first);
            List <DirectedTransitions> directed = new List <DirectedTransitions>();

            directed.Add(new DirectedTransitions(rand));
            directed[0].Add(sortedTransitions[first].Where(t => !LogicManager.GetTransitionDef(t).isolated).ToList());
            int failsafe = 0;

            while (remaining.Any())
            {
                bool placed = false;
                failsafe++;
                if (failsafe > 500 || !directed[0].AnyCompatible())
                {
                    Log("Triggered failsafe on round " + failsafe + " in BuildSpanningTree, where first transition set was: " + first + " with count: " + sortedTransitions[first].Count);
                    randomizationError = true;
                    return;
                }

                string nextRoom = remaining[rand.Next(remaining.Count)];

                foreach (DirectedTransitions dt in directed)
                {
                    List <string> nextAreaTransitions = sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).deadEnd&& dt.Test(transition)).ToList();
                    List <string> newTransitions      = sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList();

                    if (!nextAreaTransitions.Any())
                    {
                        continue;
                    }

                    string transitionTarget = nextAreaTransitions[rand.Next(nextAreaTransitions.Count)];
                    string transitionSource = dt.GetNextTransition(transitionTarget);

                    tm.PlaceTransitionPair(transitionSource, transitionTarget);
                    remaining.Remove(nextRoom);

                    dt.Add(newTransitions);
                    dt.Remove(transitionTarget, transitionSource);
                    placed = true;
                    break;
                }
                if (placed)
                {
                    continue;
                }
                else
                {
                    DirectedTransitions dt = new DirectedTransitions(rand);
                    dt.Add(sortedTransitions[nextRoom].Where(transition => !LogicManager.GetTransitionDef(transition).isolated).ToList());
                    directed.Add(dt);
                    remaining.Remove(nextRoom);
                }
            }
            //Log("Completed first pass of BuildSpanningTree with " + directed.Count + " connected component(s).");
            for (int i = 0; i < directed.Count; i++)
            {
                DirectedTransitions dt  = directed[i];
                DirectedTransitions dt1 = null;
                string transition1      = null;
                string transition2      = null;

                foreach (var dt2 in directed)
                {
                    if (dt == dt2)
                    {
                        continue;
                    }

                    if (dt.left && dt2.right)
                    {
                        transition1 = dt.leftTransitions[rand.Next(dt.leftTransitions.Count)];
                        transition2 = dt2.rightTransitions[rand.Next(dt2.rightTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.right && dt2.left)
                    {
                        transition1 = dt.rightTransitions[rand.Next(dt.rightTransitions.Count)];
                        transition2 = dt2.leftTransitions[rand.Next(dt2.leftTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.top && dt2.bot)
                    {
                        transition1 = dt.topTransitions[rand.Next(dt.topTransitions.Count)];
                        transition2 = dt2.botTransitions[rand.Next(dt2.botTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                    else if (dt.bot && dt2.top)
                    {
                        transition1 = dt.botTransitions[rand.Next(dt.botTransitions.Count)];
                        transition2 = dt2.topTransitions[rand.Next(dt2.topTransitions.Count)];
                        dt1         = dt2;
                        break;
                    }
                }
                if (!string.IsNullOrEmpty(transition1))
                {
                    tm.PlaceTransitionPair(transition1, transition2);
                    dt1.Add(dt.AllTransitions);
                    dt1.Remove(transition1, transition2);
                    directed.Remove(dt);
                    i = -1;
                }
            }
            //Log("Exited BuildSpanningTree with " + directed.Count + " connected component(s).");
        }
        public static void BuildCARSpanningTree()
        {
            List <string> areas = new List <string>();
            Dictionary <string, List <string> > rooms = new Dictionary <string, List <string> >();

            foreach (string t in tm.unplacedTransitions)
            {
                if (t == startTransition)
                {
                    continue;
                }
                if (!LogicManager.GetTransitionDef(t).isolated || !LogicManager.GetTransitionDef(t).deadEnd)
                {
                    if (!areas.Contains(LogicManager.GetTransitionDef(t).areaName))
                    {
                        areas.Add(LogicManager.GetTransitionDef(t).areaName);
                        rooms.Add(LogicManager.GetTransitionDef(t).areaName, new List <string>());
                    }


                    if (!rooms[LogicManager.GetTransitionDef(t).areaName].Contains(LogicManager.GetTransitionDef(t).sceneName))
                    {
                        rooms[LogicManager.GetTransitionDef(t).areaName].Add(LogicManager.GetTransitionDef(t).sceneName);
                    }
                }
            }

            var areaTransitions = new Dictionary <string, Dictionary <string, List <string> > >(); // [area][scene][transition]

            foreach (string area in areas)
            {
                areaTransitions.Add(area, new Dictionary <string, List <string> >());
            }
            foreach (var kvp in rooms)
            {
                foreach (string room in kvp.Value)
                {
                    areaTransitions[kvp.Key].Add(room, new List <string>());
                }
            }
            foreach (string t in tm.unplacedTransitions)
            {
                if (t == startTransition)
                {
                    continue;
                }
                TransitionDef def = LogicManager.GetTransitionDef(t);
                if (!areas.Contains(def.areaName) || !areaTransitions[def.areaName].ContainsKey(def.sceneName))
                {
                    continue;
                }
                areaTransitions[def.areaName][def.sceneName].Add(t);
            }
            foreach (string area in areas)
            {
                BuildSpanningTree(areaTransitions[area]);
            }
            var worldTransitions = new Dictionary <string, List <string> >();

            foreach (string area in areas)
            {
                worldTransitions.Add(area, new List <string>());
            }
            foreach (string t in tm.unplacedTransitions)
            {
                if (t == startTransition)
                {
                    continue;
                }
                if (areas.Contains(LogicManager.GetTransitionDef(t).areaName) && rooms[LogicManager.GetTransitionDef(t).areaName].Contains(LogicManager.GetTransitionDef(t).sceneName))
                {
                    worldTransitions[LogicManager.GetTransitionDef(t).areaName].Add(t);
                }
            }
            BuildSpanningTree(worldTransitions);
        }
        public string GetNextTransition(string input, bool favorSameArea = false)
        {
            string doorName = LogicManager.GetTransitionDef(input).doorName;
            string output   = null;

            if (favorSameArea)
            {
                string        area = LogicManager.GetTransitionDef(input).areaName;
                List <string> compatibleTransitions = new List <string>();
                switch (doorName.Substring(0, 3))
                {
                case "doo":
                case "rig":
                    compatibleTransitions = leftTransitions.Where(t => LogicManager.GetTransitionDef(t).areaName == area).ToList();
                    break;

                case "lef":
                    compatibleTransitions = rightTransitions.Where(t => LogicManager.GetTransitionDef(t).areaName == area).ToList();
                    break;

                case "top":
                    compatibleTransitions = botTransitions.Where(t => LogicManager.GetTransitionDef(t).areaName == area).ToList();
                    break;

                case "bot":
                    compatibleTransitions = topTransitions.Where(t => LogicManager.GetTransitionDef(t).areaName == area).ToList();
                    break;
                }
                if (compatibleTransitions.Any())
                {
                    output = compatibleTransitions[rand.Next(compatibleTransitions.Count)];
                }
            }

            if (string.IsNullOrEmpty(output))
            {
                switch (doorName.Substring(0, 3))
                {
                case "doo":
                case "rig":
                    if (leftTransitions.Any())
                    {
                        output = leftTransitions[rand.Next(leftTransitions.Count)];
                    }
                    break;

                case "lef":
                    if (rightTransitions.Any())
                    {
                        output = rightTransitions[rand.Next(rightTransitions.Count)];
                    }
                    break;

                case "top":
                    if (botTransitions.Any())
                    {
                        output = botTransitions[rand.Next(botTransitions.Count)];
                    }
                    break;

                case "bot":
                    if (topTransitions.Any())
                    {
                        output = topTransitions[rand.Next(topTransitions.Count)];
                    }
                    break;
                }
            }

            return(output);
        }