extends Node3D var tile_grid_size: int = 32 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") #Contains all tiles in a workplace. var place_tile_dict: Dictionary = {} #Contains the tiles in the current selection drag var selection_drag_dict: Dictionary = {} #Contains all the tiles that have been selected in the current build var selection_dict: Dictionary = {} #Contains all rooms in a workplace. var room_dict: Dictionary = {} #Tracks the previous amount of tiles counted in a selection drac var tile_count_x_hist: int = 0 var tile_count_z_hist: int = 0 #Tracks is confirming a build is allowed var build_confirm_allowed: bool = true #Tracks parts of the room currently being built var current_room: Object = null var current_room_walls: Array = [] var current_door: Object = null func _ready(): #TEMP: 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: Object = load_tile.instantiate() tile.set_position(pos) tile.grid_pos = pos tile.update(Tile.SEL_MODE.NONE, Tile.CON_MODE.CLOSED) place_tile_dict[pos] = tile add_child(tile) var pos: Vector3i = Vector3i(1, 0, 1) var tile: Object = place_tile_dict[pos] selection_drag_dict[pos] = tile end_select_drag() build_selection() 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: 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: int = build_mouse_pos.x - build_start_pos.x var tile_count_z: int = 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: Vector3i = 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 == Tile.CON_MODE.BUILT: 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: Object = place_tile_dict[i] tile.update(Tile.SEL_MODE.NONE, ) selection_drag_dict.clear() for i in array: select_tile(i) func select_tile(pos): #Tells tiles to be selected var tile: Object = place_tile_dict[pos] selection_drag_dict[pos] = tile if build_confirm_allowed: tile.update(Tile.SEL_MODE.BUILD, ) else: tile.update(Tile.SEL_MODE.INVALID, ) func verify_room(): #Verifies that a given selection is fully contiguous var verify_array: Array = selection_dict.keys() var verify_queue_array: Array = [verify_array[0]] var verify_checked_array: Array = [] while verify_array: if not verify_queue_array: return false var verify_pos: Vector3i = verify_queue_array.pop_back() var verify_neighbor_array: Array = place_tile_dict[verify_pos].direction_vector_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:Object = selection_dict[i] for j in range(4): tile.update_face(j, Tile.FACE_MODE.NONE) for j in range(4): if not selection_dict.has(i + tile.direction_vector_array[j]): tile.update_face(j, Tile.FACE_MODE.FULL) if verify_room(): build_confirm_allowed = true for i in selection_dict: place_tile_dict[i].update(Tile.SEL_MODE.BUILD, ) else: build_confirm_allowed = false for i in selection_dict: place_tile_dict[i].update(Tile.SEL_MODE.INVALID, ) 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_confirm_allowed: return if selection_dict: for i in selection_dict: var tile: Object = place_tile_dict[i] tile.update(Tile.SEL_MODE.NONE, Tile.CON_MODE.BUILT) var room: Object = 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: Object = selection_dict[i] tile.update(Tile.SEL_MODE.NONE, ) build_confirm_allowed = true for i in selection_dict.keys(): var tile: Object = selection_dict[i] for j in Tile.DIRECTION: tile.update_face(j, Tile.FACE_MODE.NONE) selection_dict.clear() func create_room(): #Creates a room from the selected tiles. var room: Object = 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 create_door(): #Creates a door to be placed. 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) var door: Object = load_door.instantiate() door.room = current_room add_child(door) current_door = door func hover_door(mouse_pos): #Hovers the door at the closest wall segment to the mouse in the current room if not current_door: create_door() var closest: Vector3 var closest_distance: float = INF for i in current_room_walls: var distance: float = mouse_pos.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.z, 1), 0) func confirm_door(): #Builds the door at the hovered location var tile_1: Object var tile_2: Object if fmod(current_door.position.x, 1) == 0: tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)] tile_2 = place_tile_dict[Vector3i(current_door.position.x - 1, 0, current_door.position.z)] else: tile_1 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z)] tile_2 = place_tile_dict[Vector3i(current_door.position.x, 0, current_door.position.z - 1)] var tile_1_door_face: Vector3i = tile_2.position - tile_1.position var tile_1_door_face_direction: int = tile_1.direction_vector_array.find(tile_1_door_face) tile_1.update_face(tile_1_door_face_direction, Tile.FACE_MODE.DOOR, current_door) var tile_1_room: Object = tile_1.room_id tile_1_room.room_door_array.append(current_door) var tile_2_door_face: Vector3i = tile_1.position - tile_2.position var tile_2_door_face_direction: int = tile_2.direction_vector_array.find(tile_2_door_face) tile_2.update_face(tile_2_door_face_direction, Tile.FACE_MODE.DOOR, current_door) var tile_2_room: Object = tile_2.room_id tile_2_room.room_door_array.append(current_door) current_door.door_room_array = [tile_1_room, tile_2_room] print(current_door.door_room_array) current_room = null current_room_walls = [] current_door = null