Files
spellforge/addons/game_designer/wave_tab.gd
T
2026-07-20 10:56:52 +08:00

87 lines
3.1 KiB
GDScript
Raw 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.
## 波次编辑器标签(关卡难度曲线:每波 怪数/血量/类型/精英/金币/XP/Boss
@tool
extends VBoxContainer
const UI = preload("res://addons/game_designer/designer_ui.gd")
const PATH = "res://data/waves.json"
const TYPE_NAMES = ["Basic", "Fast", "Armored", "Elite", "MiniBoss", "Boss"]
const BOSS_NAMES = ["无", "MiniBoss(4)", "Boss(5)"] # 映射到 boss 值 -1/4/5
const BOSS_VALS = [-1, 4, 5]
var _waves: Array = []
var _rows: Array = []
var _status: Label
func _ready() -> void:
_build()
func _build() -> void:
add_child(UI.header("🌊 波次编辑器 — 关卡难度曲线(点行号添加/删除波次)"))
_load()
var scroll := ScrollContainer.new()
scroll.custom_minimum_size = Vector2(0, 260)
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
add_child(scroll)
var grid := GridContainer.new()
grid.columns = 8
scroll.add_child(grid)
for h in ["波", "怪数", "血量", "类型", "精英", "金币", "XP", "Boss"]:
var hl := Label.new(); hl.text = h; hl.modulate = Color(0.7, 0.8, 1.0)
grid.add_child(hl)
for i in _waves.size():
_add_row(grid, i, _waves[i])
add_child(HSeparator.new())
var row := HBoxContainer.new(); add_child(row)
row.add_child(UI.btn(" 末尾加一波", _on_add))
row.add_child(UI.btn("💾 保存 waves.json", _save))
_status = UI.status_label()
add_child(_status)
func _add_row(grid: GridContainer, idx: int, w: Dictionary) -> void:
grid.add_child(UI.cell_label("W%d" % (idx + 1)))
var count := UI.spin(0, 2000, 1, float(w.get("count", 20)))
var hp := UI.spin(1, 99999, 1, float(w.get("hp", 15)))
var type_o := UI.opt(TYPE_NAMES, int(w.get("type", 0)))
var elite := UI.spin(0, 100, 1, float(w.get("elite", 0)))
var gold := UI.spin(0, 99999, 1, float(w.get("gold", 10)))
var xp := UI.spin(0, 99999, 1, float(w.get("xp", 20)))
var boss_idx := BOSS_VALS.find(int(w.get("boss", -1)))
var boss_o := UI.opt(BOSS_NAMES, max(0, boss_idx))
grid.add_child(count); grid.add_child(hp); grid.add_child(type_o)
grid.add_child(elite); grid.add_child(gold); grid.add_child(xp); grid.add_child(boss_o)
_rows.append({"count": count, "hp": hp, "type": type_o, "elite": elite,
"gold": gold, "xp": xp, "boss": boss_o})
func _load() -> void:
var d = UI.load_json(PATH)
_waves = d if d is Array else []
func _on_add() -> void:
_waves = _read_rows()
_waves.append({"count": 30, "hp": 50, "type": 0, "elite": 0, "gold": 30, "xp": 40, "boss": -1})
_rebuild()
func _rebuild() -> void:
# 简易重建:清空后重新 _init 逻辑(移除所有子节点重建)
for c in get_children():
c.queue_free()
_rows.clear()
call_deferred("_build")
func _read_rows() -> Array:
var out: Array = []
for r in _rows:
out.append({
"count": int(r["count"].value), "hp": r["hp"].value,
"type": r["type"].selected, "elite": int(r["elite"].value),
"gold": int(r["gold"].value), "xp": int(r["xp"].value),
"boss": BOSS_VALS[r["boss"].selected],
})
return out
func _save() -> void:
if UI.save_json(PATH, _read_rows()):
UI.set_status(_status, "💾 已保存 %d 波(重启游戏 F5 生效)" % _rows.size())
else:
UI.set_status(_status, "✗ 保存失败", true)