summaryrefslogtreecommitdiff
path: root/scripts/map
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/map')
-rw-r--r--scripts/map/DungeonGenerator.cs118
-rw-r--r--scripts/map/DungeonGenerator.cs.uid1
-rw-r--r--scripts/map/Map.cs28
-rw-r--r--scripts/map/Map.cs.uid1
-rw-r--r--scripts/map/MapData.cs16
-rw-r--r--scripts/map/Tile.cs4
6 files changed, 154 insertions, 14 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);
+ }
+}
diff --git a/scripts/map/DungeonGenerator.cs.uid b/scripts/map/DungeonGenerator.cs.uid
new file mode 100644
index 0000000..15aeef6
--- /dev/null
+++ b/scripts/map/DungeonGenerator.cs.uid
@@ -0,0 +1 @@
+uid://dwyr067lwqcsj
diff --git a/scripts/map/Map.cs b/scripts/map/Map.cs
new file mode 100644
index 0000000..683ae45
--- /dev/null
+++ b/scripts/map/Map.cs
@@ -0,0 +1,28 @@
+using Godot;
+using System;
+
+public partial class Map : Node2D
+{
+ public MapData Map_Data { get; private set; }
+
+ DungeonGenerator generator;
+
+ private void PlaceTiles() {
+ foreach (Tile tile in Map_Data.Tiles) {
+ AddChild(tile);
+ }
+ }
+
+ public void Generate(Player player)
+ {
+ generator = GetNode<DungeonGenerator>("Generator");
+
+ Map_Data = generator.GenerateDungeon(player);
+
+ Map_Data.InsertActor(player);
+
+ player.Map_Data = Map_Data;
+
+ PlaceTiles();
+ }
+}
diff --git a/scripts/map/Map.cs.uid b/scripts/map/Map.cs.uid
new file mode 100644
index 0000000..7306888
--- /dev/null
+++ b/scripts/map/Map.cs.uid
@@ -0,0 +1 @@
+uid://fe2h4is11tnw
diff --git a/scripts/map/MapData.cs b/scripts/map/MapData.cs
index 25d6e09..c580aa8 100644
--- a/scripts/map/MapData.cs
+++ b/scripts/map/MapData.cs
@@ -22,24 +22,16 @@ public partial class MapData : RefCounted
}
private void SetupTiles() {
- for (int i = 0; i < Width; i++)
+ for (int i = 0; i < Height; i++)
{
- for (int j = 0; j < Height; j++)
+ for (int j = 0; j < Width; j++)
{
- Tile tile;
- if (i == 0 || j == 0 || i == (Width - 1) || j == (Height - 1)) {
- tile = new Tile(new Vector2I(i, j), wallDefinition);
- } else {
- tile = new Tile(new Vector2I(i, j), floorDefinition);
- }
-
- Tiles.Add(tile);
+ Tiles.Add(new Tile(new Vector2I(j, i), wallDefinition));
}
}
}
- public void InsertActor(Vector2I pos, Actor actor) {
- actor.GridPosition = pos;
+ public void InsertActor(Actor actor) {
Actors.Add(actor);
}
diff --git a/scripts/map/Tile.cs b/scripts/map/Tile.cs
index c910b01..865cbbd 100644
--- a/scripts/map/Tile.cs
+++ b/scripts/map/Tile.cs
@@ -5,7 +5,7 @@ public partial class Tile : Sprite2D
{
private TileDefinition definition;
- public bool IsWalkable { get; set; }
+ public bool IsWalkable { get; private set; }
public Tile(Vector2I pos, TileDefinition definition)
{
@@ -17,6 +17,6 @@ public partial class Tile : Sprite2D
public void SetDefinition(TileDefinition definition) {
this.definition = definition;
Texture = definition.Texture;
- this.IsWalkable = definition.IsWalkable;
+ IsWalkable = definition.IsWalkable;
}
}