# test_all_map_height_probe.gd # 严格按照《CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md》手段 1(全图几何与阻挡坐标探针): # 自动化探针遍历多个核心地图(OutdoorA1、OutdoorC1 等),全面巡检跨河桥梁、高架栈道与悬索吊桥: # 1. 验证物体中心及行进跨度内 sample_height 稳定采样到表面高度,不跌入河床裸地形; # 2. 验证桥面行走通道未被 is_blocked 错误拦截; # 3. 验证侧向偏离点正确回退到裸地形标高; # 4. 验证高度数据不存在 NaN / Inf 异常。 extends SceneTree const ASSETS_PATH := "res://../assets" func _init() -> void: call_deferred("_run") func _run() -> void: print("=== Starting test_all_map_height_probe (Headless Coordinate Probe Suite) ===") var fails := [0] var check = func(cond: bool, msg: String): if not cond: fails[0] += 1 printerr("FAIL: ", msg) else: print("PASS: ", msg) if not ClassDB.class_exists("Metin2World"): printerr("FAIL: Metin2World class not found") quit(1) return var world: Node = ClassDB.instantiate("Metin2World") get_root().add_child(world) var assets_abs := ProjectSettings.globalize_path(ASSETS_PATH) world.set("assets_root", assets_abs) world.set("objects_enabled", true) world.set("water_enabled", true) world.set("load_radius_tiles", -1) # ------------------------------------------------------------- # 巡检 1: OutdoorA1/metin2_map_a1 跨河石桥与悬索吊桥 # ------------------------------------------------------------- print("\n--- Probing Map 1: OutdoorA1/metin2_map_a1 ---") world.set("map_path", "OutdoorA1/metin2_map_a1") var ok: bool = bool(world.call("load_map")) check.call(ok, "OutdoorA1 load_map succeeded") if ok: # 桥梁 1: a1-024-10m-bridge (Chunk 002002) var b1_x := 761.57 var b1_z := 594.55 var h1: float = float(world.call("sample_height", b1_x, b1_z)) var bl1: bool = bool(world.call("is_blocked", b1_x, b1_z)) print(" A1 Bridge 1 (a1-024-10m-bridge) at (%f, %f): height=%f m, blocked=%s" % [b1_x, b1_z, h1, bl1]) check.call(h1 >= 204.0 and h1 <= 208.0, "Bridge 1 deck elevation in expected range (204m~208m), got %f" % h1) check.call(not bl1, "Bridge 1 walking lane is NOT blocked (is_blocked == false)") # 跨桥连续性巡检 (沿 x 轴跨度从 751 到 771) var span_continuous := true for dx in range(-10, 11, 2): var step_x := b1_x + float(dx) var step_h: float = float(world.call("sample_height", step_x, b1_z)) var step_bl: bool = bool(world.call("is_blocked", step_x, b1_z)) if step_h < 203.0 or step_bl: span_continuous = false printerr(" Span defect at x=%f: height=%f (expected >= 203), blocked=%s" % [step_x, step_h, step_bl]) break check.call(span_continuous, "Bridge 1 walking span maintains elevated deck and walkable status across entire length") # 桥侧河床自然回退验证 var off_h: float = float(world.call("sample_height", b1_x, 570.0)) check.call(off_h < 200.0, "Off-bridge point correctly samples riverbed terrain (%f m < 200m)" % off_h) # 桥梁 2: 悬索吊桥 (general_obj_suspension bridge01) var b2_x := 213.91 var b2_z := 700.45 var h2: float = float(world.call("sample_height", b2_x, b2_z)) var bl2: bool = bool(world.call("is_blocked", b2_x, b2_z)) print(" A1 Bridge 2 (suspension bridge) at (%f, %f): height=%f m, blocked=%s" % [b2_x, b2_z, h2, bl2]) check.call(h2 >= 130.0 and h2 <= 140.0, "Suspension bridge deck in expected range (130m~140m), got %f" % h2) check.call(not bl2, "Suspension bridge walking deck is NOT blocked") # ------------------------------------------------------------- # 巡检 2: OutdoorC1/metin2_map_c1 跨河石桥 # ------------------------------------------------------------- print("\n--- Probing Map 2: OutdoorC1/metin2_map_c1 ---") world.call("unload_map") world.set("map_path", "OutdoorC1/metin2_map_c1") var ok_c1: bool = bool(world.call("load_map")) check.call(ok_c1, "OutdoorC1 load_map succeeded") if ok_c1: # C1 跨河石桥: c1-022-10m-bridge (位于 Chunk 001001, areadata pos: 35755.88, -50457.72, 16555.45, bias=-705.0) var c1_x := 357.56 var c1_z := 504.58 var c1_h: float = float(world.call("sample_height", c1_x, c1_z)) var c1_bl: bool = bool(world.call("is_blocked", c1_x, c1_z)) print(" C1 Bridge (c1-022-10m-bridge) at (%f, %f): height=%f m, blocked=%s" % [c1_x, c1_z, c1_h, c1_bl]) check.call(c1_h >= 170.0 and c1_h <= 180.0, "C1 Bridge deck elevation in expected range (170m~180m), got %f" % c1_h) check.call(not c1_bl, "C1 Bridge walking lane is NOT blocked") # 跨桥连续性巡检 (沿 z 轴方向,因为 rot=90度,桥面沿南北走向展开) var c1_span_continuous := true for dz in range(-12, 13, 3): var step_z := c1_z + float(dz) var step_h: float = float(world.call("sample_height", c1_x, step_z)) var step_bl: bool = bool(world.call("is_blocked", c1_x, step_z)) if step_h < 172.0 or step_bl: c1_span_continuous = false printerr(" C1 Span defect at z=%f: height=%f (expected >= 172), blocked=%s" % [step_z, step_h, step_bl]) break check.call(c1_span_continuous, "C1 Bridge walking span maintains elevated deck across entire span") # 侧向远离桥梁 15m 的点 (河道): (357.56 - 15.0, 504.58) var c1_off_x := c1_x - 15.0 var c1_off_h: float = float(world.call("sample_height", c1_off_x, c1_z)) print(" C1 Off-bridge river at (%f, %f): height=%f m (< bridge %f m)" % [c1_off_x, c1_z, c1_off_h, c1_h]) check.call(c1_off_h < c1_h - 1.0, "C1 Off-bridge point drops below bridge deck (%f m < %f m)" % [c1_off_h, c1_h]) world.call("unload_map") world.queue_free() print("\n=== All Map Height Probes finished with %d failures ===" % fails[0]) quit(fails[0])