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

141 lines
5.1 KiB
GDScript

# test_biologist_quest_parity.gd —— 40250 生物学研究家任务链 1:1 纯净回归测试套件
extends SceneTree
const BiologistQuestSystem = preload("res://biologist_quest_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_biologist_quest_parity (Direction 1: Biologist Quests 1:1) ===")
_test_level_unlock()
_test_item_submission_and_potion()
_test_soul_stone_completion_and_bonuses()
_test_full_chain_progression()
_finish()
func _test_level_unlock() -> void:
print("\n--- Test 1: Level Requirement & Stage Unlock ---")
var bio := BiologistQuestSystem.new()
bio.init_for_player(25) # Level 25
_assert(bio.current_stage_idx == -1, "Level 25 cannot start Lv30 Orc Tooth quest")
bio.init_for_player(30) # Level 30
_assert(bio.current_stage_idx == 0, "Level 30 unlocks Stage 0 (Orc Tooth)")
var stage: Dictionary = bio.get_current_stage()
_assert(stage["collect_vnum"] == 30006, "Stage 0 requires Orc Tooth (30006)")
_assert(stage["collect_count"] == 10, "Stage 0 requires 10 teeth")
func _test_item_submission_and_potion() -> void:
print("\n--- Test 2: Item Submission & Spiral Potion (71035) ---")
var bio := BiologistQuestSystem.new()
bio.init_for_player(30)
var inv: Array = [
{"vnum": 30006}, # slot 0: Orc Tooth
{"vnum": 71035}, # slot 1: Spiral Potion
null
]
# Test missing item error
var empty_inv: Array = [null, null]
var res = bio.submit_item(empty_inv)
_assert(res["ok"] == false and res["reason"] == "MISSING_ITEM", "Fails when missing tooth in inventory")
# Test successful submission with Spiral Potion
res = bio.submit_item(inv, true, true)
_assert(res["ok"] == true and res["success"] == true, "Submission succeeds with potion")
_assert(bio.delivered_count == 1, "Delivered count incremented to 1")
_assert(inv[0] == null, "Tooth consumed from slot 0")
_assert(inv[1] == null, "Spiral Potion consumed from slot 1")
_assert(bio.cooldown_remaining == 0.0, "Cooldown is 0 with potion")
func _test_soul_stone_completion_and_bonuses() -> void:
print("\n--- Test 3: Soul Stone Phase & Permanent Stat Bonus ---")
var bio := BiologistQuestSystem.new()
bio.init_for_player(30)
bio.delivered_count = 10
bio.soul_stone_phase = true
var inv: Array = [
{"vnum": 30220}, # Jinunggyi's Soul Stone
null
]
# Test without soul stone
var res = bio.submit_soul_stone([null])
_assert(res["ok"] == false and res["reason"] == "MISSING_SOUL_STONE", "Fails without soul stone")
# Submit soul stone
res = bio.submit_soul_stone(inv)
_assert(res["ok"] == true, "Soul stone submitted successfully")
_assert(res["completed_stage"] == 0, "Stage 0 completed")
_assert(bio.permanent_bonuses["move_speed"] == 10, "Permanent move speed +10 granted")
_assert(inv[0] == null, "Soul stone consumed from inventory")
func _test_full_chain_progression() -> void:
print("\n--- Test 4: Full Quest Progression Lv30 -> Lv80 ---")
var bio := BiologistQuestSystem.new()
bio.init_for_player(85) # High level to test through all stages
# Stage 0: Orc Tooth (Lv30)
_assert(bio.current_stage_idx == 0, "Current stage is 0 (Lv30)")
bio.delivered_count = 10
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30220}])
_assert(bio.permanent_bonuses["move_speed"] == 10, "Lv30 Bonus: Move speed +10")
# Stage 1: Curse Book (Lv40)
_assert(bio.current_stage_idx == 1, "Advanced to stage 1 (Lv40 Curse Book)")
bio.delivered_count = 15
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30221}])
_assert(bio.permanent_bonuses["att_speed"] == 5, "Lv40 Bonus: Attack speed +5")
# Stage 2: Demon Keepsake (Lv50)
_assert(bio.current_stage_idx == 2, "Advanced to stage 2 (Lv50 Demon Keepsake)")
bio.delivered_count = 15
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30222}])
_assert(bio.permanent_bonuses["def_grade"] == 60, "Lv50 Bonus: Defense +60")
# Stage 3: Ice Marble (Lv60)
_assert(bio.current_stage_idx == 3, "Advanced to stage 3 (Lv60 Ice Marble)")
bio.delivered_count = 20
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30223}])
_assert(bio.permanent_bonuses["att_grade"] == 50, "Lv60 Bonus: Attack power +50")
# Stage 4: Zelkova Branch (Lv70)
_assert(bio.current_stage_idx == 4, "Advanced to stage 4 (Lv70 Zelkova Branch)")
bio.delivered_count = 25
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30224}])
_assert(bio.permanent_bonuses["damage_reduction"] == 10, "Lv70 Bonus: Damage reduction 10%")
# Stage 5: Tugyi's Tablet (Lv80)
_assert(bio.current_stage_idx == 5, "Advanced to stage 5 (Lv80 Tugyi Tablet)")
bio.delivered_count = 30
bio.soul_stone_phase = true
bio.submit_soul_stone([{"vnum": 30225}])
_assert(bio.permanent_bonuses["att_grade_pct"] == 10, "Lv80 Bonus: Attack power +10%")
_assert(bio.completed_stages.size() == 6, "All 6 biologist quest stages completed")
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)