Skip to content

Commit 6d6604e

Browse files
committed
Add WIP AI navigation files template
1 parent b7b7b73 commit 6d6604e

File tree

1 file changed

+296
-0
lines changed

1 file changed

+296
-0
lines changed

RE_Engine_AIMP.bt

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
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+
if (ReadFloat() != 1) {
116+
uint32 padding;
117+
}
118+
119+
struct
120+
{
121+
float val1;
122+
float val2;
123+
float min_X;
124+
float min_Y;
125+
float min_Z;
126+
FSkip(4);
127+
float max_X;
128+
float max_Y;
129+
float max_Z;
130+
FSkip(4);
131+
} bounds;
132+
133+
uint32 typesCount1, typesCount2, typesCount3, typesCount4;
134+
if (typesCount1 > 0) uint32 type1[typesCount1];
135+
if (typesCount2 > 0) uint32 type2[typesCount2];
136+
if (typesCount3 > 0) uint32 type3[typesCount3];
137+
if (typesCount4 > 0) uint32 type4[typesCount4];
138+
139+
if (exists(nodeParentTblOffset)) {
140+
FSeek(nodeParentTblOffset);
141+
}
142+
143+
uint32 nodeParentTbl[connectionCount];
144+
};
145+
146+
struct ContentGroupTriangles {
147+
uint32 nodeCount;
148+
149+
struct {
150+
uint32 ind[3];
151+
ubyte flags[4];
152+
vec3 pos <read=(Str("%f %f %f",x, y, z))>;
153+
} TriangleNode[nodeCount] <read=(Str("%d %d %d : %f %f %f", ind[0], ind[1], ind[2], pos.x, pos.y, pos.z))>;
154+
155+
uint32 something;
156+
uint32 positionCount;
157+
struct {
158+
vec3 vec <read=(Str("%f %f %f",x, y, z))>;
159+
uint32 padding;
160+
} Positions[positionCount] <read=(Str("%f %f %f", vec.x, vec.y, vec.z))>; // ends at 196
161+
162+
uint32 countAgain, lastIndex;
163+
align(16);
164+
165+
struct TriangleInfo {
166+
uint32 n7;
167+
// TODO dmc5: index2count is in n2 instead
168+
uint32 id, n1, n2, n3, n4, index2count, n6;
169+
} Triangles[nodeCount] <read=(Str("%d", id))>;
170+
171+
local int triCount = 0;
172+
struct {
173+
local int i = 0;
174+
for (i = 0; i < nodeCount; i++) {
175+
struct {
176+
triCount += Triangles[i].index2count;
177+
struct {
178+
uint32 id, triangleIndex, n3, n4, n5, n6, n7;
179+
} faces[Triangles[i].index2count] <read=(Str("%d %d %d %d %d %d %d", triangleIndex, id, n3, n4, n5, n6, n7))>;
180+
} TriangleFaces <read=(faces[0].triangleIndex)>;
181+
}
182+
} Faces;
183+
184+
float d, e;
185+
vec3 v1 <read=(Str("%f %f %f",x, y, z))>;
186+
FSkip(4);
187+
vec3 v2 <read=(Str("%f %f %f",x, y, z))>;
188+
FSkip(4);
189+
vec3 v3 <read=(Str("%f %f %f",x, y, z))>;
190+
};
191+
192+
struct ContentGroupPolygon {
193+
uint32 nodeCount;
194+
// todo
195+
};
196+
197+
198+
199+
200+
struct ContentGroup {
201+
uint32 contentCount;
202+
// TODO: handle contentCount > 1 (e.g. wilds Npc_NPC.ainvm)
203+
// structure looks like classname1, node_count1, nodes1, classname2, node_count2, nodes2, node_data, ...
204+
FixedWString classname <read=str>;
205+
if (WStringToString(classname.str) == "via.navigation.map.ContentGroupMapPoint") {
206+
ContentGroupMapPoint points;
207+
} else if (WStringToString(classname.str) == "via.navigation.map.ContentGroupTriangle") {
208+
ContentGroupTriangles triangles;
209+
} else if (WStringToString(classname.str) == "via.navigation.map.ContentGroupPolygon") {
210+
ContentGroupPolygon polygons <read="TODO">;
211+
}
212+
// TODO via.navigation.map.ContentGroupMapBoundary
213+
};
214+
215+
if (exists(contentGroup1Offset) && contentGroup1Offset > 0) {
216+
FSeek(contentGroup1Offset);
217+
ContentGroup ContentGroup1 <read=classname.str>;
218+
} else if (exists(nodeParentTblOffset) && nodeParentTblOffset > 0) {
219+
ContentGroup ContentGroup1 <read=classname.str>;
220+
}
221+
222+
if (secondContentGroupOffset > 0 && secondNodeTableOffset) {
223+
FSeek(secondContentGroupOffset);
224+
ContentGroup ContentGroup2 <read=classname.str>;
225+
}
226+
227+
228+
if (exists(layersOffset)) {
229+
FSeek(layersOffset);
230+
if (format3) {
231+
struct {
232+
uint32 nameHash;
233+
uint32 flags <format=binary>;
234+
} layers[64] <optimize=false, read=(nameHash)>;
235+
} else {
236+
struct {
237+
FixedWString name;
238+
uint32 flags <format=binary>;
239+
} layers[64] <optimize=false, read=(name.str)>;
240+
}
241+
}
242+
243+
if (exists(rszOffset)) {
244+
FSeek(rszOffset);
245+
struct {
246+
uint magic;
247+
} RSZ;
248+
}
249+
250+
251+
string mapToUknownIdsData(uint32 val) {
252+
local uint index = val;
253+
local string result;
254+
SPrintf(result, "%u", index);
255+
if (index <= nodeParentCount) {
256+
local uint oldPos = FTell();
257+
FSeek(nodeParentTblOffset + index * 4);
258+
local uint exVal = ReadUInt();
259+
FSeek(oldPos);
260+
SPrintf(result, "%u => Parent[%u] = %u", index, index, exVal);
261+
}
262+
return result;
263+
}
264+
265+
FSeek(lastSectionOffset);
266+
struct {
267+
uint32 ukn1, ukn2;
268+
uint32 count;
269+
// very TODO
270+
271+
if (count > 0) {
272+
struct {
273+
uint32 hash1, hash2;
274+
uint32 idk[5];
275+
uint32 flags1[3] <format=binary>;
276+
uint32 idk2;
277+
uint32 flags2[3] <format=binary>;
278+
uint32 idk3[4];
279+
280+
uint32 count1, count2, count3;
281+
struct {
282+
uint32 idMaybe;
283+
uint32 numbers[6];
284+
} yetMoreData[4];
285+
uint64 offset1, offset2;
286+
287+
uint32 flags3[3] <format=binary>;
288+
uint32 idk5;
289+
uint32 flags4[3] <format=binary>;
290+
uint32 idk6[4];
291+
FixedWString hashString <read=(str)>;
292+
293+
} moreData[count] <optimize=false>;
294+
}
295+
296+
} endsection;

0 commit comments

Comments
 (0)