88 lines
2.7 KiB
GDScript
88 lines
2.7 KiB
GDScript
extends Control
|
||
|
||
## NEO-74: scrollable prototype recipe list with per-row Craft buttons.
|
||
|
||
const PrototypeHudTheme := preload("res://scripts/prototype_hud_theme.gd")
|
||
|
||
signal craft_requested(recipe_id: String)
|
||
|
||
var _item_defs_client: Node = null
|
||
var _craft_buttons: Array[Button] = []
|
||
|
||
@onready var _vbox: VBoxContainer = $ScrollContainer/VBoxContainer
|
||
|
||
|
||
func setup(item_defs_client: Node) -> void:
|
||
_item_defs_client = item_defs_client
|
||
|
||
|
||
func populate(recipes: Array) -> void:
|
||
if not is_instance_valid(_vbox):
|
||
return
|
||
for child in _vbox.get_children():
|
||
child.queue_free()
|
||
_craft_buttons.clear()
|
||
for row_variant in recipes:
|
||
if not row_variant is Dictionary:
|
||
continue
|
||
var recipe: Dictionary = row_variant
|
||
var recipe_id: String = str(recipe.get("id", ""))
|
||
if recipe_id.is_empty():
|
||
continue
|
||
var row := HBoxContainer.new()
|
||
row.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
var info := Label.new()
|
||
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||
info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||
info.text = _format_recipe_line(recipe)
|
||
PrototypeHudTheme.apply_to_label(info, false)
|
||
row.add_child(info)
|
||
var craft_btn := Button.new()
|
||
craft_btn.text = "Craft"
|
||
PrototypeHudTheme.apply_to_button(craft_btn, false)
|
||
craft_btn.pressed.connect(_on_craft_pressed.bind(recipe_id))
|
||
row.add_child(craft_btn)
|
||
_vbox.add_child(row)
|
||
_craft_buttons.append(craft_btn)
|
||
|
||
|
||
func set_craft_busy(busy: bool) -> void:
|
||
for btn in _craft_buttons:
|
||
if is_instance_valid(btn):
|
||
btn.disabled = busy
|
||
|
||
|
||
func _format_recipe_line(recipe: Dictionary) -> String:
|
||
var recipe_id: String = str(recipe.get("id", ""))
|
||
var display_name: String = str(recipe.get("displayName", recipe_id))
|
||
var inputs_line: String = _format_inputs(recipe.get("inputs", []))
|
||
return "%s (%s)\nneeds: %s" % [display_name, recipe_id, inputs_line]
|
||
|
||
|
||
func _format_inputs(raw_inputs: Variant) -> String:
|
||
if raw_inputs == null or not raw_inputs is Array:
|
||
return "—"
|
||
var parts: PackedStringArray = PackedStringArray()
|
||
for row_variant in raw_inputs as Array:
|
||
if not row_variant is Dictionary:
|
||
continue
|
||
var row: Dictionary = row_variant
|
||
var item_id: String = str(row.get("itemId", ""))
|
||
var qty: int = int(row.get("quantity", 0))
|
||
if item_id.is_empty() or qty <= 0:
|
||
continue
|
||
parts.append("%d× %s" % [qty, _item_display_name(item_id)])
|
||
if parts.is_empty():
|
||
return "—"
|
||
return ", ".join(parts)
|
||
|
||
|
||
func _item_display_name(item_id: String) -> String:
|
||
if is_instance_valid(_item_defs_client) and _item_defs_client.has_method("display_name_for"):
|
||
return str(_item_defs_client.call("display_name_for", item_id))
|
||
return item_id
|
||
|
||
|
||
func _on_craft_pressed(recipe_id: String) -> void:
|
||
craft_requested.emit(recipe_id)
|