public static void Enclose(Level level, LevelRect rect, TerrainDefinition terrain) { for (int x = rect.x1; x <= rect.x2; x++) { for (int y = rect.y1; y <= rect.y2; y++) { if (x == rect.x1) { level.Map[x, y].Terrain = terrain; continue; } else if (x == rect.x2) { level.Map[x, y].Terrain = terrain; continue; } else { if (y == rect.y1) { level.Map[x, y].Terrain = terrain; continue; } else if (y == rect.y2) { level.Map[x, y].Terrain = terrain; continue; } } } } }
public static HashSet <Cell> FillRect(Level level, LevelRect rect, Cell start) { HashSet <Cell> filled = new HashSet <Cell>(); List <Cell> open = new List <Cell>(); HashSet <Cell> closed = new HashSet <Cell>(); filled.Add(start); open.Add(start); while (open.Count > 0) { for (int i = 0; i < open.Count; i++) { closed.Add(open[i]); for (int x = -1; x <= 1; x++) { for (int y = -1; y <= 1; y++) { Vector2Int frontier = open[i].Position; frontier += new Vector2Int(x, y); Cell frontierCell; if (level.Contains(frontier) && rect.Contains(frontier)) { frontierCell = level.GetCell(frontier); } else { continue; } if (closed.Contains(frontierCell)) { continue; } if (frontierCell.Walled) { closed.Add(frontierCell); continue; } if (filled.Contains(frontierCell)) { closed.Add(frontierCell); continue; } filled.Add(frontierCell); open.Add(frontierCell); } } open.RemoveAt(i); } } return(filled); }
public override void Run(Level level) { List <Leaf> leaves = new List <Leaf>(); Leaf root = new Leaf(0, 0, level.Size.x, level.Size.y); leaves.Add(root); bool didSplit = true; while (didSplit) { didSplit = false; for (int i = leaves.Count - 1; i >= 0; i--) { if (leaves[i].LeftChild == null && leaves[i].RightChild == null) { if (leaves[i].Width > Leaf.MaxLeafSize || leaves[i].Height > Leaf.MaxLeafSize || OneChanceIn(4)) { if (leaves[i].Split()) { leaves.Add(leaves[i].LeftChild); leaves.Add(leaves[i].RightChild); didSplit = true; } } } } } root.CreateRooms(minRoomSize, tightFill); for (int i = 0; i < leaves.Count; i++) { if (leaves[i].Room != null) { Utils.FillRectTerrain(level, leaves[i].Room, terrain); } if (leaves[i].Halls != null) { foreach (LevelRect hall in leaves[i].Halls) { LevelRect rect = new LevelRect( new Vector2Int(hall.x1, hall.y1), new Vector2Int( hall.x2 - hall.x1 + 2, hall.y2 - hall.y1 + 2)); Utils.FillRectTerrain(level, hall, terrain); } } } }
public static void FillRectTerrain(Level level, LevelRect rect, TerrainDefinition terrain) { for (int x = rect.x1; x < rect.x2; x++) { for (int y = rect.y1; y < rect.y2; y++) { if (level.TryGetCell(x, y, out Cell c)) { level.Map[x, y].Terrain = terrain; } } } }
public override void Run(Level level) { rect = new LevelRect(new Vector2Int(), new Vector2Int( level.Size.x - 1, level.Size.y - 1)); for (int iterations = 0; iterations < 10; iterations++) { RandomFillMap(level); Utils.Enclose(level, wall); MakeCaverns(level); if (FillDisconnected(level)) { return; } } throw new System.Exception("Cellular automata failed after 10 tries."); }
public LevelRect GetRoom() { if (Room != null) { return(Room); } else { LevelRect lRoom = null; LevelRect rRoom = null; if (LeftChild != null) { lRoom = LeftChild.GetRoom(); } if (RightChild != null) { rRoom = RightChild.GetRoom(); } if (lRoom == null && rRoom == null) { return(null); } else if (rRoom == null) { return(lRoom); } else if (lRoom == null) { return(rRoom); } else if (OneChanceIn(2)) { return(lRoom); } else { return(rRoom); } } }
/// <summary> /// Generates all rooms and hallways for this Leaf and all its children. /// </summary> public void CreateRooms(int minRoomSize, bool tightFill) { if (LeftChild != null || RightChild != null) { if (LeftChild != null) { LeftChild.CreateRooms(minRoomSize, tightFill); } if (RightChild != null) { RightChild.CreateRooms(minRoomSize, tightFill); } if (LeftChild != null && RightChild != null) { CreateHall(LeftChild.GetRoom(), RightChild.GetRoom()); } } else { Vector2Int roomSize; Vector2Int roomPos; if (tightFill) { roomSize = new Vector2Int(Width - 1, Height - 1); } else { roomSize = new Vector2Int( RangeInclusive(minRoomSize, Width - 2), RangeInclusive(minRoomSize, Height - 2)); } roomPos = new Vector2Int( RangeInclusive(1, Width - roomSize.x - 1), RangeInclusive(1, Height - roomSize.y - 1)); Room = new LevelRect( new Vector2Int(X + roomPos.x, Y + roomPos.y), new Vector2Int(roomSize.x, roomSize.y)); } }
public void CreateHall(LevelRect l, LevelRect r) { Halls = new Stack <LevelRect>(); Vector2Int p1 = new Vector2Int( RangeInclusive(l.x1 + 1, l.x2 - 2), RangeInclusive(l.y1 + 1, l.y2 - 2)); Vector2Int p2 = new Vector2Int( RangeInclusive(r.x1 + 1, r.x2 - 2), RangeInclusive(r.y1 + 1, r.y2 - 2)); int w = p2.x - p1.x; int h = p2.y - p1.y; if (w < 0) { if (h < 0) { if (CoinFlip()) { Halls.Push(new LevelRect( new Vector2Int(p2.x, p1.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(1, Mathf.Abs(h)))); } else { Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p1.x, p2.y), new Vector2Int(1, Mathf.Abs(h)))); } } else if (h > 0) { if (CoinFlip()) { Halls.Push(new LevelRect( new Vector2Int(p2.x, p1.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p2.x, p1.y), new Vector2Int(1, Mathf.Abs(h)))); } else { Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(1, Mathf.Abs(h)))); } } else // if (h == 0) { Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(Mathf.Abs(w), 1))); } } else if (w > 0) { if (h < 0) { if (CoinFlip()) { Halls.Push(new LevelRect( new Vector2Int(p1.x, p2.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p1.x, p2.y), new Vector2Int(1, Mathf.Abs(h)))); } else { Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(1, Mathf.Abs(h)))); } } else if (h > 0) { if (CoinFlip()) { Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p2.x, p1.y), new Vector2Int(1, Mathf.Abs(h)))); } else { Halls.Push(new LevelRect( new Vector2Int(p1.x, p2.y), new Vector2Int(Mathf.Abs(w), 1))); Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(1, Mathf.Abs(h)))); } } else // if (h == 0) { Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(Mathf.Abs(w), 1))); } } else // if (w == 0) { if (h < 0) { Halls.Push(new LevelRect( new Vector2Int(p2.x, p2.y), new Vector2Int(1, Mathf.Abs(h)))); } else if (h > 0) { Halls.Push(new LevelRect( new Vector2Int(p1.x, p1.y), new Vector2Int(1, Mathf.Abs(h)))); } } }