extends Node3D var grid: Array[Tile.Tile] = [] var grid_width: int var grid_height: int var enemy_inst = preload("res://prefabs/enemy.tscn") var exit_inst = preload("res://prefabs/exit.tscn") var bsp_level_inst = preload("res://prefabs/bsp_level_generator.tscn") var level_done: bool = false # Called when the node enters the scene tree for the first time. func _ready() -> void: spawn_level() func spawn_level() -> void: var bsp_level = bsp_level_inst.instantiate() bsp_level.connect("grid_generated", _grid_generated) $LevelContainer.add_child(bsp_level) func create_enemies() -> void: var num_enemies = randi_range(4, 10) for i in range(num_enemies): var enemy = enemy_inst.instantiate() # Target is controlled through enemy wander AI enemy.target = null var found_pos = false while not found_pos: var pos = Vector2i(randi_range(0, grid_width-1), randi_range(0, grid_height-1)) if grid[pos.y * grid_width + pos.x] == Tile.Tile.FLOOR: enemy.position = Vector3(pos.x, 0, pos.y) + Vector3(0.5, 0, 0.5) found_pos = true print("Placing at ", pos) $LevelContainer.add_child.call_deferred(enemy) func create_exit() -> void: var found_pos = false var exit: Area3D = exit_inst.instantiate() exit.connect("body_entered", _on_player_exit) while not found_pos: var pos = Vector2i(randi_range(0, grid_width-1), randi_range(0, grid_height-1)) var left = pos + Vector2i.LEFT var right = pos + Vector2i.RIGHT var up = pos + Vector2i.UP var down = pos + Vector2i.DOWN if grid[pos.y * grid_width + pos.x] == Tile.Tile.FLOOR \ and grid[left.y * grid_width + left.x] == Tile.Tile.FLOOR \ and grid[right.y * grid_width + right.x] == Tile.Tile.FLOOR \ and grid[up.y * grid_width + up.x] == Tile.Tile.FLOOR \ and grid[down.y * grid_width + down.x] == Tile.Tile.FLOOR: exit.position = Vector3(pos.x, 0, pos.y) + Vector3(0.5, 0, 0.5) found_pos = true $LevelContainer.add_child.call_deferred(exit) func place_player() -> void: var found_pos = false while not found_pos: var pos = Vector2i(randi_range(0, grid_width-1), randi_range(0, grid_height-1)) if grid[pos.y * grid_width + pos.x] == Tile.Tile.FLOOR: $Player.position = Vector3(pos.x, 0, pos.y) + Vector3(0.5, 0, 0.5) found_pos = true func reset_level() -> void: for child in $LevelContainer.get_children(): print("Child is ", child) $LevelContainer.remove_child(child) child.queue_free() spawn_level() level_done = false func _process(_delta: float) -> void: if level_done: reset_level() func _on_player_exit(_body: Node3D): level_done = true func _grid_generated(p_grid: Array[Tile.Tile], p_grid_width: int, p_grid_height: int) -> void: grid = p_grid grid_width = p_grid_width grid_height = p_grid_height create_enemies() create_exit() place_player()