Randoloot/scripts/ui/planet_services_menu.gd
2026-10-18 14:46:34 +02:00

204 lines
9.7 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 Control
signal next_level_requested
const BUTTON_STYLE := preload("res://scripts/ui/hud_button_style.gd")
const CREDIT_ICON := preload("res://assets/icons/resources/credits.svg")
const CONTACT := preload("res://scripts/ui/orbital_contact_style.gd")
@onready var next_button: Button = $Center/Panel/Contents/NextButton
@onready var buy_ammunition_button: Button = $Center/Panel/Contents/BuyAmmunitionButton
@onready var reset_skills_button: Button = $Center/Panel/Contents/ResetSkillsButton
@onready var services_label: Label = $Center/Panel/Contents/Services
@onready var status_label: Label = $Center/Panel/Contents/Status
@onready var panel: PanelContainer = $Center/Panel
var _inventory: ShipInventory
var planet: Node2D
var _open_tween: Tween
var _missile_button: Button
var _gamma_buy: Button
var _stock_labels: Dictionary = {}
func _ready() -> void:
_gamma_buy = Button.new()
_gamma_buy.name = "BuyIrradiatedAmmunition"
_missile_button = Button.new()
_missile_button.name = "BuyMissile"
var contents := $Center/Panel/Contents
contents.add_child(_gamma_buy)
contents.add_child(_missile_button)
reset_skills_button.hide()
_build_compact_shop()
get_parent().get_node("FloatingWindows").call("register_window", self, panel, contents.get_node("Title"))
next_button.pressed.connect(func() -> void: next_level_requested.emit())
buy_ammunition_button.pressed.connect(_buy_ammunition)
_gamma_buy.pressed.connect(func() -> void:
if visible and _inventory:
_inventory.buy_irradiated_ammunition()
)
_missile_button.pressed.connect(func() -> void:
if visible and _inventory:
_inventory.buy_missile()
)
_inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory
if _inventory:
_inventory.ammunition_changed.connect(_refresh_ammunition_service)
_inventory.inventory_changed.connect(_refresh_ammunition_service)
GameState.captain.changed.connect(_refresh_ammunition_service)
_refresh_ammunition_service()
func _build_compact_shop() -> void:
var contents := $Center/Panel/Contents
panel.custom_minimum_size.x = 300
panel.add_theme_stylebox_override("panel",CONTACT.panel_style(Color("78d7be")))
contents.get_node("Title").text = "● STACJA / ZAOPATRZENIE"
contents.get_node("Title").horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
contents.get_node("Title").add_theme_font_size_override("font_size",11)
contents.add_theme_constant_override("separation", 5)
status_label.add_theme_font_size_override("font_size", 10)
status_label.add_theme_color_override("font_color", Color("86b7aa"))
services_label.add_theme_font_size_override("font_size", 11)
services_label.add_theme_color_override("font_color", Color("efc982"))
services_label.size_flags_vertical = Control.SIZE_FILL
var wallet := HBoxContainer.new()
wallet.name = "Wallet"
wallet.alignment = BoxContainer.ALIGNMENT_CENTER
wallet.add_theme_constant_override("separation", 6)
contents.add_child(wallet)
contents.move_child(wallet, 2)
var money_icon := TextureRect.new()
money_icon.texture = CREDIT_ICON
money_icon.custom_minimum_size = Vector2(15, 15)
money_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
money_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
money_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
wallet.add_child(money_icon)
services_label.reparent(wallet)
var offers := HBoxContainer.new()
offers.name = "Offers"
offers.add_theme_constant_override("separation", 6)
contents.add_child(offers)
contents.move_child(offers, 3)
_add_offer(offers, buy_ammunition_button, "ammunition", "Zwykła", 100, Color("e8b46f"))
_add_offer(offers, _gamma_buy, "irradiated_ammunition", "Radiacyjna", 10, Color("add580"))
_add_offer(offers, _missile_button, "missile", "Rakieta", 1, Color("82cddd"))
BUTTON_STYLE.apply(next_button, Color("78d7be"))
next_button.custom_minimum_size = Vector2(0, 30)
next_button.add_theme_font_size_override("font_size", 11)
next_button.icon = preload("res://assets/icons/extensions/teleport_art.png")
next_button.expand_icon = true
next_button.add_theme_constant_override("icon_max_width", 21)
contents.move_child(next_button, contents.get_child_count() - 1)
func _add_offer(offers: HBoxContainer, button: Button, item_id: String, caption: String, amount: int, accent: Color) -> void:
var card := PanelContainer.new()
card.name = item_id.capitalize().replace(" ", "") + "Offer"
card.custom_minimum_size.x = 86
card.size_flags_horizontal = Control.SIZE_EXPAND_FILL
var style := StyleBoxFlat.new()
style.bg_color = Color(0.035,0.075,0.105,0.60)
style.border_color = accent.darkened(0.65)
style.set_border_width_all(1)
style.border_width_top = 2
style.set_corner_radius_all(6)
style.set_content_margin_all(6)
card.add_theme_stylebox_override("panel", style)
offers.add_child(card)
var column := VBoxContainer.new()
column.add_theme_constant_override("separation", 4)
card.add_child(column)
var icon := TextureRect.new()
icon.texture = load("res://assets/icons/resources/%s.png" % item_id)
icon.custom_minimum_size = Vector2(30, 30)
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
column.add_child(icon)
var title := Label.new()
title.text = "%s ×%d" % [caption, amount]
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
title.add_theme_font_size_override("font_size", 10)
title.add_theme_color_override("font_color", accent.lightened(0.2))
column.add_child(title)
var stock := Label.new()
stock.name = "Stock"
stock.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
stock.add_theme_font_size_override("font_size", 9)
stock.add_theme_color_override("font_color", Color("8ba4b7"))
column.add_child(stock)
_stock_labels[item_id] = stock
button.reparent(column)
BUTTON_STYLE.apply(button, accent)
button.custom_minimum_size = Vector2(0, 28)
button.add_theme_font_size_override("font_size", 10)
button.icon = CREDIT_ICON
button.expand_icon = true
button.add_theme_constant_override("icon_max_width", 12)
for state in ["normal", "hover", "pressed", "disabled"]:
var frame := button.get_theme_stylebox(state).duplicate() as StyleBoxFlat
frame.set_content_margin_all(4)
frame.set_corner_radius_all(4)
frame.shadow_size = 0
button.add_theme_stylebox_override(state, frame)
func show_services(at_level_cap: bool, portal_open: bool = false) -> void:
_refresh_ammunition_service()
next_button.disabled = at_level_cap or portal_open
next_button.text = "OSTATNI UKŁAD" if at_level_cap else ("WORMHOLE OTWARTY" if portal_open else "OTWÓRZ WORMHOLE")
status_label.text = "Wleć w wormhole, aby przejść dalej." if portal_open else "Bezpieczny układ · zaopatrzenie"
if visible:
return
show()
_position_at_planet()
scale = Vector2(0.05, 1.0)
_open_tween = create_tween()
_open_tween.tween_property(self, "scale:x", 1.0, 0.2).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT)
func hide_services() -> void:
if _open_tween != null and _open_tween.is_running():
_open_tween.kill()
hide()
scale = Vector2.ONE
func _process(_delta: float) -> void:
if visible:
_position_at_planet()
func _position_at_planet() -> void:
if has_meta("floating_window_dragged"):
get_parent().get_node("FloatingWindows").call("clamp_window", self)
return
if not is_instance_valid(planet):
return
var canvas := planet.get_global_transform_with_canvas()
var planet_screen := canvas.origin
var planet_radius := float(planet.get("radius")) * canvas.x.length()
size = panel.get_combined_minimum_size()
var viewport_size := get_viewport_rect().size
var sidebar := get_parent().get_node_or_null("ShipDrawer") as Control
var screen_right := minf(viewport_size.x - 8.0, sidebar.get_global_rect().position.x - 8.0) if sidebar != null and sidebar.visible else viewport_size.x - 8.0
position = CONTACT.beside(planet_screen,planet_radius,size,Vector2(screen_right+8,viewport_size.y),CONTACT.hud_obstacles(get_parent()),false)
func _refresh_ammunition_service() -> void:
var ordinary_cost := _inventory.get_ammunition_buy_cost() if _inventory else GameState.captain.discounted_price(ShipInventory.AMMUNITION_BUY_BASE_COST * maxi(1, GameState.system_level))
var gamma_cost := _inventory.get_irradiated_ammunition_buy_cost() if _inventory else GameState.captain.discounted_price(ShipInventory.IRRADIATED_AMMUNITION_BUY_BASE_COST * maxi(1, GameState.system_level))
var missile_cost := _inventory.get_missile_buy_cost() if _inventory else GameState.captain.discounted_price(ShipInventory.MISSILE_BUY_BASE_COST * maxi(1, GameState.system_level))
buy_ammunition_button.text = "KUP %d" % ordinary_cost
_gamma_buy.text = "KUP %d" % gamma_cost
_missile_button.text = "KUP %d" % missile_cost
buy_ammunition_button.disabled = _inventory == null or not _inventory.can_buy_ammunition()
_gamma_buy.disabled = _inventory == null or not _inventory.can_buy_irradiated_ammunition()
_missile_button.disabled = _inventory == null or not _inventory.can_buy_missile()
buy_ammunition_button.tooltip_text = "Kup 100 zwykłych pocisków za %d kredytów." % ordinary_cost
_gamma_buy.tooltip_text = "Kup 10 pocisków radiacyjnych za %d kredytów." % gamma_cost
_missile_button.tooltip_text = "Kup 1 rakietę za %d kredytów." % missile_cost
var discount := roundi(GameState.captain.get_skill_bonus("business_shark") * 100)
services_label.text = "%d kredytów%s" % [GameState.captain.credits, " · rabat %d%%" % discount if discount > 0 else ""]
_stock_labels["ammunition"].text = "Zapas: %d" % (_inventory.ammunition if _inventory else 0)
_stock_labels["irradiated_ammunition"].text = "Zapas: %d" % (_inventory.irradiated_ammunition if _inventory else 0)
_stock_labels["missile"].text = "Zapas: %d" % (_inventory.missile_ammunition if _inventory else 0)
func _buy_ammunition() -> void:
if visible and _inventory:
_inventory.buy_ammunition()