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

120 lines
4.4 KiB
GDScript

# test_atlas_navigation_parity.gd —— 40250 全景大地图与寻路导航回归测试
extends SceneTree
const SystemClass = preload("res://atlas_navigation_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_atlas_navigation_parity (Batch 28 Direction 1) ===")
_test_atlas_toggle_and_map_registry()
_test_zoom_and_pan_controls()
_test_npc_directory_indexing()
_test_signal_point_and_navigation_vector()
_test_coordinate_projection()
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_atlas_toggle_and_map_registry() -> void:
print("\n--- Test 1: M Key Toggle & Map Registry ---")
var nav = SystemClass.new("metin2_map_a1")
_assert(nav.is_atlas_visible == false, "Atlas initially hidden")
# Toggle M
var state1 = nav.toggle_atlas()
_assert(state1 == true and nav.is_atlas_visible == true, "Atlas toggled open on M key")
var state2 = nav.toggle_atlas()
_assert(state2 == false and nav.is_atlas_visible == false, "Atlas toggled closed on second M key")
# Map switching
var sw_ok = nav.set_map("metin2_map_milgyo")
_assert(sw_ok == true, "Switched map to metin2_map_milgyo")
var info = nav.get_current_map_info()
_assert(info["name"] == "幽冥神殿 (Dark Temple)", "Map registry metadata correctly fetched")
var sw_fail = nav.set_map("invalid_map_id")
_assert(sw_fail == false, "Reject invalid map id")
func _test_zoom_and_pan_controls() -> void:
print("\n--- Test 2: Zoom and Pan Clamping ---")
var nav = SystemClass.new()
# Zoom clamping (0.5 to 3.0)
nav.set_zoom(0.2)
_assert(nav.zoom_level == 0.5, "Zoom clamped at lower bound 0.5x")
nav.set_zoom(5.0)
_assert(nav.zoom_level == 3.0, "Zoom clamped at upper bound 3.0x")
nav.set_zoom(1.5)
_assert(nav.zoom_level == 1.5, "Zoom set to 1.5x")
# Pan accumulation
nav.apply_pan(Vector2(20, -10))
_assert(nav.pan_offset == Vector2(20, -10), "Pan offset accumulated")
func _test_npc_directory_indexing() -> void:
print("\n--- Test 3: NPC Directory Indexing & Filtering ---")
var nav = SystemClass.new()
var all_npcs = nav.get_npcs()
_assert(all_npcs.size() >= 10, "Default town contains at least 10 key NPCs")
var smiths = nav.get_npcs("Smith")
_assert(smiths.size() == 1 and smiths[0]["vid"] == 20016, "Filtered single blacksmith (VID 20016)")
var shops = nav.get_npcs("Shop")
_assert(shops.size() == 3, "Filtered 3 shops (Weapon, Armor, General)")
var bio = nav.find_npc_by_vid(20084)
_assert(bio.get("name").contains("生物学家"), "Found Biologist by VID 20084")
func _test_signal_point_and_navigation_vector() -> void:
print("\n--- Test 4: Signal Point Waypoint & Compass Bearing ---")
var nav = SystemClass.new()
# Add signal waypoint
var sig = nav.add_signal_point(600, 600)
_assert(nav.signal_points.size() == 1, "Signal waypoint added")
_assert(sig["x"] == 600 and sig["y"] == 600, "Signal waypoint coordinates match (600, 600)")
# Calculate compass bearing: Player at (500, 600) -> Target at (600, 600)
var nav_vec = nav.calculate_navigation_vector(Vector2(500, 600), Vector2(600, 600))
_assert(nav_vec["distance"] == 100.0, "Distance is exactly 100")
_assert(is_equal_approx(nav_vec["angle_deg"], 0.0), "Heading is exactly 0 degrees (East)")
_assert(nav_vec["arrived"] == false, "Not arrived (dist 100 > 30)")
# Arrival test: Player at (590, 600) -> Target at (600, 600)
var nav_arrived = nav.calculate_navigation_vector(Vector2(590, 600), Vector2(600, 600))
_assert(nav_arrived["distance"] == 10.0, "Distance is 10")
_assert(nav_arrived["arrived"] == true, "Arrival detected when dist <= 30")
# Clear all signals
nav.clear_all_signals()
_assert(nav.signal_points.is_empty(), "All signal waypoints cleared")
func _test_coordinate_projection() -> void:
print("\n--- Test 5: World to Atlas UI Coordinate Projection ---")
var nav = SystemClass.new("metin2_map_a1") # 4000x4000 world -> 256x256 atlas
nav.set_zoom(1.0)
# World center (2000, 2000) -> Atlas center (128, 128)
var projected = nav.world_to_atlas_coord(Vector2(2000, 2000))
_assert(is_equal_approx(projected.x, 128.0) and is_equal_approx(projected.y, 128.0), "Projected world center (2000, 2000) to atlas (128, 128)")