extends PanelContainer ## Üretim paneli — tarif listeler, üretim yapar. @onready var list: VBoxContainer = $Margin/VBox/Scroll/List @onready var title_label: Label = $Margin/VBox/Title @onready var close_btn: Button = $Margin/VBox/CloseBtn @onready var filter_box: HBoxContainer = $Margin/VBox/FilterBox const SKILL_LABEL := { "mining": "Madencilik", "fishing": "Balıkçılık", "foraging": "Bitki Toplama", "woodcutting": "Ağaç Kesme", "hunting": "Avcılık", "combat": "Dövüş", "smithing": "Demircilik", "alchemy": "Simyacılık", "cooking": "Yemek Pişirme", "construction": "İnşa", } var _recipes: Array = [] var _filter: String = "" func _ready() -> void: visible = false close_btn.pressed.connect(func(): visible = false) func open() -> void: visible = true title_label.text = "Üretim — yükleniyor..." _recipes = await GameState.list_recipes() _build_filters() _render() func _build_filters() -> void: for c in filter_box.get_children(): c.queue_free() var skills_seen: Dictionary = {} for r in _recipes: skills_seen[r["skill"]] = true var all_btn := Button.new() all_btn.text = "Tümü" all_btn.toggle_mode = true all_btn.button_pressed = _filter == "" all_btn.pressed.connect(func(): _filter = "" _render() _build_filters()) filter_box.add_child(all_btn) for sk in skills_seen.keys(): var b := Button.new() b.text = SKILL_LABEL.get(sk, sk) b.toggle_mode = true b.button_pressed = _filter == sk b.pressed.connect(func(): _filter = sk _render() _build_filters()) filter_box.add_child(b) func _render() -> void: for c in list.get_children(): c.queue_free() var shown := 0 title_label.text = "Üretim" for r in _recipes: if _filter != "" and r["skill"] != _filter: continue shown += 1 list.add_child(_make_row(r)) if shown == 0: var l := Label.new() l.text = "Bu kategoride tarif yok." l.add_theme_color_override("font_color", Color(0.6, 0.6, 0.6)) list.add_child(l) func _make_row(r: Dictionary) -> Control: var card := PanelContainer.new() var sb := StyleBoxFlat.new() sb.bg_color = Color(0.16, 0.18, 0.20, 1) if r.get("craftable", false) else Color(0.12, 0.13, 0.14, 1) sb.set_corner_radius_all(6) sb.set_content_margin_all(10) card.add_theme_stylebox_override("panel", sb) var vb := VBoxContainer.new() vb.add_theme_constant_override("separation", 4) card.add_child(vb) var top := HBoxContainer.new() top.add_theme_constant_override("separation", 8) vb.add_child(top) var title := Label.new() title.text = "%s → %dx %s" % [str(r["name"]), int(r["output_qty"]), str(r["output_item_name"])] title.size_flags_horizontal = Control.SIZE_EXPAND_FILL title.add_theme_font_size_override("font_size", 15) if not r.get("unlocked", false): title.add_theme_color_override("font_color", Color(0.55, 0.55, 0.55)) top.add_child(title) var btn := Button.new() btn.text = "Üret" btn.disabled = not r.get("craftable", false) btn.pressed.connect(_on_craft.bind(str(r["code"]))) top.add_child(btn) var meta := Label.new() var skill_tr: String = SKILL_LABEL.get(r["skill"], r["skill"]) meta.text = "%s Lv %d • %d adım • +%d XP" % [skill_tr, int(r["required_level"]), int(r["step_cost"]), int(r["xp_reward"])] meta.add_theme_color_override("font_color", Color(0.7, 0.7, 0.75)) meta.add_theme_font_size_override("font_size", 12) vb.add_child(meta) for ing in r["ingredients"]: var row := Label.new() var have := int(ing["have"]) var need := int(ing["qty"]) var color: Color = Color(0.6, 0.85, 0.5) if have >= need else Color(0.85, 0.4, 0.4) row.text = " • %s %d/%d" % [str(ing["item_name"]), have, need] row.add_theme_color_override("font_color", color) row.add_theme_font_size_override("font_size", 12) vb.add_child(row) if not r.get("unlocked", false): var lock := Label.new() lock.text = " 🔒 %s Lv %d gerekli" % [skill_tr, int(r["required_level"])] lock.add_theme_color_override("font_color", Color(0.9, 0.6, 0.3)) lock.add_theme_font_size_override("font_size", 12) vb.add_child(lock) return card func _on_craft(code: String) -> void: var res: Dictionary = await GameState.craft_recipe(code, 1) if not res.ok: var msg := "Üretim başarısız" if res.body is Dictionary and res.body.has("detail"): msg = str(res.body["detail"]) print("[craft fail] ", msg) # Refresh _recipes = await GameState.list_recipes() _render()