====== Stb .Lev ====== For Easier Editing Open **STATIC_MAP_COMMON_HEADER** Last Entry in .Stb Archive \\ \\ ===== Static Map Common Header ===== [4] Bytes - Number of Entries \\ \\ Then You Need to Search for Filename (Data\Levels\FinalAlbion\xxxxx.Lev) \\ Once Desired Name is found there is an offset jump following name. \\ \\ [4] Bytes - Offset Jump to File Data \\ [4] Bytes - Start Data (01 00 00 00) \\ [4] Bytes - Level ID \\ [4] Bytes - Unknown (Relative to Dimension of Map) \\ [4] Bytes - Map Dimension (X) \\ [4] Bytes - Map Dimesnion (Y) \\ [4] Bytes - Map World Offset (X) \\ [4] Bytes - Map World Offset (Y) \\ [4] Bytes - Null \\ [4] Bytes - Current File Offset Push \\ [4] Bytes - Current File Offset Push \\ \\ [4] Bytes - New Section Start (0A 00 00 00) \\ [4] Bytes - Always (04 00 00 00) \\ [4] Bytes - Repeat of Unknown Data Above (Relative to Dimension of Map) \\ [4] Bytes - Checksum (Same as one used in .Wad Lev file) \\ [4] Bytes - Unknown (Always B3 16 34 7C?) \\ [4] Bytes - Unknown (Always 00 00 32 00) \\ [4] Bytes - Map World Offset Starting Position (X) {Float} \\ [4] Bytes - Map World Offset Starting Position (Y) {Float} \\ [4] Bytes - Map World Offset Starting Position (Z) {Float} \\ [4] Bytes - Map World Offset Ending Position (X) {Float} \\ [4] Bytes - Map World Offset Ending Position (Y) {Float} \\ [4] Bytes - Map World Offset Ending Position (Z) {Float} \\ [4] Bytes - Current File Offset Push \\ [4] Bytes - Current File Offset Push \\ \\ [4] Bytes - New Section Start (01 00 00 00) (//**.Lev File Offsets**//) \\ [4] Bytes - Offset to First Table In Desired .Lev \\ [4] Bytes - Offset to Second Table In Desired .Lev \\ [4] Bytes - Second Table Size \\ [1] Byte - Indicator For Offset Push \\ [4] Bytes - Current File Offset Push \\ \\ [4] Bytes - Section Length In Bytes *(Does not Start until after Next 4 Bytes) \\ [4] Bytes - New Section Start (01 E3 E3 12) (//**Flora Placement?**//) \\ [4] Bytes - World Placement (X) {Float} \\ [4] Bytes - World Placement (Y) {Float} \\ [4] Bytes - Height Placement (Z) {Float} \\ [4] Bytes - Unknown Placement (Rotation?) {Float} \\ [4] Bytes - Unknown Placement {Float} \\ [4] Bytes - Sections for Flora Data (In Static Map Header) (If Present) \\ [4] Bytes - Offset to Third Section (If Present) in Current .Lev \\ [4] Bytes - Size of Third Section (If Present) in Current .Lev \\ [4] Bytes - Offset in Third Section table (Third Section Offset + these bytes) \\ [4] Bytes - Null \\ [2] Bytes - Map Dimension (X) \\ [2] Bytes - Map Dimension (Y) \\ \\ [1] Byte - Indicator for Internal Loop Within Last Segment \\ [4] Bytes - Number of Sections to loop * \\ \\ *If Zero Data Ends Here for Current Map. If there is Value follow the next segment \\ === Flora Loop === [4] Bytes - BIG ID #1 \\ [4] Bytes - BIG ID #2 \\ [4] Bytes - BIG ID #3 \\ [4] Bytes - Placement (X)? {Float} \\ [4] Bytes - Placement (Y)? {Float} \\ [4] Bytes - Unknown (Area?) (Int)\\ [4] Bytes - Null (Int) \\ [4] Bytes - Unknown (Rotation/Angle?) {Float} \\ [4] Bytes - Unknown (Rotation/Angle?) {Float} \\ [4] Bytes - Unknown (Rotation/Angle?) {Float} \\ [4] Bytes - Placement on Map (X) (Secondary?) {Float} \\ [4] Bytes - Placement on Map (Y) (Secondary?) {Float} \\ [4] Bytes - Number of Sections (Int) \\ [4] Bytes - Unknown (type?) (Int) \\ [1] Byte - Boolean? Unknown \\ [1] Byte - Boolean? Unknown \\ [1] Byte - Boolean? Unknown \\ [1] Byte - Boolean? Unknown \\ [4] Bytes - Unknown (Int) \\ ====== .Lev File Spec ====== ===== First Table (Height) ===== //Each Row is 36 Bytes long. Number of Rows is relative to ((X*Y) / 256) (dimensions of map divided by area of section always 16x16) // \\ \\ [4] Bytes - Offset \\ [4] Bytes - Compressed Size \\ [4] Bytes - World Map Starting Position (X) {Float} \\ [4] Bytes - World Map Starting Position (Y) {Float} \\ [4] Bytes - World Map Starting Position (Z) {Float} \\ [4] Bytes - World Map Ending Position (X) {Float} \\ [4] Bytes - World Map Ending Position (Y) {Float} \\ [4] Bytes - World Map Ending Position (Z) {Float} \\ [4] Bytes - Unknown \\ \\ *Each Compressed Package is LZO Compressed following this format: \\ [4] Bytes - Decompressed Size \\ [4] Bytes - Compressed Size \\ ==== Decompressed Data ==== [2] Bytes - Number of Sections \\ \\ //**Looped**// \\ [2] Bytes - Number of Verts \\ [2] Bytes - Number of Faces \\ [1] Byte - Null \\ [4] Bytes - Textures.Big ID of Image used. (This may be only for Proc Textures) These are the actual Mesh \\ [4] Bytes - Textures.Big ID of Image used. (This may be repeated from above) \\ [4] Bytes - Textures.Big ID of Bump used. \\ [4] Bytes - Possibly another texture link \\ [4] Bytes - Possibly another texture link \\ [4] Bytes - Possibly another texture link \\ [1] Byte - Null \\ === Vert Listing === //15 Byte rows// \\ \\ [2] Bytes - Global X Position \\ [2] Bytes - Global Y Position \\ [4] Bytes - Height {Float} \\ [4] Bytes - Packed Normal {PackedXYZ} \\ [1] Byte - 00 or FF (indicates next X or Y value?) \\ [1] Bytes - TU offset, Actual TU = (TU + (this-127)/127) \\ [1] Bytes - TU offset, Actual TU = (TU + (this-127)/127) \\ === Faces === // 2 Bytes // \\ [2] Bytes - Number of Faces \\ ===== Second Table (Unused Graphics?) ===== //Originally believed to be the mesh, could be used for internal editor only.// \\ [2] Bytes - Placement (X) \\ [2] Bytes - Placement (Y) \\ [2] Bytes - Tile Value (X) (Based on Dimension)* \\ [2] Bytes - Tile Value (Y) (Based on Dimension)* \\ \\ *If Value is size of Map then this is the lowest LOD \\ \\ [1] Byte - Indicator (01 - Indicates that it contains Offsets. Else it is only 47 Bytes in Length) \\ [1] Byte - Indicator (Section Start) \\ [1] Byte - Indicator (Section End) \\ [4] Bytes - Offset to Compressed Chunk \\ [4] Bytes - Size of Entire Table (If Value is present this indicates a start of a new LOD) \\ [4] Bytes - Offset Push Within Table (Next Section to Read, Table treated as internal file!) \\ [4] Bytes - World Map Start Position (X) {Float} \\ [4] Bytes - World Map Start Position (Y) {Float} \\ [4] Bytes - World Map Start Position (Z) {Float} \\ [4] Bytes - World Map Ending Position (X) {Float} \\ [4] Bytes - World Map Ending Position (Y) {Float} \\ [4] Bytes - World Map Ending Position (Z) {Float} \\ ==== Offset Rows ==== //If Indicator = 01 above then loop until starting indicator equals (stop indicator above)// \\ //13 Byte Rows// \\ [1] Byte - Indicator (Row start based on LOD) \\ [4] Bytes - Offset to compressed chunk \\ [4] Bytes - Compressed Chunk Size \\ [4] Bytes - Offset to specific compressed Data (Offset to compressed chunk + Value of These Bytes) \\ *Additional Notes Number of LODs seems dependent on First Table Rows. Example Creature Hub 4 Rows in first Table. Graphics It Contains (4 High Quality, 6 Medium, 1 Low) \\ \\ *Each Compressed Package is LZO Compressed following this format: \\ [4] Bytes - Decompressed Size \\ [4] Bytes - Compressed Size \\ === Decompressed Data === [2] Bytes - Image Dimension (X) it takes up on Map *\\ [2] Bytes - Image Dimension (Y it takes up on Map *\\ \\ *If Dimension equals map dimensions then it is the lowest LOD \\ \\ [2] Bytes - Tile Placement of Image (Based on Map Dimensions) (X) \\ [2] Bytes - Tile Placement of Image (Based on Map Dimensions) (Y) \\ [1] Byte - Null \\ [1] Byte - Indicator for LOD (not an actual value!) \\ [3] Bytes - Unkown Based on LOD \\ [1] Byte - Indicator new section start \\ [1] Byte - Image Dimensions (X) (Actual Image Size, for editing) \\ [1] Byte - Image Dimensions (Y) (Actual Image Size, for editing) \\ [1] Byte - Indicator new section start \\ [2] Bytes - Image Dimensions Repeat (X) as 2 bytes \\ [2] Bytes - Image Dimensions Repeat (Y) as 2 bytes \\ [1] Byte - Indicator new section start \\ [4] Bytes - Unknown \\ [6] Bytes - Null? \\ [4] Bytes - Always (01 00 00 00) Indicates Image Start \\ ~ DXT1 Image (To get Image size take __actual dimension__ ( X * Y / 2) \\ *The Rest of file is currently Unknown ===== Third Section (Flora/Model) ===== // The only offset to this section exists in Static Map Header **see: [4] Bytes - Offset in Third Section table (Third Section Offset + these bytes)** // \\ \\ *The following entries are very sloppy and jump around quite a bit. \\ \\ [4] Bytes - always zero? \\ [4] Bytes - if zero again it will need to read until it is at least reaches 1. \\ [4] Bytes - Global X coords [Float] \\ [4] Bytes - Global Y coords [Float] \\ [4] Bytes - Global Z coords [Float] \\ [4] Bytes - Unknown (Rotation?) [Float] \\ [4] Bytes - Unknown (Always 23?) [Float] \\ [4] Bytes - Unknown [Integer] \\ [4] Bytes - Offset to Chunk [Integer] \\ [4] Bytes - Chunk Size [Integer] \\ [4] Bytes - Offset in Chunk (take above Offset + This) [Integer] \\ [2] Bytes - Placement X? [Short] \\ [2] Bytes - Placement Y? [Short] \\ [2] Bytes - Size X? [Short] \\ [2] Bytes - Size Y? [Short] \\ [1] Byte - Indicates more entries. If zero reading is finished. \\ \\ //Here is the Tricky Part. If Offset above leads **directly** to anything other than zero you read below, else the entry is dead and the loop above is redone. // \\ \\ [4] Bytes - Number of Sections (Array) [Integer] \\ [4] Bytes - Chunk Offset [Integer] \\ [4] Bytes - Chunk Size [Integer] \\ [4] Bytes - Package Offset (Chunk Offset + Package Offset) (This will lead to compressed data) [Integer] \\ [4] Bytes - Global X coords [Float] \\ [4] Bytes - Global Y coords [Float] \\ [4] Bytes - Global Z coords [Float] \\ [4] Bytes - Unknown (Rotation?) [Float] \\ [4] Bytes - Unknown [Float] \\ [4] Bytes - Unknown [Integer] \\ [4] Bytes - Unknown [Integer] \\ ==== Compressed Package ==== [4] Bytes - Decompressed Size \\ [4] Bytes - Compressed Size \\ *Data is LZO compressed \\ === Decompressed Data ===