Files
mtgodot-poc/project/guild_refine_test.gd
T
shenandshen 66d217b313 feat(client): 完成40250客户端核心功能1:1对齐与桥梁高度采样修复
- 桥梁与静态物体高度采样修复:
  - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight
  - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程
  - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题
  - 新增 test_bridge_height_parity.gd 自动化对拍测试
- 40250 怪物击杀经验动效:
  - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附
- 40250 客户端全系统功能对齐(Batches 1-31):
  - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试
- 文档沉淀:
  - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
2026-09-19 08:51:25 -07:00

108 lines
4.3 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.
# 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(ru._question_dialog.visible, "40250 规则:成功率 45% < 100% 弹出二次确认框")
ru._qd_accept_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() == 2 and fc.calls[1] == ["refine", 255, 255], "40250 规则:取消 -> 发送取消包 refine(255, 255)")