Randoloot/scripts/ui/captain_panel.gd
2026-10-19 22:33:24 +02:00

130 lines
5.4 KiB
GDScript

extends PanelContainer
signal equipment_requested
const PANEL_SCALE := 1.3
@onready var player: CharacterBody2D = get_node("../../../PlayerShip")
@onready var level_label: Label = $Contents/Header/Level
@onready var xp_label: Label = $Contents/XPLabel
@onready var xp_bar: ProgressBar = $Contents/XPBar
@onready var credits_label: Label = $Contents/Wallet/Credits
var _captain: CaptainProgress
var _level_up_button: Button
var _frame: Texture2D
func _ready() -> void:
_captain = GameState.captain
_captain.normalize_skill_ranks()
_build_portrait()
_level_up_button = Button.new()
_level_up_button.name = "LevelUpButton"
_level_up_button.text = "Nowy poziom"
_level_up_button.focus_mode = Control.FOCUS_NONE
preload("res://scripts/ui/hud_button_style.gd").apply(_level_up_button, Color("efb568"))
_level_up_button.add_theme_font_size_override("font_size", 10)
$Contents.add_child(_level_up_button)
_place(_level_up_button, Rect2(90, 17, 72, 15))
_level_up_button.pressed.connect(func() -> void:
get_node("../../CaptainSkills").call("open_management")
)
_captain.changed.connect(_refresh)
player.get_node("ShipInventory").connect("inventory_changed", _refresh)
for label in [level_label, xp_label, credits_label, $Contents/Header/Title]:
label.add_theme_color_override("font_shadow_color", Color("030811"))
label.add_theme_constant_override("shadow_offset_x", 1)
label.add_theme_constant_override("shadow_offset_y", 1)
_refresh()
mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
tooltip_text = "Kliknij, aby otworzyć ekwipunek kapitana"
_pass_clicks($Contents)
func _place(control: Control, rect: Rect2) -> void:
control.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT)
control.position = rect.position * PANEL_SCALE
control.size = rect.size * PANEL_SCALE
func _pass_clicks(node: Node) -> void:
for child in node.get_children():
if child is BaseButton: continue
if child is Control: child.mouse_filter = Control.MOUSE_FILTER_IGNORE
_pass_clicks(child)
if node == $Contents: node.mouse_filter = Control.MOUSE_FILTER_IGNORE
func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
equipment_requested.emit()
accept_event()
func _refresh() -> void:
level_label.text = "POZ. %d" % _captain.level
xp_label.text = "XP %d / %d" % [_captain.experience, _captain.get_xp_required()]
xp_bar.max_value = _captain.get_xp_required()
xp_bar.value = _captain.experience
credits_label.text = "Kredyty: %d" % _captain.credits
_level_up_button.visible = _captain.learning_points > 0
$Contents/Header/Title.visible = not _level_up_button.visible
_level_up_button.tooltip_text = "Wybierz umiejętność · oczekujące awanse: %d" % _captain.learning_points
func _build_portrait() -> void:
custom_minimum_size = Vector2(244, 72) * PANEL_SCALE
var style := StyleBoxFlat.new()
style.bg_color = Color(0, 0, 0, 0)
add_theme_stylebox_override("panel", style)
_frame = load("res://assets/ui/frames/captain_ring_frame.png") as Texture2D
_place($Contents/Header, Rect2(0, 0, 244, 72))
_place($Contents/Wallet, Rect2(0, 0, 244, 72))
_place($Contents/Header/Title, Rect2(90, 17, 66, 13))
$Contents/Header/Title.add_theme_font_size_override("font_size", 9)
_place(level_label, Rect2(175, 17, 52, 13))
level_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
level_label.add_theme_font_size_override("font_size", 9)
_place(credits_label, Rect2(90, 28, 137, 13))
credits_label.add_theme_font_size_override("font_size", 11)
credits_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
_place(xp_label, Rect2(90, 40, 137, 10))
xp_label.add_theme_font_size_override("font_size", 9)
_place(xp_bar, Rect2(90, 52, 137, 3))
xp_bar.custom_minimum_size.y = 3
for part in ["background", "fill"]:
var bar := StyleBoxFlat.new()
bar.bg_color = Color("86d1df") if part == "fill" else Color("122b3788")
bar.set_corner_radius_all(2)
xp_bar.add_theme_stylebox_override(part, bar)
var row := Control.new()
row.name = "PortraitRow"
$Contents.add_child(row)
var frame := Control.new()
frame.name = "AvatarFrame"
row.add_child(frame)
var portrait := TextureRect.new()
portrait.name = "CaptainAvatar"
portrait.custom_minimum_size = Vector2(54, 54)
portrait.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
portrait.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED
portrait.texture = load("res://assets/avatars/captain.png")
var shader := Shader.new()
shader.code = "shader_type canvas_item; void fragment(){vec4 c = texture(TEXTURE, UV); float mask = 1.0 - smoothstep(0.48, 0.5, distance(UV, vec2(0.5))); COLOR = vec4(c.rgb, c.a * mask);}"
var material := ShaderMaterial.new()
material.shader = shader
portrait.material = material
frame.add_child(portrait)
_place(portrait, Rect2(16, 12, 54, 54))
portrait.scale = Vector2.ONE * 0.85
var artwork := TextureRect.new()
artwork.name = "CaptainFrame"
artwork.texture = _frame
artwork.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
artwork.stretch_mode = TextureRect.STRETCH_SCALE
$Contents.add_child(artwork)
$Contents.move_child(artwork, $Contents.get_child_count() - 1)
_place(artwork, Rect2(0, 0, 244, 72))
queue_redraw()
func _draw() -> void:
draw_circle(Vector2(36, 36) * PANEL_SCALE, 28 * PANEL_SCALE, Color("0a141b66"))
var glass := StyleBoxFlat.new()
glass.bg_color = Color("0b18254d")
glass.set_corner_radius_all(4)
draw_style_box(glass, Rect2(Vector2(73, 17) * PANEL_SCALE, Vector2(160, 36) * PANEL_SCALE))