Files
mtgodot-poc/project/test_party_management_parity.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

125 lines
4.9 KiB
GDScript

# test_party_management_parity.gd —— 40250 8人组队面板、经验分配与领导力光环系统回归测试
extends SceneTree
const SystemClass = preload("res://party_management_system.gd")
var _passed: int = 0
var _failed: int = 0
func _assert(cond: bool, msg: String) -> void:
if cond:
_passed += 1
print(" [PASS] %s" % msg)
else:
_failed += 1
printerr(" [FAIL] %s" % msg)
func _init() -> void:
print("\n=== Running test_party_management_parity (Batch 27 Direction 4) ===")
_test_party_capacity_and_join()
_test_member_expel_and_leave()
_test_leadership_tactical_auras()
_test_exp_distribution_modes()
_test_hp_percentage_synchronization()
print("\n=== Result: %d Passed, %d Failed ===" % [_passed, _failed])
if _failed == 0:
print("ALL TESTS PASSED!\n")
else:
printerr("SOME TESTS FAILED!\n")
quit(0 if _failed == 0 else 1)
func _test_party_capacity_and_join() -> void:
print("\n--- Test 1: Party Creation & 8-Member Limit ---")
var party = SystemClass.new(1, "LeaderOne", 50)
_assert(party.members.size() == 1, "Party created with 1 member (Leader)")
_assert(party.leader_pid == 1, "Leader PID is 1")
# Add 7 more members (total 8)
for i in range(2, 9):
var r = party.add_member(i, "Member%d" % i, 40 + i)
_assert(r["success"] == true, "Member %d joined party" % i)
_assert(party.members.size() == 8, "Party reached 8 members")
# 9th member must be rejected
var r_overflow = party.add_member(9, "OverflowMember", 50)
_assert(r_overflow["error_code"] == "PARTY_FULL", "Reject 9th member (max 8)")
func _test_member_expel_and_leave() -> void:
print("\n--- Test 2: Expel & Leave Mechanics ---")
var party = SystemClass.new(1, "Leader", 60)
party.add_member(2, "Alice", 55)
party.add_member(3, "Bob", 50)
# Non-leader cannot expel
var r_fail = party.expel_member(2, 3)
_assert(r_fail["error_code"] == "NOT_LEADER", "Non-leader cannot expel member")
# Leader expels Alice
var r_expel = party.expel_member(1, 2)
_assert(r_expel["success"] == true, "Leader successfully expelled Alice")
_assert(party.members.has(2) == false, "Alice no longer in party")
# Leader leaves party -> Bob promoted to new leader
var r_lead_leave = party.leave_party(1)
_assert(r_lead_leave["success"] == true, "Leader left party")
_assert(party.leader_pid == 3, "Bob promoted to new leader")
_assert(party.members[3].is_leader == true, "Bob marked as leader")
# Bob leaves -> Party dissolves
var r_dissolve = party.leave_party(3)
_assert(r_dissolve["dissolved"] == true, "Party dissolved when last member left")
func _test_leadership_tactical_auras() -> void:
print("\n--- Test 3: Leader Tactical Auras (Roles & Buffs) ---")
var party = SystemClass.new(1, "Commander", 75)
party.add_member(2, "Warrior", 70)
party.add_member(3, "Sura", 72)
# Non-leader cannot assign role
var r_non_lead = party.set_member_role(2, 2, SystemClass.ROLE_ATTACKER)
_assert(r_non_lead["error_code"] == "NOT_LEADER", "Non-leader cannot assign role")
# Leader assigns Warrior as ATTACKER
var r1 = party.set_member_role(1, 2, SystemClass.ROLE_ATTACKER)
_assert(r1["success"] == true, "Assigned Warrior as ATTACKER")
var buff1 = party.get_member_buff(2)
_assert(buff1["stat"] == "att_grade" and buff1["val"] == 30, "Warrior receives +30 att_grade buff")
# Leader assigns Sura as TANKER
var r2 = party.set_member_role(1, 3, SystemClass.ROLE_TANKER)
_assert(r2["success"] == true, "Assigned Sura as TANKER")
var buff2 = party.get_member_buff(3)
_assert(buff2["stat"] == "max_hp" and buff2["val"] == 2500, "Sura receives +2500 max_hp buff")
# Reject duplicate ATTACKER assignment to Sura
var r_dup = party.set_member_role(1, 3, SystemClass.ROLE_ATTACKER)
_assert(r_dup["error_code"] == "ROLE_ALREADY_ASSIGNED", "Reject duplicate role assignment")
func _test_exp_distribution_modes() -> void:
print("\n--- Test 4: Experience Distribution Modes ---")
var party = SystemClass.new(1, "PlayerA", 20) # Level 20
party.add_member(2, "PlayerB", 80) # Level 80
# 1. PARITY (Equal mode)
party.set_exp_distribution_mode(1, SystemClass.EXP_MODE_PARITY)
var exp_parity = party.distribute_exp(1000)
_assert(exp_parity[1] == 500, "PlayerA gets 500 in PARITY mode")
_assert(exp_parity[2] == 500, "PlayerB gets 500 in PARITY mode")
# 2. LEVEL (Weighted mode: 20% vs 80%)
party.set_exp_distribution_mode(1, SystemClass.EXP_MODE_LEVEL)
var exp_level = party.distribute_exp(1000)
_assert(exp_level[1] == 200, "PlayerA (Lv20) gets 200 (20%) in LEVEL mode")
_assert(exp_level[2] == 800, "PlayerB (Lv80) gets 800 (80%) in LEVEL mode")
func _test_hp_percentage_synchronization() -> void:
print("\n--- Test 5: HP Gauge Percentage Synchronization ---")
var party = SystemClass.new(1, "PlayerA", 50)
party.sync_member_hp(1, 3000, 6000)
_assert(is_equal_approx(party.members[1].get_hp_percent(), 0.5), "HP percentage is exactly 50%")
party.sync_member_hp(1, 6000, 6000)
_assert(is_equal_approx(party.members[1].get_hp_percent(), 1.0), "HP percentage is 100%")