project-villain/places/base_place/place.gd
2025-06-28 15:55:28 +10:00

179 lines
4.1 KiB
GDScript

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