Files
mtgodot-poc/project/guild_refine_test.gd
shenleiandClaude Code 8092ff44e2 装备校验链/快捷栏/公会/好友情侣/交易仓库五项差距修复(增量 129)
- 装备校验: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
2026-09-07 21:43:30 +09:00

106 lines
4.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.
# 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 # Newbiegrade 3auth 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, "取消 -> 关闭且不发包")