extends Control signal play_card(card: Card) signal rps_move(move: String) @export var player_id: int @export var deck: Container @export var energy_label: Label @export var skip_card_prefab: PackedScene @export var support_red_card_prefab: PackedScene @export var support_green_card_prefab: PackedScene @export var monster_card_prefab: PackedScene @export var rps_button_container: Container @export var rps_grayed_color: Color @onready var monster_card_ui := $"MonsterCard" @onready var support1_green := $"Support1GreenCard" @onready var support2_green := $"Support2GreenCard" @onready var support2_red := $"Support2RedCard" @onready var incoming_damage_label := $"IncomingDamageLabel" var match_manager: MatchManager var show_buttons: bool var signal_connected: bool var selected_card: Control var hovering_cards_this_frame: Array[Control] = [] var hovering_cards_duration: Dictionary = {} const original_hover_position = 50 # hard coded idk what's a good way to find this value const hover_animation_time = 0.1 const hover_height_offset = -50 const selected_height_offset = -100 func attach(match_manager: MatchManager, show_buttons: bool = true): self.show_buttons = show_buttons self.match_manager = match_manager if !signal_connected: match_manager.state_transitioned.connect(_on_update) signal_connected = true func _ready(): monster_card_ui.visible = false support1_green.visible = false support2_green.visible = false support2_red.visible = false incoming_damage_label.visible = false for child in deck.get_children(): child.queue_free() func _on_update(transition): hovering_cards_duration.clear() selected_card = null incoming_damage_label.visible = true for child in deck.get_children(): child.queue_free() var player: MatchPlayer = match_manager.players.get(player_id) as MatchPlayer if not player: return energy_label.text = "Energy: " + str(player.energy) if match_manager.players[player.id].active_support_cards.size() > 0: support1_green.visible = true support1_green.card = match_manager.players[player.id].active_support_cards[0] else: support1_green.visible = false if match_manager.players[player.id].active_support_cards.size() > 1: var card: SupportCard = match_manager.players[player.id].active_support_cards[1] if card.type == "green": support2_green.visible = true support2_green.card = card else: support2_red.visible = true support2_red.card = card else: support2_green.visible = false support2_red.visible = false var monster = player.monster if monster: monster_card_ui.visible = true monster_card_ui.show_monster(monster) incoming_damage_label.text = "HP " + ("+0" if monster.health_delta == 0 else str(monster.health_delta)) else: monster_card_ui.visible = false if match_manager.phase in [Match.Phase.SUMMON, Match.Phase.SUPPORT_1, Match.Phase.SUPPORT_2]: if ( match_manager.phase != Match.Phase.SUMMON && show_buttons ) or ( match_manager.phase == Match.Phase.SUMMON and player.monster and player.monster.health > 0 && show_buttons ): var skip_btn:CardBase = skip_card_prefab.instantiate() skip_btn.left_clicked.connect(func (): _pop_this_card(skip_btn) play_card.emit(null)) skip_btn.hovering.connect(func (delta): _do_hover(skip_btn, delta)) deck.add_child(skip_btn) for card: Card in player.hand: #if match_manager.phase == Match.Phase.SUMMON and card is not MonsterCard: #continue #if (match_manager.phase == Match.Phase.SUPPORT_1 or match_manager.phase == Match.Phase.SUPPORT_2) and card is not SupportCard: #continue #if match_manager.phase == Match.Phase.SUPPORT_1 and card.type == "red": #continue if !show_buttons : continue var is_disabled = ( card is MonsterCard and match_manager.phase != Match.Phase.SUMMON ) or ( card is SupportCard and match_manager.phase != Match.Phase.SUPPORT_1 and match_manager.phase != Match.Phase.SUPPORT_2 ) or ( card is SupportCard and card.type == "red" and match_manager.phase != Match.Phase.SUPPORT_2 ) or ( card is MonsterCard and match_manager.phase == Match.Phase.SUMMON and player.monster and player.monster.health > 0 ) var btn: CardBase = null if card is MonsterCard: var monster_card:MonsterCardUI = monster_card_prefab.instantiate() monster_card.show_monster(MatchMonster.new(card, card.base_health, 0)) if !is_disabled: monster_card.left_clicked.connect(func (): _pop_this_card(monster_card) play_card.emit(card)) monster_card.hovering.connect(func (delta): _do_hover(monster_card, delta)) deck.add_child(monster_card) elif card is SupportCard and card.type == "red": btn = support_red_card_prefab.instantiate() btn.card = card deck.add_child(btn) else: btn = support_green_card_prefab.instantiate() btn.card = card deck.add_child(btn) if btn and !is_disabled: btn.left_clicked.connect(func (): _pop_this_card(btn) play_card.emit(card)) btn.hovering.connect(func (delta): _do_hover(btn, delta)) if rps_button_container: rps_button_container.visible = match_manager.phase == Match.Phase.RPS for button: TextureButton in rps_button_container.get_children(): button.modulate = rps_grayed_color func _pop_this_card(control: Control): if selected_card: selected_card.position = Vector2(selected_card.position.x, original_hover_position) selected_card = control selected_card.position = Vector2(selected_card.position.x, original_hover_position + selected_height_offset) func _do_hover(control: Control, delta: float): if control == selected_card: if control in hovering_cards_duration: hovering_cards_duration.erase(control) return var duration: float if control in hovering_cards_duration: duration = hovering_cards_duration[control] duration = clampf(duration + delta, 0, hover_animation_time) hovering_cards_duration[control] = duration else: hovering_cards_duration[control] = delta duration = delta var height = lerpf(0, hover_height_offset, duration / hover_animation_time) + original_hover_position control.position = Vector2(control.position.x, height) hovering_cards_this_frame.append(control) func _process(delta): for card in hovering_cards_duration.keys(): if !card or card in hovering_cards_this_frame: continue var duration = hovering_cards_duration[card] duration = maxf(0, duration - delta) var height = lerpf(0, hover_height_offset, duration / hover_animation_time) + original_hover_position card.position = Vector2(card.position.x, height) if duration == 0: hovering_cards_duration.erase(card) else: hovering_cards_duration[card] = duration hovering_cards_this_frame.clear() func _on_kertas_button_button_down() -> void: rps_move.emit("paper") for button: TextureButton in rps_button_container.get_children(): button.modulate = rps_grayed_color rps_button_container.get_node("KertasButton").modulate = Color.WHITE func _on_gunting_button_button_down() -> void: rps_move.emit("scissors") for button: TextureButton in rps_button_container.get_children(): button.modulate = rps_grayed_color rps_button_container.get_node("GuntingButton").modulate = Color.WHITE func _on_batu_button_button_down() -> void: rps_move.emit("rock") for button: TextureButton in rps_button_container.get_children(): button.modulate = rps_grayed_color rps_button_container.get_node("BatuButton").modulate = Color.WHITE