201 lines
9.5 KiB
GDScript
201 lines
9.5 KiB
GDScript
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")
|
||
@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
|
||
contents.add_theme_constant_override("separation", 7)
|
||
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, 34)
|
||
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 = 94
|
||
card.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var style := StyleBoxFlat.new()
|
||
style.bg_color = Color("101e2a")
|
||
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(36, 36)
|
||
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 := get_viewport().get_canvas_transform()
|
||
var planet_screen := canvas * planet.global_position
|
||
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
|
||
var target := planet_screen + Vector2(planet_radius + 24.0, -size.y * 0.5)
|
||
if target.x + size.x > screen_right:
|
||
target.x = planet_screen.x - planet_radius - 24.0 - size.x
|
||
position = Vector2(clampf(target.x, 8.0, maxf(8.0, screen_right - size.x)), clampf(target.y, 8.0, maxf(8.0, viewport_size.y - size.y - 150.0)))
|
||
|
||
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()
|