extends Node3D var tile_grid_size = 64 var load_tile = preload("res://tiles/base_tile/base_tile.tscn") var load_room = preload("res://places/base_place/base_room.tscn") var load_door = preload("res://tiles/base_tile/base_door.tscn") var place_tile_dict = {} var selection_drag_dict = {} var selection_dict = {} var room_dict = {} var tile_count_x_hist = null var tile_count_z_hist = null var build_allowed = true var current_room = null var current_room_walls = [] var current_door = null func _ready(): #connect("wall_built", record_walls) #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, z) var tile = load_tile.instantiate() tile.set_position(pos) tile.grid_pos = pos tile.update(0, 2) place_tile_dict[pos] = tile add_child(tile) func draw_tile_click(click_pos): #starts a selection drag var build_start_pos: Vector3i = click_pos.floor() tile_count_x_hist = 0 tile_count_z_hist = 0 if place_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.floor() var build_mouse_pos: Vector3i = float_build_mouse_pos.floor() 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 place_tile_dict.has(select_drag_pos): if not place_tile_dict[select_drag_pos].construction_mode == 4: 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 for i in place_tile_dict: if not selection_dict.has(i): var tile_selected = place_tile_dict[i] tile_selected.update(1, 0) selection_drag_dict.clear() for i in array: select_tile(i) func select_tile(pos): #Tells tiles to be selected var tile = place_tile_dict[pos] selection_drag_dict[pos] = tile if build_allowed: tile.update(3, 0) else: tile.update(4, 0) func verify_room(): #Verifies that a given selection is fully contiguous 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: return false var verify_pos = verify_queue_array.pop_back() var verify_neighbor_array = place_tile_dict[verify_pos].neighbor_array for n in verify_neighbor_array: if selection_dict.has(verify_pos + n): if not verify_checked_array.has(verify_pos + n): if not verify_queue_array.has(verify_pos + n): verify_queue_array.append(verify_pos + n) verify_checked_array.append(verify_pos) verify_array.erase(verify_pos) return true 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) for i in selection_dict.keys(): var tile = selection_dict[i] for j in range(4): tile.update_face(j, 1) var neighbor = 0 for j in tile.neighbor_array: if not selection_dict.has(i + j): tile.update_face(neighbor, 2) neighbor = neighbor + 1 if verify_room(): build_allowed = true for i in selection_dict: place_tile_dict[i].update(3, 0) else: build_allowed = false for i in selection_dict: place_tile_dict[i].update(4, 0) selection_drag_dict.clear() func build_selection(): #When the build or destroy button is clicked, changes the selected tiles to match the button's request if not build_allowed: return for i in selection_dict: var tile_selected = place_tile_dict[i] tile_selected.update(1, 4) var room = create_room() selection_dict.clear() return room func clear_selection(): #When the clear button is clicked, it clears the selected tiles without doing anything. for i in selection_dict: var tile_selected = selection_dict[i] tile_selected.update(1, 0) build_allowed = true for i in selection_dict.keys(): var tile = selection_dict[i] for j in range(4): tile.update_face(j, 1) selection_dict.clear() func create_room(): var room = load_room.instantiate() room.position = (selection_dict.keys().min()) room.room_tile_dict = selection_dict.duplicate() room.name = str("Room", room.get_instance_id()) add_child(room) for i in room.room_tile_dict: place_tile_dict[i].room_id = room current_room = room return room #func record_walls(): func create_door(): for i in current_room.room_tile_dict.keys(): for j in current_room.room_tile_dict[i].wall_dict.keys(): current_room_walls.append((Vector3(i) + Vector3(0.5, 0, 0.5)) + Vector3(j) / 2) current_door = true var door = load_door.instantiate() door.room = current_room add_child(door) return door func hover_door(position): if not current_door: current_door = create_door() var closest = null var closest_distance = INF for i in current_room_walls: var distance = position.distance_to(i) if closest_distance > distance: closest_distance = distance closest = i current_door.position = closest current_door.rotation_degrees = Vector3(0, 180 * fmod(closest.x, 1), 0) func build_door(): current_room = null current_room_walls = [] current_door = null