private MapArea GenerateArea(MapInfo mapInfo, RoomConnection connectAt, IGenerator rng) { MapArea area = new MapArea(); int numRects = rng.Next(MinRects, MaxRects + 1); List <Rectangle> rects = new List <Rectangle>(); Rectangle firstRect = new Rectangle(0, 0, rng.Next(MinBounds.Width, MaxBounds.Width), rng.Next(MinBounds.Height, MaxBounds.Height)); Coord offset = connectAt.Direction.Type switch { Direction.Types.LEFT => new Coord(-firstRect.Width + 1, -firstRect.Height / 2), Direction.Types.RIGHT => new Coord(0, -firstRect.Height / 2), Direction.Types.UP => new Coord(-firstRect.Width / 2, -firstRect.Height + 1), Direction.Types.DOWN => new Coord(-firstRect.Width / 2, 0), Direction.Types.NONE => new Coord(-firstRect.Height / 2, -firstRect.Width / 2), _ => throw new ArgumentOutOfRangeException() }; firstRect = firstRect.WithPosition(offset + connectAt.Position); rects.Add(firstRect); area.Add(firstRect); int fails = 0; while (rects.Count < numRects && fails < 200) { Rectangle previousRectangle = rects[^ 1];
public IRoom Generate(Floor floor, Coord connectFrom, Coord connectTo, IGenerator rng) { _floor.Place(floor, connectFrom, rng); _floor.Place(floor, connectTo, rng); List <Coord> path = HorizontalVerticalPath(connectFrom, connectTo).ToList(); MapArea area = new MapArea(); for (int i = 1; i < path.Count - 1; i++) { Coord current = path[i]; Coord next = path[i + 1]; Coord prev = path[i - 1]; area.Add(current); if (floor.MapInfo.Map.Terrain[current] != null && floor.MapInfo.Map.Terrain[current].IsWalkable) { continue; } _floor.Place(floor, current, rng); HashSet <Coord> wallOptions = new HashSet <Coord> { current + Direction.UP, current + Direction.RIGHT, current + Direction.DOWN, current + Direction.LEFT }; wallOptions.Remove(prev); wallOptions.Remove(next); foreach (Coord pos in wallOptions) { if (floor.MapInfo.Map.Terrain[pos] == null) { _wall.Place(floor, pos, rng); } } } Direction finalDirection = Direction.GetCardinalDirection(path[path.Count - 2], path[path.Count - 1]); RoomConnection finalConnection = new RoomConnection(connectTo, finalDirection, _endPossibilities, false); return(new BasicRoom(area, new List <RoomConnection> { finalConnection }, null)); }
public bool CanGenerate(Floor floor, RoomConnection connectAt, IGenerator rng) { Rectangle roomBounds = new Rectangle(0, 0, rng.Next(_minBounds.Width, _maxBounds.Width), rng.Next(_minBounds.Height, _maxBounds.Height)); Coord offset = connectAt.Direction.Type switch { Direction.Types.LEFT => new Coord(-roomBounds.Width + 1, -roomBounds.Height / 2), Direction.Types.RIGHT => new Coord(0, -roomBounds.Height / 2), Direction.Types.UP => new Coord(-roomBounds.Width / 2, -roomBounds.Height + 1), Direction.Types.DOWN => new Coord(-roomBounds.Width / 2, 0), _ => throw new ArgumentOutOfRangeException() }; roomBounds = roomBounds.WithPosition(offset + connectAt.Position); return(floor.MapInfo.Map.Terrain.AllEmpty(roomBounds.Positions())); }
public IRoom Generate(Floor floor, RoomConnection connectAt, IGenerator rng) { MapArea area = GenerateArea(floor.MapInfo, connectAt, rng); HashSet <Coord> perimeter = new HashSet <Coord>(area.Perimeter()); foreach (Coord pos in area.Positions) { if (perimeter.Contains(pos)) { _wall.Place(floor, pos, rng); } else { _floor.Place(floor, pos, rng); } } List <Coord> perimeterList = new List <Coord>(perimeter); List <RoomConnection> connections = new List <RoomConnection>(); HashSet <Direction> usedDirections = new HashSet <Direction>(); for (int n = 0; n < 20 && connections.Count < 4; n++) { Coord connectionPos = perimeterList[rng.Next(perimeterList.Count)]; if (IsCorner(connectionPos, area)) { continue; } Direction dir = GetDirection(connectionPos, area); if (usedDirections.Contains(dir)) { continue; } connections.Add(new RoomConnection(connectionPos, dir, NeighborPossibilities, true)); usedDirections.Add(dir); } return(new BasicRoom(area, connections, this)); }
public IRoom Generate(Floor floor, RoomConnection connectAt, IGenerator rng) { Rectangle roomBounds = new Rectangle(0, 0, rng.Next(_minBounds.Width, _maxBounds.Width), rng.Next(_minBounds.Height, _maxBounds.Height)); Coord offset = connectAt.Direction.Type switch { Direction.Types.LEFT => new Coord(-roomBounds.Width + 1, -roomBounds.Height / 2), Direction.Types.RIGHT => new Coord(0, -roomBounds.Height / 2), Direction.Types.UP => new Coord(-roomBounds.Width / 2, -roomBounds.Height + 1), Direction.Types.DOWN => new Coord(-roomBounds.Width / 2, 0), Direction.Types.NONE => new Coord(-roomBounds.Height / 2, -roomBounds.Width / 2), _ => throw new ArgumentOutOfRangeException() }; roomBounds = roomBounds.WithPosition(offset + connectAt.Position); foreach (Coord pos in roomBounds.PerimeterPositions()) { _wall.Place(floor, pos, rng); } foreach (Coord pos in roomBounds.ChangeSize(-2, -2).WithCenter(roomBounds.Center).Positions()) { _floor.Place(floor, pos, rng); } MapArea area = new MapArea(); area.Add(roomBounds); List <RoomConnection> connections = new List <RoomConnection>(); foreach (Direction dir in AdjacencyRule.CARDINALS.DirectionsOfNeighbors()) { if (dir.DeltaX == -connectAt.Direction.DeltaX && dir.DeltaY == -connectAt.Direction.DeltaY) { continue; } int xOffset = dir.DeltaX * (roomBounds.Width - 1) / 2; int yOffset = dir.DeltaY * (roomBounds.Height - 1) / 2; if (dir.DeltaX == 0) { xOffset += rng.Next(-roomBounds.Width / 2 + 1, roomBounds.Width / 2 - 1); } if (dir.DeltaY == 0) { yOffset += rng.Next(-roomBounds.Height / 2 + 1, roomBounds.Height / 2 - 1); } Coord door = roomBounds.Center + new Coord(xOffset, yOffset); connections.Add(new RoomConnection(door, dir, NeighborPossibilities, true)); //_floor.Place(mapInfo, door, rng); } if (connectAt.Position != Coord.NONE) { _floor.Place(floor, connectAt.Position, rng); } return(new BasicRoom(area, connections, this)); }
public bool UseConnection(RoomConnection connection) { return(_potentialConnections.Remove(connection)); }
public bool CanGenerate(Floor floor, RoomConnection connectAt, IGenerator rng) { MapArea mapArea = GenerateArea(floor.MapInfo, connectAt, rng); return(floor.MapInfo.Map.Terrain.AllEmpty(mapArea.Positions)); }