War3map.w3e
From Source Peek Wiki
Contents |
The Environment
This is the tileset file. It contains all the data about the tilesets of the map. Let's say the map is divided into squares called "tiles". Each tile has 4 corners. In 3D, we define surfaces using points and in this case tiles are defined by their corners. I call one tile corner a "tilepoint". So if you want a 256x256 map, you'll have 257x257 tilepoints. That's also why a tile texture is defined by each of its four tilepoints. A tile can be half dirt, one quarter grass and one quarter rock for example. The first tilepoint defined in the file stands for the lower left corner of the map when looking from the top, then it goes line by line (horizontal). Tilesets are the group of textures used for the ground.
Header Structure
| Type | Description |
|---|---|
| char[4] | file ID = "W3E!" |
| int | w3e format version [0B 00 00 00]h = version 11 |
| char | main tileset (See Warcraft 3 Tilesets) |
| int | custom tilesets flag (1 = using cutom, 0 = not using custom tilesets) |
| int | number a of ground tilesets used (Little Endian) (note: should not be greater than 16 because of tilesets indexing in tilepoints definition) |
| char[4][a] | ground tilesets IDs (tilesets table) Example: "Ldrt" stands for "Lordaeron Summer Dirt" |
| int | number b of cliff tilesets used (Little Endian) (note: should not be greater than 16 because of tilesets indexing in tilepoints definition) |
| char[4][b] | cliff tilesets IDs (cliff tilesets table) Example: "CLdi" stands for Lordaeron Cliff Dirt |
| int | width of the map + 1 = Mx |
| int | height of the map + 1 = My Example: if your map is 160x128, Mx=A1h and My=81h |
| float | center offeset of the map X |
| float | center offeset of the map Y These 2 offsets are used in the scripts files, doodads and more. -1*(Mx-1)*128/2 and -1*(My-1)*128/2 where: (Mx-1) and (My-1) are the width and the height of the map 128 is supposed to be the size of tile on the map /2 because we don't want the length but the middle. -1* because we're "translating" the center of the map, not giving it's new coordinates |
Each tilepoint is defined by a block of 7 bytes. The number of blocks is equal to Mx*My.
| Type | Description |
|---|---|
| short | ground height |
| C000h | minimum height (-16384) |
| 2000h | normal height (ground level 0) |
| 3FFFh | maximum height (+16383) |
| short | water level + map edge boundary flag*(see notes) |
| 4bit | flags*(see notes) |
| 4bit | ground texture type (grass, dirt, rocks,...) |
| 1byte | texture details (of the tile of which the tilepoint is the bottom left corner) (rocks, holes, bones,...). It appears that only a part of this byte is used for details. It needs more investigations |
| 4bit | cliff texture type |
| 4bit | layer height |
Flags
Flags values (shown as big endian):
- 0x4000 --> boundary flag 1 (shadow generated by the world editor on the edge of the map)
- 0x0010 --> ramp flag (used to set a ramp between two layers)
- 0x0020 --> blight flag (ground will look like Undead's ground)
- 0x0040 --> water flag (enable water)
- 0x0080 --> boundary flag 2 (used on "camera bounds" area. Usually set by the World Editor "boundary" tool.)
Water level
Water level is stored just like ground height. The highest bit (bit 15) is used for the boundary flag 1.
Tilepoint data example:
51 21 00 62 56 84 13 51 21 --(little endian)--> 0x2151 --(hex-->dec)--> height = 8529 00 62 --(little endian)--> 0x6200 (extract boundary flag)--> (0x6200 & 0xC000) = 0x4000 boundary flag set (extract water data)--> (0x6200 & 0x3FFF) = 0x2200 --(hex-->dec)--> water level = 8704 56 --> 5 sets both water flag and ramp flag, 6 means tilepoint is using ground type #6 in the tilesets table 84 --> means tilepoint is using detail texture #132 (=0x084) 13 --> 1 means cliff type #1 (cliff tilesets table), 3 means tilepoint on layer "3"
The tilepoint "final height" you see on the WE is given by:
(ground_height - 0x2000 + (layer - 2)*0x0200)/4 where "0x2000" is the "ground zero" level, 2 the "layer zero" level and "0x0200" the layer height = (0x2151 - 0x2000 + 1*0x0200)/4 = (8529 - 8192 + 512)/4 = 212,25
The tilepoint "water level" you see on the WE is given by:
(water_level - 0x2000)/4 - 89.6 where "0x2000" is the "ground zero" level, -89.6 is the water zero level (given by the water.slk file height = -0,7 --> water_zero_level = -0,7*128): = 8704/4 - 89,6 = 38,4
In this case, water flag is set and water level is below the ground level so we will not see the water. This is just an example and I don't think you can find such a tilepoint on a map. It was just here for demonstration purpose.
