Randoloot/scripts/game/flight_hud.gd

251 lines
9.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
var _ability_ready_style: StyleBoxFlat
var _ability_blocked_style: StyleBoxFlat
var _inventory_clip: Control
var _sidebar: PanelContainer
var _sidebar_toggle: Button
var _sidebar_open := false
var _sidebar_tween: Tween
const SIDEBAR_WIDTH := 344.0
func _ready() -> void:
var energy_indicator := Node2D.new()
energy_indicator.name = "EnergyIndicator"
energy_indicator.set_script(preload("res://scripts/game/ship_energy_indicator.gd"))
energy_indicator.set("player", player)
player.add_child(energy_indicator)
var feedback := Control.new()
feedback.name = "CombatFeedback"
feedback.set_script(preload("res://scripts/ui/combat_feedback.gd"))
feedback.set("player", player)
$HUDRoot.add_child(feedback)
debug_info.add_theme_font_size_override("font_size", 9)
_create_sidebar()
_inventory_clip = Control.new()
_inventory_clip.name = "InventoryDrawer"
_inventory_clip.clip_contents = true
_inventory_clip.mouse_filter = Control.MOUSE_FILTER_IGNORE
$HUDRoot.add_child(_inventory_clip)
inventory_panel.reparent(_inventory_clip, false)
inventory_panel.set("layout_mode", 0)
inventory_panel.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
inventory_panel.size = Vector2(780, inventory_panel.get_combined_minimum_size().y)
$HUDRoot.resized.connect(func() -> void: _layout_sidebar.call_deferred())
_create_ability_bar()
debug_toggle.pressed.connect(_toggle_debug)
inventory_button.pressed.connect(_toggle_inventory)
_update_debug_toggle()
_layout_sidebar.call_deferred()
func _create_sidebar() -> void:
_sidebar = PanelContainer.new()
_sidebar.name = "CaptainShipDrawer"
var style := StyleBoxFlat.new()
style.bg_color = Color(0.018, 0.028, 0.043, 0.97)
style.border_color = Color("52677e")
style.set_border_width_all(1)
style.set_content_margin_all(8)
_sidebar.add_theme_stylebox_override("panel", style)
$HUDRoot.add_child(_sidebar)
var scroll := ScrollContainer.new()
scroll.name = "Scroll"
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
_sidebar.add_child(scroll)
var contents := VBoxContainer.new()
contents.name = "Contents"
contents.size_flags_horizontal = Control.SIZE_EXPAND_FILL
contents.add_theme_constant_override("separation", 8)
scroll.add_child(contents)
var captain := $HUDRoot/CaptainPanel as PanelContainer
var equipment := $HUDRoot/ShipEquipmentPanel as PanelContainer
for panel in [captain, equipment]:
panel.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
panel.reparent(contents, false)
panel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
panel.add_theme_stylebox_override("panel", StyleBoxEmpty.new())
if panel == captain:
contents.add_child(HSeparator.new())
_sidebar_toggle = Button.new()
_sidebar_toggle.name = "CaptainShipToggle"
_sidebar_toggle.text = "KAPITAN / STATEK ◀"
_sidebar_toggle.add_theme_font_size_override("font_size", 12)
_sidebar_toggle.focus_mode = Control.FOCUS_NONE
$HUDRoot.add_child(_sidebar_toggle)
_sidebar_toggle.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
_sidebar_toggle.offset_left = -210
_sidebar_toggle.offset_right = -8
_sidebar_toggle.offset_top = 8
_sidebar_toggle.offset_bottom = 38
_sidebar_toggle.pressed.connect(_toggle_sidebar)
_sidebar.hide()
func _toggle_sidebar() -> void:
_sidebar_open = not _sidebar_open
if _sidebar_tween != null and _sidebar_tween.is_running():
_sidebar_tween.kill()
_sidebar_toggle.text = "ZAMKNIJ ▶" if _sidebar_open else "KAPITAN / STATEK ◀"
if _sidebar_open:
_sidebar.show()
else:
close_inventory()
_sidebar_tween = create_tween()
_sidebar_tween.tween_property(_sidebar, "position:x", $HUDRoot.size.x - SIDEBAR_WIDTH - 8 if _sidebar_open else $HUDRoot.size.x, 0.25).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT if _sidebar_open else Tween.EASE_IN)
if not _sidebar_open:
_sidebar_tween.tween_callback(_sidebar.hide)
func _layout_sidebar() -> void:
if _sidebar_tween != null and _sidebar_tween.is_running():
_sidebar_tween.kill()
_sidebar.size = Vector2(SIDEBAR_WIDTH, maxf(100.0, $HUDRoot.size.y - 52.0))
_sidebar.position = Vector2($HUDRoot.size.x - SIDEBAR_WIDTH - 8 if _sidebar_open else $HUDRoot.size.x, 44)
_sidebar.visible = _sidebar_open
_inventory_clip.size = inventory_panel.size
_layout_inventory()
func _layout_inventory() -> void:
if _inventory_clip == null:
return
var equipment := _sidebar.get_node("Scroll/Contents/ShipEquipmentPanel") as Control
_inventory_clip.position = Vector2(_sidebar.position.x - _inventory_clip.size.x - 8, minf(equipment.global_position.y, maxf(8.0, $HUDRoot.size.y - inventory_panel.size.y - 8)))
func _process(_delta: float) -> void:
_layout_inventory()
_update_ability_bar()
if not _debug_expanded:
return
var game := get_parent()
debug_info.text = """POZIOM UKŁADU: %d
WROGOWIE: %d
PRĘDKOŚĆ: %.1f px/s
AKTUALNA REGENERACJA
Energia: %.1f pkt/s
Tarcze: %.1f pkt/s
%s""" % [
GameState.system_level,
int(game.call("get_remaining_enemies")),
player.velocity.length(),
float(player.get("energy_regeneration")) + float(player.call("get_solar_regeneration")),
float(player.get("shield_regeneration")),
_get_bonus_summary(),
]
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:
if not _sidebar_open:
_toggle_sidebar()
inventory_panel.call("toggle_drawer")
func close_inventory() -> void:
inventory_panel.call("close_drawer", true)
func _get_bonus_summary() -> String:
var cooldown_bonus := 0.0
var inventory := player.get_node("ShipInventory") as ShipInventory
for item in inventory.weapon_slots + inventory.module_slots:
if item != null:
cooldown_bonus += item.get_stat_total("missile_cooldown_reduction")
return """BONUSY (ADDONY + KAPITAN)
Obrażenia broni: %+.1f%%
Szansa na krytyk: %+.1f%%
Obrażenia krytyczne: %+.1f%%
Szansa na unik: %+.1f%%
Redukcja obrażeń: %+.1f%%
Odzysk tarcz z obrażeń: %.1f%%
Regeneracja energii: %+.1f pkt/s
Regeneracja tarcz: %+.1f pkt/s
Kadłub: %+.1f pkt
Tarcze: %+.1f pkt
Energia: %+.1f pkt
Prędkość maks.: %+.1f%%
Skrócenie cooldownu rakiet: %.2f s
Doświadczenie: %+.1f%%
Kredyty: %+.1f%%""" % [
(float(player.call("get_weapon_damage_multiplier")) - 1.0) * 100.0,
float(player.call("get_critical_chance")) * 100.0,
float(player.get("critical_damage_bonus")) * 100.0,
float(player.call("get_evasion_chance")) * 100.0,
float(player.call("get_damage_reduction")) * 100.0,
float(player.get("shield_on_damage_percent")),
float(player.get("energy_regeneration")) - float(player.get("base_energy_regeneration")),
float(player.get("shield_regeneration")) - float(player.get("base_shield_regeneration")),
float(player.get("max_hull")) - float(player.get("base_max_hull")),
float(player.get("max_shields")) - float(player.get("base_max_shields")),
float(player.get("max_energy")) - float(player.get("base_max_energy")),
(float(player.get("max_speed")) / float(player.get("base_max_speed")) - 1.0) * 100.0,
cooldown_bonus,
(float(player.get("experience_multiplier")) - 1.0) * 100.0,
(float(player.get("credits_multiplier")) - 1.0) * 100.0,
]
func _create_ability_bar() -> void:
_ability_ready_style = _make_ability_style(true)
_ability_blocked_style = _make_ability_style(false)
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\n%s" % [index + 1, ability.display_name, "GOTOWE" if reason.is_empty() else reason]
var style := _ability_ready_style if reason.is_empty() else _ability_blocked_style
button.add_theme_stylebox_override("normal", style)
button.add_theme_stylebox_override("disabled", style)
button.add_theme_stylebox_override("hover", style)
button.add_theme_color_override("font_color", Color("a5ffda"))
button.add_theme_color_override("font_disabled_color", Color("a3aebb"))
button.tooltip_text = ability.description + ("\n" + reason if not reason.is_empty() else "\nGotowe")
_ability_bar.get_parent().visible = any_equipped
func _make_ability_style(ready: bool) -> StyleBoxFlat:
var style := StyleBoxFlat.new()
style.bg_color = Color("174237") if ready else Color("202731")
style.border_color = Color("77e8bc") if ready else Color("526071")
style.set_border_width_all(2 if ready else 1)
style.set_content_margin_all(6)
return style