Skip to content

Commit 78399c6

Browse files
committed
Add WIP AI navigation files template
1 parent b7b7b73 commit 78399c6

File tree

1 file changed

+293
-0
lines changed

1 file changed

+293
-0
lines changed

RE_Engine_AIMP.bt

Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
//------------------------------------------------
2+
//--- 010 Editor v9.0.2 Binary Template
3+
//
4+
// File: AIWAYP.bt
5+
// Authors: shadowcookie
6+
// Version: 0.1
7+
// Purpose:
8+
// Category: RE Engine
9+
// File Mask: *.aiwayp.*|*.aiwaypmgr.*|*.ainvm.*|*.aimap.*
10+
// ID Bytes: 41 49 4D 50
11+
// History:
12+
//------------------------------------------------
13+
14+
local int version = Atoi(SubStr(FileNameGetExtension(GetFileName()), 1));
15+
local int isManager = Strstr(GetFileName(), ".aiwaypmgr.") != -1;
16+
local int isMap = Strstr(GetFileName(), ".aimap.") != -1;
17+
local int isNavmesh = Strstr(GetFileName(), ".ainvm.") != -1;
18+
local int isWaypoint = !isManager && !isNavmesh && !isMap;
19+
20+
local int format3 = (isMap && version == 28); // dmc5
21+
local int format4 = (isMap && version == 41); // re2 rt
22+
local int format5 = (isWaypoint && version == 5); // re4
23+
// dd2, wilds
24+
local int format9 = (isWaypoint && version > 6 || isManager && version >= 8 || isNavmesh && version >= 30);
25+
26+
void align(int n) {
27+
if (FTell()%n == 0) return;
28+
FSkip(n - FTell()%n);
29+
}
30+
31+
typedef struct FixedWString {
32+
uint32 len;
33+
if (len > 0) {
34+
wchar_t str[len];
35+
}
36+
align(4);
37+
};
38+
39+
uint magic;
40+
FixedWString name <read=(len > 0 ? str : "<empty>")>;
41+
42+
if (!format3 && !format4) {
43+
FixedWString hash <read=(len > 0 ? str : "<empty>")>;
44+
}
45+
46+
uint32 num; // likely flags
47+
48+
if (format3 || format4 || format5) {
49+
GUID guid;
50+
int ukn;
51+
} else if (format9) {
52+
uint ukn;
53+
uint32 hash1;
54+
uint32 hash2;
55+
uint ukn2;
56+
}
57+
58+
uint64 layersOffset;
59+
uint64 rszOffset;
60+
61+
uint64 lastSectionOffset;
62+
if (format4) {
63+
uint64 contentGroup1Offset;
64+
} else {
65+
uint64 count;
66+
}
67+
68+
uint64 nodeParentTblOffset;
69+
70+
uint64 secondContentGroupOffset, secondNodeTableOffset;
71+
72+
typedef struct intOrFloat {
73+
int32 num;
74+
FSkip(-4);
75+
float flt;
76+
};
77+
78+
string readIntOrFloat(intOrFloat &vec) {
79+
string str = "";
80+
SPrintf(str, "%d / %f", vec.num, vec.flt);
81+
return str;
82+
}
83+
84+
typedef struct vec3 {
85+
float x;
86+
float y;
87+
float z;
88+
};
89+
90+
91+
// TODO ContentGroupTriangle, ContentGroupPolygon
92+
struct ContentGroupMapPoint {
93+
uint32 nodeCount;
94+
95+
struct { // via.navigation.map.NodeInfo - position and normals?
96+
vec3 pos;
97+
vec3 normal;
98+
} nodes[nodeCount];
99+
100+
uint32 a, b;
101+
uint connectionCount, maxConnectionId;
102+
struct {
103+
uint32 id, n2, n3, n4, n5, n6, n7, n8;
104+
} connections[connectionCount] <read=(Str("%d %d %d %d %d %d %d %d", id, n2, n3, n4, n5, n6, n7, n8))>;
105+
106+
uint32 newcount;
107+
108+
typedef uint32 UknownId;
109+
local uint64 count = 0;
110+
111+
struct {
112+
uint id, connectionId, n3, n4, n5, n6, n7;
113+
} connectionInfo[newcount] <read=(Str("%d %d %d %d %d %d %d", id, connectionId, n3, n4, n5, n6, n7))>;
114+
115+
struct
116+
{
117+
float v_X;
118+
float v_Y;
119+
float v_Z;
120+
float min_X;
121+
float min_Y;
122+
float min_Z;
123+
FSkip(4);
124+
float max_X;
125+
float max_Y;
126+
float max_Z;
127+
FSkip(4);
128+
} bounds;
129+
130+
uint32 typesCount1, typesCount2, typesCount3, typesCount4;
131+
uint32 type1[typesCount1];
132+
uint32 type2[typesCount2];
133+
uint32 type3[typesCount3];
134+
uint32 type4[typesCount4];
135+
136+
if (exists(nodeParentTblOffset)) {
137+
FSeek(nodeParentTblOffset);
138+
}
139+
140+
uint32 nodeParentTbl[connectionCount];
141+
};
142+
143+
struct ContentGroupTriangles {
144+
uint32 nodeCount;
145+
146+
struct {
147+
uint32 ind[3];
148+
ubyte flags[4];
149+
vec3 pos <read=(Str("%f %f %f",x, y, z))>;
150+
} TriangleNode[nodeCount] <read=(Str("%d %d %d : %f %f %f", ind[0], ind[1], ind[2], pos.x, pos.y, pos.z))>;
151+
152+
uint32 something;
153+
uint32 positionCount;
154+
struct {
155+
vec3 vec <read=(Str("%f %f %f",x, y, z))>;
156+
uint32 padding;
157+
} Positions[positionCount] <read=(Str("%f %f %f", vec.x, vec.y, vec.z))>; // ends at 196
158+
159+
uint32 countAgain, lastIndex;
160+
align(16);
161+
162+
struct TriangleInfo {
163+
uint32 n7;
164+
// TODO dmc5: index2count is in n2 instead
165+
uint32 id, n1, n2, n3, n4, index2count, n6;
166+
} Triangles[nodeCount] <read=(Str("%d", id))>;
167+
168+
local int triCount = 0;
169+
struct {
170+
local int i = 0;
171+
for (i = 0; i < nodeCount; i++) {
172+
struct {
173+
triCount += Triangles[i].index2count;
174+
struct {
175+
uint32 id, triangleIndex, n3, n4, n5, n6, n7;
176+
} faces[Triangles[i].index2count] <read=(Str("%d %d %d %d %d %d %d", triangleIndex, id, n3, n4, n5, n6, n7))>;
177+
} TriangleFaces <read=(faces[0].triangleIndex)>;
178+
}
179+
} Faces;
180+
181+
float d, e;
182+
vec3 v1 <read=(Str("%f %f %f",x, y, z))>;
183+
FSkip(4);
184+
vec3 v2 <read=(Str("%f %f %f",x, y, z))>;
185+
FSkip(4);
186+
vec3 v3 <read=(Str("%f %f %f",x, y, z))>;
187+
};
188+
189+
struct ContentGroupPolygon {
190+
uint32 nodeCount;
191+
// todo
192+
};
193+
194+
195+
196+
197+
struct ContentGroup {
198+
uint32 contentCount;
199+
// TODO: handle contentCount > 1 (e.g. wilds Npc_NPC.ainvm)
200+
// structure looks like classname1, node_count1, nodes1, classname2, node_count2, nodes2, node_data, ...
201+
FixedWString classname <read=str>;
202+
if (WStringToString(classname.str) == "via.navigation.map.ContentGroupMapPoint") {
203+
ContentGroupMapPoint points;
204+
} else if (WStringToString(classname.str) == "via.navigation.map.ContentGroupTriangle") {
205+
ContentGroupTriangles triangles;
206+
} else if (WStringToString(classname.str) == "via.navigation.map.ContentGroupPolygon") {
207+
ContentGroupPolygon polygons <read="TODO">;
208+
}
209+
// TODO via.navigation.map.ContentGroupMapBoundary
210+
};
211+
212+
if (exists(contentGroup1Offset) && contentGroup1Offset > 0) {
213+
FSeek(contentGroup1Offset);
214+
ContentGroup ContentGroup1 <read=classname.str>;
215+
} else if (exists(nodeParentTblOffset) && nodeParentTblOffset > 0) {
216+
ContentGroup ContentGroup1 <read=classname.str>;
217+
}
218+
219+
if (secondContentGroupOffset > 0 && secondNodeTableOffset) {
220+
FSeek(secondContentGroupOffset);
221+
ContentGroup ContentGroup2 <read=classname.str>;
222+
}
223+
224+
225+
if (exists(layersOffset)) {
226+
FSeek(layersOffset);
227+
if (format3) {
228+
struct {
229+
uint32 nameHash;
230+
uint32 flags <format=binary>;
231+
} layers[64] <optimize=false, read=(nameHash)>;
232+
} else {
233+
struct {
234+
FixedWString name;
235+
uint32 flags <format=binary>;
236+
} layers[64] <optimize=false, read=(name.str)>;
237+
}
238+
}
239+
240+
if (exists(rszOffset)) {
241+
FSeek(rszOffset);
242+
struct {
243+
uint magic;
244+
} RSZ;
245+
}
246+
247+
248+
string mapToUknownIdsData(uint32 val) {
249+
local uint index = val;
250+
local string result;
251+
SPrintf(result, "%u", index);
252+
if (index <= nodeParentCount) {
253+
local uint oldPos = FTell();
254+
FSeek(nodeParentTblOffset + index * 4);
255+
local uint exVal = ReadUInt();
256+
FSeek(oldPos);
257+
SPrintf(result, "%u => Parent[%u] = %u", index, index, exVal);
258+
}
259+
return result;
260+
}
261+
262+
FSeek(lastSectionOffset);
263+
struct {
264+
uint32 ukn1, ukn2;
265+
uint32 count;
266+
// very TODO
267+
268+
if (count > 0) {
269+
struct {
270+
uint32 hash1, hash2;
271+
uint32 idk[5];
272+
uint32 flags1[3] <format=binary>;
273+
uint32 idk2;
274+
uint32 flags2[3] <format=binary>;
275+
uint32 idk3[4];
276+
277+
uint32 count1, count2, count3;
278+
struct {
279+
uint32 idMaybe;
280+
uint32 numbers[6];
281+
} yetMoreData[4];
282+
uint64 offset1, offset2;
283+
284+
uint32 flags3[3] <format=binary>;
285+
uint32 idk5;
286+
uint32 flags4[3] <format=binary>;
287+
uint32 idk6[4];
288+
FixedWString hashString <read=(str)>;
289+
290+
} moreData[count] <optimize=false>;
291+
}
292+
293+
} endsection;

0 commit comments

Comments
 (0)