rw-parser-ng 2.1.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.md +252 -52
  2. package/lib/codecs/bitmap.d.ts +6 -0
  3. package/lib/codecs/bitmap.js +77 -0
  4. package/lib/codecs/color.d.ts +6 -0
  5. package/lib/codecs/color.js +43 -0
  6. package/lib/codecs/dxt.d.ts +3 -0
  7. package/lib/codecs/dxt.js +212 -0
  8. package/lib/codecs/formats.d.ts +25 -0
  9. package/lib/codecs/formats.js +32 -0
  10. package/lib/codecs/index.d.ts +5 -0
  11. package/lib/codecs/index.js +21 -0
  12. package/lib/codecs/palette.d.ts +6 -0
  13. package/lib/codecs/palette.js +86 -0
  14. package/lib/common/types.d.ts +50 -0
  15. package/lib/common/types.js +2 -0
  16. package/lib/core/byte-stream.d.ts +20 -0
  17. package/lib/core/byte-stream.js +71 -0
  18. package/lib/core/errors.d.ts +5 -0
  19. package/lib/core/errors.js +34 -0
  20. package/lib/core/index.d.ts +5 -0
  21. package/lib/core/index.js +21 -0
  22. package/lib/core/rw-file.d.ts +9 -0
  23. package/lib/core/rw-file.js +36 -0
  24. package/lib/core/rw-sections.d.ts +24 -0
  25. package/lib/core/rw-sections.js +28 -0
  26. package/lib/core/rw-version.d.ts +3 -0
  27. package/lib/core/rw-version.js +27 -0
  28. package/lib/dff/dff-model-type.d.ts +5 -0
  29. package/lib/dff/dff-model-type.js +9 -0
  30. package/lib/dff/index.d.ts +4 -0
  31. package/lib/dff/index.js +20 -0
  32. package/lib/dff/parser.d.ts +5 -0
  33. package/lib/dff/parser.js +154 -0
  34. package/lib/dff/readers/2d-effect.d.ts +3 -0
  35. package/lib/dff/readers/2d-effect.js +211 -0
  36. package/lib/dff/readers/geometry.d.ts +4 -0
  37. package/lib/dff/readers/geometry.js +229 -0
  38. package/lib/dff/readers/index.d.ts +5 -0
  39. package/lib/dff/readers/index.js +21 -0
  40. package/lib/dff/readers/material.d.ts +5 -0
  41. package/lib/dff/readers/material.js +72 -0
  42. package/lib/dff/readers/mesh.d.ts +5 -0
  43. package/lib/dff/readers/mesh.js +84 -0
  44. package/lib/dff/readers/structure.d.ts +6 -0
  45. package/lib/dff/readers/structure.js +67 -0
  46. package/lib/dff/types.d.ts +237 -0
  47. package/lib/dff/types.js +44 -0
  48. package/lib/fxp/index.d.ts +2 -0
  49. package/lib/fxp/index.js +18 -0
  50. package/lib/fxp/info-parser.d.ts +2 -0
  51. package/lib/fxp/info-parser.js +169 -0
  52. package/lib/fxp/parser.d.ts +3 -0
  53. package/lib/fxp/parser.js +285 -0
  54. package/lib/fxp/types/common.d.ts +36 -0
  55. package/lib/fxp/types/common.js +2 -0
  56. package/lib/fxp/types/index.d.ts +3 -0
  57. package/lib/fxp/types/index.js +19 -0
  58. package/lib/fxp/types/info.d.ts +186 -0
  59. package/lib/fxp/types/info.js +2 -0
  60. package/lib/fxp/types/system.d.ts +27 -0
  61. package/lib/fxp/types/system.js +2 -0
  62. package/lib/ifp/index.d.ts +4 -0
  63. package/lib/ifp/index.js +20 -0
  64. package/lib/ifp/parser.d.ts +5 -0
  65. package/lib/ifp/parser.js +38 -0
  66. package/lib/ifp/readers/anp3.d.ts +3 -0
  67. package/lib/ifp/readers/anp3.js +56 -0
  68. package/lib/ifp/readers/anpk.d.ts +3 -0
  69. package/lib/ifp/readers/anpk.js +86 -0
  70. package/lib/ifp/types.d.ts +28 -0
  71. package/lib/ifp/types.js +9 -0
  72. package/lib/index.d.ts +6 -9
  73. package/lib/index.js +6 -13
  74. package/lib/renderware/fxp/FxpData.d.ts +246 -0
  75. package/lib/renderware/fxp/FxpData.js +2 -0
  76. package/lib/renderware/fxp/FxpParser.d.ts +3 -0
  77. package/lib/renderware/fxp/FxpParser.js +512 -0
  78. package/lib/renderware/fxp/index.d.ts +2 -0
  79. package/lib/renderware/fxp/index.js +18 -0
  80. package/lib/txd/bitmap-decoder.d.ts +3 -0
  81. package/lib/txd/bitmap-decoder.js +57 -0
  82. package/lib/txd/index.d.ts +3 -0
  83. package/lib/txd/index.js +19 -0
  84. package/lib/txd/parser.d.ts +8 -0
  85. package/lib/txd/parser.js +122 -0
  86. package/lib/txd/types.d.ts +27 -0
  87. package/lib/txd/types.js +2 -0
  88. package/package.json +16 -9
  89. package/src/codecs/bitmap.ts +75 -0
  90. package/src/codecs/color.ts +40 -0
  91. package/src/codecs/dxt.ts +243 -0
  92. package/src/codecs/formats.ts +28 -0
  93. package/src/codecs/index.ts +5 -0
  94. package/src/codecs/palette.ts +106 -0
  95. package/src/common/types.ts +59 -0
  96. package/src/core/byte-stream.ts +87 -0
  97. package/src/core/errors.ts +7 -0
  98. package/src/core/index.ts +5 -0
  99. package/src/core/rw-file.ts +23 -0
  100. package/src/core/rw-sections.ts +24 -0
  101. package/src/core/rw-version.ts +24 -0
  102. package/src/dff/dff-model-type.ts +5 -0
  103. package/src/dff/index.ts +4 -0
  104. package/src/dff/parser.ts +142 -0
  105. package/src/dff/readers/2d-effect.ts +265 -0
  106. package/src/dff/readers/geometry.ts +264 -0
  107. package/src/dff/readers/index.ts +5 -0
  108. package/src/dff/readers/material.ts +89 -0
  109. package/src/dff/readers/mesh.ts +93 -0
  110. package/src/dff/readers/structure.ts +79 -0
  111. package/src/dff/types.ts +278 -0
  112. package/src/fxp/index.ts +2 -0
  113. package/src/fxp/info-parser.ts +166 -0
  114. package/src/fxp/parser.ts +323 -0
  115. package/src/fxp/types/common.ts +23 -0
  116. package/src/fxp/types/index.ts +3 -0
  117. package/src/fxp/types/info.ts +251 -0
  118. package/src/fxp/types/system.ts +30 -0
  119. package/src/ifp/index.ts +4 -0
  120. package/src/ifp/parser.ts +16 -0
  121. package/src/ifp/readers/anp3.ts +75 -0
  122. package/src/ifp/readers/anpk.ts +110 -0
  123. package/src/ifp/types.ts +33 -0
  124. package/src/index.ts +6 -12
  125. package/src/txd/bitmap-decoder.ts +73 -0
  126. package/src/txd/index.ts +3 -0
  127. package/src/txd/parser.ts +148 -0
  128. package/src/txd/types.ts +29 -0
  129. package/src/renderware/RwFile.ts +0 -26
  130. package/src/renderware/RwSections.ts +0 -27
  131. package/src/renderware/common/types.ts +0 -59
  132. package/src/renderware/dff/DffModelType.ts +0 -5
  133. package/src/renderware/dff/DffParser.ts +0 -611
  134. package/src/renderware/errors/RwParseError.ts +0 -11
  135. package/src/renderware/ifp/IfpData.ts +0 -33
  136. package/src/renderware/ifp/IfpParser.ts +0 -203
  137. package/src/renderware/txd/TxdParser.ts +0 -235
  138. package/src/renderware/utils/ImageDecoder.ts +0 -571
  139. package/src/renderware/utils/ImageFormatEnums.ts +0 -28
  140. package/src/renderware/utils/RwVersion.ts +0 -28
  141. package/src/utils/ByteStream.ts +0 -80
@@ -0,0 +1,323 @@
1
+ import { parseInfo } from "./info-parser";
2
+ import type {
3
+ FxBoundingSphere,
4
+ FxEmitterBP,
5
+ FxInfo,
6
+ FxInterpData,
7
+ FxKeyframe,
8
+ FxMatrix,
9
+ FxProject,
10
+ FxSystemBP,
11
+ } from "./types";
12
+
13
+ const INFO_TYPE_MAP: Record<string, string> = {
14
+ "FX_INFO_EMRATE_DATA:": "emrate",
15
+ "FX_INFO_EMSIZE_DATA:": "emsize",
16
+ "FX_INFO_EMSPEED_DATA:": "emspeed",
17
+ "FX_INFO_EMDIR_DATA:": "emdir",
18
+ "FX_INFO_EMANGLE_DATA:": "emangle",
19
+ "FX_INFO_EMLIFE_DATA:": "emlife",
20
+ "FX_INFO_EMPOS_DATA:": "empos",
21
+ "FX_INFO_EMWEATHER_DATA:": "emweather",
22
+ "FX_INFO_EMROTATION_DATA:": "emrotation",
23
+ "FX_INFO_NOISE_DATA:": "noise",
24
+ "FX_INFO_FORCE_DATA:": "force",
25
+ "FX_INFO_FRICTION_DATA:": "friction",
26
+ "FX_INFO_ATTRACTPT_DATA:": "attractpt",
27
+ "FX_INFO_ATTRACTLINE_DATA:": "attractline",
28
+ "FX_INFO_GROUNDCOLLIDE_DATA:": "groundcollide",
29
+ "FX_INFO_WIND_DATA:": "wind",
30
+ "FX_INFO_JITTER_DATA:": "jitter",
31
+ "FX_INFO_ROTSPEED_DATA:": "rotspeed",
32
+ "FX_INFO_FLOAT_DATA:": "float",
33
+ "FX_INFO_UNDERWATER_DATA:": "underwater",
34
+ "FX_INFO_COLOUR_DATA:": "colour",
35
+ "FX_INFO_SIZE_DATA:": "size",
36
+ "FX_INFO_SPRITERECT_DATA:": "spriterect",
37
+ "FX_INFO_HEATHAZE_DATA:": "heathaze",
38
+ "FX_INFO_TRAIL_DATA:": "trail",
39
+ "FX_INFO_FLAT_DATA:": "flat",
40
+ "FX_INFO_DIR_DATA:": "dir",
41
+ "FX_INFO_ANIMTEX_DATA:": "animtex",
42
+ "FX_INFO_COLOURRANGE_DATA:": "colourrange",
43
+ "FX_INFO_SELFLIT_DATA:": "selflit",
44
+ "FX_INFO_COLOURBRIGHT_DATA:": "colourbright",
45
+ "FX_INFO_SMOKE_DATA:": "smoke",
46
+ };
47
+
48
+ class FxpParserImpl {
49
+ private _lines: string[] = [];
50
+ private _pos = 0;
51
+
52
+ parse(content: string): FxProject {
53
+ this._lines = content.split("\n").map((l) => l.trim());
54
+ this._pos = 0;
55
+
56
+ const systems = new Map<string, FxSystemBP>();
57
+ this._expectLine("FX_PROJECT_DATA:");
58
+
59
+ while (this._pos < this._lines.length) {
60
+ const line = this._currentLine();
61
+ if (!line) {
62
+ this._pos++;
63
+ continue;
64
+ }
65
+
66
+ if (line === "FX_SYSTEM_DATA:") {
67
+ this._pos++;
68
+ this._skipEmpty();
69
+ const version = parseInt(this._currentLine(), 10);
70
+ this._pos++;
71
+ const system = this._parseSystem(version);
72
+ systems.set(system.name, system);
73
+ } else {
74
+ this._pos++;
75
+ }
76
+ }
77
+
78
+ return { systems };
79
+ }
80
+
81
+ private _parseSystem(version: number): FxSystemBP {
82
+ this._skipEmpty();
83
+
84
+ const filename = version > 100 ? this._readField("FILENAME:") : "";
85
+ const name = this._readField("NAME:");
86
+ const length = parseFloat(this._readField("LENGTH:"));
87
+
88
+ let loopIntervalMin = 0,
89
+ loopLength = 0;
90
+ if (version >= 106) {
91
+ loopIntervalMin = parseFloat(this._currentLine());
92
+ this._pos++;
93
+ loopLength = parseFloat(this._currentLine());
94
+ this._pos++;
95
+ }
96
+
97
+ const playMode = parseInt(this._readField("PLAYMODE:"), 10);
98
+ const cullDist = parseFloat(this._readField("CULLDIST:"));
99
+
100
+ let boundingSphere: FxBoundingSphere | null = null;
101
+ if (version > 103) {
102
+ const parts = this._readField("BOUNDINGSPHERE:").split(/\s+/).map(parseFloat);
103
+ boundingSphere = {
104
+ x: parts[0],
105
+ y: parts[1],
106
+ z: parts[2],
107
+ radius: parts[3],
108
+ };
109
+ }
110
+
111
+ const numPrims = parseInt(this._readField("NUM_PRIMS:"), 10);
112
+ const prims: FxEmitterBP[] = [];
113
+
114
+ for (let i = 0; i < numPrims; i++) {
115
+ this._skipEmpty();
116
+ if (this._currentLine() === "FX_PRIM_EMITTER_DATA:") {
117
+ this._pos++;
118
+ prims.push(this._parsePrimEmitter(version));
119
+ } else {
120
+ this._pos++;
121
+ i--;
122
+ }
123
+ }
124
+
125
+ if (version >= 108) {
126
+ this._skipEmpty();
127
+ if (this._currentLine()?.startsWith("OMITTEXTURES:")) this._pos++;
128
+ }
129
+ if (version >= 109) {
130
+ this._skipEmpty();
131
+ if (this._currentLine()?.startsWith("TXDNAME:")) this._pos++;
132
+ }
133
+
134
+ return {
135
+ filename,
136
+ name,
137
+ length,
138
+ loopIntervalMin,
139
+ loopLength,
140
+ playMode,
141
+ cullDist,
142
+ boundingSphere,
143
+ prims,
144
+ };
145
+ }
146
+
147
+ private _parsePrimEmitter(version: number): FxEmitterBP {
148
+ this._skipEmpty();
149
+ this._expectLine("FX_PRIM_BASE_DATA:");
150
+
151
+ const name = this._readField("NAME:");
152
+ const matrix = this._parseMatrix();
153
+
154
+ const textures: (string | null)[] = [this._readNullableTexture("TEXTURE:")];
155
+ if (version > 101) {
156
+ textures.push(this._readNullableTexture("TEXTURE2:"));
157
+ textures.push(this._readNullableTexture("TEXTURE3:"));
158
+ textures.push(this._readNullableTexture("TEXTURE4:"));
159
+ }
160
+
161
+ const alphaOn = this._readField("ALPHAON:") === "1";
162
+ const srcBlendId = parseInt(this._readField("SRCBLENDID:"), 10);
163
+ const dstBlendId = parseInt(this._readField("DSTBLENDID:"), 10);
164
+
165
+ const numInfos = parseInt(this._readField("NUM_INFOS:"), 10);
166
+ const infos: FxInfo[] = [];
167
+
168
+ for (let i = 0; i < numInfos; i++) {
169
+ this._skipEmpty();
170
+ const infoType = this._currentLine();
171
+ this._pos++;
172
+
173
+ const typeKey = INFO_TYPE_MAP[infoType];
174
+ if (!typeKey) {
175
+ this._skipUnknownInfo();
176
+ continue;
177
+ }
178
+
179
+ this._skipEmpty();
180
+ if (this._currentLine()?.startsWith("TIMEMODEPRT:")) this._pos++;
181
+
182
+ const interps =
183
+ typeKey === "underwater" || typeKey === "selflit" ? {} : this._parseAllInterps();
184
+ const info = parseInfo(typeKey, interps);
185
+ if (info) infos.push(info);
186
+ }
187
+
188
+ let lodStart = 0,
189
+ lodEnd = 0;
190
+ this._skipEmpty();
191
+ if (this._currentLine()?.startsWith("LODSTART:"))
192
+ lodStart = parseFloat(this._readField("LODSTART:"));
193
+ this._skipEmpty();
194
+ if (this._currentLine()?.startsWith("LODEND:")) lodEnd = parseFloat(this._readField("LODEND:"));
195
+
196
+ return {
197
+ name,
198
+ matrix,
199
+ textures,
200
+ alphaOn,
201
+ srcBlendId,
202
+ dstBlendId,
203
+ lodStart,
204
+ lodEnd,
205
+ infos,
206
+ };
207
+ }
208
+
209
+ private _parseAllInterps(): Record<string, FxInterpData> {
210
+ const result: Record<string, FxInterpData> = {};
211
+
212
+ while (this._pos < this._lines.length) {
213
+ this._skipEmpty();
214
+ const line = this._currentLine();
215
+ if (this._isBlockEnd(line)) break;
216
+
217
+ if (line.endsWith(":") && !line.startsWith("FX_")) {
218
+ const fieldName = line.slice(0, -1).toUpperCase();
219
+ this._pos++;
220
+ this._skipEmpty();
221
+ if (this._currentLine() === "FX_INTERP_DATA:") {
222
+ result[fieldName] = this._parseInterpolation();
223
+ }
224
+ } else {
225
+ this._pos++;
226
+ }
227
+ }
228
+
229
+ return result;
230
+ }
231
+
232
+ private _isBlockEnd(line: string): boolean {
233
+ return (
234
+ !line ||
235
+ line.startsWith("FX_INFO_") ||
236
+ line.startsWith("LODSTART:") ||
237
+ line.startsWith("LODEND:") ||
238
+ line.startsWith("FX_PRIM_") ||
239
+ line.startsWith("FX_SYSTEM_DATA:") ||
240
+ line.startsWith("OMITTEXTURES:") ||
241
+ line.startsWith("TXDNAME:")
242
+ );
243
+ }
244
+
245
+ private _parseInterpolation(): FxInterpData {
246
+ this._expectLine("FX_INTERP_DATA:");
247
+ const looped = this._readField("LOOPED:") === "1";
248
+ const numKeys = parseInt(this._readField("NUM_KEYS:"), 10);
249
+
250
+ const keys: FxKeyframe[] = [];
251
+ for (let i = 0; i < numKeys; i++) {
252
+ this._expectLine("FX_KEYFLOAT_DATA:");
253
+ keys.push({
254
+ time: parseFloat(this._readField("TIME:")),
255
+ value: parseFloat(this._readField("VAL:")),
256
+ });
257
+ }
258
+
259
+ return { looped, keys };
260
+ }
261
+
262
+ private _parseMatrix(): FxMatrix {
263
+ this._skipEmpty();
264
+ const line = this._currentLine();
265
+ if (!line?.startsWith("MATRIX:")) {
266
+ return {
267
+ right: { x: 1, y: 0, z: 0 },
268
+ up: { x: 0, y: 1, z: 0 },
269
+ at: { x: 0, y: 0, z: 1 },
270
+ pos: { x: 0, y: 0, z: 0 },
271
+ };
272
+ }
273
+
274
+ const p = line.slice(7).trim().split(/\s+/).map(parseFloat);
275
+ this._pos++;
276
+
277
+ return {
278
+ right: { x: p[0], y: p[1], z: p[2] },
279
+ up: { x: p[3], y: p[4], z: p[5] },
280
+ at: { x: p[6], y: p[7], z: p[8] },
281
+ pos: { x: p[9], y: p[10], z: p[11] },
282
+ };
283
+ }
284
+
285
+ private _skipUnknownInfo(): void {
286
+ while (this._pos < this._lines.length && !this._isBlockEnd(this._currentLine())) this._pos++;
287
+ }
288
+
289
+ private _readField(prefix: string): string {
290
+ this._skipEmpty();
291
+ const line = this._currentLine();
292
+ if (!line?.startsWith(prefix)) return "";
293
+ this._pos++;
294
+ return line.slice(prefix.length).trim();
295
+ }
296
+
297
+ private _readNullableTexture(prefix: string): string | null {
298
+ const val = this._readField(prefix);
299
+ return val === "NULL" || val === "" ? null : val;
300
+ }
301
+
302
+ private _expectLine(expected: string): void {
303
+ this._skipEmpty();
304
+ if (this._currentLine() === expected) this._pos++;
305
+ }
306
+
307
+ private _skipEmpty(): void {
308
+ while (this._pos < this._lines.length && this._lines[this._pos].trim() === "") this._pos++;
309
+ }
310
+
311
+ private _currentLine(): string {
312
+ return this._lines[this._pos] ?? "";
313
+ }
314
+ }
315
+
316
+ export function parseFxpContent(content: string): FxProject {
317
+ return new FxpParserImpl().parse(content);
318
+ }
319
+
320
+ export function parseFxpFile(filePath: string): FxProject {
321
+ const fs = require("node:fs");
322
+ return parseFxpContent(fs.readFileSync(filePath, "utf-8"));
323
+ }
@@ -0,0 +1,23 @@
1
+ export interface FxKeyframe {
2
+ time: number;
3
+ value: number;
4
+ }
5
+
6
+ export interface FxInterpData {
7
+ looped: boolean;
8
+ keys: FxKeyframe[];
9
+ }
10
+
11
+ export interface FxMatrix {
12
+ right: { x: number; y: number; z: number };
13
+ up: { x: number; y: number; z: number };
14
+ at: { x: number; y: number; z: number };
15
+ pos: { x: number; y: number; z: number };
16
+ }
17
+
18
+ export interface FxBoundingSphere {
19
+ x: number;
20
+ y: number;
21
+ z: number;
22
+ radius: number;
23
+ }
@@ -0,0 +1,3 @@
1
+ export * from "./common";
2
+ export * from "./info";
3
+ export * from "./system";
@@ -0,0 +1,251 @@
1
+ import type { FxInterpData } from "./common";
2
+
3
+ export interface FxInfoEmRate {
4
+ type: "emrate";
5
+ rate: FxInterpData;
6
+ }
7
+
8
+ export interface FxInfoEmSize {
9
+ type: "emsize";
10
+ radius: FxInterpData;
11
+ sizeMinX: FxInterpData;
12
+ sizeMaxX: FxInterpData;
13
+ sizeMinY: FxInterpData;
14
+ sizeMaxY: FxInterpData;
15
+ sizeMinZ: FxInterpData;
16
+ sizeMaxZ: FxInterpData;
17
+ }
18
+
19
+ export interface FxInfoEmSpeed {
20
+ type: "emspeed";
21
+ speed: FxInterpData;
22
+ bias: FxInterpData;
23
+ }
24
+
25
+ export interface FxInfoEmDir {
26
+ type: "emdir";
27
+ dirX: FxInterpData;
28
+ dirY: FxInterpData;
29
+ dirZ: FxInterpData;
30
+ }
31
+
32
+ export interface FxInfoEmAngle {
33
+ type: "emangle";
34
+ min: FxInterpData;
35
+ max: FxInterpData;
36
+ }
37
+
38
+ export interface FxInfoEmLife {
39
+ type: "emlife";
40
+ life: FxInterpData;
41
+ bias: FxInterpData;
42
+ }
43
+
44
+ export interface FxInfoEmPos {
45
+ type: "empos";
46
+ x: FxInterpData;
47
+ y: FxInterpData;
48
+ z: FxInterpData;
49
+ }
50
+
51
+ export interface FxInfoEmWeather {
52
+ type: "emweather";
53
+ interp: FxInterpData;
54
+ }
55
+
56
+ export interface FxInfoEmRotation {
57
+ type: "emrotation";
58
+ min: FxInterpData;
59
+ max: FxInterpData;
60
+ }
61
+
62
+ export interface FxInfoNoise {
63
+ type: "noise";
64
+ x: FxInterpData;
65
+ y: FxInterpData;
66
+ z: FxInterpData;
67
+ }
68
+
69
+ export interface FxInfoForce {
70
+ type: "force";
71
+ forceX: FxInterpData;
72
+ forceY: FxInterpData;
73
+ forceZ: FxInterpData;
74
+ }
75
+
76
+ export interface FxInfoFriction {
77
+ type: "friction";
78
+ friction: FxInterpData;
79
+ }
80
+
81
+ export interface FxInfoAttractPt {
82
+ type: "attractpt";
83
+ x: FxInterpData;
84
+ y: FxInterpData;
85
+ z: FxInterpData;
86
+ power: FxInterpData;
87
+ }
88
+
89
+ export interface FxInfoAttractLine {
90
+ type: "attractline";
91
+ x1: FxInterpData;
92
+ y1: FxInterpData;
93
+ z1: FxInterpData;
94
+ x2: FxInterpData;
95
+ y2: FxInterpData;
96
+ z2: FxInterpData;
97
+ power: FxInterpData;
98
+ }
99
+
100
+ export interface FxInfoGroundCollide {
101
+ type: "groundcollide";
102
+ damping: FxInterpData;
103
+ bounce: FxInterpData;
104
+ }
105
+
106
+ export interface FxInfoWind {
107
+ type: "wind";
108
+ interp: FxInterpData;
109
+ }
110
+
111
+ export interface FxInfoJitter {
112
+ type: "jitter";
113
+ x: FxInterpData;
114
+ y: FxInterpData;
115
+ z: FxInterpData;
116
+ }
117
+
118
+ export interface FxInfoRotSpeed {
119
+ type: "rotspeed";
120
+ speed: FxInterpData;
121
+ speedBias: FxInterpData;
122
+ accel: FxInterpData;
123
+ accelBias: FxInterpData;
124
+ }
125
+
126
+ export interface FxInfoFloat {
127
+ type: "float";
128
+ interp: FxInterpData;
129
+ }
130
+
131
+ export interface FxInfoUnderwater {
132
+ type: "underwater";
133
+ }
134
+
135
+ export interface FxInfoColour {
136
+ type: "colour";
137
+ red: FxInterpData;
138
+ green: FxInterpData;
139
+ blue: FxInterpData;
140
+ alpha: FxInterpData;
141
+ }
142
+
143
+ export interface FxInfoSize {
144
+ type: "size";
145
+ sizeX: FxInterpData;
146
+ sizeY: FxInterpData;
147
+ sizeXBias: FxInterpData;
148
+ sizeYBias: FxInterpData;
149
+ }
150
+
151
+ export interface FxInfoSpriteRect {
152
+ type: "spriterect";
153
+ interps: FxInterpData[];
154
+ }
155
+
156
+ export interface FxInfoHeatHaze {
157
+ type: "heathaze";
158
+ interps: FxInterpData[];
159
+ }
160
+
161
+ export interface FxInfoTrail {
162
+ type: "trail";
163
+ interps: FxInterpData[];
164
+ }
165
+
166
+ export interface FxInfoFlat {
167
+ type: "flat";
168
+ rightX: FxInterpData;
169
+ rightY: FxInterpData;
170
+ rightZ: FxInterpData;
171
+ upX: FxInterpData;
172
+ upY: FxInterpData;
173
+ upZ: FxInterpData;
174
+ atX: FxInterpData;
175
+ atY: FxInterpData;
176
+ atZ: FxInterpData;
177
+ }
178
+
179
+ export interface FxInfoDir {
180
+ type: "dir";
181
+ interps: FxInterpData[];
182
+ }
183
+
184
+ export interface FxInfoAnimTexture {
185
+ type: "animtex";
186
+ interps: FxInterpData[];
187
+ }
188
+
189
+ export interface FxInfoColourRange {
190
+ type: "colourrange";
191
+ redMin: FxInterpData;
192
+ redMax: FxInterpData;
193
+ greenMin: FxInterpData;
194
+ greenMax: FxInterpData;
195
+ blueMin: FxInterpData;
196
+ blueMax: FxInterpData;
197
+ alphaMin: FxInterpData;
198
+ alphaMax: FxInterpData;
199
+ }
200
+
201
+ export interface FxInfoSelfLit {
202
+ type: "selflit";
203
+ }
204
+
205
+ export interface FxInfoColourBright {
206
+ type: "colourbright";
207
+ red: FxInterpData;
208
+ green: FxInterpData;
209
+ blue: FxInterpData;
210
+ alpha: FxInterpData;
211
+ brightness: FxInterpData;
212
+ }
213
+
214
+ export interface FxInfoSmoke {
215
+ type: "smoke";
216
+ interps: FxInterpData[];
217
+ }
218
+
219
+ export type FxInfo =
220
+ | FxInfoEmRate
221
+ | FxInfoEmSize
222
+ | FxInfoEmSpeed
223
+ | FxInfoEmDir
224
+ | FxInfoEmAngle
225
+ | FxInfoEmLife
226
+ | FxInfoEmPos
227
+ | FxInfoEmWeather
228
+ | FxInfoEmRotation
229
+ | FxInfoNoise
230
+ | FxInfoForce
231
+ | FxInfoFriction
232
+ | FxInfoAttractPt
233
+ | FxInfoAttractLine
234
+ | FxInfoGroundCollide
235
+ | FxInfoWind
236
+ | FxInfoJitter
237
+ | FxInfoRotSpeed
238
+ | FxInfoFloat
239
+ | FxInfoUnderwater
240
+ | FxInfoColour
241
+ | FxInfoSize
242
+ | FxInfoSpriteRect
243
+ | FxInfoHeatHaze
244
+ | FxInfoTrail
245
+ | FxInfoFlat
246
+ | FxInfoDir
247
+ | FxInfoAnimTexture
248
+ | FxInfoColourRange
249
+ | FxInfoSelfLit
250
+ | FxInfoColourBright
251
+ | FxInfoSmoke;
@@ -0,0 +1,30 @@
1
+ import type { FxBoundingSphere, FxMatrix } from "./common";
2
+ import type { FxInfo } from "./info";
3
+
4
+ export interface FxEmitterBP {
5
+ name: string;
6
+ matrix: FxMatrix;
7
+ textures: (string | null)[];
8
+ alphaOn: boolean;
9
+ srcBlendId: number;
10
+ dstBlendId: number;
11
+ lodStart: number;
12
+ lodEnd: number;
13
+ infos: FxInfo[];
14
+ }
15
+
16
+ export interface FxSystemBP {
17
+ filename: string;
18
+ name: string;
19
+ length: number;
20
+ loopIntervalMin: number;
21
+ loopLength: number;
22
+ playMode: number;
23
+ cullDist: number;
24
+ boundingSphere: FxBoundingSphere | null;
25
+ prims: FxEmitterBP[];
26
+ }
27
+
28
+ export interface FxProject {
29
+ systems: Map<string, FxSystemBP>;
30
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./parser";
2
+ export * from "./readers/anp3";
3
+ export * from "./readers/anpk";
4
+ export * from "./types";
@@ -0,0 +1,16 @@
1
+ import { RwFile } from "../core/rw-file";
2
+ import { readAnp3 } from "./readers/anp3";
3
+ import { readAnpk } from "./readers/anpk";
4
+ import type { RwIfp } from "./types";
5
+
6
+ export class IfpParser extends RwFile {
7
+ public parse(): RwIfp {
8
+ const signature = this.readString(4);
9
+ this.setPosition(0);
10
+
11
+ if (signature === "ANP3") return readAnp3(this);
12
+ if (signature === "ANPK") return readAnpk(this);
13
+
14
+ throw new Error("Unsupported IFP version");
15
+ }
16
+ }