78 lines
2.9 KiB
GDScript
78 lines
2.9 KiB
GDScript
## 平衡编辑器标签 — 难度乘子(3 档)+ Boss 基础血量
|
||
@tool
|
||
extends VBoxContainer
|
||
|
||
const UI = preload("res://addons/game_designer/designer_ui.gd")
|
||
const PATH = "res://data/balance.json"
|
||
const MULT_KEYS = ["enemy_hp", "player_dmg", "wave_count", "boss_hp"]
|
||
const MULT_LABELS = ["敌人血量×", "玩家受伤×", "波次怪数×", "Boss血量×"]
|
||
const DIFF_NAMES = ["初学者", "标准", "挑战"]
|
||
|
||
var _data: Dictionary = {}
|
||
var _mult_spins: Dictionary = {} # key → [SpinBox ×3]
|
||
var _miniboss: SpinBox
|
||
var _boss: SpinBox
|
||
var _aether
|
||
var _status: Label
|
||
|
||
func _ready() -> void:
|
||
add_child(UI.header("⚖ 平衡编辑器 — 难度乘子 & Boss 血量"))
|
||
_load()
|
||
# 难度乘子表格:4 行 × 3 难度
|
||
var grid := GridContainer.new(); grid.columns = 4; add_child(grid)
|
||
grid.add_child(Label.new()) # 角
|
||
for dn in DIFF_NAMES:
|
||
var l := Label.new(); l.text = dn; l.modulate = Color(0.7, 0.8, 1.0)
|
||
grid.add_child(l)
|
||
var mults: Dictionary = _data.get("difficulty_mults", {})
|
||
for i in MULT_KEYS.size():
|
||
var key: String = MULT_KEYS[i]
|
||
grid.add_child(UI.cell_label(MULT_LABELS[i]))
|
||
var arr: Array = mults.get(key, [1.0, 1.0, 1.0])
|
||
var spins: Array = []
|
||
for d in 3:
|
||
var sp := UI.spin(0.0, 10.0, 0.05, float(arr[d]) if d < arr.size() else 1.0)
|
||
grid.add_child(sp); spins.append(sp)
|
||
_mult_spins[key] = spins
|
||
add_child(HSeparator.new())
|
||
# Boss 基础血量
|
||
var bhp: Dictionary = _data.get("boss_hp", {})
|
||
var h1 := HBoxContainer.new(); add_child(h1)
|
||
h1.add_child(UI.cell_label("MiniBoss(W8) 血量"))
|
||
_miniboss = UI.spin(1, 999999, 10, float(bhp.get("4", 450)))
|
||
h1.add_child(_miniboss)
|
||
var h2 := HBoxContainer.new(); add_child(h2)
|
||
h2.add_child(UI.cell_label("Final Boss(W20) 血量"))
|
||
_boss = UI.spin(1, 999999, 10, float(bhp.get("5", 1800)))
|
||
h2.add_child(_boss)
|
||
add_child(HSeparator.new())
|
||
var al := Label.new(); al.text = "碎片奖励阈值 aether_thresholds(波次 → 碎片)"; add_child(al)
|
||
_aether = preload("res://addons/game_designer/tuple_list_editor.gd").new()
|
||
_aether.setup([
|
||
{"label": "波次", "min": 1, "max": 9999, "step": 1, "int": true},
|
||
{"label": "碎片", "min": 0, "max": 9999, "step": 1, "int": true}], "➕ 加行")
|
||
add_child(_aether)
|
||
_aether.set_values(_data.get("aether_thresholds", [[1, 0], [5, 3], [10, 8], [15, 14], [20, 20]]))
|
||
add_child(UI.btn("💾 保存 balance.json", _save))
|
||
_status = UI.status_label(); add_child(_status)
|
||
|
||
func _load() -> void:
|
||
var d = UI.load_json(PATH)
|
||
_data = d if d is Dictionary else {}
|
||
|
||
func _save() -> void:
|
||
var mults: Dictionary = {}
|
||
for key in MULT_KEYS:
|
||
var spins: Array = _mult_spins[key]
|
||
mults[key] = [spins[0].value, spins[1].value, spins[2].value]
|
||
var thresholds = _aether.get_values()
|
||
var out := {
|
||
"difficulty_mults": mults,
|
||
"boss_hp": {"4": _miniboss.value, "5": _boss.value},
|
||
"aether_thresholds": thresholds,
|
||
}
|
||
if UI.save_json(PATH, out):
|
||
UI.set_status(_status, "💾 已保存(重启 F5 生效)")
|
||
else:
|
||
UI.set_status(_status, "✗ 保存失败", true)
|