private void SplitVertical(float minDivRatio) { float div = Rand.Range(minDivRatio, 1.0f - minDivRatio, Rand.RandSync.Server); subRooms[0] = new BTRoom(new Rectangle(rect.X, rect.Y, (int)(rect.Width * div), rect.Height)); subRooms[1] = new BTRoom(new Rectangle(rect.X + subRooms[0].rect.Width, rect.Y, rect.Width - subRooms[0].rect.Width, rect.Height)); }
private void SplitHorizontal(float minDivRatio) { float div = Rand.Range(minDivRatio, 1.0f - minDivRatio, Rand.RandSync.Server); subRooms[0] = new BTRoom(new Rectangle(rect.X, rect.Y, rect.Width, (int)(rect.Height * div))); subRooms[1] = new BTRoom(new Rectangle(rect.X, rect.Y + subRooms[0].rect.Height, rect.Width, rect.Height - subRooms[0].rect.Height)); }
private bool CheckForIntersection(BTRoom potential1, BTRoom potential2, List <BTRoom> leaves1, List <BTRoom> leaves2, int width, bool isHorizontal) { Rectangle potentialCorridorRectangle = CalculateRectangle(potential1.Rect, potential2.Rect, width, isHorizontal); if (potentialCorridorRectangle.Width <= 0 || potentialCorridorRectangle.Height <= 0) { return(true); // Invalid rectangle } for (int i = 0; i < leaves1.Count; i++) { if (leaves1[i] == potential1) { continue; } if (potentialCorridorRectangle.Intersects(leaves1[i].Rect)) { return(true); } } for (int i = 0; i < leaves2.Count; i++) { if (leaves2[i] == potential2) { continue; } if (potentialCorridorRectangle.Intersects(leaves2[i].Rect)) { return(true); } } rect = potentialCorridorRectangle; // Save the rectangle that passes the test return(false); }
public void Generate(VoronoiCell closestPathCell, List <VoronoiCell> caveCells, Rectangle area, bool mirror = false) { corridors.Clear(); rooms.Clear(); //area = new Rectangle(area.X, area.Y - area.Height, area.Width, area.Height); int iterations = Rand.Range(3, 4, Rand.RandSync.Server); float verticalProbability = Rand.Range(0.4f, 0.6f, Rand.RandSync.Server); BTRoom baseRoom = new BTRoom(area); rooms = new List <BTRoom> { baseRoom }; for (int i = 0; i < iterations; i++) { rooms.ForEach(l => l.Split(0.3f, verticalProbability, 300)); rooms = baseRoom.GetLeaves(); } foreach (BTRoom leaf in rooms) { leaf.Scale ( new Vector2(Rand.Range(0.5f, 0.9f, Rand.RandSync.Server), Rand.Range(0.5f, 0.9f, Rand.RandSync.Server)) ); } baseRoom.GenerateCorridors(200, 256, corridors); walls = new List <Line>(); rooms.ForEach(leaf => { leaf.CreateWalls(); //walls.AddRange(leaf.Walls); }); //--------------------------- BTRoom entranceRoom = null; float shortestDistance = 0.0f; foreach (BTRoom leaf in rooms) { Vector2 leafPos = leaf.Rect.Center.ToVector2(); if (mirror) { leafPos.X = area.Center.X + (area.Center.X - leafPos.X); } float distance = Vector2.Distance(leafPos, closestPathCell.Center); if (entranceRoom == null || distance < shortestDistance) { entranceRoom = leaf; shortestDistance = distance; } } rooms.Remove(entranceRoom); //--------------------------- foreach (BTRoom leaf in rooms) { foreach (Corridor corridor in corridors) { leaf.SplitWalls(corridor.Rect); } walls.AddRange(leaf.Walls); } foreach (Corridor corridor in corridors) { corridor.CreateWalls(); foreach (BTRoom leaf in rooms) { corridor.SplitWalls(leaf.Rect); } foreach (Corridor corridor2 in corridors) { if (corridor == corridor2) { continue; } corridor.SplitWalls(corridor2.Rect); } walls.AddRange(corridor.Walls); } //leaves.Remove(entranceRoom); BTRoom.CalculateDistancesFromEntrance(entranceRoom, corridors); allShapes = GenerateStructures(caveCells, area, mirror); }
public static void CalculateDistancesFromEntrance(BTRoom entrance, List <BTRoom> rooms, List <Corridor> corridors) { entrance.CalculateDistanceFromEntrance(0, rooms, new List <Corridor>(corridors)); }
public Corridor(BTRoom room, int width, List <Corridor> corridors) { System.Diagnostics.Debug.Assert(room.Adjacent != null); ConnectedRooms = new BTRoom[2]; ConnectedRooms[0] = room; ConnectedRooms[1] = room.Adjacent; Rectangle room1, room2; room1 = room.Rect; room2 = room.Adjacent.Rect; isHorizontal = (room1.Right <= room2.X || room2.Right <= room1.X); //use the leaves as starting points for the corridor if (room.SubRooms != null) { var leaves1 = room.GetLeaves(); var leaves2 = room.Adjacent.GetLeaves(); var suitableLeaves = GetSuitableLeafRooms(leaves1, leaves2, width, isHorizontal); if (suitableLeaves == null || suitableLeaves.Length < 2) { // No suitable leaves found due to intersections //DebugConsole.ThrowError("Error while generating ruins. Could not find a suitable position for a corridor. The width of the corridors may be too large compared to the sizes of the rooms."); return; } else { room1 = suitableLeaves[0].Rect; room2 = suitableLeaves[1].Rect; ConnectedRooms[0] = suitableLeaves[0]; ConnectedRooms[1] = suitableLeaves[1]; } } else { rect = CalculateRectangle(room1, room2, width, isHorizontal); if (rect.Width <= 0 || rect.Height <= 0) { DebugConsole.ThrowError("Error while generating ruins. Attempted to create a corridor with a width or height of <= 0"); return; } } room.Corridor = this; room.Adjacent.Corridor = this; for (int i = corridors.Count - 1; i >= 0; i--) { var corridor = corridors[i]; if (corridor.rect.Intersects(this.rect)) { if (isHorizontal && corridor.isHorizontal) { if (this.rect.Width < corridor.rect.Width) { return; } else { corridors.RemoveAt(i); } } else if (!isHorizontal && !corridor.isHorizontal) { if (this.rect.Height < corridor.rect.Height) { return; } else { corridors.RemoveAt(i); } } } } corridors.Add(this); }
public Corridor(BTRoom room, int width, List <Corridor> corridors) { System.Diagnostics.Debug.Assert(room.Adjacent != null); ConnectedRooms = new BTRoom[2]; ConnectedRooms[0] = room; ConnectedRooms[1] = room.Adjacent; Rectangle room1, room2; room1 = room.Rect; room2 = room.Adjacent.Rect; isHorizontal = (room1.Right <= room2.X || room2.Right <= room1.X); //use the leaves as starting points for the corridor if (room.SubRooms != null) { var leaves1 = room.GetLeaves(); var leaves2 = room.Adjacent.GetLeaves(); var suitableLeaves = GetSuitableLeafRooms(leaves1, leaves2, width, isHorizontal); room1 = suitableLeaves[0].Rect; room2 = suitableLeaves[1].Rect; ConnectedRooms[0] = suitableLeaves[0]; ConnectedRooms[1] = suitableLeaves[1]; } if (isHorizontal) { int left = Math.Min(room1.Right, room2.Right); int right = Math.Max(room1.X, room2.X); int top = Math.Max(room1.Y, room2.Y); int bottom = Math.Min(room1.Bottom, room2.Bottom); int yPos = Rand.Range(top, bottom - width, Rand.RandSync.Server); rect = new Rectangle(left, yPos, right - left, width); } else if (room1.Y > room2.Bottom || room2.Y > room1.Bottom) { int left = Math.Max(room1.X, room2.X); int right = Math.Min(room1.Right, room2.Right); int top = Math.Min(room1.Bottom, room2.Bottom); int bottom = Math.Max(room1.Y, room2.Y); int xPos = Rand.Range(left, right - width, Rand.RandSync.Server); rect = new Rectangle(xPos, top, width, bottom - top); } else { DebugConsole.ThrowError("wat"); } room.Corridor = this; room.Adjacent.Corridor = this; for (int i = corridors.Count - 1; i >= 0; i--) { var corridor = corridors[i]; if (corridor.rect.Intersects(this.rect)) { if (isHorizontal && corridor.isHorizontal) { if (this.rect.Width < corridor.rect.Width) { return; } else { corridors.RemoveAt(i); } } else if (!isHorizontal && !corridor.isHorizontal) { if (this.rect.Height < corridor.rect.Height) { return; } else { corridors.RemoveAt(i); } } } } corridors.Add(this); }