Skip to content

Commit 4ca9472

Browse files
committed
1 parent 240407d commit 4ca9472

6 files changed

Lines changed: 181 additions & 84 deletions

File tree

build.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ project(":core") {
7676
api "org.apache.commons:commons-compress:1.20"
7777
api "net.nikr:dds:1.0.0"
7878
api files(fileTree(dir:'../jars', includes: ['*.jar']))
79+
80+
testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.2"
81+
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.2"
82+
}
83+
84+
test {
85+
useJUnitPlatform()
7986
}
8087
}
8188

core/build.gradle

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@
22

33
sourceCompatibility = 1.17
44

5-
sourceSets.main.java.srcDirs = [ "src/" ]
6-
5+
sourceSets {
6+
main {
7+
java.srcDirs = [ "src/" ]
8+
}
9+
test {
10+
java.srcDirs = [ "test/" ]
11+
resources.srcDirs = [ "test/resources" ]
12+
}
13+
}
714

815
eclipse.project {
916
name = appName + "-core"

core/src/com/etheller/warsmash/parsers/w3x/w3i/Player.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ public void load(final LittleEndianDataInputStream stream, final int version) th
3030
ParseUtils.readFloatArray(stream, this.startLocation);
3131
this.allyLowPriorities = ParseUtils.readUInt32(stream);
3232
this.allyHighPriorities = ParseUtils.readUInt32(stream);
33-
if (version > 30) {
33+
if (version >= 31) {
3434
this.enemyLowPrioritiesFlags = ParseUtils.readUInt32(stream);
3535
this.enemyHighPrioritiesFlags = ParseUtils.readUInt32(stream);
3636
}
3737
}
3838

39-
public void save(final LittleEndianDataOutputStream stream) throws IOException {
39+
public void save(final LittleEndianDataOutputStream stream, int version) throws IOException {
4040
ParseUtils.writeUInt32(stream, this.id);
4141
stream.writeInt(this.type);
4242
stream.writeInt(this.race);
@@ -45,10 +45,10 @@ public void save(final LittleEndianDataOutputStream stream) throws IOException {
4545
ParseUtils.writeFloatArray(stream, this.startLocation);
4646
ParseUtils.writeUInt32(stream, this.allyLowPriorities);
4747
ParseUtils.writeUInt32(stream, this.allyHighPriorities);
48-
}
49-
50-
public int getByteLength() {
51-
return 33 + this.name.length();
48+
if (version >= 31) {
49+
ParseUtils.writeUInt32(stream, this.enemyLowPrioritiesFlags);
50+
ParseUtils.writeUInt32(stream, this.enemyHighPrioritiesFlags);
51+
}
5252
}
5353

5454
public int getId() {

core/src/com/etheller/warsmash/parsers/w3x/w3i/War3MapW3i.java

Lines changed: 117 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
import java.util.List;
66

77
import com.etheller.warsmash.util.ParseUtils;
8+
import com.etheller.warsmash.util.War3ID;
89
import com.google.common.io.LittleEndianDataInputStream;
910
import com.google.common.io.LittleEndianDataOutputStream;
1011

1112
/**
1213
* war3map.w3i - the general map information file.
14+
* https://github.com/ChiefOfGxBxL/WC3MapSpecification/blob/master/Info/0-33.md
1315
*/
1416
public class War3MapW3i {
1517
private int version;
@@ -33,7 +35,7 @@ public class War3MapW3i {
3335
private String loadingScreenText;
3436
private String loadingScreenTitle;
3537
private String loadingScreenSubtitle;
36-
private int gameDataSet;
38+
private int gameDataSet = 0;
3739
private String prologueScreenModel;
3840
private String prologueScreenText;
3941
private String prologueScreenTitle;
@@ -42,13 +44,16 @@ public class War3MapW3i {
4244
private final float[] fogHeight = new float[2];
4345
private float fogDensity;
4446
private final short[] fogColor = new short[4];
45-
private int globalWeather;
47+
private War3ID globalWeather;
4648
private String soundEnvironment;
4749
private char lightEnvironmentTileset;
4850
private final short[] waterVertexColor = new short[4];
49-
private final short[] unknown2ProbablyLua = new short[4];
50-
private long supportedModes;
51-
private long gameDataVersion;
51+
private int scriptLanguage = 0; // 0 = JASS, 1 = Lua
52+
private long supportedModes; // 1=SD, 2=HD, 3=SD+HD
53+
private long gameDataVersion = 0; // 0=ROC, 1=TFT
54+
private int forceDefaultCameraZoom;
55+
private int forceMaxCameraZoom;
56+
private int forceMinCameraZoom;
5257
private final List<Player> players = new ArrayList<>();
5358
private final List<Force> forces = new ArrayList<>();
5459
private final List<UpgradeAvailabilityChange> upgradeAvailabilityChanges = new ArrayList<>();
@@ -83,45 +88,78 @@ private void load(final LittleEndianDataInputStream stream) throws IOException {
8388
ParseUtils.readInt32Array(stream, this.playableSize);
8489
this.flags = ParseUtils.readUInt32(stream);
8590
this.tileset = (char) stream.read();
86-
this.campaignBackground = stream.readInt();
8791

88-
if (this.version > 24) {
92+
if (this.version >= 17) {
93+
this.campaignBackground = stream.readInt();
94+
}
95+
96+
if (this.version >= 10 && this.version != 18 && this.version != 19) {
8997
this.loadingScreenModel = ParseUtils.readUntilNull(stream);
9098
}
9199

92-
this.loadingScreenText = ParseUtils.readUntilNull(stream);
93-
this.loadingScreenTitle = ParseUtils.readUntilNull(stream);
94-
this.loadingScreenSubtitle = ParseUtils.readUntilNull(stream);
95-
this.gameDataSet = stream.readInt();
100+
if (this.version >= 10) {
101+
this.loadingScreenText = ParseUtils.readUntilNull(stream);
102+
}
96103

97-
if (this.version > 24) {
104+
if (this.version >= 11) {
105+
this.loadingScreenTitle = ParseUtils.readUntilNull(stream);
106+
this.loadingScreenSubtitle = ParseUtils.readUntilNull(stream);
107+
}
108+
109+
if (this.version >= 17) {
110+
this.gameDataSet = stream.readInt();
111+
}
112+
113+
if (this.version >= 13 && this.version != 18 && this.version != 19) {
98114
this.prologueScreenModel = ParseUtils.readUntilNull(stream);
99115
}
100116

101-
this.prologueScreenText = ParseUtils.readUntilNull(stream);
102-
this.prologueScreenTitle = ParseUtils.readUntilNull(stream);
103-
this.prologueScreenSubtitle = ParseUtils.readUntilNull(stream);
117+
if (this.version >= 13) {
118+
this.prologueScreenText = ParseUtils.readUntilNull(stream);
119+
this.prologueScreenTitle = ParseUtils.readUntilNull(stream);
120+
this.prologueScreenSubtitle = ParseUtils.readUntilNull(stream);
121+
}
104122

105-
if (this.version > 24) {
123+
if (this.version >= 19) {
106124
this.useTerrainFog = stream.readInt();
107125
ParseUtils.readFloatArray(stream, this.fogHeight);
108126
this.fogDensity = stream.readFloat();
109127
ParseUtils.readUInt8Array(stream, this.fogColor);
110-
this.globalWeather = stream.readInt(); // TODO probably war3id, right?
128+
}
129+
130+
if (this.version >= 21) {
131+
this.globalWeather = ParseUtils.readWar3ID(stream);
132+
}
133+
134+
if (this.version >= 22) {
111135
this.soundEnvironment = ParseUtils.readUntilNull(stream);
136+
}
137+
138+
if (this.version >= 23) {
112139
this.lightEnvironmentTileset = (char) stream.read();
140+
}
141+
142+
if (this.version >= 25) {
113143
ParseUtils.readUInt8Array(stream, this.waterVertexColor);
114144
}
115145

116-
if (this.version > 27) {
117-
ParseUtils.readUInt8Array(stream, this.unknown2ProbablyLua);
146+
if (this.version >= 28) {
147+
this.scriptLanguage = stream.readInt();
118148
}
119-
if (this.version > 30) {
149+
if (this.version >= 29) {
120150
this.supportedModes = ParseUtils.readUInt32(stream);
151+
}
152+
if (this.version >= 30) {
121153
this.gameDataVersion = ParseUtils.readUInt32(stream);
122154
}
123-
else {
124-
this.gameDataVersion = -1; // indicate to the outside that this was unspecified
155+
156+
if (this.version >= 32) {
157+
this.forceDefaultCameraZoom = stream.readInt();
158+
this.forceMaxCameraZoom = stream.readInt();
159+
}
160+
161+
if (this.version >= 33) {
162+
this.forceMinCameraZoom = stream.readInt();
125163
}
126164

127165
for (int i = 0, l = stream.readInt(); i < l; i++) {
@@ -144,6 +182,7 @@ private void load(final LittleEndianDataInputStream stream) throws IOException {
144182
// some kind of really stupid protected map???
145183
return;
146184
}
185+
147186
if (stream.available() > 0) {
148187
for (int i = 0, l = stream.readInt(); i < l; i++) {
149188
final UpgradeAvailabilityChange upgradeAvailabilityChange = new UpgradeAvailabilityChange();
@@ -208,49 +247,86 @@ public void save(final LittleEndianDataOutputStream stream) throws IOException {
208247
ParseUtils.writeInt32Array(stream, this.playableSize);
209248
ParseUtils.writeUInt32(stream, this.flags);
210249
stream.write((byte) this.tileset);
211-
stream.writeInt(this.campaignBackground);
212250

213-
if (this.version > 24) {
251+
if (this.version >= 17) {
252+
stream.writeInt(this.campaignBackground);
253+
}
254+
255+
if (this.version >= 10 && this.version != 18 && this.version != 19) {
214256
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenModel);
215257
}
216258

217-
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenText);
218-
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenTitle);
219-
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenSubtitle);
220-
stream.writeInt(this.gameDataSet);
259+
if (this.version >= 10) {
260+
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenText);
261+
}
221262

222-
if (this.version > 24) {
263+
if (this.version >= 11) {
264+
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenTitle);
265+
ParseUtils.writeWithNullTerminator(stream, this.loadingScreenSubtitle);
266+
}
267+
268+
if (this.version >= 17) {
269+
stream.writeInt(this.gameDataSet);
270+
}
271+
272+
if (this.version >= 13 && this.version != 18 && this.version != 19) {
223273
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenModel);
224274
}
225275

226-
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenText);
227-
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenTitle);
228-
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenSubtitle);
276+
if (this.version >= 13) {
277+
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenText);
278+
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenTitle);
279+
ParseUtils.writeWithNullTerminator(stream, this.prologueScreenSubtitle);
280+
}
229281

230-
if (this.version > 24) {
282+
if (this.version >= 19) {
231283
stream.writeInt(this.useTerrainFog);
232284
ParseUtils.writeFloatArray(stream, this.fogHeight);
233285
stream.writeFloat(this.fogDensity);
234286
ParseUtils.writeUInt8Array(stream, this.fogColor);
235-
stream.writeInt(this.globalWeather); // TODO War3ID???
287+
}
288+
289+
if (this.version >= 21) {
290+
ParseUtils.writeWar3ID(stream, this.globalWeather);
291+
}
292+
293+
if (this.version >= 22) {
236294
ParseUtils.writeWithNullTerminator(stream, this.soundEnvironment);
295+
}
296+
297+
if (this.version >= 23) {
237298
stream.write((byte) this.lightEnvironmentTileset);
299+
}
300+
301+
if (this.version >= 25) {
238302
ParseUtils.writeUInt8Array(stream, this.waterVertexColor);
239303
}
240304

241-
if (this.version > 27) {
242-
ParseUtils.writeUInt8Array(stream, this.unknown2ProbablyLua);
305+
if (this.version >= 28) {
306+
ParseUtils.writeUInt32(stream, this.scriptLanguage);
243307
}
244308

245-
if (this.version > 30) {
309+
if (this.version >= 29) {
246310
ParseUtils.writeUInt32(stream, this.supportedModes);
311+
}
312+
313+
if (this.version >= 30) {
247314
ParseUtils.writeUInt32(stream, this.gameDataVersion);
248315
}
249316

317+
if (this.version >= 32) {
318+
ParseUtils.writeUInt32(stream, this.forceDefaultCameraZoom);
319+
ParseUtils.writeUInt32(stream, this.forceMaxCameraZoom);
320+
}
321+
322+
if (this.version >= 33) {
323+
ParseUtils.writeUInt32(stream, this.forceMinCameraZoom);
324+
}
325+
250326
ParseUtils.writeUInt32(stream, this.players.size());
251327

252328
for (final Player player : this.players) {
253-
player.save(stream);
329+
player.save(stream, this.version);
254330
}
255331

256332
ParseUtils.writeUInt32(stream, this.forces.size());
@@ -284,41 +360,6 @@ public void save(final LittleEndianDataOutputStream stream) throws IOException {
284360
table.save(stream);
285361
}
286362
}
287-
288-
}
289-
290-
public int getByteLength() {
291-
int size = 111 + this.name.length() + this.author.length() + this.description.length()
292-
+ this.recommendedPlayers.length() + this.loadingScreenText.length() + this.loadingScreenTitle.length()
293-
+ this.loadingScreenSubtitle.length() + this.prologueScreenText.length()
294-
+ this.prologueScreenTitle.length() + this.prologueScreenSubtitle.length();
295-
296-
for (final Player player : this.players) {
297-
size += player.getByteLength();
298-
}
299-
300-
for (final Force force : this.forces) {
301-
size += force.getByteLength();
302-
}
303-
304-
size += this.upgradeAvailabilityChanges.size() * 16;
305-
306-
size += this.techAvailabilityChanges.size() * 8;
307-
308-
for (final RandomUnitTable table : this.randomUnitTables) {
309-
size += table.getByteLength();
310-
}
311-
312-
if (this.version > 24) {
313-
size += 36 + this.loadingScreenModel.length() + this.prologueScreenModel.length()
314-
+ this.soundEnvironment.length();
315-
316-
for (final RandomItemTable table : this.randomItemTables) {
317-
size += table.getByteLength();
318-
}
319-
}
320-
321-
return size;
322363
}
323364

324365
public int getVersion() {
@@ -429,7 +470,7 @@ public short[] getFogColor() {
429470
return this.fogColor;
430471
}
431472

432-
public int getGlobalWeather() {
473+
public War3ID getGlobalWeather() {
433474
return this.globalWeather;
434475
}
435476

@@ -445,8 +486,8 @@ public short[] getWaterVertexColor() {
445486
return this.waterVertexColor;
446487
}
447488

448-
public short[] getUnknown2() {
449-
return this.unknown2ProbablyLua;
489+
public int getScriptLanguage() {
490+
return this.scriptLanguage;
450491
}
451492

452493
public long getSupportedModes() {

0 commit comments

Comments
 (0)