Now About Social Code
summaryrefslogtreecommitdiff
path: root/scripts/level_generator.gd
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/level_generator.gd')
-rw-r--r--scripts/level_generator.gd118
1 files changed, 118 insertions, 0 deletions
diff --git a/scripts/level_generator.gd b/scripts/level_generator.gd
new file mode 100644
index 0000000..94a87dd
--- /dev/null
+++ b/scripts/level_generator.gd
@@ -0,0 +1,118 @@
+extends Node3D
+
+@export var width: int = 10
+@export var height: int = 10
+
+var room = preload("res://prefabs/round_room.tscn")
+var door = preload("res://prefabs/door.tscn")
+
+var bounds: Vector3 = Vector3.ZERO
+var astar: AStar3D
+
+signal astar_created
+
+func get_grid_index(pos: Vector2i) -> int:
+ return pos.y*height + pos.x
+
+func set_grid_index(grid: Array[int], pos: Vector2i):
+ # If the point lies outside the grid we return
+ if pos.x < 0 or pos.x >= width or pos.y < 0 or pos.y >= height:
+ return
+
+ var index = get_grid_index(pos)
+
+ # If we already set this point we exit
+ if grid[index] != 0:
+ return
+
+ grid[index] = 1
+ var new_room: Node3D = room.instantiate()
+ var mesh = new_room.find_child("MeshInstance3D")
+ # TODO can we just load and cache the bounds?
+ bounds = mesh.get_aabb().size
+ var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2)
+ new_room.position = (offset_pos * bounds)
+ #print("Placing at ", pos)
+ add_child(new_room)
+
+ var next = [pos + Vector2i.UP,
+ pos + Vector2i.LEFT,
+ pos + Vector2i.DOWN,
+ pos + Vector2i.RIGHT]
+
+ for n in next:
+ var chance = randi_range(0, 1)
+ if chance == 0:
+ set_grid_index(grid, n)
+
+func place_door(grid: Array[int], pos: Vector2i):
+ var index = get_grid_index(pos)
+ if grid[index] == 0:
+ return
+
+ var next = [pos + Vector2i.UP,
+ pos + Vector2i.LEFT,
+ pos + Vector2i.DOWN,
+ pos + Vector2i.RIGHT]
+
+ var angle = -90
+ for n in next:
+ angle += 90
+ var next_index = get_grid_index(n)
+ if n.x < 0 or n.x >= width or n.y < 0 or n.y >= height or grid[next_index] == 0:
+ var new_door: Node3D = door.instantiate()
+ var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2)
+ new_door.position = (offset_pos * bounds)
+ new_door.rotate_y(deg_to_rad(angle))
+ add_child(new_door)
+
+func place_doors(grid: Array[int]):
+ for y in range(0, height):
+ for x in range(0, width):
+ place_door(grid, Vector2i(x, y))
+
+func compute_astar(grid: Array[int]):
+ for y in range(0, height):
+ for x in range(0, width):
+ var pos = Vector2i(x, y)
+ var index = get_grid_index(pos)
+ if grid[index] == 0:
+ continue
+ var offset_pos = Vector3(pos.x - width / 2, 0, pos.y - height / 2)
+ astar.add_point(index, offset_pos * bounds)
+
+ for y in range(0, height):
+ for x in range(0, width):
+ var pos = Vector2i(x, y)
+ var index = get_grid_index(pos)
+ if grid[index] == 0:
+ continue
+
+ var next = [pos + Vector2i.UP,
+ pos + Vector2i.LEFT,
+ pos + Vector2i.DOWN,
+ pos + Vector2i.RIGHT]
+ for n in next:
+ var next_index = get_grid_index(n)
+ if n.x < 0 or n.x >= width or n.y < 0 or n.y >= height or grid[next_index] == 0:
+ continue
+
+ astar.connect_points(index, next_index)
+
+# Called when the node enters the scene tree for the first time.
+func _ready() -> void:
+ astar = AStar3D.new()
+ var grid: Array[int] = [0]
+ grid.resize(width*height)
+ grid.fill(0)
+
+ var middle_x: int = width / 2
+ var middle_y: int = height / 2
+
+ var pos = Vector2i(middle_x, middle_y)
+ set_grid_index(grid, pos)
+
+ place_doors(grid)
+ compute_astar(grid)
+
+ astar_created.emit(astar)