Files
mtgodot-poc/project/system_menu_ui_test.gd
T

159 lines
6.5 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.
# system_menu_ui_test —— ESC 系统菜单 + 游戏设置窗 headless 自检(真 uiscript + 假 client)。
# godot --headless --path project --script system_menu_ui_test.gd
# 校验 systemdialog.py / gameoptiondialog.py 装载、/setblockmode + /pkmode 真命令、
# /in_game_mall + /phase_select + /logout、显示开关持久化。缺 uiscript 时优雅跳过。
extends SceneTree
const GameOptionUI = preload("res://ui/game_option_ui.gd")
const SystemMenuUI = preload("res://ui/system_menu_ui.gd")
class FakeClient extends Node:
var says: Array = []
func say(type: int, text: String) -> bool:
says.append([type, text]); return true
func last_say() -> String:
return String(says[-1][1]) if not says.is_empty() else ""
class StubWin extends Node:
var opened := 0
func open() -> void: opened += 1
var _fail := 0
func _ck(c: bool, m: String) -> void:
if not c:
_fail += 1
printerr("FAIL: " + m)
func _init() -> void:
_run()
if _fail == 0:
print("PASS: system_menu_ui_test (systemdialog + gameoptiondialog + /setblockmode /pkmode /phase_select)")
quit(0)
else:
printerr("%d check(s) failed" % _fail)
quit(1)
func _cfg_path() -> String:
return ProjectSettings.globalize_path(GameOptionUI.config_path())
func _has_say(fc, text: String) -> bool:
for s in fc.says:
if String(s[1]) == text:
return true
return false
func _run() -> void:
var assets := AssetRoot.path()
if not FileAccess.file_exists(assets.path_join("uiscript/uiscript/systemdialog.py")) \
or not FileAccess.file_exists(assets.path_join("uiscript/uiscript/gameoptiondialog.py")):
print(" (skip: no systemdialog.py / gameoptiondialog.py — assets checkout missing)")
return
if FileAccess.file_exists(_cfg_path()):
DirAccess.remove_absolute(_cfg_path())
var UiManager = load("res://ui/ui_manager.gd")
var ui: CanvasLayer = UiManager.new()
get_root().add_child(ui)
ui._ready()
var fc := FakeClient.new()
get_root().add_child(fc)
# ---------------- GameOptionUI ----------------
var go: Node = GameOptionUI.new()
get_root().add_child(go)
go.setup(ui, fc, assets)
go.open()
_ck(go.is_open(), "game_option window opened")
if not go.is_open():
return
# 屏蔽 toggle -> /setblockmode <mask ^ bit>EBlockAction 位)
(go._node("block_exchange_button") as BaseButton).pressed.emit()
_ck(fc.last_say() == "/setblockmode 1", "block exchange -> /setblockmode 1 (bit 1<<0)")
(go._node("block_party_button") as BaseButton).pressed.emit()
_ck(fc.last_say() == "/setblockmode 3", "block party -> /setblockmode 3 (1|2)")
(go._node("block_exchange_button") as BaseButton).pressed.emit()
_ck(fc.last_say() == "/setblockmode 2", "block exchange again -> /setblockmode 2 (bit cleared)")
_ck(go._block_mode == 2, "_block_mode tracked = 2")
# PK radio -> /pkmode {0,1,4,2}
(go._node("pvp_revenge") as BaseButton).pressed.emit()
_ck(fc.last_say() == "/pkmode 1", "pvp_revenge -> /pkmode 1")
(go._node("pvp_guild") as BaseButton).pressed.emit()
_ck(fc.last_say() == "/pkmode 4", "pvp_guild -> /pkmode 4")
_ck(not (go._node("pvp_revenge") as BaseButton).button_pressed, "pvp radio exclusive")
# 显示开关 -> 持久化 user://system_option.cfg [gameopt]
(go._node("always_show_name_off_button") as BaseButton).pressed.emit()
_ck(int(go._display.get("always_show_name", -1)) == 0, "always_show_name -> 0")
var cfg := ConfigFile.new()
cfg.load(_cfg_path())
_ck(int(cfg.get_value("gameopt", "always_show_name", -1)) == 0, "cfg gameopt.always_show_name persisted")
_ck(int(cfg.get_value("gameopt", "block_mode", -1)) == 2, "cfg gameopt.block_mode persisted")
# §8.4 名字色 radioname_color_normal / name_color_empire-> _display + cfg + 信号
var opt_evt := []
go.display_option_changed.connect(func(k, v): opt_evt.append([k, v]))
(go._node("name_color_empire") as BaseButton).pressed.emit()
_ck(int(go._display.get("name_color", -1)) == 1, "name_color_empire -> _display.name_color = 1")
_ck(opt_evt.size() >= 1 and opt_evt[-1] == ["name_color", 1], "name_color_empire -> display_option_changed('name_color',1)")
# §8.4 看他国目标框 radiotarget_board_view / target_board_no_viewconstinfo 默认 1 = 看)
_ck(int(go._display.get("target_board", -1)) == 1, "target_board 默认 1VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD")
(go._node("target_board_no_view") as BaseButton).pressed.emit()
_ck(int(go._display.get("target_board", -1)) == 0, "target_board_no_view -> _display.target_board = 0")
_ck(opt_evt[-1] == ["target_board", 0], "target_board_no_view -> display_option_changed('target_board',0)")
var cfg2 := ConfigFile.new()
cfg2.load(_cfg_path())
_ck(int(cfg2.get_value("gameopt", "name_color", -1)) == 1, "cfg gameopt.name_color persisted")
_ck(int(cfg2.get_value("gameopt", "target_board", -1)) == 0, "cfg gameopt.target_board persisted")
go.close()
# 二次实例读 cfgblock_mode 回填
var go2: Node = GameOptionUI.new()
get_root().add_child(go2)
go2.setup(ui, fc, assets)
_ck(go2._block_mode == 2, "reload: block_mode from cfg")
go2.open()
_ck((go2._node("block_party_button") as BaseButton).button_pressed, "reload: block_party button reflects bit 1<<1")
_ck(not (go2._node("block_exchange_button") as BaseButton).button_pressed, "reload: block_exchange button off")
go2.close()
# ---------------- SystemMenuUI ----------------
fc.says.clear()
var sys_opt := StubWin.new()
var game_opt := StubWin.new()
get_root().add_child(sys_opt)
get_root().add_child(game_opt)
var sm: Node = SystemMenuUI.new()
get_root().add_child(sm)
sm.setup(ui, fc, assets, sys_opt, game_opt)
sm.open()
_ck(sm.is_open(), "system menu opened")
(sm._node("mall_button") as BaseButton).pressed.emit()
_ck(_has_say(fc, "/in_game_mall"), "mall_button -> /in_game_mall")
_ck(not sm.is_open(), "mall_button closes menu")
sm.open()
(sm._node("change_button") as BaseButton).pressed.emit()
_ck(_has_say(fc, "/phase_select"), "change_button -> /phase_select (net.ExitGame)")
sm.open()
(sm._node("logout_button") as BaseButton).pressed.emit()
_ck(_has_say(fc, "/logout"), "logout_button -> /logout (net.LogOutGame)")
sm.open()
(sm._node("system_option_button") as BaseButton).pressed.emit()
_ck(sys_opt.opened == 1 and not sm.is_open(), "system_option_button -> opens system_option_ui + closes menu")
sm.open()
(sm._node("game_option_button") as BaseButton).pressed.emit()
_ck(game_opt.opened == 1 and not sm.is_open(), "game_option_button -> opens game_option_ui + closes menu")
sm.open()
(sm._node("cancel_button") as BaseButton).pressed.emit()
_ck(not sm.is_open(), "cancel_button closes menu")
if FileAccess.file_exists(_cfg_path()):
DirAccess.remove_absolute(_cfg_path())