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

123 lines
5.5 KiB
GDScript

# test_dragon_soul_parity.gd —— 40250 龙神炼金石系统 1:1 纯净回归测试套件
extends SceneTree
const DragonSoulSystem = preload("res://dragon_soul_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_dragon_soul_parity (Direction 1: Dragon Soul Alchemy 1:1) ===")
_test_stone_creation_and_attributes()
_test_grade_and_clarity_refinement()
_test_deck_equipping_and_switching()
_test_active_bonuses_and_duration_decay()
_finish()
func _test_stone_creation_and_attributes() -> void:
print("\n--- Test 1: Stone Creation & 40250 Attribute Scaling ---")
# Diamond: Rough, Matt, +0
var diamond := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.DIAMOND, 0, 0, 0)
var attrs: Dictionary = diamond["attributes"]
_assert(attrs["int_bonus"] == 5, "Diamond +0 int_bonus is 5")
_assert(attrs["magic_defense"] == 2, "Diamond +0 magic_defense is 2")
# Ruby: Legendary (Grade 4), Excellent (Clarity 4), +6 Refine
var ruby := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, 4, 4, 6)
attrs = ruby["attributes"]
# str_bonus: 5 + (4*3) + (4*2) + 6 = 31
_assert(attrs["str_bonus"] == 31, "Legendary Ruby STR bonus is 31")
# att_grade: 20 + (4*15) + (4*10) + (6*5) = 20 + 60 + 40 + 30 = 150
_assert(attrs["att_grade"] == 150, "Legendary Ruby Attack Power bonus is 150")
# Jade: Max HP
var jade := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.JADE, 4, 0, 0)
_assert(jade["attributes"]["max_hp"] == 1300, "Legendary Jade Max HP is 1300")
func _test_grade_and_clarity_refinement() -> void:
print("\n--- Test 2: Grade & Clarity Refinement ---")
var r1 := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, DragonSoulSystem.Grade.ROUGH, 0)
var r2 := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, DragonSoulSystem.Grade.ROUGH, 0)
var d1 := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.DIAMOND, DragonSoulSystem.Grade.ROUGH, 0)
# Mismatched type rejected
var res = DragonSoulSystem.refine_grade(r1, d1)
_assert(res["ok"] == false and res["reason"] == "MISMATCHED_STONES", "Cannot fuse Ruby with Diamond")
# Grade refine success
res = DragonSoulSystem.refine_grade(r1, r2, true)
_assert(res["ok"] == true and res["success"] == true, "Ruby successfully upgraded to Cut grade")
_assert(res["stone"]["grade"] == DragonSoulSystem.Grade.CUT, "New stone grade is Cut (1)")
# Clarity refine success
var c1 := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, DragonSoulSystem.Grade.CUT, DragonSoulSystem.Clarity.MATT)
var c2 := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, DragonSoulSystem.Grade.CUT, DragonSoulSystem.Clarity.MATT)
res = DragonSoulSystem.refine_clarity(c1, c2, true)
_assert(res["ok"] == true and res["success"] == true, "Ruby clarity successfully upgraded to Clear")
_assert(res["stone"]["clarity"] == DragonSoulSystem.Clarity.CLEAR, "New stone clarity is Clear (1)")
func _test_deck_equipping_and_switching() -> void:
print("\n--- Test 3: Sky Deck & Earth Deck Equipping ---")
var dss := DragonSoulSystem.new()
var diamond := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.DIAMOND)
var ruby := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY)
# Equip in Sky Deck (0)
var res = dss.equip_stone(DragonSoulSystem.DECK_SKY, diamond)
_assert(res["ok"] == true and res["slot"] == 0, "Diamond equipped into Sky Deck slot 0")
_assert(dss.decks[DragonSoulSystem.DECK_SKY][0] != null, "Sky Deck slot 0 is filled")
res = dss.equip_stone(DragonSoulSystem.DECK_SKY, ruby)
_assert(res["ok"] == true and res["slot"] == 1, "Ruby equipped into Sky Deck slot 1")
# Unequip from Sky Deck
res = dss.unequip_stone(DragonSoulSystem.DECK_SKY, 0)
_assert(res["ok"] == true, "Diamond unequipped")
_assert(dss.decks[DragonSoulSystem.DECK_SKY][0] == null, "Sky Deck slot 0 is now empty")
func _test_active_bonuses_and_duration_decay() -> void:
print("\n--- Test 4: Active Deck Stat Injection & Duration Decay ---")
var dss := DragonSoulSystem.new()
var ruby := DragonSoulSystem.create_dragon_stone(DragonSoulSystem.DragonStoneType.RUBY, 4, 4, 6, 10.0) # 10s duration
dss.equip_stone(DragonSoulSystem.DECK_SKY, ruby)
# Initially inactive: 0 bonuses
var bonuses = dss.get_active_bonuses()
_assert(bonuses.is_empty(), "No bonuses when deck is inactive")
# Toggle Sky Deck on
var active = dss.toggle_deck(DragonSoulSystem.DECK_SKY)
_assert(active == true and dss.active_deck == DragonSoulSystem.DECK_SKY, "Sky Deck activated")
bonuses = dss.get_active_bonuses()
_assert(bonuses["str_bonus"] == 31, "Active deck injects +31 STR bonus")
_assert(bonuses["att_grade"] == 150, "Active deck injects +150 Attack Power")
# Update 5s -> still active
var expired = dss.update(5.0)
_assert(expired.is_empty(), "No stones expired after 5s")
_assert(dss.decks[DragonSoulSystem.DECK_SKY][1]["duration"] == 5.0, "5s duration remaining")
# Update 6s -> expires
expired = dss.update(6.0)
_assert(expired.size() == 1, "1 stone expired after duration reached 0")
bonuses = dss.get_active_bonuses()
_assert(bonuses.is_empty(), "Expired stones no longer provide stat bonuses")
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)