- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
114 lines
4.1 KiB
GDScript
114 lines
4.1 KiB
GDScript
# test_herbal_dew_parity.gd —— 40250 草药炼丹与 6 色神圣露水 1:1 纯净回归测试套件
|
|
extends SceneTree
|
|
|
|
const HerbalDewSystem = preload("res://herbal_dew_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_herbal_dew_parity (Direction 2: Herbal Dews 1:1) ===")
|
|
_test_herb_to_water_extraction()
|
|
_test_dew_brewing_with_bottle()
|
|
_test_six_color_dew_drinking_and_stacking()
|
|
_test_dew_decay_and_expiration()
|
|
_finish()
|
|
|
|
func _test_herb_to_water_extraction() -> void:
|
|
print("\n--- Test 1: Herb to Water Intermediate Extraction ---")
|
|
var inv: Array = [
|
|
{"vnum": 50701, "count": 1}, # Peach Blossom
|
|
null,
|
|
null
|
|
]
|
|
|
|
# Extract Peach Blossom -> Sim-Water (50721)
|
|
var res = HerbalDewSystem.brew_water(inv, 50701)
|
|
_assert(res["ok"] == true, "Peach Blossom extracted successfully")
|
|
_assert(res["water_vnum"] == 50721, "Yielded Sim-Water (50721)")
|
|
_assert(inv[res["slot"]]["vnum"] == 50721, "Sim-Water stored in slot %d" % res["slot"])
|
|
|
|
# Missing herb fails
|
|
var empty_inv: Array = [null, null]
|
|
res = HerbalDewSystem.brew_water(empty_inv, 50701)
|
|
_assert(res["ok"] == false and res["reason"] == "MISSING_HERB", "Extraction fails without herb")
|
|
|
|
func _test_dew_brewing_with_bottle() -> void:
|
|
print("\n--- Test 2: Dew Brewing with Empty Bottle (70030) ---")
|
|
var inv: Array = [
|
|
{"vnum": 50723}, # Bo-Water (for Blue Dew 50823)
|
|
{"vnum": 70030}, # Empty Bottle
|
|
null
|
|
]
|
|
|
|
# Brew Blue Dew (50823)
|
|
var res = HerbalDewSystem.brew_dew(inv, 50823, true)
|
|
_assert(res["ok"] == true, "Blue Dew brewed successfully")
|
|
_assert(res["dew_vnum"] == 50823, "Vnum is 50823 (Blue Dew)")
|
|
_assert(res["value"] == 120, "Rolled max ATK +120")
|
|
_assert(inv[res["slot"] if res.has("slot") else 0]["vnum"] == 50823, "Blue Dew stored in inventory")
|
|
|
|
# Missing bottle fails
|
|
var inv_no_bottle: Array = [{"vnum": 50723}, null]
|
|
res = HerbalDewSystem.brew_dew(inv_no_bottle, 50823)
|
|
_assert(res["ok"] == false and res["reason"] == "MISSING_BOTTLE", "Brewing fails without empty bottle")
|
|
|
|
func _test_six_color_dew_drinking_and_stacking() -> void:
|
|
print("\n--- Test 3: Drinking Dews & Multi-Dew Stacking ---")
|
|
var hds := HerbalDewSystem.new()
|
|
|
|
var blue_dew := {"vnum": 50823, "value": 100} # +100 ATK
|
|
var red_dew := {"vnum": 50822, "value": 15} # +15% Crit
|
|
var white_dew := {"vnum": 50824, "value": 80} # +80 DEF
|
|
|
|
# Drink Blue Dew
|
|
var res = hds.drink_dew(blue_dew)
|
|
_assert(res["ok"] == true, "Blue Dew consumed")
|
|
_assert(hds.has_dew(50823) == true, "Blue Dew active")
|
|
_assert(hds.get_stat_bonus("att_grade") == 100, "ATK bonus is 100")
|
|
|
|
# Drink Red Dew (stack together)
|
|
hds.drink_dew(red_dew)
|
|
_assert(hds.has_dew(50822) == true, "Red Dew active")
|
|
_assert(hds.get_stat_bonus("critical_pct") == 15, "Critical bonus is 15%")
|
|
_assert(hds.get_stat_bonus("att_grade") == 100, "ATK bonus remains active alongside Red Dew")
|
|
|
|
# Drink White Dew
|
|
hds.drink_dew(white_dew)
|
|
_assert(hds.get_stat_bonus("def_grade") == 80, "DEF bonus is 80")
|
|
_assert(hds.active_dews.size() == 3, "3 distinct dews simultaneously active")
|
|
|
|
func _test_dew_decay_and_expiration() -> void:
|
|
print("\n--- Test 4: Dew Duration Decay & Expiration ---")
|
|
var hds := HerbalDewSystem.new()
|
|
hds.drink_dew({"vnum": 50826, "value": 5}) # Yellow Dew (Attack Speed)
|
|
_assert(hds.has_dew(50826) == true, "Yellow Dew active")
|
|
|
|
# Fast forward 500s -> still active
|
|
var expired = hds.update(500.0)
|
|
_assert(expired.is_empty(), "Not expired after 500s")
|
|
_assert(hds.has_dew(50826) == true, "Still active at 100s remaining")
|
|
|
|
# Fast forward another 101s -> expired
|
|
expired = hds.update(101.0)
|
|
_assert(expired == [50826], "Yellow Dew expired")
|
|
_assert(hds.has_dew(50826) == false, "Yellow Dew no longer active")
|
|
_assert(hds.get_stat_bonus("att_speed") == 0, "Attack speed bonus reset to 0")
|
|
|
|
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)
|