路径节点
此文档最初来源于 GTAMods Wiki - Paths (GTA SA),在此处保存以供存档之用。内容保持不变,仅对格式进行了改进以增强在 open.mp 文档中的可读性。
概述
gta3.img(或任何其他存档)中的 64 个 nodes*.dat 文件包含了 GTA SA 的车辆和行人路径及相关信息。从西南角 (-3000, -3000) 开始,每个 750×750 单位方块都有一个文件,按行优先顺序排列。
飞机和火车的路径不存储在节点文件中。火车使用四个 tracks*.dat 文件。carrec.img 中还有一些用于多个任务和混凝土车辆的路径。
可以通过脚本使用操作码 01EB 和 03DE 来影响节点。
通常,车辆和行人如果以任何方式未链接到脚本或 carrec.img 路径,就会使用节点。
路径格式有一个修改版本,可与 fastman92 的 Limit Adjuster 一起使用,它移除或扩展了原生格式施加的一些限制。
用途
据信节点文件是在游戏开发期间由某种路径编译器生成的,代表了处理友好的二进制数据结构,否则这些结构会在运行时由游戏先前版本从 paths.ipl 等文件生成。此类文件在 SA 中仍然存在,但未被使用。
由于内置路径编译器显然已从游戏代码中移除或至少变得无法正常工作,因此需要自定义工具和技术来为 SA 生成新路径。
节点文件由游戏流加载——一次只加载活动区域及其周围区域。因此,损坏的文件只有在玩家进入特定区域时才会导致游戏崩溃。
data/paths/ 目录中单独的 nodes*.dat 文件被游戏忽略。
文件格式
每个文件以头部开始,后跟 7 个不同的部分。
路径以双链接(因此无向)图的形式存储在邻接表表示中。不同区域之间可能存在连接。
数据类型
本文中使用以下数据类型和结构:
| 类型 | 说明 | 大小 |
|---|---|---|
| INT8/UINT8 | 有符号/无符号 8 位整数 | 1 字节 |
| INT16/UINT16 | 有符号/无符号 16 位整数 | 2 字节 |
| INT32/UINT32 | 有符号/无符号 32 位整数 | 4 字节 |
| FLOAT | 单精度浮点数 | 4 字节 |
关键概念
有几个主要概念对于理解路径文件的工作方式很重要:
- **"节点"**是空间中的一个单独点,用作路径的锚点
- 路径是节点之间的路线。这些在游戏中由行人和车辆追踪,但在编辑器中通常显示为图形线条
- 两个节点通过一个引用指向另一个的**"链接"**连接
- 大多数节点链接到另外两个节点,路径每个方向一个,但可能存在更多(如在交叉路口)
头部
头部包含文件中各个部分内容的信息。它的大小为 20 字节。
| 大小 | 类型 | 说明 |
|---|---|---|
| 4b | UINT32 | 节点数量(第 1 部分) |
| 4b | UINT32 | 车辆节点数量(第 1a 部分) |
| 4b | UINT32 | 行人节点数量(第 1b 部分) |
| 4b | UINT32 | 导航节点数量(第 2 部分) |
| 4b | UINT32 | 链接数量(第 3/5/6 部分) |
与链接相关的部分(3/5/6)具有相同数量的条目。这些条目属于一起,编辑器可以将其视为一个记录。
第 1 部分 - 路径节点
第一部分包含路径的节点数据。它们按类型分组:车辆节点列表(汽车、船只、赛道)后跟行人节点。每个节点条目的大小为 28 字节。
| 大小 | 类型 | 说明 |
|---|---|---|
| 4b | UINT32 | 内存地址,未使用 |
| 4b | UINT32 | 始终为零,未使用 |
| 6b | INT16[3] | 位置(XYZ),见下文 |
| 2b | INT16 | 启发式成本,始终为 0x7FFE,在内部用于计算路线 |
| 2b | UINT16 | 链接 ID |
| 2b | UINT16 | 区域 ID(与文件名中相同) |
| 2b | UINT16 | 节点 ID(递增 1) |
| 1b | UINT8 | 路径宽度 |
| 1b | UINT8 | 洪水填充,用于路线计算 |
| 4b | UINT32 | 标志 |
字段描述
- 内存地址:这些可能是 R* 路径编译器内路径段结构的指针。显然游戏忽略了它们,可以设置为零。
- 位置:这是节点在世界坐标中的位置。将有符号字转换为浮点值时,将它们除以 8。
- 链接 ID:此节点链接到的第一个节点的 ID。链接节点的范围是 链接 ID ≤ x < (链接 ID + 链接数量),其中链接数量由标志的前四位给出。
- 区域 ID 和节点 ID:信息数据,用于通过链接连接节点。区域 ID 始终与文件名中的数字相同,节点 ID 用于标识节点。
- 路径宽度:这用于修改路径的宽度。默认值为 0(零)。将有符号字转换为浮点值时,将其除以 8。
- 洪水填充:用于 NPC 路线计算的洪水 ID。对于正常 NPC 车辆交通,使用值 1,2 用于船只,更高的值分配给断开的路径区域段,例如赛道和其他任务应用。
- 标志:前 4 位定义了到相邻节点的链接数量。其他位用于表征节点行为,更多信息请参见下表。
路径节点标志
节点标志位,从低到高:
| 位 | 说明 |
|---|---|
| 0-3 | 链接数量 |
| 4-5 | 交通级别 |
LinkCount 定义了从 LinkID 开始递增的条目数量。TrafficLevel 使用 4 个步骤:
- 0 = 完整
- 1 = 高
- 2 = 中等
- 3 = 低
| 标志 | 位 | 说明 |
|---|---|---|
| A | 06 | 路障 |
| B | 07 | 船只 |
| C | 08 | 仅紧急车辆 |
| D | 09 | 零/未使用 |
| E | 10 | 未知,格罗夫房屋入口路径? |
| F | 11 | 零/未使用 |
| G | 12 | 非高速公路 |
| H | 13 | 是高速公路(行人节点忽略,汽车永远不会是 11 或 00!) |
| I | 14 | 零 |
| J | 15 | 零 |
| K-M | 16-19 | 生成概率(0x00 到 0x0F) |
| O | 20 | 路障? |
| P | 21 | 停车 |
| Q | 22 | 零 |
| R | 23 | 路障? |
| 24-31 | 零(未使用) |
以下按路径类型分组的标志使用统计可能对进一步研究有用:
| 标志 | 行人 | 汽车 | 总计 |
|---|---|---|---|
| 总计 | 37,650 | 30,587 | 68,237 |
| A | 0 | 391 (1.28%) | 391 |
| B | 0 | 1,596 (5.22%) | 1,596 |
| C | 6,019 (15.99%) | 7,669 (25.08%) | 13,688 |
| D | 0 | 0 | 0 |
| E | 17 (0.05%) | 0 | 17 |
| F | 0 | 0 | 0 |
| G | 0 | 27,936 (91.33%) | 27,936 |
| H | 0 | 2,539 (8.3%) | 2,539 |
| I | 0 | 0 | 0 |
| J | 0 | 0 | 0 |
| K | 37,646 (99.98%) | 30,582 (99.98%) | 68,228 |
| L | 36,676 (97.41%) | 30,141 (98.54%) | 66,817 |
| M | 36,676 (97.41%) | 30,136 (98.52%) | 66,812 |
| N | 36,607 (97.22%) | 30,046 (98.23%) | 66,653 |
| O | 0 | 8 (0.03%) | 8 |
| P | 0 | 215 (0.7%) | 215 |
| Q | 0 | 0 | 0 |
| R | 0 | 16 (0.05%) | 16 |
第 2 部分 - 导航节点
第二部分包含额外的节点。这些节点是导航节点(但在本文中为简洁起见称为"navi 节点")。每个记录的大小为 14 字节。
导航节点用于为车辆路径段定义额外信息;行人路径不使用它们。它们通常位于两个相邻车辆节点之间的插值曲线上。
如果你没有正确连接导航节点,可能会出现错误。链接总是从具有较高区域/节点 ID 的节点指向具有较低 ID 的节点,因此目标始终是较低的节点。
| 大小 | 类型 | 说明 |
|---|---|---|
| 4b | INT16[2] | 位置(XY),见下文 |
| 2b | UINT16 | 区域 ID |
| 2b | UINT16 | 节点 ID |
| 2b | INT8[2] | 方向(XY),见下文 |
| 4b | UINT32 | 标志 |
导航节点字段描述
- 位置:这是导航节点在世界坐标中的位置。将有符号字转换为浮点值时,将它们除以 8。
- 区域 ID 和节点 ID:这些标识导航节点附加到的目标节点。
- 方向:这是一个指向上述目标节点的归一化向量,从而定义路径段的大致方向。向量分量由有符号字节表示,值在区间 [-100, 100] 内,对应于浮点值范围 [-1.0, 1.0]。
导航节点标志
这些用于表征路径段行为,更多信息请参见下表。
| 位 | 说明 |
|---|---|
| 0-7 | 路径节点宽度,通常是链接节点路径宽度的副本(字节) |
| 8-10 | 左车道数量 |
| 11-13 | 右车道数量 |
| 14 | 交通灯方向行为 |
| 15 | 零/未使用 |
| 16,17 | 交通灯行为 |
| 18 | 火车道口 |
| 19-31 | 零/未使用 |
重要说明
- 右(向前)和左(向后)车道是相对于方向向量的。
- 经验表明,具有跨区域边界附加的导航节点效果不佳。一个可能的解决方案是将它们附加到最后一个节点而不是下一个节点,反转方向并交换车道编号(如果不同)和其他方向相关标志。但是,如果前一个、导航和下一个节点各自位于不同区域,这将永远不会工作。(*)
- 交通灯行为可以是 0 到 2 的值,其中 0 表示交通灯禁用,1 和 2 用于交通灯,分别是交通灯同步的南北和东西周期。
- 交通灯方向行为如果导航节点与交通灯方向相同则为 1,如果导航节点指向其他地方则为 0。
(*) 在确切了解导航节点如何链接后变得清晰。因此你可以使用它,但这不是义务。
第 3 部分 - 链接
这些是到相邻节点的链接,每个条目 4 字节。
| 大小 | 类型 | 说明 |
|---|---|---|
| 2b | UINT16 | 区域 ID |
| 2b | UINT16 | 节点 ID |
第 4 部分 - 填充
此部分保存恒定大小和内容的数据;其用途未知。这 768 字节填充了 192 个重复的模式 0xFF 0xFF 0x00 0x00,但也可以用零填充。
第 5 部分 - 导航链接
这些是到相邻导航节点的链接,每个链接(在第 3 部分中)一个,每个条目 2 字节。来自行人节点的索引(在第 1b 部分中)为零(未使用)。
| 大小 | 类型 | 说明 |
|---|---|---|
| 2b | UINT16 | 低 10 位是导航节点 ID,高 6 位是对应的区域 ID |
导航节点限制:
- 每个区域文件最多 1024 个导航节点
- 总共最多 64 个文件/区域
导航节点 ID 说明:
- 导航节点 ID 不是第 2 部分中的链接节点 ID,而是导航节点在文件中出现的顺序。
第 6 部分 - 链接长度
这些是链接节点之间的完整单位距离,每个条目 1 字节。它们对于路径查找算法至关重要。
| 大小 | 类型 | 说明 |
|---|---|---|
| 1b | UINT8 | 长度 |
第 7 部分 - 路径交叉标志
此部分由每个节点地址(即节点链接)的交叉标志值组成。
class CPathIntersectionInfo
{
public:
unsigned char m_bRoadCross : 1;
unsigned char m_bPedTrafficLight : 1;
};
部分的大小等于节点地址的数量。 该部分后跟 192 字节的未知数据。
工具和脚本
- Fastman92 路径格式
- SA 路径编辑器(开发中) 作者:JGuntherS@NL - 仅用于编辑现有路径数据
- 路径编译器(开发中) 作者:ocram88 - 允许通过在游戏内生成路径点来创建线性行人路径
- 路径工具(开发中) 作者:steve-m - 附带 MaxScript,可从 Max 导出行人和车辆路径(通过使用样条线形状)
- APE v1.1 作者:Aschratt - 基于内存破解并包含反编译器,可以添加路径到现有路径或在游戏内创建全新的路径!
- 路径脚本 - Deniska 为 3DSMax 编写的脚本,直接创建路径文件
- PathViewer - Aschratt 的工具,允许在 3D 中查看路径并突出显示具有特殊标志的节点
- fastman92 limit adjuster - fastman92 的限制调整器,允许增加路径限制
另请参阅
- 编译路径节点 - 原始讨论线程
- SA、VC 和 GTA3 的路径文档