256 lines
5.7 KiB
GDScript
256 lines
5.7 KiB
GDScript
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
|
|
|
|
|