123 lines
5.6 KiB
GDScript
123 lines
5.6 KiB
GDScript
# 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])
|