From 11f8a71f522232f6f2d3daab37331c41a5bd014a Mon Sep 17 00:00:00 2001 From: Sch1nken Date: Thu, 14 Mar 2024 19:30:18 +0100 Subject: [PATCH] Refactored to use Vector4i. Added Spider/Grasshopper. TODO: Ant --- Globals/GameData.gd | 1 + Globals/GameEvents.gd | 5 +- HexGrid3D/HexGrid3D.gd | 413 ++++++++++-------- HexOutline.gd | 9 +- InsectButton.gd | 60 +-- InsectTiles/BuildGhost.gd | 2 + InsectTiles/HoverShader.tres | 2 +- InsectTiles/SelectionFailedMat.tres | 4 +- .../MovementBehaviourResource.gd | 2 +- .../Prefabs/MovementBehaviourAnt.gd | 36 ++ .../Prefabs/MovementBehaviourBee.gd | 33 +- .../Prefabs/MovementBehaviourGrasshopper.gd | 36 ++ .../Prefabs/MovementBehaviourSpider.gd | 36 ++ PlayerInventory.gd | 15 + Tile/Prefabs/Grasshopper.tres | 7 +- Tile/Prefabs/Spider.tres | 8 +- Tile/Tile.gd | 130 +++--- Tile/TileResource.gd | 3 + node_3d.tscn | 6 +- 19 files changed, 482 insertions(+), 326 deletions(-) create mode 100644 PlayerInventory.gd diff --git a/Globals/GameData.gd b/Globals/GameData.gd index 11eca81..0f2c495 100644 --- a/Globals/GameData.gd +++ b/Globals/GameData.gd @@ -1,3 +1,4 @@ extends Node var is_player_black: bool = false +var debug: bool = true diff --git a/Globals/GameEvents.gd b/Globals/GameEvents.gd index 0b82ac6..5e6ed0a 100644 --- a/Globals/GameEvents.gd +++ b/Globals/GameEvents.gd @@ -1,13 +1,10 @@ extends Node -signal insect_selected(insect_resource, is_black) +signal insect_selected(button, is_black) 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 33b5b2d..0d792c3 100644 --- a/HexGrid3D/HexGrid3D.gd +++ b/HexGrid3D/HexGrid3D.gd @@ -13,6 +13,13 @@ const DIR_ALL: Array[Vector3] = [DIR_N, DIR_NE, DIR_SE, DIR_S, DIR_SW, DIR_NW] #const size = Vector2(1, sqrt(3.0)/2.0) +# We can hover all of our tiles (will show on-hover shader) +# If we click on a placed tile, we do the following +# Check if we would split the hive -> deny selection +# Get possible movement tiles (via MovementBehaviour) +# If 0 -> Deny +# Filter remaining movement spots to not include hive-splitting moves(?) + const size: float = 0.5 var used_cells: Dictionary = {} @@ -26,30 +33,20 @@ class TileStorage: # we use a vector4i for coordinates # q r s y (layer) - func add_tile(tile: InsectTile, coords: CubeCoordinates, layer: int = 0) -> void: - tiles[Vector4i(coords.q, coords.r, coords.s, layer)] = tile + func add_tile(tile: InsectTile, coords: Vector4i) -> void: + tiles[coords] = tile pass - func remove_tile(coords: CubeCoordinates, layer: int = 0) -> void: + func remove_tile(coords: Vector4i) -> void: pass - func has_tile(coords: CubeCoordinates, layer: int = 0) -> bool: - return tiles.has(Vector4i(coords.q, coords.r, coords.s, layer)) + func has_tile(coords: Vector4i) -> bool: + return tiles.has(coords) - func get_tile(coords: CubeCoordinates, layer: int = 0) -> InsectTile: - return tiles[Vector4i(coords.q, coords.r, coords.s, layer)] + func get_tile(coords: Vector4i) -> InsectTile: + return tiles[coords] -class CubeCoordinates: - var q: float - var r: float - var s: float - - func _init(_q: float, _r: float, _s: float): - q = _q - r = _r - s = _s - class AxialCoordinates: var q: float var r: float @@ -68,7 +65,7 @@ func flat_hex_to_world_position(coords: AxialCoordinates) -> Vector2: 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: +func cube_to_world_pos(coords: Vector4i) -> Vector2: return flat_hex_to_world_position(cube_to_axial(coords)) #func world_to_hex_tile(world_pos: Vector3) -> Vector2: @@ -86,28 +83,28 @@ func world_to_hex_tile(coords: Vector2) -> AxialCoordinates: var r = (-1.0/3.0 * coords.x + sqrt(3.0)/3.0 * coords.y) / size return axial_round(AxialCoordinates.new(q, r)) -func axial_to_cube(coords: AxialCoordinates) -> CubeCoordinates: - var q = coords.q - var r = coords.r - var s = -q-r - return CubeCoordinates.new(q, r, s) - -func cube_to_axial(coords: CubeCoordinates) -> AxialCoordinates: - var q = coords.q - var r = coords.r +func cube_to_axial(coords: Vector4i) -> AxialCoordinates: + var q = coords.x + var r = coords.y return AxialCoordinates.new(q, r) func axial_round(coords: AxialCoordinates) -> AxialCoordinates: return cube_to_axial(cube_round(axial_to_cube(coords))) -func cube_round(coords: CubeCoordinates) -> CubeCoordinates: - var q: float = round(coords.q) - var r: float = round(coords.r) - var s: float = round(coords.s) +func axial_to_cube(coords: AxialCoordinates) -> Vector4i: + var q = coords.q + var r = coords.r + var s = -q-r + return Vector4i(q, r, s, 0) + +func cube_round(coords: Vector4i) -> Vector4i: + var q: float = round(coords.x) + var r: float = round(coords.y) + var s: float = round(coords.z) - var q_diff: float = abs(q - coords.q) - var r_diff: float = abs(r - coords.r) - var s_diff: float = abs(s - coords.s) + var q_diff: float = abs(q - coords.x) + var r_diff: float = abs(r - coords.y) + var s_diff: float = abs(s - coords.z) if q_diff > r_diff and q_diff > s_diff: q = -r-s @@ -116,7 +113,7 @@ func cube_round(coords: CubeCoordinates) -> CubeCoordinates: else: s = -q-r - return CubeCoordinates.new(q, r, s) + return Vector4i(q, r, s, 0) @export var dragging_intersect_plane_normal: Vector3 = Vector3.UP @export var dragging_intersect_plane_distance: float = 0.0 @@ -126,105 +123,173 @@ func get_3d_pos(position2D: Vector2): var placements: Dictionary = {} -func is_cell_empty(coords: CubeCoordinates) -> bool: - return !used_cells.has(Vector4i(coords.q, coords.r, coords.s, 0)) +func is_cell_empty(coords: Vector4i) -> bool: + return !used_cells.has(coords) -func is_cell_not_empty(coords: CubeCoordinates) -> bool: +func is_cell_not_empty(coords: Vector4i) -> bool: return !is_cell_empty(coords) -func get_empty_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]: +func get_empty_neighbours(coords: Vector4i) -> Array[Vector4i]: return get_neighbours(coords).filter(is_cell_empty) -func get_neighbours(coords: CubeCoordinates) -> Array[CubeCoordinates]: +func get_neighbours(coords: Vector4i) -> Array[Vector4i]: return [ - 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) + Vector4i(coords.x + 1, coords.y, coords.z - 1, coords.w), + Vector4i(coords.x + 1, coords.y - 1, coords.z, coords.w), + Vector4i(coords.x, coords.y - 1, coords.z + 1, coords.w), + Vector4i(coords.x - 1, coords.y, coords.z + 1, coords.w), + Vector4i(coords.x - 1, coords.y + 1, coords.z, coords.w), + Vector4i(coords.x, coords.y + 1, coords.z - 1, coords.w) ] var current_tile: Node3D const HEX_OUTLINE = preload("res://hex_outline.tscn") -func _on_insect_selected(insect_resource: TileResource, is_black: bool) -> void: +func get_placeable_positions(button: InsectButton) -> Array: + if used_cells.size() == 0: + return [Vector4i.ZERO] + elif used_cells.size() == 1: + var single_cell = used_cells.keys().front() + var neighbours = get_neighbours(single_cell) + var positions = [] + + for neighbour in neighbours: + #var hex_pos = cube_to_world_pos(neighbour) + positions.push_back(neighbour) + return positions + + var possible_placements: Dictionary = {} + var positions = [] + + for hex in used_cells.keys(): + for neighbour in get_empty_neighbours(hex): + if not used_cells.has(neighbour): + possible_placements[neighbour] = true + + for p in possible_placements: + var eligible: bool = true + + for neighbour in get_neighbours(p): + if not used_cells.has(neighbour): + continue + + if used_cells[neighbour].is_black != button.is_black: + eligible = false + break + + if eligible: + positions.push_back(p) + + return positions + + +func get_left_neighbour(pos: Vector4i) -> Vector4i: + return Vector4i(-pos.z, -pos.x, -pos.y, 0) + +func get_right_neighbour(pos: Vector4i) -> Vector4i: + return Vector4i(-pos.y, -pos.z, -pos.x, 0) + +func can_reach(start: Vector4i, target: Vector4i) -> bool: + # if we have 5 potential spaces it can never be blocked + var offset: Vector4i = Vector4i.ZERO + + offset.x = target.x - start.x + offset.y = target.y - start.y + offset.z = target.z - start.z + + var left = get_left_neighbour(offset) + var right = get_right_neighbour(offset) + + var left_coord = Vector4i(left.x + start.x, left.y + start.y, left.z + start.z, 0) + var right_coord = Vector4i(right.x + start.x, right.y + start.y, right.z + start.z, 0) + + return is_cell_empty(left_coord) or is_cell_empty(right_coord) + +func _on_insect_selected(button: InsectButton, is_black: bool) -> void: + var positions = get_placeable_positions(button) + for p in positions: + var outline = HEX_OUTLINE.instantiate() + var hex_pos = cube_to_world_pos(p) + outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) + outline.visible = true + outline.insect_resource = button.insect_resource + outline.is_black = is_black + outline.coordinates = p + outline.map_reference = self + placement_visualizer.add_child(outline) + #placements[p] = outline + # create a hexagon with insect resource data #var tile = INSECT_TILE.instantiate() #tile.resource = insect_resource #tile.is_black = is_black #current_tile = tile #add_child(tile) - - # 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 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.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(CubeCoordinates.new(single_cell.x, single_cell.y, single_cell.z)) - for neighbour in neighbours: - var outline = HEX_OUTLINE.instantiate() - var hex_pos = cube_to_world_pos(neighbour) - outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - 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: - # iterate over all used_cells, get all empty cells surrounding those cells - # iterate over all those empty cells, check if they only neighbour the same color - var possible_placements: Dictionary = {} - - for hex in used_cells.keys(): + #var insect_resource: TileResource = button.insect_resource + # + ## 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 cubepos = Vector4i.new(0, 0, 0) + #var hex_pos = cube_to_world_pos(cubepos) + #outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) + #outline.visible = true + #outline.insect_resource = insect_resource + #outline.is_black = is_black + #outline.coordinates = cubepos + #outline.map_reference = self + #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(Vector4i.new(single_cell.x, single_cell.y, single_cell.z)) + #for neighbour in neighbours: + #var outline = HEX_OUTLINE.instantiate() + #var hex_pos = cube_to_world_pos(neighbour) + #outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) + #outline.visible = true + #outline.insect_resource = insect_resource + #outline.is_black = is_black + #outline.coordinates = neighbour + #outline.map_reference = self + #placement_visualizer.add_child(outline) + #placements[hex_pos] = outline + #else: + ## iterate over all used_cells, get all empty cells surrounding those cells + ## iterate over all those empty cells, check if they only neighbour the same color + #var possible_placements: Dictionary = {} + # + #for hex in used_cells.keys(): + ##var eligible: bool = true + #for neighbour in get_empty_neighbours(Vector4i.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 eligible: bool = 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 eligible: bool = true - - 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[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 = cube_to_world_pos(CubeCoordinates.new(p.x, p.y, p.z)) - outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - 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 - - pass - - pass + # + #for neighbour in get_neighbours(Vector4i.new(p.x, p.y, p.z)): + #if not used_cells.has(Vector4i(neighbour.q, neighbour.r, neighbour.s, 0)): + #continue + # + #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 = cube_to_world_pos(Vector4i.new(p.x, p.y, p.z)) + #outline.position = Vector3(hex_pos.x, 0.0, hex_pos.y) + #outline.visible = true + #outline.insect_resource = insect_resource + #outline.is_black = is_black + #outline.coordinates = Vector4i.new(p.x, p.y, p.z) + #outline.map_reference = self + #placement_visualizer.add_child(outline) + #placements[p] = outline func _on_insect_placement_cancelled() -> void: if current_tile: @@ -234,7 +299,7 @@ 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: CubeCoordinates) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void: var tile_copy = INSECT_TILE.instantiate() var hex_pos = cube_to_world_pos(pos) @@ -242,41 +307,42 @@ func _on_insect_placed(resource: TileResource, is_black: bool, pos: CubeCoordina tile_copy.resource = resource tile_copy.is_black = is_black tile_copy.coordinates = pos + tile_copy.map_reference = self var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y) - used_cells[Vector4i(pos.q, pos.r, pos.s, 0)] = tile_copy + used_cells[pos] = tile_copy add_child(tile_copy) var tween = get_tree().create_tween() tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO) +func can_move(tile: InsectTile) -> bool: + return can_hive_exist_without_tile(tile) + +func create_move_positions() -> void: + pass + func _on_insect_tile_selected(tile: InsectTile) -> void: + if not can_hive_exist_without_tile(tile): + return + if tile.resource.movement_behaviour == null: return 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) + #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: + if occupied_neighbour == tile.coordinates: continue var outline = HEX_OUTLINE.instantiate() @@ -292,8 +358,8 @@ func _on_insect_tile_selected(tile: InsectTile) -> void: placements[space] = outline -func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void: - used_cells.erase(Vector4i(tile.coordinates.q, tile.coordinates.r, tile.coordinates.s, 0)) +func _on_insect_tile_moved(tile: InsectTile, target: Vector4i) -> void: + used_cells.erase(tile.coordinates) 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) @@ -309,19 +375,34 @@ func _on_insect_tile_moved(tile: InsectTile, target: CubeCoordinates) -> void: tile.coordinates = target - used_cells[Vector4i(target.q, target.r, target.s, 0)] = tile + used_cells[tile.coordinates] = tile + +func get_same_neighbours(cell1: Vector4i, cell2: Vector4i) -> Array[Vector4i]: + var neighbours1 = get_neighbours(cell1).filter(is_cell_not_empty) + var neighbours2 = get_neighbours(cell2).filter(is_cell_not_empty) + + var shared_neighbours: Array[Vector4i] = [] + + for n1 in neighbours1: + for n2 in neighbours2: + if n1 == n2: + if n1 not in shared_neighbours: + shared_neighbours.push_back(n1) + + return shared_neighbours + +func is_position_on_hive(pos: Vector4i) -> bool: + return get_empty_neighbours(pos).size() > 0 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) + var tiles_available: Array = used_cells.keys().filter(func(coords): return coords != tile.coordinates) if tiles_available.size() <= 1: # If we only have 1 or 2 total tiles, we can always move @@ -338,65 +419,17 @@ func can_hive_exist_without_tile(tile: InsectTile) -> bool: 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) + for neighbour in get_neighbours(m): + if neighbour not in tiles_reached and neighbour != tile.coordinates: + if used_cells.has(neighbour): + tiles_reached.push_back(neighbour) + queue.push_back(neighbour) 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) GameEvents.insect_placement_cancelled.connect(_on_insect_placement_cancelled) 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) - -#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))) -# - #tile_copy.position = Vector3(hex_pos.x, 20.0, hex_pos.y) - #var target_pos = Vector3(hex_pos.x, 0.0, hex_pos.y) - # - #add_child(tile_copy) - # - #var tween = get_tree().create_tween() - #tween.tween_property(tile_copy, "position", target_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO) - # -#func move_tile_to_random_position() -> void: - #var new_hex_pos = flat_hex_to_world_position(AxialCoordinates.new(randi_range(-20, 20), randi_range(-20, 20))) - #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) - # - #var current_hex_pos = hex.position - #var sky_current_hex_pos = hex.position + Vector3(0.0, 20.0, 0.0) -# - #var tween = get_tree().create_tween() - #tween.tween_property(hex, "position", sky_current_hex_pos, 0.5).set_ease(Tween.EASE_IN).set_trans(Tween.TRANS_EXPO) - #tween.tween_property(hex, "position", sky_new_hex_pos, 0.0) - #tween.tween_property(hex, "position", ground_new_hex_pos, 1.0).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_EXPO) - -func _process(delta) -> void: - #if Input.is_action_just_pressed("ui_accept"): - # print("yay") - # spawn_random_tile() - return - - if current_tile == null: - return - - #var pos3d = get_3d_pos(get_viewport().get_mouse_position()) - #if pos3d: - #var hex_pos = flat_hex_to_world_position(world_to_hex_tile(Vector2(pos3d.x, pos3d.z))) - #current_tile.position = Vector3(hex_pos.x, 0.0, hex_pos.y) - #coord_label.text = "%d, %d" % [hex_pos.x, hex_pos.y] diff --git a/HexOutline.gd b/HexOutline.gd index cac9715..0e43021 100644 --- a/HexOutline.gd +++ b/HexOutline.gd @@ -2,7 +2,7 @@ extends Area3D var hovered: bool = false -var coordinates: HexGrid.CubeCoordinates +var coordinates: Vector4i var insect_resource: TileResource var is_black: bool = false @@ -13,6 +13,8 @@ var tile: Node3D var is_moving: bool = false +var map_reference: HexGrid + const BUILD_GHOST = preload("res://InsectTiles/BuildGhost.tscn") # Called when the node enters the scene tree for the first time. func _ready(): @@ -25,10 +27,10 @@ func _ready(): else: GameEvents.insect_placed.connect(_on_insect_placed) -func _on_insect_tile_moved(tile: InsectTile, to: HexGrid.CubeCoordinates) -> void: +func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void: queue_free() -func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void: queue_free() # Called every frame. 'delta' is the elapsed time since the previous frame. @@ -46,6 +48,7 @@ func _on_mouse_entered(): tile = BUILD_GHOST.instantiate() tile.resource = insect_resource tile.is_black = is_black + tile.map_reference = map_reference add_child(tile) diff --git a/InsectButton.gd b/InsectButton.gd index 7552de9..740e0b3 100644 --- a/InsectButton.gd +++ b/InsectButton.gd @@ -1,4 +1,5 @@ extends TextureButton +class_name InsectButton @onready var hex = $Hex @onready var tile_count_label = $Hex/TileCountLabel @@ -45,30 +46,24 @@ func enable() -> void: func _on_placement_cancelled() -> void: - selected = false + refresh_state() + +func _on_insect_placed(resource: TileResource, _is_black: bool, pos: Vector4i) -> void: + refresh_state() - if not is_empty(): - enable() + if insect_resource == resource and _is_black == is_black: + decrement_tile_count() - if hovered and not is_empty(): - hover() - else: - unhover() - -func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: +func refresh_state() -> void: selected = false if not is_empty(): enable() - if hovered and not is_empty(): + if hovered and not is_empty(): hover() else: unhover() - - if insect_resource == resource: - decrement_tile_count() - # Called when the node enters the scene tree for the first time. func _ready() -> void: @@ -78,33 +73,40 @@ func _ready() -> void: update_tile_count_display() insect_icon.texture = insect_resource.ui_texture - if is_black != GameData.is_player_black: - #disabled = true - #return - pass + if is_black != GameData.is_player_black and not GameData.debug: + disabled = true + return GameEvents.insect_selected.connect(_on_insect_selected) GameEvents.insect_placement_cancelled.connect(_on_placement_cancelled) 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_deselected.connect(_on_insect_tile_deselected) + +func _on_insect_tile_deselected(tile: InsectTile) -> void: + refresh_state() -func _on_insect_selected(_resource: TileResource, _is_black: bool) -> void: - if _resource != insect_resource: +func _on_insect_tile_selected(tile: InsectTile) -> void: + disable() + +func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void: + refresh_state() + +func _on_insect_selected(button: InsectButton, _is_black: bool) -> void: + if button != self: disable() - pass - func hover() -> void: - if GameData.is_player_black != is_black: - pass - #return + if GameData.is_player_black != is_black and not GameData.debug: + return var tween = get_tree().create_tween() tween.tween_property(hex, "position", Vector2(0, -16), 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING) func unhover() -> void: - if GameData.is_player_black != is_black: - pass - #return + if GameData.is_player_black != is_black and not GameData.debug: + return var tween = get_tree().create_tween() tween.tween_property(hex, "position", Vector2(0, 0), 0.25).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING) @@ -127,7 +129,7 @@ func _on_pressed(): selected = true - GameEvents.insect_selected.emit(insect_resource, is_black) + GameEvents.insect_selected.emit(self, is_black) release_focus() diff --git a/InsectTiles/BuildGhost.gd b/InsectTiles/BuildGhost.gd index 9a2148f..9d0b800 100644 --- a/InsectTiles/BuildGhost.gd +++ b/InsectTiles/BuildGhost.gd @@ -4,6 +4,8 @@ extends Area3D @export var is_black: bool = false @export var resource: TileResource +var map_reference: HexGrid + @onready var hexagon_small = $HexagonSmall func _ready() -> void: diff --git a/InsectTiles/HoverShader.tres b/InsectTiles/HoverShader.tres index 1d737b1..f49de4d 100644 --- a/InsectTiles/HoverShader.tres +++ b/InsectTiles/HoverShader.tres @@ -6,6 +6,6 @@ render_priority = 0 shader = ExtResource("1_pk3ok") shader_parameter/albedo = Color(0, 0, 0, 1) -shader_parameter/emission_color = Color(0, 0, 0, 1) +shader_parameter/emission_color = Color(0, 0, 0, 0) shader_parameter/emission_amount = 5.0 shader_parameter/rim_steepness = 0.214 diff --git a/InsectTiles/SelectionFailedMat.tres b/InsectTiles/SelectionFailedMat.tres index 835b80d..4d4fcc8 100644 --- a/InsectTiles/SelectionFailedMat.tres +++ b/InsectTiles/SelectionFailedMat.tres @@ -5,7 +5,7 @@ [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/albedo = Color(0, 0, 0, 0) +shader_parameter/emission_color = Color(0, 0, 0, 0) shader_parameter/emission_amount = 5.0 shader_parameter/rim_steepness = 0.214 diff --git a/MovementBehaviour/MovementBehaviourResource.gd b/MovementBehaviour/MovementBehaviourResource.gd index 77d806d..45132e5 100644 --- a/MovementBehaviour/MovementBehaviourResource.gd +++ b/MovementBehaviour/MovementBehaviourResource.gd @@ -1,5 +1,5 @@ extends Resource class_name MovementBehaviour -func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]: +func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]: return [] diff --git a/MovementBehaviour/Prefabs/MovementBehaviourAnt.gd b/MovementBehaviour/Prefabs/MovementBehaviourAnt.gd index 136015b..de60368 100644 --- a/MovementBehaviour/Prefabs/MovementBehaviourAnt.gd +++ b/MovementBehaviour/Prefabs/MovementBehaviourAnt.gd @@ -1,2 +1,38 @@ extends MovementBehaviour class_name MovementBehaviourAnt + +# Ant uses a modified BFS? It's basically a supercharged spider with limitlesss movement range +# Naive approach: BFS from all neighbours, don't go to already visited cells, check if can reach +# Maybe better: Get al "placecable tiles" from the map, go over those. Might be faster but more complicated + +func simulate_move_recursive(start: Vector4i, exclude: Array[Vector4i], map: HexGrid, visited_cells: Array[Vector4i] = []) -> Array[Vector4i]: + var visited = visited_cells + var possible: Array[Vector4i] = [] + + #if max_num < 1: + # return [start] + + for neighbour in map.get_empty_neighbours(start): + if neighbour in visited: + continue + + if not map.can_reach(start, neighbour): + continue + + var same_neighbours = map.get_same_neighbours(start, neighbour) + for e in exclude: + same_neighbours.erase(e) + + if same_neighbours.size() > 0: + visited.append(neighbour) + print("yay?") + possible.append_array(simulate_move_recursive(neighbour, exclude, map, visited)) + + return possible + +func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]: + var possible_places: Array[Vector4i] = [] + + possible_places = simulate_move_recursive(pos, [pos], map) + + return possible_places diff --git a/MovementBehaviour/Prefabs/MovementBehaviourBee.gd b/MovementBehaviour/Prefabs/MovementBehaviourBee.gd index 94bc6d9..c821460 100644 --- a/MovementBehaviour/Prefabs/MovementBehaviourBee.gd +++ b/MovementBehaviour/Prefabs/MovementBehaviourBee.gd @@ -1,38 +1,13 @@ extends MovementBehaviour class_name MovementBehaviourBee -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 = start - var cubecoord: HexGrid.CubeCoordinates = target - - 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(cubetest) - var right = get_right_neighbour(cubetest) - - 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(left_coord) or map.is_cell_empty(right_coord) - -func get_left_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates: - return HexGrid.CubeCoordinates.new(-pos.s, -pos.q, -pos.r) - -func get_right_neighbour(pos: HexGrid.CubeCoordinates) -> HexGrid.CubeCoordinates: - return HexGrid.CubeCoordinates.new(-pos.r, -pos.s, -pos.q) - -func get_available_spaces(pos: HexGrid.CubeCoordinates, map: HexGrid) -> Array[HexGrid.CubeCoordinates]: +func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]: var potential_spaces = map.get_empty_neighbours(pos) - var target_spaces: Array[HexGrid.CubeCoordinates] = [] + var target_spaces: Array[Vector4i] = [] - for neighbour in potential_spaces: - if can_reach(pos, neighbour, map): + for neighbour in potential_spaces: + if map.can_reach(pos, neighbour): target_spaces.append(neighbour) return target_spaces diff --git a/MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd b/MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd index 554953e..7b413d0 100644 --- a/MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd +++ b/MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd @@ -1,2 +1,38 @@ extends MovementBehaviour class_name MovementBehaviourGrasshopper + +const DIRS = [ + Vector4i(0, -1, +1, 0), #UP + Vector4i(-1, 0, +1, 0), #UP_LEFT + Vector4i(-1, +1, 0, 0), #DOWN_LEFT + Vector4i(0, +1, -1, 0), #DOWN + Vector4i(+1, 0, -1, 0), #DOWN_RIGHT + Vector4i(+1, -1, 0, 0), #UP_RIGHT +] + +func simulate_move_dirs(start: Vector4i, map: HexGrid) -> Array[Vector4i]: + var possible: Array[Vector4i] = [] + for dir in DIRS: + possible.push_back(simulate_move_recursive(start, dir, map)) + + return possible + +func simulate_move_recursive(start: Vector4i, dir: Vector4i, map: HexGrid) -> Vector4i: + var possible: Array[Vector4i] = [] + + var target: Vector4i = start + dir + + if map.is_cell_empty(target): + return target + + return simulate_move_recursive(target, dir, map) + +func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]: + var possible_places: Array[Vector4i] = [] + + possible_places = simulate_move_dirs(pos, map) + + for neighbour in map.get_empty_neighbours(pos): + possible_places.erase(neighbour) + + return possible_places diff --git a/MovementBehaviour/Prefabs/MovementBehaviourSpider.gd b/MovementBehaviour/Prefabs/MovementBehaviourSpider.gd index fd97403..2e29953 100644 --- a/MovementBehaviour/Prefabs/MovementBehaviourSpider.gd +++ b/MovementBehaviour/Prefabs/MovementBehaviourSpider.gd @@ -1,2 +1,38 @@ extends MovementBehaviour class_name MovementBehaviourSpider + +@export var max_movement_reach: int = 3 + +func simulate_move_recursive(start: Vector4i, max_num: int, exclude: Array[Vector4i], map: HexGrid, visited_cells: Array[Vector4i] = []) -> Array[Vector4i]: + var visited = visited_cells.duplicate() + var possible: Array[Vector4i] = [] + + visited.append(start) + + if max_num < 1: + return [start] + + for neighbour in map.get_empty_neighbours(start): + if neighbour in visited: + continue + + if not map.can_reach(start, neighbour): + continue + + var same_neighbours = map.get_same_neighbours(start, neighbour) + for e in exclude: + same_neighbours.erase(e) + + if same_neighbours.size() > 0: + visited.append(neighbour) + print("yay?") + possible.append_array(simulate_move_recursive(neighbour, max_num - 1, exclude, map, visited)) + + return possible + +func get_available_spaces(pos: Vector4i, map: HexGrid) -> Array[Vector4i]: + var possible_places: Array[Vector4i] = [] + + possible_places = simulate_move_recursive(pos, max_movement_reach, [pos], map) + + return possible_places diff --git a/PlayerInventory.gd b/PlayerInventory.gd new file mode 100644 index 0000000..7244974 --- /dev/null +++ b/PlayerInventory.gd @@ -0,0 +1,15 @@ +extends HBoxContainer + + +var available_insects: Array[TileResource] = [] + +# Called when the node enters the scene tree for the first time. +func _ready() -> void: + # create all neccessary buttons for the inventory + # when an insect gets placed, we can check it here and + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta: float) -> void: + pass diff --git a/Tile/Prefabs/Grasshopper.tres b/Tile/Prefabs/Grasshopper.tres index 51296c5..7250797 100644 --- a/Tile/Prefabs/Grasshopper.tres +++ b/Tile/Prefabs/Grasshopper.tres @@ -1,13 +1,18 @@ -[gd_resource type="Resource" script_class="TileResource" load_steps=5 format=3 uid="uid://chuci1mu106hs"] +[gd_resource type="Resource" script_class="TileResource" load_steps=7 format=3 uid="uid://chuci1mu106hs"] [ext_resource type="Material" uid="uid://tbfvmxogabnr" path="res://InsectTiles/Materials/Grasshopper_Black.tres" id="1_vut3o"] [ext_resource type="Material" uid="uid://csuox1kvmm78p" path="res://InsectTiles/Materials/Grasshopper_White.tres" id="2_gc341"] [ext_resource type="Script" path="res://Tile/TileResource.gd" id="3_t3kan"] +[ext_resource type="Script" path="res://MovementBehaviour/Prefabs/MovementBehaviourGrasshopper.gd" id="3_tid3l"] [ext_resource type="Texture2D" uid="uid://dhnrq0gxmv7cr" path="res://InsectTiles/Assets/UI/grasshopper.png" id="4_tpusd"] +[sub_resource type="Resource" id="Resource_ynqk8"] +script = ExtResource("3_tid3l") + [resource] script = ExtResource("3_t3kan") tile_name = "Grasshopper" +movement_behaviour = SubResource("Resource_ynqk8") material_black = ExtResource("1_vut3o") material_white = ExtResource("2_gc341") ui_texture = ExtResource("4_tpusd") diff --git a/Tile/Prefabs/Spider.tres b/Tile/Prefabs/Spider.tres index ebbf836..1b7a804 100644 --- a/Tile/Prefabs/Spider.tres +++ b/Tile/Prefabs/Spider.tres @@ -1,13 +1,19 @@ -[gd_resource type="Resource" script_class="TileResource" load_steps=5 format=3 uid="uid://dhvfn1adyay8i"] +[gd_resource type="Resource" script_class="TileResource" load_steps=7 format=3 uid="uid://dhvfn1adyay8i"] [ext_resource type="Material" uid="uid://csjte7l8m4gwp" path="res://InsectTiles/Materials/Spider_Black.tres" id="1_htbqr"] [ext_resource type="Material" uid="uid://dh2ehs3h106sb" path="res://InsectTiles/Materials/Spider_White.tres" id="2_ji24g"] +[ext_resource type="Script" path="res://MovementBehaviour/Prefabs/MovementBehaviourSpider.gd" id="3_8daio"] [ext_resource type="Script" path="res://Tile/TileResource.gd" id="3_semk6"] [ext_resource type="Texture2D" uid="uid://bgyve5fappdn5" path="res://InsectTiles/Assets/UI/spider.png" id="4_e73ch"] +[sub_resource type="Resource" id="Resource_pm2yd"] +script = ExtResource("3_8daio") +max_movement_reach = 3 + [resource] script = ExtResource("3_semk6") tile_name = "Spider" +movement_behaviour = SubResource("Resource_pm2yd") material_black = ExtResource("1_htbqr") material_white = ExtResource("2_ji24g") ui_texture = ExtResource("4_e73ch") diff --git a/Tile/Tile.gd b/Tile/Tile.gd index fa02303..6147fc2 100644 --- a/Tile/Tile.gd +++ b/Tile/Tile.gd @@ -1,8 +1,10 @@ extends Area3D class_name InsectTile +var map_reference: HexGrid -var coordinates: HexGrid.CubeCoordinates + +var coordinates: Vector4i var layer: int = 0 @export var is_black: bool = false @@ -10,9 +12,14 @@ var layer: int = 0 @onready var hexagon_small = $HexagonSmall +var hat: InsectTile = null + var build_in_progress: bool = false var move_in_progress: bool = false + +var deactivated: bool = false + var hovered: bool = false var selected: bool = false @@ -35,16 +42,17 @@ func _ready() -> void: 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) + mat.next_pass = hover_shader.duplicate() + 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_placement_cancelled.connect(_on_insect_placement_cancelled, CONNECT_DEFERRED) 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: + +func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void: move_in_progress = false selected = false @@ -62,82 +70,78 @@ func _on_insect_tile_selected(tile: InsectTile) -> void: if tile == self: selected = true -func _on_insect_placed(resource: TileResource, is_black: bool, pos: HexGrid.CubeCoordinates) -> void: +func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> 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: +func _on_insect_selected(button: InsectButton, 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 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 + if deactivated: + return - hovered = false + if not hovered: + return + + ## Check with map if we can be placed + #if not map_reference.can_move(self): + #return + # + # + #if resource.movement_behaviour == null: + ## TODO: Play fail animation/tween + #return + # + #var spaces = resource.movement_behaviour.get_available_spaces(coordinates, map_reference) + # + #if spaces.is_empty(): + ##GameEvents.insect_tile_selection_request_failed.emit(tile) + #return + + + GameEvents.insect_tile_selected.emit(self) + +func hover() -> void: + #if GameData.is_player_black != is_black: + #return - # 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) + #tween.tween_property(self, "position", Vector3(0, 0, 5), 0.5).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING) + tween.tween_method(tween_hover_shader, Color(0, 0, 0, 0), Color(0, 0, 0, 1), 0.1).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) + + +func tween_hover_shader(color: Color) -> void: + if mat.next_pass != null: + mat.next_pass.set_shader_parameter("albedo", color) + mat.next_pass.set_shader_parameter("emission_color", color) - GameEvents.insect_tile_deselected.emit(self) +func unhover() -> void: + #if GameData.is_player_black != is_black: + #return + + if tween != null: + tween.kill() + + tween = get_tree().create_tween() + #tween.tween_property(hex, "position", Vector2(0, -16), 0.1).set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_SPRING) + tween.tween_method(tween_hover_shader, Color(0, 0, 0, 1), Color(0, 0, 0, 0), 0.25).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) + func _on_mouse_entered(): - if build_in_progress or move_in_progress: - return + hovered = true + + if not deactivated: + hover() - if GameData.is_player_black == is_black: - if tween == null: - mat.next_pass = hover_shader - hovered = true - func _on_mouse_exited(): - if selected: - return - hovered = false - if tween == null: - mat.next_pass = null + if not selected: + unhover() diff --git a/Tile/TileResource.gd b/Tile/TileResource.gd index 7cf6107..45f9ee0 100644 --- a/Tile/TileResource.gd +++ b/Tile/TileResource.gd @@ -8,3 +8,6 @@ class_name TileResource @export var material_white: StandardMaterial3D @export var ui_texture: Texture2D + +func _to_string() -> String: + return tile_name diff --git a/node_3d.tscn b/node_3d.tscn index ac5e848..e0b63e7 100644 --- a/node_3d.tscn +++ b/node_3d.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=18 format=3 uid="uid://bx0bbrwdr0h40"] +[gd_scene load_steps=19 format=3 uid="uid://bx0bbrwdr0h40"] [ext_resource type="Script" path="res://HexGrid3D/HexGrid3D.gd" id="2_xcbqy"] [ext_resource type="Script" path="res://WebLightChecker.gd" id="6_uu0ab"] [ext_resource type="Texture2D" uid="uid://cilgpyanfb3a8" path="res://Testbed/textures/wood_table_001_diff_4k.jpg" id="6_x76sf"] [ext_resource type="Texture2D" uid="uid://diamo44e2x4if" path="res://Testbed/textures/wood_table_001_disp_4k.png" id="7_xr322"] +[ext_resource type="Script" path="res://PlayerInventory.gd" id="8_kqchc"] [ext_resource type="Script" path="res://BuildMenu.gd" id="8_lxt1e"] [ext_resource type="Texture2D" uid="uid://b6ejmikbfrprs" path="res://Testbed/textures/wood_table_001_rough_4k.jpg" id="8_wvt2u"] [ext_resource type="PackedScene" uid="uid://bo8hgq66dbbb6" path="res://UI/insect_button.tscn" id="11_pmmaq"] @@ -82,7 +83,7 @@ camera_attributes = SubResource("CameraAttributesPractical_41x5h") [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] transform = Transform3D(0.843961, -0.46784, 0.262404, -0.0775016, 0.377705, 0.922677, -0.530777, -0.79904, 0.28251, 0.262159, 3.27869, -0.104568) -light_color = Color(1, 0.803922, 0.631373, 1) +light_color = Color(1, 0.941176, 0.823529, 1) shadow_enabled = true directional_shadow_blend_splits = true script = ExtResource("6_uu0ab") @@ -148,6 +149,7 @@ alignment = 1 [node name="LocalPlayerInsects" type="HBoxContainer" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2"] layout_mode = 2 mouse_filter = 0 +script = ExtResource("8_kqchc") [node name="InsectButton" parent="BuildMenu/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2/LocalPlayerInsects" instance=ExtResource("11_pmmaq")] layout_mode = 2