public void PlaceTransitionPair(string transition1, string transition2)
 {
     transitionPlacements.Add(transition1, transition2);
     transitionPlacements.Add(transition2, transition1);
     unplacedTransitions.Remove(transition1);
     unplacedTransitions.Remove(transition2);
     dt.Remove(transition1, transition2);
     pm.Add(transition1);
     pm.Add(transition2);
     UpdateReachableTransitions(transition1);
     UpdateReachableTransitions(transition2);
     UpdateTransitionStandby(transition1, transition2);
 }
Example #2
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);
            }
        }
Example #3
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);
            }
        }
Example #4
0
        public void UpdateTransitionStandby(string transition1, string transition2)
        {
            bool ableToRelink1;
            bool ableToRelink2;

            bool T1InStandby = standbyTransitions.TryGetValue(transition1, out string oldTransition2);
            bool T2InStandby = standbyTransitions.TryGetValue(transition2, out string oldTransition1);

            standbyTransitions.Remove(transition1);
            standbyTransitions.Remove(transition2);

            if (T1InStandby && oldTransition1 == transition1)
            {
                return;                                               // this means t1 and t2 were already linked in standby
            }
            if (T1InStandby || T2InStandby)
            {
                DirectedTransitions dt = new DirectedTransitions(rand);
                dt.Add(unplacedTransitions);
                if (T1InStandby && dt.GetNextTransition(oldTransition2) is string newTransition1)
                {
                    standbyTransitions[oldTransition2] = newTransition1;
                    standbyTransitions[newTransition1] = oldTransition2;
                    unplacedTransitions.Remove(newTransition1);
                    dt.Remove(newTransition1);
                    ableToRelink1 = true;
                }
                else
                {
                    ableToRelink1 = !T1InStandby;
                }

                if (T2InStandby && dt.GetNextTransition(oldTransition1) is string newTransition2)
                {
                    standbyTransitions[oldTransition1] = newTransition2;
                    standbyTransitions[newTransition2] = oldTransition1;
                    unplacedTransitions.Remove(newTransition2);
                    ableToRelink2 = true;
                }
                else
                {
                    ableToRelink2 = !T2InStandby;
                }

                if (T1InStandby && T2InStandby && !ableToRelink1 && !ableToRelink2)
                {
                    standbyTransitions[oldTransition1] = oldTransition2;
                    standbyTransitions[oldTransition2] = oldTransition1;
                    return;
                }

                if (!ableToRelink1 || !ableToRelink2)
                {
                    LogError("Error encountered in updating standby transitions. Unable to relink after removing standby transition.");
                    Randomizer.randomizationError = true;
                }
            }
        }
        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).");
        }