Files
mtgodot-poc/project/net/mapcoord.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

42 lines
1.8 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MapCoord —— 网络实体坐标 ↔ Metin2World 本地坐标。
#
# M2Client 给的实体 pos 是「全局服务器 cm」经 position_to_godot 后的结果:
# net = (sx*0.01, h, -sy*0.01) sx/sy 含地图 BasePosition
# 而 Metin2World 的地形/物件是「地图本地」帧(tile 0 在原点,+Z 朝南):
# world = ((sx-bx)*0.01, h, (sy-by)*0.01)
# 两者差一个 BasePosition 平移 + Z 轴翻向。没对齐时角色会飘在几公里外的黑void里。
#
# MapCoord.set_base(world.get_map_base_cm()) # Vector2cm
# var p := MapCoord.to_world(client.get_entity(vid).pos)
# var sc := MapCoord.to_server_cm(player.position) # -> Vector2 (sx_cm, sy_cm)
class_name MapCoord
extends RefCounted
static var _bx := 0.0 # BasePosition.x, cm
static var _by := 0.0
static func set_base(base_cm: Vector2) -> void:
_bx = base_cm.x
_by = base_cm.y
static func has_base() -> bool:
return _bx != 0.0 or _by != 0.0
# net 帧 (sx*.01, h, -sy*.01) -> world 本地帧 ((sx-bx)*.01, h, (sy-by)*.01)
static func to_world(net_pos: Vector3) -> Vector3:
return Vector3(net_pos.x - _bx * 0.01, net_pos.y, -net_pos.z - _by * 0.01)
# world 本地帧 -> 服务器全局 cm (sx, sy)
static func to_server_cm(world_pos: Vector3) -> Vector2:
return Vector2(world_pos.x * 100.0 + _bx, world_pos.z * 100.0 + _by)
# 服务器 heading(度) -> world 帧 Godot yaw(弧度)。
# Metin2 heading: 0°=南, 90°=东, 180°=北, 270°=西。
# Godot yaw: atan2(x, z) 中 +Z(南)=0, +X(东)=PI/2(90°), -Z(北)=PI(180°), -X(西)=-PI/2(270°)。
# 两者定义完全一致,无需额外偏移。
static func heading_to_yaw(angle_deg: float) -> float:
return deg_to_rad(angle_deg)
static func yaw_to_heading(yaw_rad: float) -> float:
return fposmod(rad_to_deg(yaw_rad), 360.0)