wc3maptranslator 4.0.0 → 4.0.2

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 (118) hide show
  1. package/LICENSE.md +23 -23
  2. package/dist/AngleConverter.d.ts +3 -0
  3. package/dist/AngleConverter.d.ts.map +1 -0
  4. package/dist/AngleConverter.js +12 -0
  5. package/dist/AngleConverter.js.map +1 -0
  6. package/dist/CommonInterfaces.d.ts +17 -0
  7. package/dist/CommonInterfaces.d.ts.map +1 -0
  8. package/dist/CommonInterfaces.js +3 -0
  9. package/dist/CommonInterfaces.js.map +1 -0
  10. package/dist/HexBuffer.d.ts +15 -0
  11. package/dist/HexBuffer.d.ts.map +1 -0
  12. package/{lib/HexBuffer.ts → dist/HexBuffer.js} +71 -81
  13. package/dist/HexBuffer.js.map +1 -0
  14. package/dist/W3Buffer.d.ts +14 -0
  15. package/dist/W3Buffer.d.ts.map +1 -0
  16. package/{lib/W3Buffer.ts → dist/W3Buffer.js} +63 -69
  17. package/dist/W3Buffer.js.map +1 -0
  18. package/dist/index.d.ts +3 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/{index.js → dist/index.js} +1 -1
  21. package/dist/index.js.map +1 -0
  22. package/dist/translators/CamerasTranslator.d.ts +23 -0
  23. package/dist/translators/CamerasTranslator.d.ts.map +1 -0
  24. package/{lib/translators/CamerasTranslator.ts → dist/translators/CamerasTranslator.js} +76 -101
  25. package/dist/translators/CamerasTranslator.js.map +1 -0
  26. package/dist/translators/DoodadsTranslator.d.ts +23 -0
  27. package/dist/translators/DoodadsTranslator.d.ts.map +1 -0
  28. package/{lib/translators/DoodadsTranslator.ts → dist/translators/DoodadsTranslator.js} +146 -178
  29. package/dist/translators/DoodadsTranslator.js.map +1 -0
  30. package/dist/translators/ImportsTranslator.d.ts +16 -0
  31. package/dist/translators/ImportsTranslator.d.ts.map +1 -0
  32. package/{lib/translators/ImportsTranslator.ts → dist/translators/ImportsTranslator.js} +62 -78
  33. package/dist/translators/ImportsTranslator.js.map +1 -0
  34. package/dist/translators/InfoTranslator.d.ts +124 -0
  35. package/dist/translators/InfoTranslator.d.ts.map +1 -0
  36. package/{lib/translators/InfoTranslator.ts → dist/translators/InfoTranslator.js} +422 -584
  37. package/dist/translators/InfoTranslator.js.map +1 -0
  38. package/dist/translators/ObjectsTranslator.d.ts +23 -0
  39. package/dist/translators/ObjectsTranslator.d.ts.map +1 -0
  40. package/{lib/translators/ObjectsTranslator.ts → dist/translators/ObjectsTranslator.js} +91 -125
  41. package/dist/translators/ObjectsTranslator.js.map +1 -0
  42. package/dist/translators/RegionsTranslator.d.ts +22 -0
  43. package/dist/translators/RegionsTranslator.d.ts.map +1 -0
  44. package/{lib/translators/RegionsTranslator.ts → dist/translators/RegionsTranslator.js} +96 -123
  45. package/dist/translators/RegionsTranslator.js.map +1 -0
  46. package/dist/translators/SoundsTranslator.d.ts +35 -0
  47. package/dist/translators/SoundsTranslator.d.ts.map +1 -0
  48. package/{lib/translators/SoundsTranslator.ts → dist/translators/SoundsTranslator.js} +183 -237
  49. package/dist/translators/SoundsTranslator.js.map +1 -0
  50. package/dist/translators/StringsTranslator.d.ts +7 -0
  51. package/dist/translators/StringsTranslator.d.ts.map +1 -0
  52. package/{lib/translators/StringsTranslator.ts → dist/translators/StringsTranslator.js} +44 -49
  53. package/dist/translators/StringsTranslator.js.map +1 -0
  54. package/dist/translators/TerrainTranslator.d.ts +33 -0
  55. package/dist/translators/TerrainTranslator.d.ts.map +1 -0
  56. package/{lib/translators/TerrainTranslator.ts → dist/translators/TerrainTranslator.js} +221 -276
  57. package/dist/translators/TerrainTranslator.js.map +1 -0
  58. package/dist/translators/UnitsTranslator.d.ts +40 -0
  59. package/dist/translators/UnitsTranslator.d.ts.map +1 -0
  60. package/{lib/translators/UnitsTranslator.ts → dist/translators/UnitsTranslator.js} +199 -261
  61. package/dist/translators/UnitsTranslator.js.map +1 -0
  62. package/{lib/translators/index.ts → dist/translators/index.d.ts} +11 -10
  63. package/dist/translators/index.d.ts.map +1 -0
  64. package/dist/translators/index.js +23 -0
  65. package/dist/translators/index.js.map +1 -0
  66. package/package.json +4 -2
  67. package/.codeclimate.yml +0 -12
  68. package/.editorconfig +0 -8
  69. package/.eslintignore +0 -5
  70. package/.eslintrc +0 -55
  71. package/.github/workflows/codeql-analysis.yml +0 -54
  72. package/.nycrc +0 -18
  73. package/.travis.yml +0 -23
  74. package/CHANGELOG.md +0 -73
  75. package/index.ts +0 -14
  76. package/lib/AngleConverter.ts +0 -7
  77. package/lib/CommonInterfaces.ts +0 -22
  78. package/test/.mocharc.json +0 -4
  79. package/test/AngleConverterTest.ts +0 -18
  80. package/test/HexBufferTest.ts +0 -170
  81. package/test/TranslatorReversion.ts +0 -218
  82. package/test/W3BufferTest.ts +0 -50
  83. package/test/data/cameras.json +0 -16
  84. package/test/data/doodads.json +0 -2730
  85. package/test/data/imports.json +0 -386
  86. package/test/data/info.json +0 -250
  87. package/test/data/obj-abilities.json +0 -4892
  88. package/test/data/obj-buffs.json +0 -38
  89. package/test/data/obj-destructables.json +0 -31
  90. package/test/data/obj-doodads.json +0 -38
  91. package/test/data/obj-items.json +0 -31
  92. package/test/data/obj-units.json +0 -40
  93. package/test/data/obj-upgrades.json +0 -38
  94. package/test/data/regions.json +0 -206
  95. package/test/data/sounds.json +0 -50
  96. package/test/data/strings.json +0 -115
  97. package/test/data/terrain.json +0 -1
  98. package/test/data/units.json +0 -452
  99. package/test/data/war3map.doo +0 -0
  100. package/test/data/war3map.imp +0 -0
  101. package/test/data/war3map.j +0 -3442
  102. package/test/data/war3map.shd +0 -0
  103. package/test/data/war3map.w3a +0 -0
  104. package/test/data/war3map.w3b +0 -0
  105. package/test/data/war3map.w3c +0 -0
  106. package/test/data/war3map.w3d +0 -0
  107. package/test/data/war3map.w3e +0 -0
  108. package/test/data/war3map.w3h +0 -0
  109. package/test/data/war3map.w3i +0 -0
  110. package/test/data/war3map.w3q +0 -0
  111. package/test/data/war3map.w3r +0 -0
  112. package/test/data/war3map.w3s +0 -0
  113. package/test/data/war3map.w3t +0 -0
  114. package/test/data/war3map.w3u +0 -0
  115. package/test/data/war3map.wts +0 -631
  116. package/test/data/war3mapUnits.doo +0 -0
  117. package/tsconfig.json +0 -25
  118. package/tslint.json +0 -47
@@ -1,584 +1,422 @@
1
- import { HexBuffer } from '../HexBuffer';
2
- import { W3Buffer } from '../W3Buffer';
3
- import { WarResult, JsonResult } from '../CommonInterfaces'
4
-
5
- interface Map {
6
- name: string;
7
- author: string;
8
- description: string;
9
- recommendedPlayers: string;
10
- playableArea: PlayableMapArea;
11
- flags: MapFlags;
12
- mainTileType: string;
13
- }
14
-
15
- interface GameVersion {
16
- major: number;
17
- minor: number;
18
- patch: number;
19
- build: number;
20
- }
21
-
22
- interface Camera {
23
- bounds: number[];
24
- complements: number[];
25
- }
26
-
27
- interface MapFlags {
28
- hideMinimapInPreview: boolean; // 0x0001: 1=hide minimap in preview screens
29
- modifyAllyPriorities: boolean; // 0x0002: 1=modify ally priorities
30
- isMeleeMap: boolean; // 0x0004: 1=melee map
31
- // 0x0008: 1=playable map size was large and has never been reduced to medium (?)
32
- maskedPartiallyVisible: boolean; // 0x0010: 1=masked area are partially visible
33
- fixedPlayerSetting: boolean; // 0x0020: 1=fixed player setting for custom forces
34
- useCustomForces: boolean; // 0x0040: 1=use custom forces
35
- useCustomTechtree: boolean; // 0x0080: 1=use custom techtree
36
- useCustomAbilities: boolean; // 0x0100: 1=use custom abilities
37
- useCustomUpgrades: boolean; // 0x0200: 1=use custom upgrades
38
- // 0x0400: 1=map properties menu opened at least once since map creation (?)
39
- waterWavesOnCliffShores: boolean; // 0x0800: 1=show water waves on cliff shores
40
- waterWavesOnRollingShores: boolean; // 0x1000: 1=show water waves on rolling shores
41
- // 0x2000: 1=unknown
42
- // 0x4000: 1=unknown
43
- useItemClassificationSystem: boolean; // 0x8000: 1=use item classification system
44
- enableWaterTinting: boolean; // 0x10000
45
- useAccurateProbabilityForCalculations: boolean; // 0x20000
46
- useCustomAbilitySkins: boolean; // 0x40000
47
- }
48
-
49
- interface LoadingScreen {
50
- background: number;
51
- path: string;
52
- text: string;
53
- title: string;
54
- subtitle: string;
55
- }
56
-
57
- enum FogType {
58
- Linear = 0,
59
- Exponential1 = 1,
60
- Exponential2 = 2
61
- }
62
-
63
- interface Fog {
64
- type: FogType;
65
- startHeight: number;
66
- endHeight: number;
67
- density: number;
68
- color: number[]; // R G B A
69
- }
70
-
71
- interface PlayableMapArea {
72
- width: number;
73
- height: number;
74
- }
75
-
76
- interface Prologue {
77
- path: string;
78
- text: string;
79
- title: string;
80
- subtitle: string;
81
- }
82
-
83
- interface Info {
84
- saves: number;
85
- gameVersion: GameVersion;
86
- editorVersion: number;
87
- scriptLanguage: ScriptLanguage;
88
- supportedModes: SupportedModes;
89
- map: Map;
90
- camera: Camera;
91
- prologue: Prologue;
92
- loadingScreen: LoadingScreen;
93
- fog: Fog;
94
- globalWeather: string;
95
- customSoundEnvironment: string;
96
- customLightEnv: string;
97
- water: number[]; // R G B A
98
- players: Player[];
99
- forces: Force[];
100
- }
101
-
102
- interface PlayerStartingPosition {
103
- x: number;
104
- y: number;
105
- fixed: boolean;
106
- }
107
-
108
- interface Player {
109
- playerNum: number;
110
- type: number; // 1=Human, 2=Computer, 3=Neutral, 4=Rescuable
111
- race: number; // 1=Human, 2=Orc, 3=Undead, 4=Night Elf
112
-
113
- name: string;
114
- startingPos: PlayerStartingPosition;
115
- }
116
-
117
- interface ForceFlags {
118
- allied: boolean; // 0x00000001: allied (force 1)
119
- alliedVictory: boolean; // 0x00000002: allied victory
120
- // 0x00000004: share vision (the documentation has this incorrect)
121
- shareVision: boolean; // 0x00000008: share vision
122
- shareUnitControl: boolean; // 0x00000010: share unit control
123
- shareAdvUnitControl: boolean; // 0x00000020: share advanced unit control
124
- }
125
-
126
- interface Force {
127
- flags: ForceFlags;
128
- players: number; // UNSUPPORTED: (bit "x"=1 --> player "x" is in this force)
129
- name: string;
130
- }
131
-
132
- enum ScriptLanguage {
133
- JASS = 0,
134
- Lua = 1
135
- }
136
-
137
- enum SupportedModes {
138
- SD = 1,
139
- HD = 2,
140
- Both = 3
141
- }
142
-
143
- export abstract class InfoTranslator {
144
-
145
- public static jsonToWar(infoJson: Info): WarResult {
146
- const outBufferToWar = new HexBuffer();
147
-
148
- outBufferToWar.addInt(31); // file version, 0x1F
149
- outBufferToWar.addInt(infoJson.saves || 0);
150
- outBufferToWar.addInt(infoJson.editorVersion || 0);
151
-
152
- outBufferToWar.addInt(infoJson.gameVersion.major);
153
- outBufferToWar.addInt(infoJson.gameVersion.minor);
154
- outBufferToWar.addInt(infoJson.gameVersion.patch);
155
- outBufferToWar.addInt(infoJson.gameVersion.build);
156
-
157
- // Map information
158
- outBufferToWar.addString(infoJson.map.name);
159
- outBufferToWar.addString(infoJson.map.author);
160
- outBufferToWar.addString(infoJson.map.description);
161
- outBufferToWar.addString(infoJson.map.recommendedPlayers);
162
-
163
- // Camera bounds (8 floats total)
164
- for (let cbIndex = 0; cbIndex < 8; cbIndex++) {
165
- outBufferToWar.addFloat(infoJson.camera.bounds[cbIndex]);
166
- }
167
-
168
- // Camera complements (4 floats total)
169
- for (let ccIndex = 0; ccIndex < 4; ccIndex++) {
170
- outBufferToWar.addInt(infoJson.camera.complements[ccIndex]);
171
- }
172
-
173
- // Playable area
174
- outBufferToWar.addInt(infoJson.map.playableArea.width);
175
- outBufferToWar.addInt(infoJson.map.playableArea.height);
176
-
177
- /*
178
- * Flags
179
- */
180
- let flags = 0;
181
- if (infoJson.map.flags) { // can leave out the entire flags object, all flags will default to false
182
- if (infoJson.map.flags.hideMinimapInPreview) flags |= 0x0001; // hide minimap in preview screens
183
- if (infoJson.map.flags.modifyAllyPriorities) flags |= 0x0002; // modify ally priorities
184
- if (infoJson.map.flags.isMeleeMap) flags |= 0x0004; // melee map
185
- // 0x0008 - unknown; // playable map size was large and never reduced to medium (?)
186
- if (infoJson.map.flags.maskedPartiallyVisible) flags |= 0x0010; // masked area are partially visible
187
- if (infoJson.map.flags.fixedPlayerSetting) flags |= 0x0020; // fixed player setting for custom forces
188
- if (infoJson.map.flags.useCustomForces) flags |= 0x0040; // use custom forces
189
- if (infoJson.map.flags.useCustomTechtree) flags |= 0x0080; // use custom techtree
190
- if (infoJson.map.flags.useCustomAbilities) flags |= 0x0100; // use custom abilities
191
- if (infoJson.map.flags.useCustomUpgrades) flags |= 0x0200; // use custom upgrades
192
- // 0x0400 - unknown; // map properties menu opened at least once since map creation (?)
193
- if (infoJson.map.flags.waterWavesOnCliffShores) flags |= 0x0800; // show water waves on cliff shores
194
- if (infoJson.map.flags.waterWavesOnRollingShores) flags |= 0x1000; // show water waves on rolling shores
195
- // 0x2000: 1=unknown
196
- // 0x4000: 1=unknown
197
- if (infoJson.map.flags.useItemClassificationSystem) flags |= 0x8000
198
- if (infoJson.map.flags.enableWaterTinting) flags |= 0x10000
199
- if (infoJson.map.flags.useAccurateProbabilityForCalculations) flags |= 0x20000
200
- if (infoJson.map.flags.useCustomAbilitySkins) flags |= 0x40000
201
- }
202
-
203
- // Unknown, but these seem to always be on, at least for default maps
204
- flags |= 0x8000;
205
- flags |= 0x4000;
206
- flags |= 0x0400;
207
-
208
- outBufferToWar.addInt(flags); // Add flags
209
-
210
- // Map main ground type
211
- outBufferToWar.addChar(infoJson.map.mainTileType);
212
-
213
- // Loading screen
214
- outBufferToWar.addInt(infoJson.loadingScreen.background);
215
- outBufferToWar.addString(infoJson.loadingScreen.path);
216
- outBufferToWar.addString(infoJson.loadingScreen.text);
217
- outBufferToWar.addString(infoJson.loadingScreen.title);
218
- outBufferToWar.addString(infoJson.loadingScreen.subtitle);
219
-
220
- // Use game data set (Unsupported)
221
- outBufferToWar.addInt(0);
222
-
223
- // Prologue
224
- outBufferToWar.addString(infoJson.prologue.path);
225
- outBufferToWar.addString(infoJson.prologue.text);
226
- outBufferToWar.addString(infoJson.prologue.title);
227
- outBufferToWar.addString(infoJson.prologue.subtitle);
228
-
229
- // Fog
230
- outBufferToWar.addInt(infoJson.fog.type);
231
- outBufferToWar.addFloat(infoJson.fog.startHeight);
232
- outBufferToWar.addFloat(infoJson.fog.endHeight);
233
- outBufferToWar.addFloat(infoJson.fog.density);
234
- outBufferToWar.addByte(infoJson.fog.color[0]);
235
- outBufferToWar.addByte(infoJson.fog.color[1]);
236
- outBufferToWar.addByte(infoJson.fog.color[2]);
237
- outBufferToWar.addByte(255); // Fog alpha - unsupported
238
-
239
- // Misc.
240
- // If globalWeather is not defined or is set to 'none', use 0 sentinel value, else add char[4]
241
- if (!infoJson.globalWeather || infoJson.globalWeather.toLowerCase() === 'none') {
242
- outBufferToWar.addInt(0);
243
- } else {
244
- outBufferToWar.addChars(infoJson.globalWeather); // char[4] - lookup table
245
- }
246
- outBufferToWar.addString(infoJson.customSoundEnvironment || '');
247
- outBufferToWar.addChar(infoJson.customLightEnv || 'L');
248
-
249
- // Custom water tinting
250
- outBufferToWar.addByte(infoJson.water[0]);
251
- outBufferToWar.addByte(infoJson.water[1]);
252
- outBufferToWar.addByte(infoJson.water[2]);
253
- outBufferToWar.addByte(255); // Water alpha - unsupported
254
-
255
- outBufferToWar.addInt(infoJson.scriptLanguage);
256
- outBufferToWar.addInt(infoJson.supportedModes);
257
- outBufferToWar.addInt(0); // unknown
258
-
259
- // Players
260
- outBufferToWar.addInt(infoJson.players.length);
261
- infoJson.players.forEach((player) => {
262
- outBufferToWar.addInt(player.playerNum);
263
- outBufferToWar.addInt(player.type);
264
- outBufferToWar.addInt(player.race);
265
- outBufferToWar.addInt(player.startingPos.fixed ? 1 : 0);
266
- outBufferToWar.addString(player.name);
267
- outBufferToWar.addFloat(player.startingPos.x);
268
- outBufferToWar.addFloat(player.startingPos.y);
269
- outBufferToWar.addInt(0); // ally low prio flags - unsupported
270
- outBufferToWar.addInt(0); // ally high prio flags - unsupported
271
- outBufferToWar.addInt(0); // enemy low prio flags - unsupported
272
- outBufferToWar.addInt(0); // enemy high prio flags - unsupported
273
- });
274
-
275
- // Forces
276
- outBufferToWar.addInt(infoJson.forces.length);
277
- infoJson.forces.forEach((force) => {
278
- // Calculate flags
279
- let forceFlags = 0;
280
- if (force.flags.allied) forceFlags |= 0x0001;
281
- if (force.flags.alliedVictory) forceFlags |= 0x0002;
282
- // Skip 0x0004
283
- if (force.flags.shareVision) forceFlags |= 0x0008;
284
- if (force.flags.shareUnitControl) forceFlags |= 0x0010;
285
- if (force.flags.shareAdvUnitControl) forceFlags |= 0x0020;
286
-
287
- outBufferToWar.addInt(forceFlags);
288
- outBufferToWar.addInt(force.players);
289
- outBufferToWar.addString(force.name);
290
- });
291
-
292
- // Upgrades - unsupported
293
- outBufferToWar.addInt(0);
294
-
295
- // Tech availability - unsupported
296
- outBufferToWar.addInt(0);
297
-
298
- // Unit table (random) - unsupported
299
- outBufferToWar.addInt(0);
300
-
301
- // Item table (random) - unsupported
302
- outBufferToWar.addInt(0);
303
-
304
- return {
305
- errors: [],
306
- buffer: outBufferToWar.getBuffer()
307
- };
308
- }
309
-
310
- public static warToJson(buffer: Buffer): JsonResult<Info> {
311
- const result: Info = {
312
- map: {
313
- name: '',
314
- author: '',
315
- description: '',
316
- recommendedPlayers: '',
317
- playableArea: {
318
- width: 64,
319
- height: 64
320
- },
321
- mainTileType: '',
322
- flags: {
323
- hideMinimapInPreview: false, // 0x0001: 1=hide minimap in preview screens
324
- modifyAllyPriorities: true, // 0x0002: 1=modify ally priorities
325
- isMeleeMap: false, // 0x0004: 1=melee map
326
- // 0x0008: 1=playable map size was large and has never been reduced to medium (?)
327
- maskedPartiallyVisible: false, // 0x0010: 1=masked area are partially visible
328
- fixedPlayerSetting: false, // 0x0020: 1=fixed player setting for custom forces
329
- useCustomForces: false, // 0x0040: 1=use custom forces
330
- useCustomTechtree: false, // 0x0080: 1=use custom techtree
331
- useCustomAbilities: false, // 0x0100: 1=use custom abilities
332
- useCustomUpgrades: false, // 0x0200: 1=use custom upgrades
333
- // 0x0400: 1=map properties menu opened at least once since map creation (?)
334
- waterWavesOnCliffShores: false, // 0x0800: 1=show water waves on cliff shores
335
- waterWavesOnRollingShores: false, // 0x1000: 1=show water waves on rolling shores
336
- useItemClassificationSystem: false, // 0x8000: 1=use item classification system
337
- enableWaterTinting: false, // 0x10000
338
- useAccurateProbabilityForCalculations: false, // 0x20000
339
- useCustomAbilitySkins: false // 0x40000
340
- }
341
- },
342
- loadingScreen: {
343
- background: 0,
344
- path: '',
345
- text: '',
346
- title: '',
347
- subtitle: ''
348
- }, prologue: {
349
- path: '',
350
- text: '',
351
- title: '',
352
- subtitle: ''
353
- }, fog: {
354
- type: FogType.Linear,
355
- startHeight: 0,
356
- endHeight: 0,
357
- density: 0,
358
- color: [0, 0, 0, 1]
359
- }, camera: {
360
- bounds: [],
361
- complements: []
362
- }, players: [
363
-
364
- ], forces: [
365
-
366
- ],
367
- saves: 0,
368
- editorVersion: 0,
369
- scriptLanguage: ScriptLanguage.JASS,
370
- supportedModes: SupportedModes.Both,
371
- gameVersion: {
372
- major: 0,
373
- minor: 0,
374
- patch: 0,
375
- build: 0
376
- },
377
- globalWeather: '',
378
- customSoundEnvironment: '',
379
- customLightEnv: '',
380
- water: []
381
- };
382
- const outBufferToJSON = new W3Buffer(buffer);
383
-
384
- const fileVersion = outBufferToJSON.readInt();
385
-
386
- result.saves = outBufferToJSON.readInt(),
387
- result.editorVersion = outBufferToJSON.readInt();
388
-
389
- result.gameVersion = {
390
- major: outBufferToJSON.readInt(),
391
- minor: outBufferToJSON.readInt(),
392
- patch: outBufferToJSON.readInt(),
393
- build: outBufferToJSON.readInt()
394
- };
395
-
396
- result.map.name = outBufferToJSON.readString();
397
- result.map.author = outBufferToJSON.readString();
398
- result.map.description = outBufferToJSON.readString();
399
- result.map.recommendedPlayers = outBufferToJSON.readString();
400
-
401
- result.camera.bounds = [
402
- outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(),
403
- outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat()
404
- ];
405
-
406
- result.camera.complements = [
407
- outBufferToJSON.readInt(), outBufferToJSON.readInt(), outBufferToJSON.readInt(), outBufferToJSON.readInt()
408
- ];
409
-
410
- result.map.playableArea = {
411
- width: outBufferToJSON.readInt(),
412
- height: outBufferToJSON.readInt()
413
- };
414
-
415
- const flags = outBufferToJSON.readInt();
416
- result.map.flags = {
417
- hideMinimapInPreview: !!(flags & 0x0001),
418
- modifyAllyPriorities: !!(flags & 0x0002),
419
- isMeleeMap: !!(flags & 0x0004),
420
- // skip 0x008
421
- maskedPartiallyVisible: !!(flags & 0x0010),
422
- fixedPlayerSetting: !!(flags & 0x0020),
423
- useCustomForces: !!(flags & 0x0040),
424
- useCustomTechtree: !!(flags & 0x0080),
425
- useCustomAbilities: !!(flags & 0x0100),
426
- useCustomUpgrades: !!(flags & 0x0200),
427
- waterWavesOnCliffShores: !!(flags & 0x0800),
428
- waterWavesOnRollingShores: !!(flags & 0x1000),
429
- // skip 0x2000
430
- // skip 0x4000
431
- useItemClassificationSystem: !!(flags & 0x8000),
432
- enableWaterTinting: !!(flags & 0x10000),
433
- useAccurateProbabilityForCalculations: !!(flags & 0x20000),
434
- useCustomAbilitySkins: !!(flags & 0x40000)
435
- };
436
-
437
- result.map.mainTileType = outBufferToJSON.readChars();
438
-
439
- result.loadingScreen.background = outBufferToJSON.readInt();
440
- result.loadingScreen.path = outBufferToJSON.readString();
441
- result.loadingScreen.text = outBufferToJSON.readString();
442
- result.loadingScreen.title = outBufferToJSON.readString();
443
- result.loadingScreen.subtitle = outBufferToJSON.readString();
444
-
445
- const gameDataSet = outBufferToJSON.readInt(); // 0 = standard
446
-
447
- result.prologue = {
448
- path: outBufferToJSON.readString(),
449
- text: outBufferToJSON.readString(),
450
- title: outBufferToJSON.readString(),
451
- subtitle: outBufferToJSON.readString()
452
- };
453
-
454
- result.fog = {
455
- type: outBufferToJSON.readInt(),
456
- startHeight: outBufferToJSON.readFloat(),
457
- endHeight: outBufferToJSON.readFloat(),
458
- density: outBufferToJSON.readFloat(),
459
- color: [outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte()] // R G B A
460
- };
461
-
462
- result.globalWeather = outBufferToJSON.readChars(4);
463
- result.customSoundEnvironment = outBufferToJSON.readString();
464
- result.customLightEnv = outBufferToJSON.readChars();
465
- result.water = [outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte()]; // R G B A
466
-
467
- result.scriptLanguage = outBufferToJSON.readInt();
468
- result.supportedModes = outBufferToJSON.readInt();
469
- outBufferToJSON.readInt(); // unknown
470
-
471
- // Struct: players
472
- const numPlayers = outBufferToJSON.readInt();
473
- for (let i = 0; i < numPlayers; i++) {
474
- const player: Player = {
475
- name: '',
476
- startingPos: { x: 0, y: 0, fixed: false },
477
- playerNum: 0,
478
- type: 0,
479
- race: 0
480
- };
481
-
482
- player.playerNum = outBufferToJSON.readInt();
483
- player.type = outBufferToJSON.readInt(); // 1=Human, 2=Computer, 3=Neutral, 4=Rescuable
484
- player.race = outBufferToJSON.readInt(); // 1=Human, 2=Orc, 3=Undead, 4=Night Elf
485
-
486
- const isPlayerStartPositionFixed: boolean = outBufferToJSON.readInt() === 1; // 00000001 = fixed start position
487
-
488
- player.name = outBufferToJSON.readString();
489
- player.startingPos = {
490
- x: outBufferToJSON.readFloat(),
491
- y: outBufferToJSON.readFloat(),
492
- fixed: isPlayerStartPositionFixed
493
- };
494
-
495
- outBufferToJSON.readInt(); // ally low priorities flags (bit "x"=1 --> set for player "x")
496
- outBufferToJSON.readInt(); // ally high priorities flags (bit "x"=1 --> set for player "x")
497
- outBufferToJSON.readInt(); // enemy low priorities flags
498
- outBufferToJSON.readInt(); // enemy high priorities flags
499
-
500
- result.players.push(player);
501
- }
502
-
503
- // Struct: forces
504
- const numForces = outBufferToJSON.readInt();
505
- for (let i = 0; i < numForces; i++) {
506
- const force: Force = {
507
- flags: { allied: false, alliedVictory: true, shareVision: true, shareUnitControl: false, shareAdvUnitControl: false },
508
- players: 0,
509
- name: ''
510
- };
511
-
512
- const forceFlag = outBufferToJSON.readInt();
513
- force.flags = {
514
- allied: !!(forceFlag & 0b1), // 0x00000001: allied (force 1)
515
- alliedVictory: !!(forceFlag & 0b10), // 0x00000002: allied victory
516
- // 0x00000004: share vision (the documentation has this incorrect)
517
- shareVision: !!(forceFlag & 0b1000), // 0x00000008: share vision
518
- shareUnitControl: !!(forceFlag & 0b10000), // 0x00000010: share unit control
519
- shareAdvUnitControl: !!(forceFlag & 0b100000) // 0x00000020: share advanced unit control
520
- };
521
- force.players = outBufferToJSON.readInt(); // UNSUPPORTED: (bit "x"=1 --> player "x" is in this force; but carried over for accurate translation
522
- force.name = outBufferToJSON.readString();
523
-
524
- result.forces.push(force);
525
- }
526
-
527
- // UNSUPPORTED: Struct: upgrade avail.
528
- const numUpgrades = outBufferToJSON.readInt();
529
- for (let i = 0; i < numUpgrades; i++) {
530
- outBufferToJSON.readInt(); // Player Flags (bit "x"=1 if this change applies for player "x")
531
- outBufferToJSON.readChars(4); // upgrade id (as in UpgradeData.slk)
532
- outBufferToJSON.readInt(); // Level of the upgrade for which the availability is changed (this is actually the level - 1, so 1 => 0)
533
- outBufferToJSON.readInt(); // Availability (0 = unavailable, 1 = available, 2 = researched)
534
- }
535
-
536
- // UNSUPPORTED: Struct: tech avail.
537
- const numTech = outBufferToJSON.readInt();
538
- for (let i = 0; i < numTech; i++) {
539
- outBufferToJSON.readInt(); // Player Flags (bit "x"=1 if this change applies for player "x")
540
- outBufferToJSON.readChars(4); // tech id (this can be an item, unit or ability)
541
- }
542
-
543
- // UNSUPPORTED: Struct: random unit table
544
- const numUnitTable = outBufferToJSON.readInt();
545
- for (let i = 0; i < numUnitTable; i++) {
546
- outBufferToJSON.readInt(); // Group number
547
- outBufferToJSON.readString(); // Group name
548
-
549
- const numPositions = outBufferToJSON.readInt(); // Number "m" of positions
550
- for (let j = 0; j < numPositions; j++) {
551
- outBufferToJSON.readInt(); // unit table (=0), a building table (=1) or an item table (=2)
552
-
553
- const numLinesInTable = outBufferToJSON.readInt();
554
- for (let k = 0; k < numLinesInTable; k++) {
555
- outBufferToJSON.readInt(); // Chance of the unit/item (percentage)
556
- outBufferToJSON.readChars(4); // unit/item id's for this line specified
557
- }
558
- }
559
- }
560
-
561
- // UNSUPPORTED: Struct: random item table
562
- const numItemTable = outBufferToJSON.readInt();
563
- for (let i = 0; i < numItemTable; i++) {
564
- outBufferToJSON.readInt(); // Table number
565
- outBufferToJSON.readString(); // Table name
566
-
567
- const itemSetsCurrentTable = outBufferToJSON.readInt(); // Number "m" of item sets on the current item table
568
- for (let j = 0; j < itemSetsCurrentTable; j++) {
569
-
570
- const itemsInItemSet = outBufferToJSON.readInt(); // Number "i" of items on the current item set
571
- for (let k = 0; k < itemsInItemSet; k++) {
572
- outBufferToJSON.readInt(); // Percentual chance
573
- outBufferToJSON.readChars(4); // Item id (as in ItemData.slk)
574
- }
575
-
576
- }
577
- }
578
-
579
- return {
580
- errors: [],
581
- json: result
582
- };
583
- }
584
- }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InfoTranslator = void 0;
4
+ const HexBuffer_1 = require("../HexBuffer");
5
+ const W3Buffer_1 = require("../W3Buffer");
6
+ var FogType;
7
+ (function (FogType) {
8
+ FogType[FogType["Linear"] = 0] = "Linear";
9
+ FogType[FogType["Exponential1"] = 1] = "Exponential1";
10
+ FogType[FogType["Exponential2"] = 2] = "Exponential2";
11
+ })(FogType || (FogType = {}));
12
+ var ScriptLanguage;
13
+ (function (ScriptLanguage) {
14
+ ScriptLanguage[ScriptLanguage["JASS"] = 0] = "JASS";
15
+ ScriptLanguage[ScriptLanguage["Lua"] = 1] = "Lua";
16
+ })(ScriptLanguage || (ScriptLanguage = {}));
17
+ var SupportedModes;
18
+ (function (SupportedModes) {
19
+ SupportedModes[SupportedModes["SD"] = 1] = "SD";
20
+ SupportedModes[SupportedModes["HD"] = 2] = "HD";
21
+ SupportedModes[SupportedModes["Both"] = 3] = "Both";
22
+ })(SupportedModes || (SupportedModes = {}));
23
+ class InfoTranslator {
24
+ static jsonToWar(infoJson) {
25
+ const outBufferToWar = new HexBuffer_1.HexBuffer();
26
+ outBufferToWar.addInt(31); // file version, 0x1F
27
+ outBufferToWar.addInt(infoJson.saves || 0);
28
+ outBufferToWar.addInt(infoJson.editorVersion || 0);
29
+ outBufferToWar.addInt(infoJson.gameVersion.major);
30
+ outBufferToWar.addInt(infoJson.gameVersion.minor);
31
+ outBufferToWar.addInt(infoJson.gameVersion.patch);
32
+ outBufferToWar.addInt(infoJson.gameVersion.build);
33
+ // Map information
34
+ outBufferToWar.addString(infoJson.map.name);
35
+ outBufferToWar.addString(infoJson.map.author);
36
+ outBufferToWar.addString(infoJson.map.description);
37
+ outBufferToWar.addString(infoJson.map.recommendedPlayers);
38
+ // Camera bounds (8 floats total)
39
+ for (let cbIndex = 0; cbIndex < 8; cbIndex++) {
40
+ outBufferToWar.addFloat(infoJson.camera.bounds[cbIndex]);
41
+ }
42
+ // Camera complements (4 floats total)
43
+ for (let ccIndex = 0; ccIndex < 4; ccIndex++) {
44
+ outBufferToWar.addInt(infoJson.camera.complements[ccIndex]);
45
+ }
46
+ // Playable area
47
+ outBufferToWar.addInt(infoJson.map.playableArea.width);
48
+ outBufferToWar.addInt(infoJson.map.playableArea.height);
49
+ /*
50
+ * Flags
51
+ */
52
+ let flags = 0;
53
+ if (infoJson.map.flags) { // can leave out the entire flags object, all flags will default to false
54
+ if (infoJson.map.flags.hideMinimapInPreview)
55
+ flags |= 0x0001; // hide minimap in preview screens
56
+ if (infoJson.map.flags.modifyAllyPriorities)
57
+ flags |= 0x0002; // modify ally priorities
58
+ if (infoJson.map.flags.isMeleeMap)
59
+ flags |= 0x0004; // melee map
60
+ // 0x0008 - unknown; // playable map size was large and never reduced to medium (?)
61
+ if (infoJson.map.flags.maskedPartiallyVisible)
62
+ flags |= 0x0010; // masked area are partially visible
63
+ if (infoJson.map.flags.fixedPlayerSetting)
64
+ flags |= 0x0020; // fixed player setting for custom forces
65
+ if (infoJson.map.flags.useCustomForces)
66
+ flags |= 0x0040; // use custom forces
67
+ if (infoJson.map.flags.useCustomTechtree)
68
+ flags |= 0x0080; // use custom techtree
69
+ if (infoJson.map.flags.useCustomAbilities)
70
+ flags |= 0x0100; // use custom abilities
71
+ if (infoJson.map.flags.useCustomUpgrades)
72
+ flags |= 0x0200; // use custom upgrades
73
+ // 0x0400 - unknown; // map properties menu opened at least once since map creation (?)
74
+ if (infoJson.map.flags.waterWavesOnCliffShores)
75
+ flags |= 0x0800; // show water waves on cliff shores
76
+ if (infoJson.map.flags.waterWavesOnRollingShores)
77
+ flags |= 0x1000; // show water waves on rolling shores
78
+ // 0x2000: 1=unknown
79
+ // 0x4000: 1=unknown
80
+ if (infoJson.map.flags.useItemClassificationSystem)
81
+ flags |= 0x8000;
82
+ if (infoJson.map.flags.enableWaterTinting)
83
+ flags |= 0x10000;
84
+ if (infoJson.map.flags.useAccurateProbabilityForCalculations)
85
+ flags |= 0x20000;
86
+ if (infoJson.map.flags.useCustomAbilitySkins)
87
+ flags |= 0x40000;
88
+ }
89
+ // Unknown, but these seem to always be on, at least for default maps
90
+ flags |= 0x8000;
91
+ flags |= 0x4000;
92
+ flags |= 0x0400;
93
+ outBufferToWar.addInt(flags); // Add flags
94
+ // Map main ground type
95
+ outBufferToWar.addChar(infoJson.map.mainTileType);
96
+ // Loading screen
97
+ outBufferToWar.addInt(infoJson.loadingScreen.background);
98
+ outBufferToWar.addString(infoJson.loadingScreen.path);
99
+ outBufferToWar.addString(infoJson.loadingScreen.text);
100
+ outBufferToWar.addString(infoJson.loadingScreen.title);
101
+ outBufferToWar.addString(infoJson.loadingScreen.subtitle);
102
+ // Use game data set (Unsupported)
103
+ outBufferToWar.addInt(0);
104
+ // Prologue
105
+ outBufferToWar.addString(infoJson.prologue.path);
106
+ outBufferToWar.addString(infoJson.prologue.text);
107
+ outBufferToWar.addString(infoJson.prologue.title);
108
+ outBufferToWar.addString(infoJson.prologue.subtitle);
109
+ // Fog
110
+ outBufferToWar.addInt(infoJson.fog.type);
111
+ outBufferToWar.addFloat(infoJson.fog.startHeight);
112
+ outBufferToWar.addFloat(infoJson.fog.endHeight);
113
+ outBufferToWar.addFloat(infoJson.fog.density);
114
+ outBufferToWar.addByte(infoJson.fog.color[0]);
115
+ outBufferToWar.addByte(infoJson.fog.color[1]);
116
+ outBufferToWar.addByte(infoJson.fog.color[2]);
117
+ outBufferToWar.addByte(255); // Fog alpha - unsupported
118
+ // Misc.
119
+ // If globalWeather is not defined or is set to 'none', use 0 sentinel value, else add char[4]
120
+ if (!infoJson.globalWeather || infoJson.globalWeather.toLowerCase() === 'none') {
121
+ outBufferToWar.addInt(0);
122
+ }
123
+ else {
124
+ outBufferToWar.addChars(infoJson.globalWeather); // char[4] - lookup table
125
+ }
126
+ outBufferToWar.addString(infoJson.customSoundEnvironment || '');
127
+ outBufferToWar.addChar(infoJson.customLightEnv || 'L');
128
+ // Custom water tinting
129
+ outBufferToWar.addByte(infoJson.water[0]);
130
+ outBufferToWar.addByte(infoJson.water[1]);
131
+ outBufferToWar.addByte(infoJson.water[2]);
132
+ outBufferToWar.addByte(255); // Water alpha - unsupported
133
+ outBufferToWar.addInt(infoJson.scriptLanguage);
134
+ outBufferToWar.addInt(infoJson.supportedModes);
135
+ outBufferToWar.addInt(0); // unknown
136
+ // Players
137
+ outBufferToWar.addInt(infoJson.players.length);
138
+ infoJson.players.forEach((player) => {
139
+ outBufferToWar.addInt(player.playerNum);
140
+ outBufferToWar.addInt(player.type);
141
+ outBufferToWar.addInt(player.race);
142
+ outBufferToWar.addInt(player.startingPos.fixed ? 1 : 0);
143
+ outBufferToWar.addString(player.name);
144
+ outBufferToWar.addFloat(player.startingPos.x);
145
+ outBufferToWar.addFloat(player.startingPos.y);
146
+ outBufferToWar.addInt(0); // ally low prio flags - unsupported
147
+ outBufferToWar.addInt(0); // ally high prio flags - unsupported
148
+ outBufferToWar.addInt(0); // enemy low prio flags - unsupported
149
+ outBufferToWar.addInt(0); // enemy high prio flags - unsupported
150
+ });
151
+ // Forces
152
+ outBufferToWar.addInt(infoJson.forces.length);
153
+ infoJson.forces.forEach((force) => {
154
+ // Calculate flags
155
+ let forceFlags = 0;
156
+ if (force.flags.allied)
157
+ forceFlags |= 0x0001;
158
+ if (force.flags.alliedVictory)
159
+ forceFlags |= 0x0002;
160
+ // Skip 0x0004
161
+ if (force.flags.shareVision)
162
+ forceFlags |= 0x0008;
163
+ if (force.flags.shareUnitControl)
164
+ forceFlags |= 0x0010;
165
+ if (force.flags.shareAdvUnitControl)
166
+ forceFlags |= 0x0020;
167
+ outBufferToWar.addInt(forceFlags);
168
+ outBufferToWar.addInt(force.players);
169
+ outBufferToWar.addString(force.name);
170
+ });
171
+ // Upgrades - unsupported
172
+ outBufferToWar.addInt(0);
173
+ // Tech availability - unsupported
174
+ outBufferToWar.addInt(0);
175
+ // Unit table (random) - unsupported
176
+ outBufferToWar.addInt(0);
177
+ // Item table (random) - unsupported
178
+ outBufferToWar.addInt(0);
179
+ return {
180
+ errors: [],
181
+ buffer: outBufferToWar.getBuffer()
182
+ };
183
+ }
184
+ static warToJson(buffer) {
185
+ const result = {
186
+ map: {
187
+ name: '',
188
+ author: '',
189
+ description: '',
190
+ recommendedPlayers: '',
191
+ playableArea: {
192
+ width: 64,
193
+ height: 64
194
+ },
195
+ mainTileType: '',
196
+ flags: {
197
+ hideMinimapInPreview: false,
198
+ modifyAllyPriorities: true,
199
+ isMeleeMap: false,
200
+ // 0x0008: 1=playable map size was large and has never been reduced to medium (?)
201
+ maskedPartiallyVisible: false,
202
+ fixedPlayerSetting: false,
203
+ useCustomForces: false,
204
+ useCustomTechtree: false,
205
+ useCustomAbilities: false,
206
+ useCustomUpgrades: false,
207
+ // 0x0400: 1=map properties menu opened at least once since map creation (?)
208
+ waterWavesOnCliffShores: false,
209
+ waterWavesOnRollingShores: false,
210
+ useItemClassificationSystem: false,
211
+ enableWaterTinting: false,
212
+ useAccurateProbabilityForCalculations: false,
213
+ useCustomAbilitySkins: false // 0x40000
214
+ }
215
+ },
216
+ loadingScreen: {
217
+ background: 0,
218
+ path: '',
219
+ text: '',
220
+ title: '',
221
+ subtitle: ''
222
+ }, prologue: {
223
+ path: '',
224
+ text: '',
225
+ title: '',
226
+ subtitle: ''
227
+ }, fog: {
228
+ type: FogType.Linear,
229
+ startHeight: 0,
230
+ endHeight: 0,
231
+ density: 0,
232
+ color: [0, 0, 0, 1]
233
+ }, camera: {
234
+ bounds: [],
235
+ complements: []
236
+ }, players: [], forces: [],
237
+ saves: 0,
238
+ editorVersion: 0,
239
+ scriptLanguage: ScriptLanguage.JASS,
240
+ supportedModes: SupportedModes.Both,
241
+ gameVersion: {
242
+ major: 0,
243
+ minor: 0,
244
+ patch: 0,
245
+ build: 0
246
+ },
247
+ globalWeather: '',
248
+ customSoundEnvironment: '',
249
+ customLightEnv: '',
250
+ water: []
251
+ };
252
+ const outBufferToJSON = new W3Buffer_1.W3Buffer(buffer);
253
+ const fileVersion = outBufferToJSON.readInt();
254
+ result.saves = outBufferToJSON.readInt(),
255
+ result.editorVersion = outBufferToJSON.readInt();
256
+ result.gameVersion = {
257
+ major: outBufferToJSON.readInt(),
258
+ minor: outBufferToJSON.readInt(),
259
+ patch: outBufferToJSON.readInt(),
260
+ build: outBufferToJSON.readInt()
261
+ };
262
+ result.map.name = outBufferToJSON.readString();
263
+ result.map.author = outBufferToJSON.readString();
264
+ result.map.description = outBufferToJSON.readString();
265
+ result.map.recommendedPlayers = outBufferToJSON.readString();
266
+ result.camera.bounds = [
267
+ outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(),
268
+ outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat(), outBufferToJSON.readFloat()
269
+ ];
270
+ result.camera.complements = [
271
+ outBufferToJSON.readInt(), outBufferToJSON.readInt(), outBufferToJSON.readInt(), outBufferToJSON.readInt()
272
+ ];
273
+ result.map.playableArea = {
274
+ width: outBufferToJSON.readInt(),
275
+ height: outBufferToJSON.readInt()
276
+ };
277
+ const flags = outBufferToJSON.readInt();
278
+ result.map.flags = {
279
+ hideMinimapInPreview: !!(flags & 0x0001),
280
+ modifyAllyPriorities: !!(flags & 0x0002),
281
+ isMeleeMap: !!(flags & 0x0004),
282
+ // skip 0x008
283
+ maskedPartiallyVisible: !!(flags & 0x0010),
284
+ fixedPlayerSetting: !!(flags & 0x0020),
285
+ useCustomForces: !!(flags & 0x0040),
286
+ useCustomTechtree: !!(flags & 0x0080),
287
+ useCustomAbilities: !!(flags & 0x0100),
288
+ useCustomUpgrades: !!(flags & 0x0200),
289
+ waterWavesOnCliffShores: !!(flags & 0x0800),
290
+ waterWavesOnRollingShores: !!(flags & 0x1000),
291
+ // skip 0x2000
292
+ // skip 0x4000
293
+ useItemClassificationSystem: !!(flags & 0x8000),
294
+ enableWaterTinting: !!(flags & 0x10000),
295
+ useAccurateProbabilityForCalculations: !!(flags & 0x20000),
296
+ useCustomAbilitySkins: !!(flags & 0x40000)
297
+ };
298
+ result.map.mainTileType = outBufferToJSON.readChars();
299
+ result.loadingScreen.background = outBufferToJSON.readInt();
300
+ result.loadingScreen.path = outBufferToJSON.readString();
301
+ result.loadingScreen.text = outBufferToJSON.readString();
302
+ result.loadingScreen.title = outBufferToJSON.readString();
303
+ result.loadingScreen.subtitle = outBufferToJSON.readString();
304
+ const gameDataSet = outBufferToJSON.readInt(); // 0 = standard
305
+ result.prologue = {
306
+ path: outBufferToJSON.readString(),
307
+ text: outBufferToJSON.readString(),
308
+ title: outBufferToJSON.readString(),
309
+ subtitle: outBufferToJSON.readString()
310
+ };
311
+ result.fog = {
312
+ type: outBufferToJSON.readInt(),
313
+ startHeight: outBufferToJSON.readFloat(),
314
+ endHeight: outBufferToJSON.readFloat(),
315
+ density: outBufferToJSON.readFloat(),
316
+ color: [outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte()] // R G B A
317
+ };
318
+ result.globalWeather = outBufferToJSON.readChars(4);
319
+ result.customSoundEnvironment = outBufferToJSON.readString();
320
+ result.customLightEnv = outBufferToJSON.readChars();
321
+ result.water = [outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte(), outBufferToJSON.readByte()]; // R G B A
322
+ result.scriptLanguage = outBufferToJSON.readInt();
323
+ result.supportedModes = outBufferToJSON.readInt();
324
+ outBufferToJSON.readInt(); // unknown
325
+ // Struct: players
326
+ const numPlayers = outBufferToJSON.readInt();
327
+ for (let i = 0; i < numPlayers; i++) {
328
+ const player = {
329
+ name: '',
330
+ startingPos: { x: 0, y: 0, fixed: false },
331
+ playerNum: 0,
332
+ type: 0,
333
+ race: 0
334
+ };
335
+ player.playerNum = outBufferToJSON.readInt();
336
+ player.type = outBufferToJSON.readInt(); // 1=Human, 2=Computer, 3=Neutral, 4=Rescuable
337
+ player.race = outBufferToJSON.readInt(); // 1=Human, 2=Orc, 3=Undead, 4=Night Elf
338
+ const isPlayerStartPositionFixed = outBufferToJSON.readInt() === 1; // 00000001 = fixed start position
339
+ player.name = outBufferToJSON.readString();
340
+ player.startingPos = {
341
+ x: outBufferToJSON.readFloat(),
342
+ y: outBufferToJSON.readFloat(),
343
+ fixed: isPlayerStartPositionFixed
344
+ };
345
+ outBufferToJSON.readInt(); // ally low priorities flags (bit "x"=1 --> set for player "x")
346
+ outBufferToJSON.readInt(); // ally high priorities flags (bit "x"=1 --> set for player "x")
347
+ outBufferToJSON.readInt(); // enemy low priorities flags
348
+ outBufferToJSON.readInt(); // enemy high priorities flags
349
+ result.players.push(player);
350
+ }
351
+ // Struct: forces
352
+ const numForces = outBufferToJSON.readInt();
353
+ for (let i = 0; i < numForces; i++) {
354
+ const force = {
355
+ flags: { allied: false, alliedVictory: true, shareVision: true, shareUnitControl: false, shareAdvUnitControl: false },
356
+ players: 0,
357
+ name: ''
358
+ };
359
+ const forceFlag = outBufferToJSON.readInt();
360
+ force.flags = {
361
+ allied: !!(forceFlag & 0b1),
362
+ alliedVictory: !!(forceFlag & 0b10),
363
+ // 0x00000004: share vision (the documentation has this incorrect)
364
+ shareVision: !!(forceFlag & 0b1000),
365
+ shareUnitControl: !!(forceFlag & 0b10000),
366
+ shareAdvUnitControl: !!(forceFlag & 0b100000) // 0x00000020: share advanced unit control
367
+ };
368
+ force.players = outBufferToJSON.readInt(); // UNSUPPORTED: (bit "x"=1 --> player "x" is in this force; but carried over for accurate translation
369
+ force.name = outBufferToJSON.readString();
370
+ result.forces.push(force);
371
+ }
372
+ // UNSUPPORTED: Struct: upgrade avail.
373
+ const numUpgrades = outBufferToJSON.readInt();
374
+ for (let i = 0; i < numUpgrades; i++) {
375
+ outBufferToJSON.readInt(); // Player Flags (bit "x"=1 if this change applies for player "x")
376
+ outBufferToJSON.readChars(4); // upgrade id (as in UpgradeData.slk)
377
+ outBufferToJSON.readInt(); // Level of the upgrade for which the availability is changed (this is actually the level - 1, so 1 => 0)
378
+ outBufferToJSON.readInt(); // Availability (0 = unavailable, 1 = available, 2 = researched)
379
+ }
380
+ // UNSUPPORTED: Struct: tech avail.
381
+ const numTech = outBufferToJSON.readInt();
382
+ for (let i = 0; i < numTech; i++) {
383
+ outBufferToJSON.readInt(); // Player Flags (bit "x"=1 if this change applies for player "x")
384
+ outBufferToJSON.readChars(4); // tech id (this can be an item, unit or ability)
385
+ }
386
+ // UNSUPPORTED: Struct: random unit table
387
+ const numUnitTable = outBufferToJSON.readInt();
388
+ for (let i = 0; i < numUnitTable; i++) {
389
+ outBufferToJSON.readInt(); // Group number
390
+ outBufferToJSON.readString(); // Group name
391
+ const numPositions = outBufferToJSON.readInt(); // Number "m" of positions
392
+ for (let j = 0; j < numPositions; j++) {
393
+ outBufferToJSON.readInt(); // unit table (=0), a building table (=1) or an item table (=2)
394
+ const numLinesInTable = outBufferToJSON.readInt();
395
+ for (let k = 0; k < numLinesInTable; k++) {
396
+ outBufferToJSON.readInt(); // Chance of the unit/item (percentage)
397
+ outBufferToJSON.readChars(4); // unit/item id's for this line specified
398
+ }
399
+ }
400
+ }
401
+ // UNSUPPORTED: Struct: random item table
402
+ const numItemTable = outBufferToJSON.readInt();
403
+ for (let i = 0; i < numItemTable; i++) {
404
+ outBufferToJSON.readInt(); // Table number
405
+ outBufferToJSON.readString(); // Table name
406
+ const itemSetsCurrentTable = outBufferToJSON.readInt(); // Number "m" of item sets on the current item table
407
+ for (let j = 0; j < itemSetsCurrentTable; j++) {
408
+ const itemsInItemSet = outBufferToJSON.readInt(); // Number "i" of items on the current item set
409
+ for (let k = 0; k < itemsInItemSet; k++) {
410
+ outBufferToJSON.readInt(); // Percentual chance
411
+ outBufferToJSON.readChars(4); // Item id (as in ItemData.slk)
412
+ }
413
+ }
414
+ }
415
+ return {
416
+ errors: [],
417
+ json: result
418
+ };
419
+ }
420
+ }
421
+ exports.InfoTranslator = InfoTranslator;
422
+ //# sourceMappingURL=InfoTranslator.js.map