class_name MainUI extends CanvasLayer @onready var health_bar: ProgressBar = $StatusBars/HealthBar @onready var charge_bar: ProgressBar = $StatusBars/ChargeBar @onready var combo_skill_label: Label = $ComboSkillLabel var charge_bar_ready := false var charge_flash := 0.0 func _ready() -> void: _apply_bar_styles() var bus := _event_bus() bus.connect("player_health_changed", _on_health_changed) bus.connect("player_charge_changed", _on_charge_changed) bus.connect("skill_executed", _on_skill_executed) func _process(delta: float) -> void: _update_charge_bar_flash(delta) func _on_health_changed(current: int, maximum: int) -> void: health_bar.max_value = max(1, maximum) health_bar.value = clampi(current, 0, maximum) func _on_charge_changed(current: float, maximum: float, ready: bool, active: bool) -> void: charge_bar.max_value = maxf(0.01, maximum) charge_bar.value = clampf(current, 0.0, maximum) charge_bar_ready = ready and active if charge_bar_ready: return charge_bar.modulate = Color(1.0, 1.0, 1.0, 1.0 if active or ready else 0.45) func _on_skill_executed(skill: Resource, _judgement: StringName) -> void: var display_name := str(skill.get("display_name")) if display_name.is_empty(): display_name = str(skill.get("id")).to_upper() combo_skill_label.text = display_name var tween := create_tween() combo_skill_label.scale = Vector2(1.12, 1.12) tween.tween_property(combo_skill_label, "scale", Vector2.ONE, 0.12) func _update_charge_bar_flash(delta: float) -> void: if not charge_bar_ready: charge_flash = 0.0 return charge_flash = fmod(charge_flash + delta * 7.0, TAU) var alpha := 0.62 + 0.38 * absf(sin(charge_flash)) charge_bar.modulate = Color(1.0, 1.0, 1.0, alpha) func _apply_bar_styles() -> void: health_bar.add_theme_stylebox_override( "background", _make_style(Color(0.12, 0.08, 0.08, 0.86), Color(0.6, 0.12, 0.16, 0.95)) ) health_bar.add_theme_stylebox_override( "fill", _make_style(Color(0.86, 0.11, 0.18, 1.0), Color.TRANSPARENT, false) ) charge_bar.add_theme_stylebox_override( "background", _make_style(Color(0.08, 0.07, 0.12, 0.86), Color(0.42, 0.36, 0.75, 0.9)) ) charge_bar.add_theme_stylebox_override( "fill", _make_style(Color(0.92, 0.72, 0.25, 1.0), Color.TRANSPARENT, false) ) func _make_style(bg_color: Color, border_color: Color, has_border := true) -> StyleBoxFlat: var style := StyleBoxFlat.new() style.bg_color = bg_color if has_border: style.border_width_left = 1 style.border_width_top = 1 style.border_width_right = 1 style.border_width_bottom = 1 style.border_color = border_color return style func _event_bus() -> Node: var root := get_tree().root var bus := root.get_node_or_null("EventBus") if bus == null: bus = load("res://autoload/event_bus.gd").new() bus.name = "EventBus" root.add_child(bus) return bus