neon-sprawl/client/scripts/craft_recipe_panel.gd

88 lines
2.7 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

extends Control
## NEO-74: scrollable prototype recipe list with per-row Craft buttons.
signal craft_requested(recipe_id: String)
const PrototypeHudTheme := preload("res://scripts/prototype_hud_theme.gd")
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)