- 装备校验:can_equip 按 CanEquipNow→FindEquipCell→EquipItem 精确重排, 新增 find_equip_cell() 1:1 复刻(RING/UNIQUE 占用翻转、COSTUME/BELT/DS), 帝国 antiflag 降级为 tooltip 提示,LIMIT_PCBANG/REAL_TIME* 语义与倒计时文案 - 快捷栏:死亡全槽禁用+激活守卫、变身(affect 220)技能置灰、 物品槽失配置灰(服务器回收/换武器后刷新) - 公会:GUILD_AUTH_* 权限位门控踢人/公告/技能升级,/gskillup、 被宣战应答弹窗(/war·/nowar)、资金存取行(40250 服务端已禁用仍保留 1:1) - 好友/情侣:messenger 三固定组(好友/公会/情侣),lover_login/logout/ near/far/divorce 命令事件→在线/在身边状态与离婚隐藏 - 交易/仓库:ExchangeState.last_notice(ALREADY/LESS_GOLD)结束浮层提示; 仓库改密 /safebox_change_password 三段输入;关窗补 /safebox_close·/mall_close; 仓库金钱经核实 40250 无 wire 协议,UI 定界只读 - app_flow:重连时 guild_marks_ready 重复连接加 is_connected 守卫 - 相机 look_at 零向量守卫(首帧/传送落点) - 测试:equip/love/guild 断言更新,79 项中 78 绿(game_camera_test 为 HEAD 既有失败);真服冒烟 LIVE_SMOKE PASS(192.168.21.203 全链路) - docs/CLIENT-GAP.md 同步增量 129 Co-Authored-By: Claude Code <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018kUFvQGYusuY3dkfGitmAe
106 lines
4.1 KiB
GDScript
106 lines
4.1 KiB
GDScript
# guild_refine_test —— 公会窗 + 精炼对话框 headless 自检。
|
||
# godot --headless --path project --script guild_refine_test.gd
|
||
extends SceneTree
|
||
|
||
const GuildUI = preload("res://ui/guild_ui.gd")
|
||
const RefineUI = preload("res://ui/refine_ui.gd")
|
||
|
||
class FakeClient extends Node:
|
||
signal guild_changed()
|
||
signal refine_ask(info: Dictionary)
|
||
signal refine_result(ok: bool)
|
||
var guild := {"in_guild": false}
|
||
var members := []
|
||
var grades := []
|
||
var calls := []
|
||
func is_in_game() -> bool: return true
|
||
func get_guild() -> Dictionary: return guild
|
||
func get_guild_members() -> Array: return members
|
||
func get_guild_grades() -> Array: return grades
|
||
func get_main_pid() -> int: return 2 # Newbie(grade 3,auth 0 → 无踢人权)
|
||
func guild_deposit_money(v: int) -> bool: calls.append(["deposit", v]); return true
|
||
func guild_withdraw_money(v: int) -> bool: calls.append(["withdraw", v]); return true
|
||
func refine(pos, type) -> bool: calls.append(["refine", pos, type]); return true
|
||
|
||
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: guild_refine_test")
|
||
quit(0)
|
||
else:
|
||
printerr("%d check(s) failed" % _fail)
|
||
quit(1)
|
||
|
||
func _run() -> void:
|
||
var canvas := CanvasLayer.new()
|
||
get_root().add_child(canvas)
|
||
var fc := FakeClient.new()
|
||
get_root().add_child(fc)
|
||
|
||
# --- 公会窗 ---
|
||
var gu: Node = GuildUI.new()
|
||
get_root().add_child(gu)
|
||
gu.setup(fc, canvas)
|
||
gu.toggle()
|
||
_ck(gu.is_open(), "公会窗打开")
|
||
_ck(gu._info.text.contains("未加入"), "无公会 -> 提示")
|
||
fc.guild = {"in_guild": true, "name": "Dragons", "level": 12, "member_count": 2,
|
||
"max_member_count": 32, "gold": 500000}
|
||
fc.grades = [{"name": "会长", "auth": 15}, {"name": "官员", "auth": 7}, {"name": "会员", "auth": 0}]
|
||
fc.members = [
|
||
{"pid": 1, "name": "Master", "grade": 1, "level": 90, "offer": 99999, "general": true},
|
||
{"pid": 2, "name": "Newbie", "grade": 3, "level": 5, "offer": 10, "general": false},
|
||
]
|
||
fc.guild_changed.emit()
|
||
_ck(gu._info.text.contains("Dragons") and gu._info.text.contains("Lv.12"), "公会信息行")
|
||
# 成员页 = 1 资金行 + 2 成员行(成员行是 HBox:Label [+ 踢出按钮])
|
||
var rows: Array = gu._pages[0].get_children()
|
||
_ck(rows.size() == 3, "资金行 + 2 个成员行")
|
||
_ck(String((rows[0].get_child(0) as Label).text).contains("500000"), "资金行显示公会资金")
|
||
var member_labels: Array[String] = []
|
||
for r in rows.slice(1):
|
||
member_labels.append(String((r.get_child(0) as Label).text))
|
||
_ck(r.get_child_count() == 1, "无 REMOVE_MEMBER 权限 -> 无踢出按钮")
|
||
# 会长排前(grade 1 < grade 3)
|
||
_ck(member_labels[0].begins_with("Master"), "按 grade 排序")
|
||
_ck(member_labels[0].contains("[会长]"), "grade 名解析")
|
||
|
||
# --- 精炼对话框 ---
|
||
var ru: Node = RefineUI.new()
|
||
get_root().add_child(ru)
|
||
ru.setup(fc, canvas)
|
||
_ck(not ru.is_open(), "精炼框初始隐藏")
|
||
fc.refine_ask.emit({
|
||
"type": 1, "pos": 7, "src_vnum": 11209, "result_vnum": 11219,
|
||
"cost": 200000, "prob": 45,
|
||
"materials": [{"vnum": 30001, "count": 3}, {"vnum": 30002, "count": 1}],
|
||
})
|
||
_ck(ru.is_open(), "refine_ask -> 弹出")
|
||
_ck(ru._text.text.contains("45%") and ru._text.text.contains("200000"), "成功率 + 费用")
|
||
_ck(ru._text.text.contains("#30001 ×3"), "材料行")
|
||
# 找「精炼」按钮
|
||
var ok_btn: Button = null
|
||
for b in ru._root.find_children("*", "Button", true, false):
|
||
if b.text == "精炼":
|
||
ok_btn = b
|
||
_ck(ok_btn != null, "有「精炼」按钮")
|
||
if ok_btn:
|
||
ok_btn.pressed.emit()
|
||
_ck(fc.calls == [["refine", 7, 1]], "精炼 -> client.refine(pos=7, type=1)")
|
||
_ck(not ru.is_open(), "确认后关闭")
|
||
fc.refine_result.emit(true)
|
||
_ck(ru.is_open() and ru._text.text.contains("成功"), "精炼成功结果回显")
|
||
ru._root.visible = false
|
||
# 取消
|
||
fc.refine_ask.emit({"type": 0, "pos": 3, "src_vnum": 1, "result_vnum": 2, "cost": 0, "prob": 100, "materials": []})
|
||
for b in ru._root.find_children("*", "Button", true, false):
|
||
if b.text == "取消":
|
||
b.pressed.emit()
|
||
_ck(not ru.is_open() and fc.calls.size() == 1, "取消 -> 关闭且不发包")
|