Files

143 lines
5.1 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Core(法杖)编辑器标签 — 槽位/拓扑/CPU/施法间隔/特性/矩阵·电路结构
@tool
extends VBoxContainer
const UI = preload("res://addons/game_designer/designer_ui.gd")
const PATH = "res://data/cores.json"
const TOPO = ["线性 LINEAR", "矩阵 MATRIX", "电路 CIRCUIT"]
const FEAT = ["无 None", "记忆 PERSISTENT_MEMORY", "双流 DUAL_STREAM", "末位施法 ALWAYS_CAST_LAST", "洗牌 SHUFFLE_DECK", "无限法术 INFINITE_SPELLS"]
var _data: Dictionary = {}
var _cur: String = ""
var _list: ItemList
var _id: LineEdit
var _name: LineEdit
var _slots: SpinBox
var _topo: OptionButton
var _cpu: SpinBox
var _interval: SpinBox
var _mana_max: SpinBox
var _mana_regen: SpinBox
var _mana_leech: SpinBox
var _feat: OptionButton
var _rows: SpinBox
var _cols: SpinBox
var _edges
var _status: Label
func _ready() -> void:
add_child(UI.header("🪄 Core 编辑器 — 法杖拓扑与特性"))
_load()
_list = ItemList.new()
_list.custom_minimum_size = Vector2(0, 90)
_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(""))
_name = _row("显示名", UI.line("", "tr 键或文本"))
_slots = _row("槽位数", UI.spin(1, 20, 1, 5))
_topo = _row("拓扑", UI.opt(TOPO, 0))
_cpu = _row("CPU 上限", UI.spin(1, 40, 1, 5))
_interval = _row("施法间隔(s)", UI.spin(0.05, 5, 0.05, 0.5))
_mana_max = _row("蓝上限(Mana Max)", UI.spin(0, 1000, 5, 100))
_mana_regen = _row("回蓝/秒(Mana Regen)", UI.spin(0, 100, 0.5, 5))
_mana_leech = _row("击杀回蓝(Mana Leech)", UI.spin(0, 100, 0.5, 0))
_feat = _row("特性", UI.opt(FEAT, 0))
_rows = _row("矩阵行(MATRIX)", UI.spin(1, 8, 1, 1))
_cols = _row("矩阵列(MATRIX)", UI.spin(1, 16, 1, 5))
add_child(Label.new())
var el := Label.new(); el.text = "电路边(CIRCUITfrom → to)"; add_child(el)
_edges = preload("res://addons/game_designer/tuple_list_editor.gd").new()
_edges.setup([
{"label": "from", "min": 0, "max": 63, "step": 1, "int": true},
{"label": "→ to", "min": 0, "max": 63, "step": 1, "int": true}], " 加边")
add_child(_edges)
add_child(HSeparator.new())
var srow := HBoxContainer.new(); add_child(srow)
srow.add_child(UI.btn("✓应用", _on_apply))
srow.add_child(UI.btn("💾保存 cores.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 Dictionary else {}
func _refresh() -> void:
_list.clear()
var ids: Array = _data.keys(); ids.sort()
for cid in ids:
_list.add_item("%s%s" % [cid, _data[cid].get("display_name", "")])
_list.set_item_metadata(_list.item_count - 1, cid)
func _on_select(idx: int) -> void:
_cur = String(_list.get_item_metadata(idx))
var d: Dictionary = _data.get(_cur, {})
_id.text = _cur
_name.text = String(d.get("display_name", ""))
_slots.value = float(d.get("slot_count", 5))
_topo.selected = int(d.get("topology", 0))
_cpu.value = float(d.get("cpu_limit", 5))
_interval.value = float(d.get("cast_interval", 0.5))
_mana_max.value = float(d.get("mana_max", 100))
_mana_regen.value = float(d.get("mana_regen", 5))
_mana_leech.value = float(d.get("mana_leech", 0))
_feat.selected = int(d.get("feature_tags", 0))
_rows.value = float(d.get("grid_rows", 1))
_cols.value = float(d.get("grid_cols", 5))
var erows := []
for e in d.get("edges", []):
erows.append([int(e.get("from", 0)), int(e.get("to", 0))])
_edges.set_values(erows)
func _on_apply() -> void:
var cid: String = _id.text.strip_edges()
if cid == "":
UI.set_status(_status, "✗ ID 不能为空", true); return
var edges := []
for r in _edges.get_values():
edges.append({"from": r[0], "to": r[1]})
if _cur != "" and _cur != cid and _data.has(_cur):
_data.erase(_cur)
_data[cid] = {
"display_name": _name.text, "slot_count": int(_slots.value),
"topology": _topo.selected, "cpu_limit": int(_cpu.value),
"cast_interval": _interval.value, "feature_tags": _feat.selected,
"mana_max": int(_mana_max.value), "mana_regen": _mana_regen.value,
"mana_leech": _mana_leech.value,
"grid_rows": int(_rows.value), "grid_cols": int(_cols.value), "edges": edges,
}
_cur = cid
_refresh()
UI.set_status(_status, "✓ 已应用『%s』(记得保存)" % cid)
func _on_new() -> void:
var cid := "new_core"
var i := 1
while _data.has(cid): cid = "new_core_%d" % i; i += 1
_data[cid] = {"display_name": cid, "slot_count": 5, "topology": 0,
"cpu_limit": 5, "cast_interval": 0.5, "feature_tags": 0,
"mana_max": 100, "mana_regen": 5, "mana_leech": 0, "edges": []}
_refresh()
func _on_delete() -> void:
if _cur != "" and _data.has(_cur):
_data.erase(_cur); _cur = ""; _refresh()
UI.set_status(_status, "已删除(记得保存)")
func _save() -> void:
if UI.save_json(PATH, _data):
UI.set_status(_status, "💾 已保存 %d 个 Core(重启 F5 生效)" % _data.size())
else:
UI.set_status(_status, "✗ 保存失败", true)