527 lines
24 KiB
GDScript
527 lines
24 KiB
GDScript
extends Control
|
||
signal closed
|
||
const UI := preload("res://scripts/planets/expedition_ui.gd")
|
||
const MENU := preload("res://scripts/planets/freighter_menu.gd")
|
||
const GEAR := preload("res://scripts/planets/captain_equipment.gd")
|
||
const RECIPES := preload("res://scripts/items/crafting_recipes.gd")
|
||
const CATALOG := preload("res://scripts/game/ship_catalog.gd")
|
||
var captain: Resource
|
||
var inventory: Node
|
||
var _content: VBoxContainer
|
||
var _tab := "overview"
|
||
var _drawer: PanelContainer
|
||
var _drawer_title: Label
|
||
var _wallet: Label
|
||
var _hint: Label
|
||
var _owned_open := false
|
||
var _storage_columns: GridContainer
|
||
var _storage_notice := ""
|
||
@onready var deck: Control = $Deck
|
||
@onready var _audio: Node = $FreighterAudio
|
||
|
||
func _ready() -> void:
|
||
if captain == null:
|
||
captain = GameState.captain
|
||
deck.sync_rooms(captain.expedition.freighter_rooms)
|
||
deck.section_selected.connect(_select_section)
|
||
deck.section_hovered.connect(_hover_section)
|
||
var chassis := CATALOG.for_path(GameState.selected_ship_path)
|
||
deck.ship_name = str(chassis.name)
|
||
var sprite: Sprite2D
|
||
if is_instance_valid(inventory):
|
||
var ship: Node = inventory.get_parent()
|
||
sprite = ship.get_node_or_null("Sprite2D") as Sprite2D
|
||
deck.ship_texture = sprite.texture if sprite != null else load(CATALOG.texture_path(chassis))
|
||
if sprite != null:
|
||
deck.ship_name = str(CATALOG.for_path(sprite.texture.resource_path).name)
|
||
_build_header()
|
||
_build_footer()
|
||
_build_drawer()
|
||
resized.connect(_layout)
|
||
captain.changed.connect(_sync_header)
|
||
_sync_header()
|
||
_layout()
|
||
_refresh()
|
||
|
||
func _build_header() -> void:
|
||
var header := HBoxContainer.new()
|
||
header.name = "Header"
|
||
header.set_anchors_and_offsets_preset(Control.PRESET_TOP_WIDE)
|
||
header.offset_left = 26
|
||
header.offset_right = -26
|
||
header.offset_top = 20
|
||
header.add_theme_constant_override("separation",22)
|
||
add_child(header)
|
||
var heading := VBoxContainer.new()
|
||
heading.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
header.add_child(heading)
|
||
MENU.label(heading,"FREGATA / POKŁAD OPERACYJNY",24,Color("e3e9e8"))
|
||
MENU.label(heading,"01 / POKŁAD GŁÓWNY · POŁĄCZENIE ZABEZPIECZONE",11,Color("77969f"))
|
||
_wallet = MENU.label(header,"",13,Color("c9aa7c"))
|
||
_wallet.custom_minimum_size.x = 150
|
||
_wallet.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||
var storage_button := MENU.button(header,"MAGAZYN",func(): _select_section("storage"))
|
||
storage_button.custom_minimum_size.x = 100
|
||
storage_button.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||
var leave := MENU.button(header,"ODLOT [L]",func(): closed.emit())
|
||
leave.custom_minimum_size.x = 110
|
||
leave.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||
|
||
func _build_footer() -> void:
|
||
var footer := HBoxContainer.new()
|
||
footer.name = "Footer"
|
||
footer.set_anchors_and_offsets_preset(Control.PRESET_BOTTOM_WIDE)
|
||
footer.offset_left = 26
|
||
footer.offset_right = -26
|
||
footer.offset_top = -43
|
||
footer.offset_bottom = -12
|
||
add_child(footer)
|
||
_hint = MENU.label(footer,"Wybierz pomieszczenie na pokładzie. · Warsztat i hangar są dostępne.",12,Color("91a9ae"))
|
||
_hint.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
footer.add_theme_constant_override("separation",18)
|
||
MENU.label(footer,"● OPERACYJNE",11,Color("79d9d8")).custom_minimum_size.x = 110
|
||
MENU.label(footer,"● W REMONCIE",11,Color("bca078")).custom_minimum_size.x = 110
|
||
|
||
func _build_drawer() -> void:
|
||
_drawer = UI.panel(self)
|
||
_drawer.name = "SectionPanel"
|
||
MENU.style(_drawer)
|
||
var stack := VBoxContainer.new()
|
||
stack.add_theme_constant_override("separation",8)
|
||
_drawer.add_child(stack)
|
||
var row := HBoxContainer.new()
|
||
stack.add_child(row)
|
||
_drawer_title = MENU.label(row,"",18,MENU.GOLD)
|
||
_drawer_title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
MENU.button(row,"×",_close_section).custom_minimum_size.x = 32
|
||
var scroll := ScrollContainer.new()
|
||
scroll.name = "SectionScroll"
|
||
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
||
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
||
stack.add_child(scroll)
|
||
_content = VBoxContainer.new()
|
||
_content.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
_content.add_theme_constant_override("separation",8)
|
||
scroll.add_child(_content)
|
||
|
||
func _layout() -> void:
|
||
if not is_instance_valid(_drawer): return
|
||
var viewport_size := size
|
||
var storage: bool = _tab == "storage" or (_tab == "expansion_3" and deck.is_built(_tab))
|
||
var width := minf(700 if storage else (440 if _tab == "hangar" else 490),viewport_size.x-32)
|
||
var target_height := 420 if _tab == "hangar" else (520 if _tab == "workshop" else (600 if storage else (300 if _tab == "command" else 260)))
|
||
var height := minf(target_height,maxf(240,viewport_size.y-140))
|
||
_drawer.position = Vector2(16 if _tab == "hangar" else viewport_size.x-width-16,maxf(90,(viewport_size.y-height)*0.5))
|
||
_drawer.size = Vector2(width,height)
|
||
if is_instance_valid(_storage_columns): _storage_columns.columns = 2 if width >= 640 else 1
|
||
|
||
func _sync_header() -> void:
|
||
if is_instance_valid(_wallet):
|
||
_wallet.text = "%d KREDYTÓW\n%d CZĘŚCI" % [captain.credits,floori(captain.parts)]
|
||
|
||
func _hover_section(section: String) -> void:
|
||
var data: Dictionary = deck.room(section)
|
||
_hint.text = "%s / %s" % [data.title,data.status] if not data.is_empty() else "Wybierz pomieszczenie na pokładzie. · Warsztat i hangar są dostępne."
|
||
|
||
func _select_section(section: String) -> void:
|
||
var room: Dictionary = deck.room("expansion_3" if section == "storage" else section)
|
||
var pan: float = 0.0 if room.is_empty() else ((room.rect as Rect2).get_center().x / deck.DESIGN_SIZE.x - 0.5)*1.4
|
||
_audio.enter_section(section,pan)
|
||
_storage_notice = ""
|
||
_tab = section
|
||
deck.selected = section
|
||
_refresh()
|
||
|
||
func _close_section() -> void:
|
||
_audio.close_section()
|
||
_tab = "overview"
|
||
deck.selected = ""
|
||
_drawer.hide()
|
||
deck.queue_redraw()
|
||
|
||
func _input(event: InputEvent) -> void:
|
||
if not event is InputEventKey or not event.pressed or event.echo:
|
||
return
|
||
if event.keycode not in [KEY_L,KEY_ESCAPE]:
|
||
return
|
||
# Docking removes this scene immediately, so consume input before emitting closed.
|
||
get_viewport().set_input_as_handled()
|
||
if event.keycode == KEY_L:
|
||
closed.emit()
|
||
elif _drawer.visible:
|
||
_close_section()
|
||
else:
|
||
closed.emit()
|
||
|
||
func _label(text: String, size_value := 14, color := Color("c5d3d7")) -> Label:
|
||
var node := MENU.label(_content,text,size_value,color)
|
||
node.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||
return node
|
||
|
||
func _refresh() -> void:
|
||
_storage_columns = null
|
||
_audio.set_maintenance_needed(captain.expedition.lander_hp < 30)
|
||
for child in _content.get_children():
|
||
_content.remove_child(child)
|
||
child.queue_free()
|
||
_sync_header()
|
||
if _tab == "overview":
|
||
_drawer.hide()
|
||
return
|
||
_drawer.show()
|
||
_layout()
|
||
_content.get_parent().set("scroll_vertical",0)
|
||
if _tab == "workshop":
|
||
_drawer_title.text = "WARSZTAT"
|
||
_build_workshop()
|
||
elif _tab == "hangar":
|
||
_drawer_title.text = "HANGAR / OBSŁUGA"
|
||
_build_hangar()
|
||
elif _tab == "command":
|
||
_drawer_title.text = "CENTRUM DOWODZENIA"
|
||
_build_command()
|
||
elif _tab == "storage" or (_tab == "expansion_3" and deck.is_built(_tab)):
|
||
_drawer_title.text = "MAGAZYN FRACHTOWCA"
|
||
_build_storage()
|
||
else:
|
||
_build_room()
|
||
|
||
func _build_room() -> void:
|
||
var section: Dictionary = deck.room(_tab)
|
||
_drawer_title.text = str(section.get("title","SEKCJA ROZWOJOWA"))
|
||
if not deck.is_buildable(_tab):
|
||
_label("Wybierz pomieszczenie na pokładzie.")
|
||
return
|
||
var plan: Dictionary = deck.plan(_tab)
|
||
_label("ZBUDOWANO" if deck.is_built(_tab) else "W REMONCIE",21,UI.CYAN if deck.is_built(_tab) else Color("e0b16a"))
|
||
_label(str(plan.description))
|
||
if str(plan.kind) == "alien_research":
|
||
_label("Próbki oczekujące na analizę: %d" % captain.expedition.analysis_samples,16,UI.CYAN)
|
||
_label("Próbki z jaskiń są przechowywane po powrocie. Analiza będzie dostępna później.",13)
|
||
if deck.is_built(_tab):
|
||
_label("Pomieszczenie jest wyposażone. Jego mechanika zostanie dodana w kolejnym etapie.",14,Color("849da5"))
|
||
else:
|
||
_label("Budowa jest teraz bezpłatna. Wyposażenie pojawi się od razu na pokładzie.",14,Color("849da5"))
|
||
MENU.button(_content,"ZBUDUJ · BEZ KOSZTÓW",_construct_room.bind(_tab))
|
||
MENU.button(_content,"Wróć na pokład",_close_section)
|
||
|
||
func _construct_room(id: String) -> void:
|
||
if not deck.is_buildable(id) or deck.is_built(id): return
|
||
captain.expedition.freighter_rooms[id] = str(deck.plan(id).kind)
|
||
captain.expedition.emit_changed()
|
||
deck.sync_rooms(captain.expedition.freighter_rooms)
|
||
_audio.service_completed()
|
||
_hover_section(id)
|
||
_refresh()
|
||
|
||
func _build_hangar() -> void:
|
||
var progress: Resource = captain.expedition
|
||
MENU.hero(_content,"hangar","")
|
||
var ship_row := MENU.row(_content)
|
||
MENU.icon(ship_row,deck.ship_texture,32)
|
||
var ship_text := VBoxContainer.new()
|
||
ship_text.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
ship_row.add_child(ship_text)
|
||
MENU.label(ship_text,deck.ship_name,15,MENU.GOLD)
|
||
MENU.label(ship_text,"Żelazo %d · Części %d" % [int(captain.minerals.get("iron",0)),int(captain.parts)],12,MENU.MUTED)
|
||
var service := MENU.card(_content)
|
||
MENU.style(service.get_parent(),8,0.70)
|
||
var row := MENU.row(service)
|
||
MENU.icon(row,preload("res://assets/planets/lander.png"),34)
|
||
var info := VBoxContainer.new()
|
||
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
row.add_child(info)
|
||
MENU.label(info,"Lądownik · %d%%" % ceili(progress.lander_hp),13,MENU.GOLD)
|
||
var bar := ProgressBar.new()
|
||
bar.value = progress.lander_hp
|
||
bar.show_percentage = false
|
||
bar.custom_minimum_size.y = 5
|
||
var fill := StyleBoxFlat.new()
|
||
fill.bg_color = Color("85b7a0")
|
||
fill.set_corner_radius_all(3)
|
||
bar.add_theme_stylebox_override("fill",fill)
|
||
info.add_child(bar)
|
||
var cost: int = progress.repair_cost()
|
||
var cost_row := MENU.row(info)
|
||
MENU.icon(cost_row,RECIPES.icon("parts"),14)
|
||
var repair_cost := MENU.label(cost_row,str(cost),11,MENU.MUTED)
|
||
repair_cost.name = "RepairCost"
|
||
repair_cost.autowrap_mode = TextServer.AUTOWRAP_OFF
|
||
var repair := MENU.button(row,"Napraw",func():
|
||
if progress.repair(captain): _audio.service_completed(0.65)
|
||
_refresh(),true)
|
||
repair.name = "RepairLander"
|
||
repair.custom_minimum_size = Vector2(58,26)
|
||
repair.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||
repair.tooltip_text = "Napraw do 100%% · koszt %d części. Pełny kadłub wymagany do lądowania." % cost
|
||
repair.disabled = cost == 0 or captain.parts < cost
|
||
_build_slot_upgrades()
|
||
var delivery := MENU.card(_content)
|
||
MENU.style(delivery.get_parent(),8,0.70)
|
||
var delivery_row := MENU.row(delivery)
|
||
MENU.icon(delivery_row,preload("res://assets/icons/shield.png"),24)
|
||
var label := MENU.label(delivery_row,"Odzyskane moduły · %d" % progress.delivered_modules.size(),12,MENU.MUTED)
|
||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var take := MENU.button(delivery_row,"Odbierz",func():
|
||
if is_instance_valid(inventory): progress.deliver_modules(inventory)
|
||
_refresh())
|
||
take.name = "CollectRecovered"
|
||
take.custom_minimum_size = Vector2(58,26)
|
||
take.tooltip_text = "Odbierz do ładowni statku. Przedmioty bez miejsca pozostają na fregacie."
|
||
take.disabled = progress.delivered_modules.is_empty() or not is_instance_valid(inventory)
|
||
|
||
func _build_slot_upgrades() -> void:
|
||
if not is_instance_valid(inventory):
|
||
_label("Zadokuj statkiem, aby rozbudować sloty.",12,MENU.MUTED)
|
||
return
|
||
_label("ROZBUDOWA STATKU",13,MENU.GOLD)
|
||
var grid := GridContainer.new()
|
||
grid.columns = 3
|
||
grid.add_theme_constant_override("h_separation",6)
|
||
_content.add_child(grid)
|
||
for kind in ["cargo","weapon","extension"]:
|
||
var count: int = inventory.unlocked_cargo_rows if kind == "cargo" else (inventory.unlocked_weapon_slots if kind == "weapon" else inventory.unlocked_extension_slots)
|
||
var limit: int = inventory.CARGO_ROW_COUNT if kind == "cargo" else (inventory.WEAPON_SLOT_COUNT if kind == "weapon" else inventory.EXTENSION_SLOT_COUNT)
|
||
var card := MENU.card(grid)
|
||
MENU.style(card.get_parent(),6,0.70)
|
||
card.add_theme_constant_override("separation",4)
|
||
var row := MENU.row(card)
|
||
row.add_theme_constant_override("separation",5)
|
||
var icons := {"cargo":"res://assets/icons/cargo_crate.svg","weapon":"res://assets/icons/machine_gun.png","extension":"res://assets/icons/computer.png"}
|
||
MENU.icon(row,load(icons[kind]),26)
|
||
var title := VBoxContainer.new()
|
||
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
row.add_child(title)
|
||
MENU.label(title,{"cargo":"Ładownia","weapon":"Broń","extension":"Rozszerzenia"}[kind],11,MENU.TEXT)
|
||
MENU.label(title,"%d / %d" % [count,limit],11,MENU.MUTED)
|
||
var action := MENU.row(card)
|
||
action.add_theme_constant_override("separation",4)
|
||
MENU.icon(action,RECIPES.icon("iron"),14)
|
||
var price := MENU.label(action,"10",11,MENU.MUTED)
|
||
price.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var unlock := MENU.button(action,"+1" if count < limit else "✓",_unlock_ship_slot.bind(kind),true)
|
||
unlock.name = "Unlock"+kind.capitalize()
|
||
unlock.custom_minimum_size = Vector2(30,24)
|
||
unlock.tooltip_text = "Osiągnięto limit." if count >= limit else "Odblokuj %s · koszt 10 żelaza." % ("rząd ładowni (+5 miejsc)" if kind == "cargo" else "kolejny slot")
|
||
unlock.disabled = not (inventory.can_unlock_cargo_row(captain) if kind == "cargo" else inventory.can_unlock_slot(kind,captain))
|
||
|
||
func _unlock_ship_slot(kind: String) -> void:
|
||
if is_instance_valid(inventory):
|
||
if kind == "cargo": inventory.unlock_cargo_row(captain)
|
||
else: inventory.unlock_slot(kind,captain)
|
||
_refresh()
|
||
|
||
func _build_storage() -> void:
|
||
MENU.hero(_content,"storage","MAGAZYN / ZASOBY I WYPOSAŻENIE")
|
||
if not deck.is_built("expansion_3"):
|
||
_build_resource_overview()
|
||
var construction := MENU.card(_content)
|
||
MENU.label(construction,"SKŁAD MODUŁÓW W REMONCIE",15,MENU.GOLD)
|
||
MENU.button(construction,"ZBUDUJ SKŁAD · BEZ KOSZTÓW",_construct_room.bind("expansion_3"),true)
|
||
return
|
||
if not is_instance_valid(inventory): return
|
||
_label("MODUŁY / Kliknij ikonę, aby przenieść przedmiot",14,MENU.GOLD)
|
||
if not _storage_notice.is_empty(): _label(_storage_notice,12,MENU.GOLD)
|
||
_storage_columns = GridContainer.new()
|
||
_storage_columns.columns = 2 if _drawer.size.x >= 640 else 1
|
||
_storage_columns.add_theme_constant_override("h_separation",12)
|
||
_storage_columns.add_theme_constant_override("v_separation",12)
|
||
_content.add_child(_storage_columns)
|
||
for retrieve in [false,true]:
|
||
var column := VBoxContainer.new()
|
||
column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
column.add_theme_constant_override("separation",6)
|
||
_storage_columns.add_child(column)
|
||
var storage: Array = captain.expedition.freighter_storage
|
||
MENU.label(column,"FREGATA · %d" % storage.size() if retrieve else "STATEK · %d / %d" % [inventory.get_cargo_used(),inventory.get_cargo_capacity()],14,MENU.GOLD)
|
||
var bulk := MENU.button(column,"← Odbierz wszystko" if retrieve else "Odłóż wszystko →",_transfer_all.bind(retrieve))
|
||
bulk.disabled = storage.is_empty() or inventory.get_cargo_used() >= inventory.get_cargo_capacity() if retrieve else inventory.get_cargo_used() == 0
|
||
var grid := GridContainer.new()
|
||
grid.name = "FreighterSlots" if retrieve else "ShipSlots"
|
||
grid.columns = 5
|
||
grid.add_theme_constant_override("h_separation",4)
|
||
grid.add_theme_constant_override("v_separation",4)
|
||
column.add_child(grid)
|
||
var count: int = maxi(20,ceili(storage.size()/5.0)*5) if retrieve else inventory.CARGO_SIZE
|
||
for index in count:
|
||
var item: ItemInstance = storage[index] if retrieve and index < storage.size() else (inventory.get_item("cargo",index) if not retrieve else null)
|
||
var slot := Button.new()
|
||
slot.set_script(preload("res://scripts/planets/freighter_storage_slot.gd"))
|
||
slot.item = item
|
||
slot.retrieve = retrieve
|
||
slot.locked = not retrieve and index >= inventory.get_cargo_capacity()
|
||
if item != null: slot.transfer = _transfer_storage.bind(retrieve,index,item)
|
||
grid.add_child(slot)
|
||
if retrieve and item != null: slot.disabled = inventory.get_cargo_used() >= inventory.get_cargo_capacity()
|
||
_label("ZAMONTOWANE NA STATKU",12,MENU.MUTED)
|
||
var mounted := HFlowContainer.new()
|
||
_content.add_child(mounted)
|
||
for group in [inventory.weapon_slots,inventory.module_slots,inventory.extension_slots]:
|
||
for item in group:
|
||
if item == null: continue
|
||
var picture := MENU.icon(mounted,item.definition.icon,32)
|
||
picture.mouse_filter = Control.MOUSE_FILTER_STOP
|
||
picture.tooltip_text = item.get_tooltip_text()+"\nZamontowane — najpierw zdejmij do ładowni."
|
||
_label("SPRZĘT KAPITANA · %d szt. ODZYSKANE MODUŁY · %d" % [captain.gear_items.size(),captain.expedition.delivered_modules.size()],12,MENU.MUTED)
|
||
var owned := HFlowContainer.new()
|
||
_content.add_child(owned)
|
||
for gear in captain.gear_items:
|
||
var picture := MENU.icon(owned,GEAR.icon(str(gear.kind)),28)
|
||
picture.mouse_filter = Control.MOUSE_FILTER_STOP
|
||
picture.tooltip_text = "%s · poziom %d" % [GEAR.NAMES[gear.kind],gear.level]
|
||
for item in captain.expedition.delivered_modules:
|
||
var picture := MENU.icon(owned,item.definition.icon,28)
|
||
picture.mouse_filter = Control.MOUSE_FILTER_STOP
|
||
picture.tooltip_text = item.get_tooltip_text()+"\nOdbierz w Hangarze."
|
||
_content.add_child(HSeparator.new())
|
||
_build_resource_overview()
|
||
|
||
func _build_resource_overview() -> void:
|
||
_label("ZAPASY GRACZA",14,MENU.GOLD)
|
||
var grid := GridContainer.new()
|
||
grid.name = "ResourceOverview"
|
||
grid.columns = 4 if _drawer.size.x >= 600 else 3
|
||
grid.add_theme_constant_override("h_separation",6)
|
||
grid.add_theme_constant_override("v_separation",5)
|
||
_content.add_child(grid)
|
||
var values: Dictionary = {"credits":captain.credits,"parts":int(captain.parts)}
|
||
for key in RECIPES.MINERALS+preload("res://scripts/planets/planet_profiles.gd").MATERIALS:
|
||
values[key] = int(captain.minerals.get(key,0))
|
||
for key in captain.minerals: values[key] = int(captain.minerals[key])
|
||
if is_instance_valid(inventory):
|
||
for key in ["ammunition","missile","irradiated_ammunition","energy_bank"]: values[key] = inventory.get_crafted_stock(key)
|
||
values.samples = captain.expedition.analysis_samples
|
||
var names: Dictionary = RECIPES.NAMES.duplicate()
|
||
names.merge(GEAR.MATERIAL_NAMES)
|
||
names.merge({"credits":"Kredyty","parts":"Części","ammunition":"Amunicja","missile":"Rakiety","irradiated_ammunition":"Radiacyjna","energy_bank":"Powerbanki","samples":"Próbki"})
|
||
for key in values:
|
||
var tile := MENU.card(grid)
|
||
tile.get_parent().name = "Stock_"+key
|
||
var row := MENU.row(tile)
|
||
var path := "res://assets/icons/resources/%s.%s" % [key,"svg" if key in ["credits","energy_bank"] else "png"]
|
||
if ResourceLoader.exists(path): MENU.icon(row,load(path),22)
|
||
var labels := VBoxContainer.new()
|
||
labels.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
row.add_child(labels)
|
||
MENU.label(labels,str(names.get(key,key)),11,MENU.MUTED)
|
||
MENU.label(labels,str(values[key]),13,MENU.GOLD)
|
||
tile.get_parent().tooltip_text = "%s: %d" % [names.get(key,key),values[key]]
|
||
|
||
func _transfer_all(retrieve: bool) -> void:
|
||
if not is_instance_valid(inventory): return
|
||
var count := 0
|
||
if retrieve:
|
||
for index in range(captain.expedition.freighter_storage.size()-1,-1,-1):
|
||
if inventory.retrieve_from_freighter(index,captain.expedition.freighter_storage[index],captain): count += 1
|
||
else:
|
||
for index in range(inventory.get_cargo_capacity()-1,-1,-1):
|
||
var item: ItemInstance = inventory.get_item("cargo",index)
|
||
if item != null and inventory.store_on_freighter(index,item,captain): count += 1
|
||
_storage_notice = "Przeniesiono %d przedmiotów." % count
|
||
_refresh()
|
||
|
||
func _transfer_storage(retrieve: bool, index: int, expected: ItemInstance) -> void:
|
||
if not is_instance_valid(inventory): return
|
||
if retrieve: inventory.retrieve_from_freighter(index,expected,captain)
|
||
else: inventory.store_on_freighter(index,expected,captain)
|
||
_refresh()
|
||
|
||
func _build_supply_production() -> void:
|
||
for group in [["AMUNICJA I RAKIETY",["ammunition","missile","irradiated_ammunition"]],["ZAOPATRZENIE",["parts","energy_bank"]]]:
|
||
_label(group[0],13,MENU.GOLD)
|
||
var grid := GridContainer.new()
|
||
grid.columns = 3
|
||
grid.add_theme_constant_override("h_separation",6)
|
||
_content.add_child(grid)
|
||
for id in group[1]:
|
||
var recipe: Dictionary = RECIPES.DATA[id]
|
||
var card := MENU.card(grid)
|
||
MENU.style(card.get_parent(),6)
|
||
card.add_theme_constant_override("separation",4)
|
||
card.get_parent().tooltip_text = recipe.name+" · partia: %d szt." % recipe.amount
|
||
var row := MENU.row(card)
|
||
MENU.icon(row,RECIPES.icon(id),28)
|
||
var stock := MENU.label(row,str(inventory.get_crafted_stock(id) if is_instance_valid(inventory) else 0),13,MENU.GOLD)
|
||
stock.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var actions := MENU.row(card)
|
||
actions.add_theme_constant_override("separation",4)
|
||
for batches in [1,10]:
|
||
var button := MENU.button(actions,"+%d" % batches,_craft_supply.bind(id,batches),true)
|
||
button.name = ("Craft_" if batches == 1 else "Craft10_")+id
|
||
button.custom_minimum_size = Vector2(36,24)
|
||
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var cost: Dictionary = recipe.cost.duplicate()
|
||
for key in cost: cost[key] = int(cost[key])*batches
|
||
button.tooltip_text = "%s: %d partii = %d szt.\nKoszt: %s" % [recipe.name,batches,int(recipe.amount)*batches,UI.material_text(cost)]
|
||
button.disabled = not _can_craft_supply(id,batches)
|
||
|
||
func _can_craft_supply(id: String, batches: int) -> bool:
|
||
if not is_instance_valid(inventory) or not RECIPES.DATA.has(id) or batches not in [1,10]: return false
|
||
for key in RECIPES.DATA[id].cost:
|
||
if int(captain.minerals.get(key,0)) < int(RECIPES.DATA[id].cost[key])*batches: return false
|
||
return true
|
||
|
||
func _craft_supply(id: String, batches := 1) -> void:
|
||
if _tab != "workshop" or not _can_craft_supply(id,batches): return
|
||
for index in batches: inventory.craft(id)
|
||
_audio.service_completed(-0.48)
|
||
_refresh()
|
||
|
||
func _build_workshop() -> void:
|
||
MENU.hero(_content,"workshop","")
|
||
_build_supply_production()
|
||
_label("EKWIPUNEK KAPITANA",13,MENU.GOLD)
|
||
var grid := GridContainer.new()
|
||
grid.columns = 3
|
||
grid.add_theme_constant_override("h_separation",6)
|
||
_content.add_child(grid)
|
||
for kind in GEAR.KINDS:
|
||
var card := MENU.card(grid)
|
||
MENU.style(card.get_parent(),6)
|
||
card.add_theme_constant_override("separation",4)
|
||
var row := MENU.row(card)
|
||
MENU.icon(row,GEAR.icon(kind),32)
|
||
var levels := MENU.label(row,"L%d → L%d" % [GEAR.level(captain,kind),GEAR.next_level(captain,kind)],12,GEAR.COLORS[kind])
|
||
levels.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var build := MENU.button(row,"+1",_craft.bind(kind),true)
|
||
build.name = "CraftGear_"+kind
|
||
build.custom_minimum_size = Vector2(36,24)
|
||
build.size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||
build.tooltip_text = "%s · poziom %d\nKoszt: %s\nWytwarza i zakłada nowy przedmiot." % [GEAR.NAMES[kind],GEAR.next_level(captain,kind),GEAR.recipe_text(captain,kind)]
|
||
card.get_parent().tooltip_text = build.tooltip_text
|
||
build.disabled = not GEAR.can_craft(captain,kind)
|
||
MENU.button(_content,"Posiadane "+("−" if _owned_open else "+"),func():
|
||
_owned_open = not _owned_open
|
||
_refresh())
|
||
if _owned_open:
|
||
for gear in captain.gear_items:
|
||
var equipped: bool = captain.gear_slots.get(gear.kind,-1) == gear.uid
|
||
var label_text := "%s · L%d%s" % [GEAR.NAMES[gear.kind],gear.level," [ZAŁOŻONE]" if equipped else ""]
|
||
var button := MENU.button(_content,label_text,_equip.bind(gear.kind,gear.uid))
|
||
button.disabled = equipped
|
||
|
||
func _build_command() -> void:
|
||
var progress: Resource = captain.expedition
|
||
_label("MOSTEK / SYSTEMY NAWIGACYJNE",13,Color("8bd9d0"))
|
||
_label("Łączność z twoim statkiem jest stabilna. Fregata pozostaje gotowa do przejścia do kolejnego układu.")
|
||
_label("Zeskanowane planety: %d" % progress.scans.size(),16)
|
||
_label("Próbki do analizy w dziale badań obcych: %d" % progress.analysis_samples,15,UI.CYAN)
|
||
_label("ODZYSKANE ARCHIWA",15,UI.CYAN)
|
||
if progress.research_records.is_empty():
|
||
_label("Brak odzyskanych zapisów.",13,Color("819ca5"))
|
||
for key in progress.research_records:
|
||
_label("%s ×%d" % [key,progress.research_records[key]],13)
|
||
_label("Rozbudowa centrum dowodzenia oraz pozostałych sekcji będzie dostępna później.",13,Color("bc9e72"))
|
||
|
||
func _craft(kind: String) -> void:
|
||
if _tab != "workshop": return
|
||
var gear: Dictionary = GEAR.craft(captain,kind)
|
||
if not gear.is_empty():
|
||
GEAR.equip(captain,kind,int(gear.uid))
|
||
_audio.service_completed(-0.48)
|
||
_refresh()
|
||
|
||
func _equip(kind: String, uid: int) -> void:
|
||
GEAR.equip(captain,kind,uid)
|
||
_refresh()
|