extends Node3D var tile_grid_size = 64 var astar_grid_room = AStarGrid2D.new() var load_tile = preload("res://tiles/base_tile/tile.tscn") var tile_dict = {} var selection_drag_dict = {} var selection_dict = {} var tile_count_x_hist = null var tile_count_z_hist = null var build_forbidden = false func _ready(): # Sets up a simple 2D grid of blank tiles. for x in range(tile_grid_size): for z in range (tile_grid_size): var pos = Vector3i(x + 0.5,0 ,z + 0.5) var tile = load_tile.instantiate() tile.set_position(pos) tile.type = 0 tile_dict[pos] = tile add_child(tile) func build_selection(b): # When the build or destroy button is clicked, changes the selected tiles to match the button's request if build_forbidden: print("can't build") return for i in selection_dict: var tile_selected = tile_dict[i] tile_selected.build_this_tile(b) selection_dict.clear() for i in tile_dict: if not selection_dict.has(i): var tile_selected = tile_dict[i] tile_selected.select_this_tile(false) func clear_selection(): # When the clear button is clicked, it clears the selected tiles without doing anything. for i in tile_dict: var tile_selected = tile_dict[i] tile_selected.select_this_tile(false) selection_dict.clear() func end_select_drag(): # Adds dragged tiles to the current selection on mouse-up tile_count_x_hist = 0 tile_count_z_hist = 0 selection_dict.merge(selection_drag_dict) if verify_room(): build_forbidden = false else: build_forbidden = true selection_drag_dict.clear() func draw_tile_click(start_pos): # starts a selection drag var build_start_pos: Vector3i = start_pos.snapped(Vector3i(1, 1, 1)) tile_count_x_hist = 0 tile_count_z_hist = 0 if tile_dict.has(build_start_pos): select_tile(build_start_pos) func init_select_drag(float_build_start_pos, float_build_mouse_pos): # Creats an array of dragged tiles between mouse start and current position var select_drag_array = [] var build_start_pos: Vector3i = float_build_start_pos.snapped(Vector3i(1.0, 1.0, 1.0)) var build_mouse_pos: Vector3i = float_build_mouse_pos.snapped(Vector3i(1.0, 1.0, 1.0)) var tile_count_x = build_mouse_pos.x - build_start_pos.x var tile_count_z = build_mouse_pos.z - build_start_pos.z if not tile_count_x_hist == tile_count_x or not tile_count_z_hist == tile_count_z: tile_count_x_hist = tile_count_x tile_count_z_hist = tile_count_z for x in range(min(0, tile_count_x), max(0, tile_count_x) + 1): for z in range(min(0, tile_count_z), max(0, tile_count_z) + 1): var select_drag_pos = build_start_pos + Vector3i(x, 0, z) if tile_dict.has(select_drag_pos): select_drag_array.append(select_drag_pos) if select_drag_array: draw_select_drag(select_drag_array) func draw_select_drag(array): # Clears previous drag, then calls tile selection on all currently dragged tiles selection_drag_dict.clear() for i in tile_dict: if not selection_dict.has(i): var tile_selected = tile_dict[i] tile_selected.select_this_tile(false) for i in array: var id = i select_tile(id) func select_tile(pos): # Tells tiles to be selected var tile = tile_dict[pos] tile.select_this_tile(true) selection_drag_dict[pos] = tile func verify_room(): # Verifies that a given selection is fully contiguous if selection_dict == selection_drag_dict: return true var verify_array = selection_dict.keys() var verify_queue_array = [verify_array[0]] var verify_checked_array = [] while verify_array: if not verify_queue_array: print("no good") return false var verify_pos = verify_queue_array.pop_back() var verify_neighbor_array = [ Vector3i(verify_pos.x + 1, 0, verify_pos.z), Vector3i(verify_pos.x - 1, 0, verify_pos.z), Vector3i(verify_pos.x, 0, verify_pos.z + 1), Vector3i(verify_pos.x, 0, verify_pos.z - 1) ] for n in verify_neighbor_array: if selection_dict.has(n): if not verify_checked_array.has(n): if not verify_queue_array.has(n): verify_queue_array.append(n) verify_checked_array.append(verify_pos) verify_array.erase(verify_pos) print("all good") return true