extends CanvasLayer @onready var debug_toggle: Button = $HUDRoot/DebugToggle @onready var debug_info: Label = $HUDRoot/DebugInfo @onready var player: CharacterBody2D = get_parent().get_node("PlayerShip") @onready var inventory_button: Button = $HUDRoot/ShipEquipmentPanel/Contents/InventoryButton @onready var inventory_panel: Control = $HUDRoot/ShipInventoryPanel var _debug_expanded := true var _ability_buttons: Dictionary = {} var _ability_bar: HBoxContainer func _ready() -> void: _create_ability_bar() debug_toggle.pressed.connect(_toggle_debug) inventory_button.pressed.connect(_toggle_inventory) _update_debug_toggle() $HUDRoot/CaptainPanel.resized.connect(func() -> void: _layout_sidebar.call_deferred()) _layout_sidebar.call_deferred() func _layout_sidebar() -> void: var captain_panel := $HUDRoot/CaptainPanel as Control var equipment_panel := $HUDRoot/ShipEquipmentPanel as Control captain_panel.grow_vertical = Control.GROW_DIRECTION_END equipment_panel.grow_vertical = Control.GROW_DIRECTION_END equipment_panel.position.y = captain_panel.position.y + captain_panel.size.y + 6.0 equipment_panel.size.y = equipment_panel.get_combined_minimum_size().y func _process(_delta: float) -> void: _update_ability_bar() if not _debug_expanded: return var ship_position := player.global_position var ship_velocity := player.velocity var angular_speed := float(player.get("angular_velocity")) var game := get_parent() var enemy_count: int = game.call("get_remaining_enemies") var goal: Node2D = game.get("protected_planet") var to_planet := goal.global_position - player.global_position debug_info.text = """STEROWANIE W: ciąg S: hamulec / wsteczny Q / E: strafe A / D: obrót LPM / PPM: broń 1 / broń 2 1–6: aktywne rozszerzenia UKŁAD: %d · PLANETY: %d WROGOWIE: %d CEL: %s PLANETA RASY: %.0f px · %.0f° STATEK KADŁUB: %d / %d TARCZE: %d / %d ENERGIA: %d / %d REGEN E / T: %.1f / %.1f /s RUCH PRĘDKOŚĆ: %.1f px/s WEKTOR: [%.1f, %.1f] px/s POZYCJA: [%.1f, %.1f] KIERUNEK: %.1f° OBRÓT: %.2f rad/s""" % [ GameState.system_level, int(game.get("system_data")["planets"].size()), enemy_count, "Odwiedź chronioną rasę" if bool(game.get("system_cleared")) else "Oczyść układ", to_planet.length(), wrapf(rad_to_deg(to_planet.angle()) + 90.0, 0.0, 360.0), roundi(float(player.get("hull"))), roundi(float(player.get("max_hull"))), roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), float(player.get("energy_regeneration")), float(player.get("shield_regeneration")), ship_velocity.length(), ship_velocity.x, ship_velocity.y, ship_position.x, ship_position.y, rad_to_deg(player.rotation), angular_speed, ] func _toggle_debug() -> void: _debug_expanded = not _debug_expanded debug_info.visible = _debug_expanded _update_debug_toggle() func _update_debug_toggle() -> void: debug_toggle.text = "DEBUG [−]" if _debug_expanded else "DEBUG [+]" func _toggle_inventory() -> void: inventory_panel.visible = not inventory_panel.visible func _create_ability_bar() -> void: var panel := PanelContainer.new() panel.name = "ActiveAbilities" $HUDRoot.add_child(panel) panel.set_anchors_and_offsets_preset(Control.PRESET_BOTTOM_LEFT) panel.offset_left = 12.0 panel.offset_right = 12.0 panel.offset_top = -54.0 panel.offset_bottom = -12.0 _ability_bar = HBoxContainer.new() _ability_bar.add_theme_constant_override("separation", 4) panel.add_child(_ability_bar) for index in 6: var button := Button.new() button.name = "Ability%d" % (index + 1) button.custom_minimum_size = Vector2(120, 40) button.add_theme_font_size_override("font_size", 11) button.pressed.connect(func() -> void: player.call("activate_ability", index)) _ability_bar.add_child(button) _ability_buttons[index] = button _update_ability_bar() func _update_ability_bar() -> void: var any_equipped := false for index in _ability_buttons: var button: Button = _ability_buttons[index] var ability: ActiveAbility = player.call("get_active_ability", index) button.visible = ability != null if ability == null: continue any_equipped = true var reason: String = player.call("ability_unavailable_reason", index) button.disabled = not reason.is_empty() button.text = "[%d] %s" % [index + 1, ability.display_name] button.tooltip_text = ability.description + ("\n" + reason if not reason.is_empty() else "\nGotowe") _ability_bar.get_parent().visible = any_equipped