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); }
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); } }
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 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)."); }