extends Area3D class_name InsectTile var map_reference: HexGrid var is_blacks_turn: bool = false var coordinates: Vector4i @export var is_black: bool = false @export var resource: TileResource var temporary_resource: TileResource = null @onready var hexagon_small = $HexagonSmall var hat: InsectTile = null var deactivated: bool = false var hovered: bool = false var selected: bool = false var hover_shader: ShaderMaterial = preload("res://InsectTiles/HoverShader.tres") var mat: StandardMaterial3D var tween: Tween var selected_for_action: bool = false var action_callback: Callable = Callable() var can_be_selected: bool = false var move_round_penalty: int = 0 func get_action_behaviour() -> ActionBehaviour: if temporary_resource == null: return resource.action_behaviour return temporary_resource.action_behaviour func get_movement_behaviour() -> MovementBehaviour: if temporary_resource == null: return resource.movement_behaviour return temporary_resource.movement_behaviour func get_resource() -> TileResource: if temporary_resource == null: return resource return temporary_resource func is_in_stack() -> bool: return hat != null or coordinates.w != 0 func can_move() -> bool: # if any tile gets moved, set move_round_penalty to 2 # on turn start subtract 1 # we can't move if its 1, so we have to wait an additional round # this is ued for the pillbug ability # also if we move, we also set it to 2 return move_round_penalty == 0 func is_players_turn() -> bool: return is_blacks_turn == is_black # Have a functions that checks if we're the "owner" func is_owner() -> bool: # TODO: Only use multiplayer authority # According to https://docs.godotengine.org/en/stable/classes/class_offlinemultiplayerpeer.html # Even without active multiplayer, the normal calls just work as expected #if GameData.is_hot_seat: # return true #elif GameData.is_player_black == is_black: # we could use multiplayer authority here # return true #return false return is_multiplayer_authority() 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) mat.next_pass = hover_shader.duplicate() if is_black: hexagon_small.rotation.y = PI GameEvents.insect_selected.connect(_on_insect_selected) GameEvents.insect_tile_selecetion_failed.connect(_on_selection_failed) 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) #GameEvents.insect_tiles_selected_for_action.connect(_on_tiles_selected_for_action) GameEvents.insect_action_cancelled.connect(_on_action_cancelled) GameEvents.turn_started.connect(_on_turn_started) func _on_action_cancelled() -> void: selected_for_action = false selected = false action_callback = Callable() if hovered: hover() else: if tween != null: tween.kill() tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(1, 1, 1, 0), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) func _on_selection_failed(tile: InsectTile) -> void: if tile != self: return # Show selection failed mat func _on_turn_started(turn_num: int, map: HexGrid, _is_blacks_turn: bool) -> void: is_blacks_turn = _is_blacks_turn move_round_penalty -= 1 if move_round_penalty < 0: move_round_penalty = 0 can_be_selected = GameData.bees_placed.has(is_black) #print(GameData.has_bee_been_placed) if turn_num >= 7 and not GameData.bees_placed.has(is_black): can_be_selected = false if can_be_selected: tween_normal() else: tween_disabled() func tween_disabled() -> void: if tween != null: tween.kill() tween = get_tree().create_tween() tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(0, 0, 0, 1), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) func tween_normal() -> void: if tween != null: tween.kill() tween = get_tree().create_tween() tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(1, 1, 1, 0), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) func highlight_for_action() -> void: selected_for_action = true if tween != null: tween.kill() tween = get_tree().create_tween() #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_shader, Color(0, 0.6, 0, 0), Color(0, 0.6, 0, 0.8), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) func _on_insect_tile_moved(tile: InsectTile, to: Vector4i) -> void: selected = false deactivated = false temporary_resource = null action_callback = Callable() if tile == self: move_round_penalty == 2 func _on_insect_tile_deselected(tile: InsectTile) -> void: selected = false deactivated = false temporary_resource = null action_callback = Callable() if can_be_selected: tween_normal() else: tween_disabled() if hovered: hover() #else: #if tween != null: #tween.kill() #tween.tween_method(tween_shader, mat.next_pass.get_shader_parameter("albedo"), Color(1, 1, 1, 0), 0.5).set_ease(Tween.EASE_IN_OUT).set_trans(Tween.TRANS_EXPO) func _on_insect_tile_selected(tile: InsectTile) -> void: deactivated = true if tile == self: selected = true return func _on_insect_placed(resource: TileResource, is_black: bool, pos: Vector4i) -> void: deactivated = false func _on_insect_placement_cancelled() -> void: deactivated = false temporary_resource = null action_callback = Callable() if can_be_selected: tween_normal() else: tween_disabled() func _on_insect_selected(button: InsectButton, is_black: bool) -> void: deactivated = true #func _process(delta): func _input_event(camera, event, position, normal, shape_idx): if Input.is_action_just_pressed("place_tile"): if selected_for_action and not action_callback.is_null(): action_callback.call() action_callback = Callable() if deactivated: return if not can_be_selected: return #if not hovered: #return if not is_owner(): return if not is_players_turn(): return # Move up the insect stack.... or just do not react while we have something on top of us? if GameData.allow_selecting_in_stack: var top: InsectTile = self while top.hat != null: top = top.hat if top.is_black == GameData.is_player_black or GameData.debug: GameEvents.insect_tile_selected.emit(top) else: if hat != null: return else: GameEvents.insect_tile_selected.emit(self) func hover() -> void: if is_blacks_turn != is_black: return # mat.next_pass = hover_shader.duplicate() if tween != null: tween.kill() tween = get_tree().create_tween() #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_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_shader(color: Color) -> void: mat.next_pass.set_shader_parameter("albedo", color) mat.next_pass.set_shader_parameter("emission_color", color) func unhover() -> void: if is_blacks_turn != 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_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(): return if hat != null: return hovered = true if not deactivated: hover() func _on_mouse_exited(): return if hat != null: return hovered = false if not selected: unhover()