summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorMatheus <matheus.guedes.mg.m@gmail.com>2025-08-25 13:42:29 -0300
committerMatheus <matheus.guedes.mg.m@gmail.com>2025-08-25 13:42:29 -0300
commit832fe5e98842123bcc9d0c3245babf172bb10578 (patch)
tree4a787f44d5e960748e95a0f2f6b3177158e8d886 /scripts
parentefb712cb70ca1d0913bb69456ac2344fbaacad0e (diff)
Gerador melhorado.
Diffstat (limited to 'scripts')
-rw-r--r--scripts/map/DungeonGenerator.cs72
-rw-r--r--scripts/map/MapDivision.cs71
-rw-r--r--scripts/map/MapDivision.cs.uid1
3 files changed, 107 insertions, 37 deletions
diff --git a/scripts/map/DungeonGenerator.cs b/scripts/map/DungeonGenerator.cs
index 75b375d..0d94724 100644
--- a/scripts/map/DungeonGenerator.cs
+++ b/scripts/map/DungeonGenerator.cs
@@ -1,5 +1,6 @@
using Godot;
using System;
+using System.Drawing;
using System.Linq;
using System.Net.NetworkInformation;
@@ -18,15 +19,7 @@ public partial class DungeonGenerator : Node
[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;
+ private int iterations = 3;
public override void _Ready()
{
@@ -46,11 +39,9 @@ public partial class DungeonGenerator : Node
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 y = room.Position.Y; y < room.End.Y; y++)
{
- for (int x = inner.Position.X; x <= inner.End.X; x++)
+ for (int x = room.Position.X; x < room.End.X; x++)
{
CarveTile(data, new Vector2I(x, y));
}
@@ -61,35 +52,32 @@ public partial class DungeonGenerator : Node
{
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);
+ MapDivision root = new MapDivision(0, 0, width, height);
- int x = rng.RandiRange(0, data.Width - 1 - roomWidth);
- int y = rng.RandiRange(0, data.Height - 1 - roomHeight);
+ root.Split(iterations, rng);
- Rect2I newRoom = new(x, y, roomWidth, roomHeight);
+ bool first = true;
- bool intersects = false;
- foreach (Rect2I room in rooms) {
- if (newRoom.Intersects(room)) {
- intersects = true;
- break;
- }
- }
- if (intersects) {
- continue;
- }
+ TunnelDivisions(data, root);
- CarveRoom(data, newRoom);
- if (rooms.Count <= 0) {
- player.GridPosition = newRoom.GetCenter();
- } else {
- TunnelBetween(data, rooms.Last().GetCenter(), newRoom.GetCenter());
+ foreach(MapDivision division in root.GetLeaves())
+ {
+ Rect2I room = new(division.Position, division.Size);
+
+ room = room.GrowIndividual(
+ -rng.RandiRange(1, 2),
+ -rng.RandiRange(1, 2),
+ -rng.RandiRange(1, 2),
+ -rng.RandiRange(1, 2)
+ );
+
+ GD.Print($"Division {room}");
+ CarveRoom(data, room);
+ if (first)
+ {
+ first = false;
+ player.GridPosition = room.GetCenter();
}
- rooms.Add(newRoom);
}
return data;
@@ -115,4 +103,14 @@ public partial class DungeonGenerator : Node
HorizontalCorridor(data, start.Y, start.X, end.X);
VerticalCorridor(data, end.X, start.Y, end.Y);
}
+
+ private void TunnelDivisions(MapData data, MapDivision root) {
+ if (root.IsLeaf) {
+ return;
+ }
+
+ TunnelBetween(data, root.Right.Center, root.Left.Center);
+ TunnelDivisions(data, root.Left);
+ TunnelDivisions(data, root.Right);
+ }
}
diff --git a/scripts/map/MapDivision.cs b/scripts/map/MapDivision.cs
new file mode 100644
index 0000000..15a6be8
--- /dev/null
+++ b/scripts/map/MapDivision.cs
@@ -0,0 +1,71 @@
+using System.Linq;
+using System.Numerics;
+using System.Xml.Schema;
+using Godot;
+
+public partial class MapDivision : RefCounted {
+ public Vector2I Position { get; set; }
+ public Vector2I Size { get; set; }
+
+ public Vector2I Center {
+ get => new(Position.X + Size.X/2, Position.Y + Size.Y/2);
+ }
+
+ private MapDivision left;
+ public MapDivision Left { get => this.left; }
+ private MapDivision right;
+ public MapDivision Right { get => this.right; }
+
+ public bool IsLeaf {
+ get => left == null && right == null;
+ }
+
+ public MapDivision(Vector2I position, Vector2I size) {
+ Position = position;
+ Size = size;
+ }
+
+ public MapDivision(Vector2I position, int width, int height) {
+ Position = position;
+ Size = new(width, height);
+ }
+
+ public MapDivision(int x, int y, int width, int height) {
+ Position = new(x, y);
+ Size = new(width, height);
+ }
+
+ public Godot.Collections.Array<MapDivision> GetLeaves() {
+ if (IsLeaf) {
+ Godot.Collections.Array<MapDivision> list = [];
+ list.Add(this);
+ return list;
+ }
+ return left.GetLeaves() + right.GetLeaves();
+ }
+
+ public void Split(int iterations, RandomNumberGenerator rng) {
+ float SplitRatio = rng.RandfRange(0.35f, 0.65f);
+ bool horizontalSplit = Size.X <= Size.Y;
+
+ if (horizontalSplit) {
+ int leftHeight = (int) (Size.Y * SplitRatio);
+ if (leftHeight > 4 && Size.Y - leftHeight > 4) {
+ left = new MapDivision(Position, Size.X, leftHeight);
+ right = new MapDivision(Position.X, Position.Y + leftHeight, Size.X, Size.Y - leftHeight);
+ }
+ } else {
+ int leftWidth = (int) (Size.Y * SplitRatio);
+
+ if (leftWidth > 4 && Size.Y - leftWidth > 4) {
+ left = new MapDivision(Position, leftWidth, Size.Y);
+ right = new MapDivision(Position.X + leftWidth, Position.Y, Size.X - leftWidth, Size.Y);
+ }
+ }
+
+ if (iterations > 1) {
+ left?.Split(iterations - 1, rng);
+ right?.Split(iterations - 1, rng);
+ }
+ }
+} \ No newline at end of file
diff --git a/scripts/map/MapDivision.cs.uid b/scripts/map/MapDivision.cs.uid
new file mode 100644
index 0000000..fdd53a4
--- /dev/null
+++ b/scripts/map/MapDivision.cs.uid
@@ -0,0 +1 @@
+uid://c3niegr686acj