From 5b79dc9822b8f39a22ecabfd44483a466afbb3b4 Mon Sep 17 00:00:00 2001 From: Sch1nken Date: Wed, 6 Mar 2024 19:55:13 +0100 Subject: [PATCH] TODO: Fix UI Button reaching 0 not greying out, fix state behaviour for selected tiles --- Globals/GameEvents.gd | 3 + HexGrid3D/HexGrid3D.gd | 176 +++++++++++------- HexOutline.gd | 12 +- InsectButton.gd | 6 +- InsectTiles/SelectionFailedMat.tres | 11 ++ .../MovementBehaviourResource.gd | 2 +- .../Prefabs/MovementBehaviourBee.gd | 30 +-- Tile/Tile.gd | 117 +++++++++++- export_presets.cfg | 63 +++++++ 9 files changed, 325 insertions(+), 95 deletions(-) create mode 100644 InsectTiles/SelectionFailedMat.tres diff --git a/Globals/GameEvents.gd b/Globals/GameEvents.gd index 8b1dd01..67c289c 100644 --- a/Globals/GameEvents.gd +++ b/Globals/GameEvents.gd @@ -5,6 +5,9 @@ signal insect_placed(insect_resource, is_black, position) signal insect_placement_cancelled signal insect_tile_selected(tile) +signal insect_tile_request_selection(tile) +signal insect_tile_selection_request_successful(tile) +signal insect_tile_selection_request_failed(tile) signal insect_tile_deselected(tile) signal insect_tile_moved(tile, to) diff --git a/HexGrid3D/HexGrid3D.gd b/HexGrid3D/HexGrid3D.gd index f489ef9..8a4e83b 100644 --- a/HexGrid3D/HexGrid3D.gd +++ b/HexGrid3D/HexGrid3D.gd @@ -21,18 +21,23 @@ var used_cells: Dictionary = {} # have all used_cells be saved as Vector4i (q, r, s, y) -class CellStorage: - var cells: Dictionary = {} +class TileStorage: + var tiles: Dictionary = {} + # we use a vector4i for coordinates + # q r s y (layer) - func add_cell(coords: CubeCoordinates, layer: int = 0) -> void: + func add_tile(tile: InsectTile, coords: CubeCoordinates, layer: int = 0) -> void: + tiles[Vector4i(coords.q, coords.r, coords.s, layer)] = tile pass - func remove_cell(coords: CubeCoordinates, layer: int = 0) -> void: + func remove_tile(coords: CubeCoordinates, layer: int = 0) -> void: pass - func has_cell(cords: CubeCoordinates, layer: int = 0) -> bool: - return false + func has_tile(coords: CubeCoordinates, layer: int = 0) -> bool: + return tiles.has(Vector4i(coords.q, coords.r, coords.s, layer)) + func get_tile(coords: CubeCoordinates, layer: int = 0) -> InsectTile: + return tiles[Vector4i(coords.q, coords.r, coords.s, layer)] class CubeCoordinates: @@ -62,6 +67,9 @@ func flat_hex_to_world_position(coords: AxialCoordinates) -> Vector2: var x = size * (3.0/2.0 * coords.q) var y = size * (sqrt(3.0)/2.0 * coords.q + sqrt(3.0) * coords.r) return Vector2(x, y) + +func cube_to_world_pos(coords: CubeCoordinates) -> Vector2: + return flat_hex_to_world_position(cube_to_axial(coords)) #func world_to_hex_tile(world_pos: Vector3) -> Vector2: # var q = (2.0/3.0 * world_pos.x) @@ -118,16 +126,23 @@ func get_3d_pos(position2D: Vector2): var placements: Dictionary = {} -func is_cell_empty(coords: Vector2i) -> bool: - return !used_cells.has(coords) +func is_cell_empty(coords: CubeCoordinates) -> bool: + return !used_cells.has(Vector4i(coords.q, coords.r, coords.s, 0)) -func get_empty_neighbours(coords: Vector2i) -> Array[Vector2i]: +func is_cell_not_empty(coords: CubeCoordinates) -> bool: + return !is_cell_empty(coords) + +func get_empty_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]: return get_neighbours(coords).filter(is_cell_empty) -func get_neighbours(coords: Vector2i) -> Array[Vector2i]: +func get_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]: return [ - Vector2i(coords.x + 1, coords.y), Vector2i(coords.x + 1, coords.y - 1), Vector2i(coords.x, coords.y - 1), - Vector2i(coords.x - 1, coords.y), Vector2i(coords.x - 1, coords.y + 1), Vector2i(coords.x, coords.y + 1) + CubeCoordinates.new(coords.q + 1, coords.r, coords.s - 1), + CubeCoordinates.new(coords.q + 1, coords.r - 1, coords.s), + CubeCoordinates.new(coords.q, coords.r - 1, coords.s + 1), + CubeCoordinates.new(coords.q - 1, coords.r, coords.s + 1), + CubeCoordinates.new(coords.q - 1, coords.r + 1, coords.s), + CubeCoordinates.new(coords.q, coords.r + 1, coords.s - 1) ] var current_tile: Node3D @@ -145,27 +160,28 @@ func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void: # spawn possible placement locations :) if used_cells.size() == 0: # we have no cells placed, display a placement outline at 0, 0 var outline = HEX_OUTLINE.instantiate() - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(0, 0)) + var cubepos = CubeCoordinates.new(0, 0, 0) + var hex_pos = cube_to_world_pos(cubepos) outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - outline.hex_pos = Vector2i(0, 0) outline.visible = true outline.insect_resource = insect_resource outline.is_black = is_black + outline.coordinates = cubepos placement_visualizer.add_child(outline) placements[hex_pos] = outline elif used_cells.size() == 1: # we have ONE cell placed, this is a special case in which # the opposing player is allowed to place a tile that touches the enemy color # We display outline placement around all spaces of this single cell var single_cell = used_cells.keys().front() - var neighbours = get_neighbours(single_cell) + var neighbours = get_neighbours(CubeCoordinates.new(single_cell.x, single_cell.y, single_cell.z)) for neighbour in neighbours: var outline = HEX_OUTLINE.instantiate() - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(neighbour.x, neighbour.y)) + var hex_pos = cube_to_world_pos(neighbour) outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - outline.hex_pos = neighbour outline.visible = true outline.insect_resource = insect_resource outline.is_black = is_black + outline.coordinates = neighbour placement_visualizer.add_child(outline) placements[hex_pos] = outline else: @@ -174,40 +190,35 @@ func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void: var possible_placements: Dictionary = {} for hex in used_cells.keys(): - var neighbours = [ - Vector2i(hex.x + 1, hex.y), Vector2i(hex.x + 1, hex.y - 1), Vector2i(hex.x, hex.y - 1), - Vector2i(hex.x - 1, hex.y), Vector2i(hex.x - 1, hex.y + 1), Vector2i(hex.x, hex.y + 1) - ] #var eligible: bool = true - for neighbour in neighbours: - if not used_cells.has(neighbour): - possible_placements[neighbour] = true + for neighbour in get_empty_neighbours(CubeCoordinates.new(hex.x, hex.y, hex.z)): + if not used_cells.has(Vector4(neighbour.q, neighbour.r, neighbour.s, 0)): + possible_placements[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)] = true for p in possible_placements: - var neighbours = [ - Vector2i(p.x + 1, p.y), Vector2i(p.x + 1, p.y - 1), Vector2i(p.x, p.y - 1), - Vector2i(p.x - 1, p.y), Vector2i(p.x - 1, p.y + 1), Vector2i(p.x, p.y + 1) - ] + #var neighbours = [ + # Vector2i(p.x + 1, p.y), Vector2i(p.x + 1, p.y - 1), Vector2i(p.x, p.y - 1), + # Vector2i(p.x - 1, p.y), Vector2i(p.x - 1, p.y + 1), Vector2i(p.x, p.y + 1) + #] var eligible: bool = true - for neighbour in neighbours: - - if not used_cells.has(neighbour): + for neighbour in get_neighbours(CubeCoordinates.new(p.x, p.y, p.z)): + if not used_cells.has(Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)): continue - if used_cells[neighbour].is_black != is_black: + if used_cells[Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)].is_black != is_black: eligible = false break if eligible: var outline = HEX_OUTLINE.instantiate() - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(p.x, p.y)) + var hex_pos = cube_to_world_pos(CubeCoordinates.new(p.x, p.y, p.z)) outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - outline.hex_pos = p outline.visible = true outline.insect_resource = insect_resource outline.is_black = is_black + outline.coordinates = CubeCoordinates.new(p.x, p.y, p.z) placement_visualizer.add_child(outline) placements[p] = outline @@ -223,9 +234,9 @@ func _on_insect_placement_cancelled() -> void: for child in placement_visualizer.get_children(): child.queue_free() -func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: CubeCoordinates) -> void: var tile_copy = INSECT_TILE.instantiate() - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(pos.x, pos.y)) + var hex_pos = cube_to_world_pos(pos) tile_copy.position = Vector3(hex_pos.x, 20.0, hex_pos.y) tile_copy.resource = resource @@ -233,7 +244,7 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> tile_copy.coordinates = pos var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y) - used_cells[Vector2i(pos.x, pos.y)] = tile_copy + used_cells[Vector4i(pos.q, pos.r, pos.s, 0)] = tile_copy add_child(tile_copy) @@ -244,14 +255,34 @@ func _on_insect_tile_selected(tile: InsectTile) -> void: if tile.resource.movement_behaviour == null: return - var pos = world_to_hex_tile(Vector2(tile.position.x, tile.position.z)) - var spaces = tile.resource.movement_behaviour.get_available_spaces(Vector2i(pos.q, pos.r), self) + var spaces = tile.resource.movement_behaviour.get_available_spaces(tile.coordinates, self) + + print(spaces.size()) + + if spaces.is_empty(): + GameEvents.insect_tile_selection_request_failed.emit(tile) + return for space in spaces: + var neighbours = get_neighbours(space) + # if all neighbours are empty, move would disconnect us from the hive + # so we discard it + # also: if there are 5 empty space and the only remaining one is our current tile... + # we would also be disconnected after the move + # maybe the 6 check is not needed + var non_empty_neighbours = neighbours.filter(is_cell_not_empty) + var coords_vec4: Vector4i = Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0) + + if non_empty_neighbours.size() == 1: + var occupied_neighbour = non_empty_neighbours.front() + var neighbour_vec4: Vector4i = Vector4i(occupied_neighbour.q, occupied_neighbour.r, occupied_neighbour.s, 0) + if neighbour_vec4 == coords_vec4: + continue + var outline = HEX_OUTLINE.instantiate() - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(space.x, space.y)) + var hex_pos = cube_to_world_pos(space) # flat_hex_to_world_position(AxialCoordinates.new(space.x, space.y)) outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - outline.hex_pos = space + outline.coordinates = space outline.visible = true outline.insect_tile = tile outline.is_moving = true @@ -261,10 +292,10 @@ func _on_insect_tile_selected(tile: InsectTile) -> void: placements[space] = outline -func _on_insect_tile_moved(tile: InsectTile, target: Vector2i) -> void: - used_cells.erase(tile.coordinates) +func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void: + used_cells.erase(Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0)) - var new_hex_pos = flat_hex_to_world_position(AxialCoordinates.new(target.x, target.y)) + var new_hex_pos = cube_to_world_pos(target) var sky_new_hex_pos = Vector3(new_hex_pos.x, 20.0, new_hex_pos.y) var ground_new_hex_pos = Vector3(new_hex_pos.x, 0.0, new_hex_pos.y) # @@ -278,7 +309,43 @@ func _on_insect_tile_moved(tile: InsectTile, target: Vector2i) -> void: tile.coordinates = target - used_cells[target] = tile + used_cells[Vector4i(target.q, target.r, target.s, 0)] = tile + +func can_hive_exist_without_tile(tile: InsectTile) -> bool: + # TODO: BFS-Search from random cell to see if all other cells could still be reached when this + # tile would be empty space + if get_empty_neighbours(tile.coordinates).size() == 5: # we only have one real neighbour, so can't break anything + return true + + var vector_coords: Vector4i = Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0) + + # DO BFS + var tiles_reached: Array = [] + var tiles_available: Array = used_cells.keys().filter(func(coords): return coords != vector_coords) + + # tiles_available has all remaining tiles, we just need to visit every tile from a (random) starting tile + # and compare the size with these of all tiles - 1 (our to be moved one) + var start: Vector4i = tiles_available.front() + tiles_reached.push_back(start) + var queue: Array[Vector4i] = [start] + + while queue.size() > 0: + var m = queue.pop_front() + + for neighbour in get_neighbours(CubeCoordinates.new(m.x, m.y, m.z)): + var neighbour_vec4: Vector4i = Vector4i(neighbour.q, neighbour.r, neighbour.s, 0) + if neighbour_vec4 not in tiles_reached and neighbour_vec4 != vector_coords: + if used_cells.has(neighbour_vec4): + tiles_reached.push_back(neighbour_vec4) + queue.push_back(neighbour_vec4) + + return tiles_reached.size() == used_cells.size() - 1 + +func _on_insect_tile_request_selection(tile: InsectTile) -> void: + if can_hive_exist_without_tile(tile): + GameEvents.insect_tile_selection_request_successful.emit(tile) + else: + GameEvents.insect_tile_selection_request_failed.emit(tile) func _ready() -> void: GameEvents.insect_selected.connect(_on_insect_selected) @@ -286,25 +353,8 @@ func _ready() -> void: GameEvents.insect_placed.connect(_on_insect_placed) GameEvents.insect_tile_selected.connect(_on_insect_tile_selected) GameEvents.insect_tile_moved.connect(_on_insect_tile_moved) + GameEvents.insect_tile_request_selection.connect(_on_insect_tile_request_selection) - return - - for x in range(-6, 5): - for y in range(-6, 5): - var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(x, y)) - - if randi_range(0, 1) == 0: - var new_hex = INSECT_TILE.instantiate() - new_hex.resource = preload("res://Tile/Prefabs/Bee.tres") - new_hex.is_black = false - new_hex.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - var hex_id = world_to_hex_tile(Vector2(hex_pos.x, hex_pos.y)) - add_child(new_hex) - used_cells[Vector2i(x, y)] = new_hex - else: - continue - - #func spawn_random_tile() -> void: #var tile_copy = hex.duplicate() #var hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20))) diff --git a/HexOutline.gd b/HexOutline.gd index d76a793..cac9715 100644 --- a/HexOutline.gd +++ b/HexOutline.gd @@ -2,13 +2,13 @@ extends Area3D var hovered: bool = false +var coordinates: HexGrid.CubeCoordinates + var insect_resource: TileResource var is_black: bool = false var insect_tile: InsectTile -var hex_pos: Vector2i = Vector2i.ZERO - var tile: Node3D var is_moving: bool = false @@ -25,10 +25,10 @@ func _ready(): else: GameEvents.insect_placed.connect(_on_insect_placed) -func _on_insect_tile_moved(tile: InsectTile, to: Vector2i) -> void: +func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void: queue_free() -func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: queue_free() # Called every frame. 'delta' is the elapsed time since the previous frame. @@ -36,9 +36,9 @@ func _process(delta): if Input.is_action_just_pressed("place_tile"): if hovered: if is_moving: - GameEvents.insect_tile_moved.emit(insect_tile, hex_pos) + GameEvents.insect_tile_moved.emit(insect_tile, coordinates) else: - GameEvents.insect_placed.emit(insect_resource, is_black, hex_pos) + GameEvents.insect_placed.emit(insect_resource, is_black, coordinates) func _on_mouse_entered(): hovered = true diff --git a/InsectButton.gd b/InsectButton.gd index dcd12a0..71030e1 100644 --- a/InsectButton.gd +++ b/InsectButton.gd @@ -46,7 +46,7 @@ func _on_placement_cancelled() -> void: enable() return -func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector2i) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: if selected: selected = false @@ -71,7 +71,7 @@ func _ready(): if is_black: hex.texture = HEX_BLACK -func _on_insect_selected(_resource, _is_black) -> void: +func _on_insect_selected(_resource: TileResource, _is_black: bool) -> void: disabled = true if _resource == insect_resource and _is_black == is_black: @@ -118,8 +118,6 @@ func _on_pressed(): if selected: return - - print("??") if tile_count <= 0: return diff --git a/InsectTiles/SelectionFailedMat.tres b/InsectTiles/SelectionFailedMat.tres new file mode 100644 index 0000000..835b80d --- /dev/null +++ b/InsectTiles/SelectionFailedMat.tres @@ -0,0 +1,11 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://djlhrbvvbgpd0"] + +[ext_resource type="Shader" path="res://InsectTiles/HoverShader.gdshader" id="1_8diwm"] + +[resource] +render_priority = 0 +shader = ExtResource("1_8diwm") +shader_parameter/albedo = Color(0, 0, 0, 1) +shader_parameter/emission_color = Color(0, 0, 0, 1) +shader_parameter/emission_amount = 5.0 +shader_parameter/rim_steepness = 0.214 diff --git a/MovementBehaviour/MovementBehaviourResource.gd b/MovementBehaviour/MovementBehaviourResource.gd index 7be5346..77d806d 100644 --- a/MovementBehaviour/MovementBehaviourResource.gd +++ b/MovementBehaviour/MovementBehaviourResource.gd @@ -1,5 +1,5 @@ extends Resource class_name MovementBehaviour -func get_available_spaces(pos: Vector2i, map: HexGrid) -> Array[Vector2i]: +func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]: return [] diff --git a/MovementBehaviour/Prefabs/MovementBehaviourBee.gd b/MovementBehaviour/Prefabs/MovementBehaviourBee.gd index 7f8cdef..94bc6d9 100644 --- a/MovementBehaviour/Prefabs/MovementBehaviourBee.gd +++ b/MovementBehaviour/Prefabs/MovementBehaviourBee.gd @@ -1,35 +1,35 @@ extends MovementBehaviour class_name MovementBehaviourBee -func can_reach(start: Vector2i, target: Vector2i, map: HexGrid) -> bool: +func can_reach(start: HexGrid.CubeCoordinates, target: HexGrid.CubeCoordinates, map: HexGrid) -> bool: # if we have 5 potential spaces it can never be blocked - var cubepos: HexGrid.CubeCoordinates = map.axial_to_cube(HexGrid.AxialCoordinates.new(start.x, start.y)) - var cubecoord = map.axial_to_cube(HexGrid.AxialCoordinates.new(target.x, target.y)) + var cubepos: HexGrid.CubeCoordinates = start + var cubecoord: HexGrid.CubeCoordinates = target - var cubetest: HexGrid.CubeCoordinates = map.axial_to_cube(HexGrid.AxialCoordinates.new(0, 0)) + var cubetest: HexGrid.CubeCoordinates = HexGrid.CubeCoordinates.new(0, 0, 0) cubetest.q = cubecoord.q - cubepos.q cubetest.r = cubecoord.r - cubepos.r cubetest.s = cubecoord.s - cubepos.s - var left = get_left_neighbour(Vector3i(cubetest.q, cubetest.r, cubetest.s)) - var right = get_right_neighbour(Vector3i(cubetest.q, cubetest.r, cubetest.s)) + var left = get_left_neighbour(cubetest) + var right = get_right_neighbour(cubetest) - var left_coord = map.cube_to_axial(HexGrid.CubeCoordinates.new(left.x + cubepos.q, left.y + cubepos.r, left.z + cubepos.s)) - var right_coord = map.cube_to_axial(HexGrid.CubeCoordinates.new(right.x + cubepos.q, right.y + cubepos.r, right.z + cubepos.s)) + var left_coord = HexGrid.CubeCoordinates.new(left.q + cubepos.q, left.r + cubepos.r, left.s + cubepos.s) + var right_coord = HexGrid.CubeCoordinates.new(right.q + cubepos.q, right.r + cubepos.r, right.s + cubepos.s) - return map.is_cell_empty(Vector2i(left_coord.q, left_coord.r)) or map.is_cell_empty(Vector2i(right_coord.q, right_coord.r)) + return map.is_cell_empty(left_coord) or map.is_cell_empty(right_coord) -func get_left_neighbour(pos: Vector3i) -> Vector3i: - return Vector3(-pos.z, -pos.x, -pos.y) +func get_left_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates: + return HexGrid.CubeCoordinates.new(-pos.s, -pos.q, -pos.r) -func get_right_neighbour(pos: Vector3i) -> Vector3i: - return Vector3(-pos.y, -pos.z, -pos.x) +func get_right_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates: + return HexGrid.CubeCoordinates.new(-pos.r, -pos.s, -pos.q) -func get_available_spaces(pos: Vector2i, map: HexGrid) -> Array[Vector2i]: +func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]: var potential_spaces = map.get_empty_neighbours(pos) - var target_spaces: Array[Vector2i] = [] + var target_spaces: Array[HexGrid.CubeCoordinates] = [] for neighbour in potential_spaces: if can_reach(pos, neighbour, map): diff --git a/Tile/Tile.gd b/Tile/Tile.gd index 3f821f3..fa02303 100644 --- a/Tile/Tile.gd +++ b/Tile/Tile.gd @@ -2,37 +2,142 @@ extends Area3D class_name InsectTile -@export var coordinates: Vector2i +var coordinates: HexGrid.CubeCoordinates +var layer: int = 0 + @export var is_black: bool = false @export var resource: TileResource @onready var hexagon_small = $HexagonSmall +var build_in_progress: bool = false +var move_in_progress: bool = false + var hovered: bool = false +var selected: bool = false + var hover_shader: ShaderMaterial = preload("res://InsectTiles/HoverShader.tres") +const SELECTION_FAILED_MAT: ShaderMaterial = preload("res://InsectTiles/SelectionFailedMat.tres") + var mat: StandardMaterial3D -func _ready() -> void: +var tween: Tween + +var tweening: bool = false + +func _ready() -> void: if is_black: hexagon_small.set_surface_override_material(0, resource.material_black.duplicate()) else: hexagon_small.set_surface_override_material(0, resource.material_white.duplicate()) mat = hexagon_small.get_surface_override_material(0) + + GameEvents.insect_tile_selection_request_failed.connect(_on_insect_tile_request_failed) + GameEvents.insect_tile_selection_request_successful.connect(_on_insect_tile_selection_request_sucessful) + GameEvents.insect_selected.connect(_on_insect_selected) + GameEvents.insect_placed.connect(_on_insect_placed) + GameEvents.insect_placement_cancelled.connect(_on_insect_placement_cancelled) + GameEvents.insect_tile_selected.connect(_on_insect_tile_selected) + GameEvents.insect_tile_deselected.connect(_on_insect_tile_deselected) + GameEvents.insect_tile_moved.connect(_on_insect_tile_moved) + +func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void: + move_in_progress = false + selected = false + + if tile == self: + hovered = false + if not tweening: + mat.next_pass = null + +func _on_insect_tile_deselected(tile: InsectTile) -> void: + move_in_progress = false + selected = false + +func _on_insect_tile_selected(tile: InsectTile) -> void: + move_in_progress = true + if tile == self: + selected = true + +func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: + build_in_progress = false + +func _on_insect_placement_cancelled() -> void: + build_in_progress = false + +func _on_insect_selected(resource: TileResource, is_black: bool) -> void: + build_in_progress = true + +func _on_insect_tile_selection_request_sucessful(tile: InsectTile) -> void: + if tile != self: + return + + GameEvents.insect_tile_selected.emit(self) + +func _tween_shader(value: Color) -> void: + var shader: ShaderMaterial = mat.next_pass + shader.set_shader_parameter("albedo", value) + pass + +func _shader_done() -> void: + tweening = false + + if hovered: + mat.next_pass = hover_shader + else: + mat.next_pass = null func _process(delta): if Input.is_action_just_pressed("place_tile"): - if hovered: - GameEvents.insect_tile_selected.emit(self) + if hovered and not (build_in_progress or move_in_progress): + # check if is movable, either with direct reference to the map, or by ping-ponging a signal + # request_selection + # selection_reguest_successfull + # selection_request_failed + + GameEvents.insect_tile_request_selection.emit(self) + +func _on_insect_tile_request_failed(tile) -> void: + move_in_progress = false + selected = false + + if tile != self: + return + + hovered = false + + # siomulate a failed selection request + mat.next_pass = SELECTION_FAILED_MAT + + tweening = true + + if tween != null: + tween.kill() + + tween = get_tree().create_tween() + tween.tween_method(_tween_shader, Color.BLACK, Color.DARK_RED, 0.1).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) + tween.tween_method(_tween_shader, Color.DARK_RED, Color.BLACK, 0.35).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) + tween.tween_callback(_shader_done) + + GameEvents.insect_tile_deselected.emit(self) func _on_mouse_entered(): + if build_in_progress or move_in_progress: + return + if GameData.is_player_black == is_black: - mat.next_pass = hover_shader + if tween == null: + mat.next_pass = hover_shader hovered = true func _on_mouse_exited(): + if selected: + return + hovered = false - mat.next_pass = null + if tween == null: + mat.next_pass = null diff --git a/export_presets.cfg b/export_presets.cfg index f29e133..a5f77a6 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -35,3 +35,66 @@ progressive_web_app/icon_144x144="" progressive_web_app/icon_180x180="" progressive_web_app/icon_512x512="" progressive_web_app/background_color=Color(0, 0, 0, 1) + +[preset.1] + +name="Windows Desktop" +platform="Windows Desktop" +runnable=true +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="" +export_path="" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false + +[preset.1.options] + +custom_template/debug="" +custom_template/release="" +debug/export_console_wrapper=1 +binary_format/embed_pck=false +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false +binary_format/architecture="x86_64" +codesign/enable=false +codesign/timestamp=true +codesign/timestamp_server_url="" +codesign/digest_algorithm=1 +codesign/description="" +codesign/custom_options=PackedStringArray() +application/modify_resources=true +application/icon="" +application/console_wrapper_icon="" +application/icon_interpolation=4 +application/file_version="" +application/product_version="" +application/company_name="" +application/product_name="" +application/file_description="" +application/copyright="" +application/trademarks="" +application/export_angle=0 +ssh_remote_deploy/enabled=false +ssh_remote_deploy/host="user@host_ip" +ssh_remote_deploy/port="22" +ssh_remote_deploy/extra_args_ssh="" +ssh_remote_deploy/extra_args_scp="" +ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}' +$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}' +$trigger = New-ScheduledTaskTrigger -Once -At 00:00 +$settings = New-ScheduledTaskSettingsSet +$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings +Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true +Start-ScheduledTask -TaskName godot_remote_debug +while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 } +Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue" +ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue +Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue +Remove-Item -Recurse -Force '{temp_dir}'"