diff options
| author | Matheus <matheus.guedes.mg.m@gmail.com> | 2025-08-24 21:46:00 -0300 |
|---|---|---|
| committer | Matheus <matheus.guedes.mg.m@gmail.com> | 2025-08-24 21:46:00 -0300 |
| commit | efb712cb70ca1d0913bb69456ac2344fbaacad0e (patch) | |
| tree | f59a1ce426ed8ee9373b1577126c55c8017dbc4a /scripts/map/DungeonGenerator.cs | |
| parent | 723e66a82606ee78ca4156a0c0a850185b4c0369 (diff) | |
Gerador de masmorras.
Diffstat (limited to 'scripts/map/DungeonGenerator.cs')
| -rw-r--r-- | scripts/map/DungeonGenerator.cs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/scripts/map/DungeonGenerator.cs b/scripts/map/DungeonGenerator.cs new file mode 100644 index 0000000..75b375d --- /dev/null +++ b/scripts/map/DungeonGenerator.cs @@ -0,0 +1,118 @@ +using Godot; +using System; +using System.Linq; +using System.Net.NetworkInformation; + +public partial class DungeonGenerator : Node +{ + [ExportCategory("Dimension")] + [Export] + private int width = 80; + [Export] + private int height = 60; + + [ExportCategory("RNG")] + private RandomNumberGenerator rng = new(); + [Export] + private ulong seed; + [Export] + private bool useSeed = true; + [Export] + private int maxRooms = 10; + [Export] + private int roomMaxWidth = 10; + [Export] + private int roomMinWidth = 3; + [Export] + private int roomMaxHeight = 10; + [Export] + private int roomMinHeight = 2; + + public override void _Ready() + { + base._Ready(); + if (useSeed) { + rng.Seed = seed; + } + } + + private static void CarveTile(MapData data, Vector2I pos) + { + Tile tile = data.GetTile(pos); + if (tile == null) return; + + tile.SetDefinition(MapData.floorDefinition); + } + + private static void CarveRoom(MapData data, Rect2I room) + { + Rect2I inner = room.Grow(-1); + + for (int y = inner.Position.Y; y <= inner.End.Y; y++) + { + for (int x = inner.Position.X; x <= inner.End.X; x++) + { + CarveTile(data, new Vector2I(x, y)); + } + } + } + + public MapData GenerateDungeon(Player player) + { + MapData data = new MapData(width, height); + + Godot.Collections.Array<Rect2I> rooms = []; + + for (int tryroom = 0; tryroom < maxRooms; tryroom++) { + int roomWidth = rng.RandiRange(roomMinWidth, roomMaxWidth); + int roomHeight = rng.RandiRange(roomMinHeight, roomMaxHeight); + + int x = rng.RandiRange(0, data.Width - 1 - roomWidth); + int y = rng.RandiRange(0, data.Height - 1 - roomHeight); + + Rect2I newRoom = new(x, y, roomWidth, roomHeight); + + bool intersects = false; + foreach (Rect2I room in rooms) { + if (newRoom.Intersects(room)) { + intersects = true; + break; + } + } + if (intersects) { + continue; + } + + CarveRoom(data, newRoom); + if (rooms.Count <= 0) { + player.GridPosition = newRoom.GetCenter(); + } else { + TunnelBetween(data, rooms.Last().GetCenter(), newRoom.GetCenter()); + } + rooms.Add(newRoom); + } + + return data; + } + + private static void HorizontalCorridor(MapData data, int y, int xBegin, int xEnd) { + int begin = (xBegin < xEnd) ? xBegin : xEnd; + int end = (xEnd > xBegin) ? xEnd : xBegin; + for (int i = begin; i <= end; i++) { + CarveTile(data, new Vector2I(i, y)); + } + } + + private static void VerticalCorridor(MapData data, int x, int yBegin, int yEnd) { + int begin = (yBegin < yEnd) ? yBegin : yEnd; + int end = (yEnd > yBegin) ? yEnd : yBegin; + for (int i = begin; i <= end; i++) { + CarveTile(data, new Vector2I(x, i)); + } + } + + private void TunnelBetween(MapData data, Vector2I start, Vector2I end) { + HorizontalCorridor(data, start.Y, start.X, end.X); + VerticalCorridor(data, end.X, start.Y, end.Y); + } +} |
