extends Node3D class_name Place var tile_grid_size: int = 8 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 place_room_array: Array = [] #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(): pass func place_tile_check(new_dict): place_tile_dict = new_dict #if type_string(typeof(new_dict)) == "Array": #for i in new_dict: # #place_tile_dict[] func init_grid(): #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.name = str("Tile", tile.get_instance_id()) tile.place_id = self.get_instance_id() tile.selection_mode = Tile.SEL_MODE.NONE tile.construction_mode = Tile.CON_MODE.CLOSED place_tile_dict[pos] = tile $TileContainer.add_child(tile) #var pos = Vector3i(1, 0, 1) # #var tile = place_tile_dict[pos] # #var trickydict = {pos: tile} # #tile.room = create_room(trickydict) # #tile.construction_mode = Tile.CON_MODE.BUILT # #selection_drag_dict[pos] = tile #end_select_drag() #build_selection() func save(): var save_data = { # Basics "name": name, "type": "Place", "id": self.get_instance_id(), "scene_file_path": scene_file_path, "parent": get_parent().get_path(), # Connections # Data } return save_data func draw_tile_click(click_pos): #starts a selection drag var build_start_pos: Vector3i = click_pos.floor() if place_tile_dict.has(build_start_pos): if not place_tile_dict[build_start_pos].construction_mode == Tile.CON_MODE.BUILT: 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.selection_mode = 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.selection_mode = Tile.SEL_MODE.BUILD else: tile.selection_mode = 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_dict.values() 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].selection_mode = Tile.SEL_MODE.BUILD else: build_confirm_allowed = false for i in selection_dict: place_tile_dict[i].selection_mode = Tile.SEL_MODE.INVALID selection_drag_dict.clear() func build_selection(): #When the build button is clicked, changes the selected tiles to match the button's request if not build_confirm_allowed: return if selection_dict: var room: Object = create_room(selection_dict) for i in selection_dict: var tile: Object = place_tile_dict[i] tile.selection_mode = Tile.SEL_MODE.NONE tile.construction_mode = Tile.CON_MODE.BUILT 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.selection_mode = Tile.SEL_MODE.NONE build_confirm_allowed = true #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) selection_dict.clear() func create_room(selection): #Creates a room from the selected tiles. var room: Object = load_room.instantiate() room.position = (selection.keys().min()) room.room_tile_array = selection.values() room.place_id = self.get_instance_id() room.name = str("Room", room.get_instance_id()) $RoomContainer.add_child(room) for i in room.room_tile_array: i.room_array.append(room) place_room_array.append(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] # #current_room = null #current_room_walls = [] #current_door = null func give_neighbors(tile, grid_pos, directions): var neighbor_dict = {} for i in directions.keys(): if place_tile_dict.has(directions[i] + grid_pos): neighbor_dict[directions[i]] = place_tile_dict[directions[i] + grid_pos] tile.neighbor_dict = neighbor_dict func _on_tile_container_child_entered_tree(node: Node) -> void: node.connect("neighbor_request", give_neighbors)