neon-sprawl/client/scripts/craft_recipe_panel.gd

110 lines
3.5 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 VBoxContainer
## NEO-74: prototype recipe list with per-row Craft buttons.
## NEO-122: rows live in economy BodyScroll (no nested scroll).
signal craft_requested(recipe_id: String)
const PrototypeHudTheme := preload("res://scripts/prototype_hud_theme.gd")
const HudThemeConstants := preload("res://scripts/prototype_hud_theme_constants.gd")
var _item_defs_client: Node = null
var _craft_buttons: Array[Button] = []
@onready var _rows: VBoxContainer = $RecipeRows
func setup(item_defs_client: Node) -> void:
_item_defs_client = item_defs_client
func populate(recipes: Array) -> void:
if not is_instance_valid(_rows):
return
for child in _rows.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 := VBoxContainer.new()
row.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_theme_constant_override("separation", 4)
var info := Label.new()
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
info.text = _format_recipe_line(recipe)
_apply_recipe_row_label(info)
row.add_child(info)
var btn_row := HBoxContainer.new()
btn_row.size_flags_horizontal = Control.SIZE_EXPAND_FILL
btn_row.alignment = BoxContainer.ALIGNMENT_END
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))
btn_row.add_child(craft_btn)
row.add_child(btn_row)
_rows.add_child(row)
_craft_buttons.append(craft_btn)
call_deferred("_scroll_economy_body_to_recipes")
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)
func _apply_recipe_row_label(label: Label) -> void:
label.add_theme_font_size_override("font_size", HudThemeConstants.FONT_SIZE_SECONDARY)
label.add_theme_constant_override("outline_size", HudThemeConstants.OUTLINE_SIZE)
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
func _scroll_economy_body_to_recipes() -> void:
var node: Node = get_parent()
while node != null:
if node.has_method("scroll_body_to_recipes"):
node.call("scroll_body_to_recipes")
return
node = node.get_parent()