## 共鸣配方编辑器标签 — 元素组合 → 产物法术 @tool extends VBoxContainer const UI = preload("res://addons/game_designer/designer_ui.gd") const PATH = "res://data/resonance.json" const MATCH = ["adjacent", "anywhere_in_deck"] # 存储 key const MATCH_LABELS = ["相邻 adjacent", "卡组内任意 anywhere_in_deck"] var _data: Array = [] var _cur: int = -1 var _id: LineEdit var _p0: OptionButton var _p1: OptionButton var _match: OptionButton var _result: LineEdit var _consume: CheckBox var _list: ItemList var _status: Label func _ready() -> void: add_child(UI.header("🔮 共鸣配方 — 元素组合相邻 → 自动合成产物法术")) _load() _list = ItemList.new() _list.custom_minimum_size = Vector2(0, 80) _list.item_selected.connect(_on_select) add_child(_list) var brow := HBoxContainer.new(); add_child(brow) brow.add_child(UI.btn("➕新增", _on_new)) brow.add_child(UI.btn("🗑删除", _on_delete)) add_child(HSeparator.new()) _id = _row("配方 ID", UI.line("")) _p0 = _row("元素 A", UI.opt(UI.ELEM_LABELS, 0)) _p1 = _row("元素 B", UI.opt(UI.ELEM_LABELS, 0)) _match = _row("匹配方式", UI.opt(MATCH_LABELS, 0)) _result = _row("产物法术 ID", UI.line("", "action_plasma_storm")) _consume = CheckBox.new(); _consume.text = "消耗输入法术(合成后移除原法术)" add_child(_consume) add_child(HSeparator.new()) var srow := HBoxContainer.new(); add_child(srow) srow.add_child(UI.btn("✓应用", _on_apply)) srow.add_child(UI.btn("💾保存 resonance.json", _save)) _status = UI.status_label(); add_child(_status) _refresh() func _row(label: String, ctrl: Control) -> Control: var h := HBoxContainer.new(); h.add_child(UI.cell_label(label)); h.add_child(ctrl); add_child(h) return ctrl func _load() -> void: var d = UI.load_json(PATH) _data = d if d is Array else [] func _refresh() -> void: _list.clear() for r in _data: var p: Array = r.get("pattern", ["?", "?"]) _list.add_item("%s (%s + %s)" % [r.get("id", "?"), p[0] if p.size() > 0 else "", p[1] if p.size() > 1 else ""]) func _on_select(idx: int) -> void: _cur = idx var d: Dictionary = _data[idx] var p: Array = d.get("pattern", ["", ""]) _id.text = String(d.get("id", "")) _p0.selected = max(0, UI.ELEM_TAGS.find(String(p[0])) if p.size() > 0 else 0) _p1.selected = max(0, UI.ELEM_TAGS.find(String(p[1])) if p.size() > 1 else 0) _match.selected = max(0, MATCH.find(String(d.get("match", "adjacent")))) _result.text = String(d.get("result_spell_id", "")) _consume.button_pressed = bool(d.get("consume_inputs", false)) func _on_apply() -> void: var r := { "id": _id.text.strip_edges(), "pattern": [UI.ELEM_TAGS[_p0.selected], UI.ELEM_TAGS[_p1.selected]], "match": MATCH[_match.selected], "result_spell_id": _result.text.strip_edges(), "consume_inputs": _consume.button_pressed, } if _cur >= 0 and _cur < _data.size(): _data[_cur] = r else: _data.append(r); _cur = _data.size() - 1 _refresh() UI.set_status(_status, "✓ 已应用(记得保存)") func _on_new() -> void: _data.append({"id": "new_recipe", "pattern": ["tag:water", "tag:lightning"], "match": "adjacent", "result_spell_id": "", "consume_inputs": true}) _cur = _data.size() - 1 _refresh() func _on_delete() -> void: if _cur >= 0 and _cur < _data.size(): _data.remove_at(_cur); _cur = -1; _refresh() UI.set_status(_status, "已删除(记得保存)") func _save() -> void: if UI.save_json(PATH, _data): UI.set_status(_status, "💾 已保存 %d 个配方(重启 F5 生效)" % _data.size()) else: UI.set_status(_status, "✗ 保存失败", true)