Swarm/Tile/Tile.gd
2024-03-30 19:41:23 +01:00

313 lines
8.2 KiB
GDScript

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)
GameEvents.turn_ended.connect(_on_turn_ended)
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_ended(turn_num: int, map: HexGrid) -> void:
move_round_penalty = move_round_penalty - 1
if move_round_penalty < 0:
move_round_penalty = 0
func _on_turn_started(turn_num: int, map: HexGrid, _is_blacks_turn: bool) -> void:
is_blacks_turn = _is_blacks_turn
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 not can_move():
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 = 1
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 can_move():
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()