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

117 lines
4.7 KiB
GDScript

# test_polymorph_parity.gd —— 40250 变身球与变身术技能 1:1 纯净回归测试套件
extends SceneTree
const PolymorphSystem = preload("res://polymorph_system.gd")
var _passed := 0
var _failed := 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_polymorph_parity (Direction 2: Polymorph System 1:1) ===")
_test_marble_item_and_prerequisites()
_test_duration_and_skill_scaling()
_test_transformation_stat_boost()
_test_combat_and_action_restrictions()
_test_termination_and_death()
_finish()
func _test_marble_item_and_prerequisites() -> void:
print("\n--- Test 1: Marble Item & Transformation Prerequisites ---")
var ps := PolymorphSystem.new()
var marble := {"vnum": 70104, "mob_vnum": 101} # Wild Boar
var non_marble := {"vnum": 10, "mob_vnum": 101}
# Non marble rejected
var res = ps.use_polymorph_marble(non_marble, false, false)
_assert(res["ok"] == false and res["reason"] == "NOT_A_MARBLE", "Non-marble item rejected")
# Dead player rejected
res = ps.use_polymorph_marble(marble, true, false)
_assert(res["ok"] == false and res["reason"] == "PLAYER_DEAD", "Dead player cannot transform")
# Mounted player rejected
res = ps.use_polymorph_marble(marble, false, true)
_assert(res["ok"] == false and res["reason"] == "PLAYER_MOUNTED", "Mounted player cannot transform")
# Peaceful on foot succeeds
res = ps.use_polymorph_marble(marble, false, false)
_assert(res["ok"] == true, "Transformation succeeds on foot while alive")
_assert(ps.is_polymorphed == true, "Player is now in polymorphed state")
_assert(ps.current_mob_vnum == 101, "Current mob vnum is 101 (Wild Boar)")
func _test_duration_and_skill_scaling() -> void:
print("\n--- Test 2: Duration Scaling with Skill Level (1~P) ---")
# Level 1: 620s (~10 min)
_assert(PolymorphSystem.get_duration_by_skill(1) == 620.0, "Skill Lv1: 620s")
# Level 20 (M1): 1200s (20 min)
_assert(PolymorphSystem.get_duration_by_skill(20) == 1200.0, "Skill M1 (Lv20): 1200s (20 min)")
# Level 30 (G1): 1500s (25 min)
_assert(PolymorphSystem.get_duration_by_skill(30) == 1500.0, "Skill G1 (Lv30): 1500s (25 min)")
# Level 40 (P): 2100s (35 min)
_assert(PolymorphSystem.get_duration_by_skill(40) == 2100.0, "Skill P (Lv40): 2100s (35 min)")
func _test_transformation_stat_boost() -> void:
print("\n--- Test 3: Monster Attributes & Skill Scaling Boost ---")
var ps := PolymorphSystem.new()
ps.poly_skill_level = 40 # P grade (multiplier 1.0 + 40*0.025 = 2.0x)
var tiger_marble := {"vnum": 70104, "mob_vnum": 114} # White Tiger (base atk: 85)
var res = ps.use_polymorph_marble(tiger_marble, false, false)
_assert(res["ok"] == true, "White tiger transformation succeeds")
_assert(ps.bonus_atk == 170, "P-Grade Tiger ATK is doubled: 85 * 2.0 = 170")
_assert(ps.bonus_def == 40, "Tiger DEF is 40")
_assert(ps.bonus_speed == 140, "Tiger movement speed is 140")
func _test_combat_and_action_restrictions() -> void:
print("\n--- Test 4: Action Restrictions (Skills, Mount, Weapon) ---")
var ps := PolymorphSystem.new()
var marble := {"vnum": 70104, "mob_vnum": 110} # Bear
ps.use_polymorph_marble(marble, false, false)
# Active skills blocked
_assert(ps.can_use_skill(1) == false, "Warrior skill 1 (Three-way Cut) blocked")
_assert(ps.can_use_skill(2) == false, "Warrior skill 2 (Sword Spin) blocked")
_assert(ps.can_use_skill(129) == true, "Polymorph skill 129 permitted")
# Weapon change blocked
_assert(ps.can_change_weapon() == false, "Weapon swapping blocked while transformed")
# Mounting blocked
_assert(ps.can_mount() == false, "Mounting horse blocked while transformed")
func _test_termination_and_death() -> void:
print("\n--- Test 5: Revert on Countdown Expiry & Death ---")
var ps := PolymorphSystem.new()
var marble := {"vnum": 70104, "mob_vnum": 101}
ps.use_polymorph_marble(marble, false, false)
_assert(ps.is_polymorphed == true, "Polymorphed initially")
# Fast forward time to expire
ps.update(ps.remaining_time + 1.0)
_assert(ps.is_polymorphed == false, "Polymorph ended after countdown expired")
_assert(ps.bonus_atk == 0, "Bonus ATK cleared")
_assert(ps.can_use_skill(1) == true, "Skills unlocked again after polymorph ends")
# Re-transform and test death
ps.use_polymorph_marble(marble, false, false)
_assert(ps.is_polymorphed == true, "Re-transformed")
ps.on_player_death()
_assert(ps.is_polymorphed == false, "Polymorph immediately cancelled on player death")
func _finish() -> void:
print("\n=== SUMMARY: %d passed, %d failed ===" % [_passed, _failed])
if _failed == 0:
print("ALL TESTS PASSED!\n")
quit(0)
else:
printerr("SOME TESTS FAILED!\n")
quit(1)