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)