Line 6: |
Line 6: |
| A .gbx file more specifically stores the serialization of one or more class instances. There is one main instance, and optionally a number of auxiliary instances. | | A .gbx file more specifically stores the serialization of one or more class instances. There is one main instance, and optionally a number of auxiliary instances. |
| | | |
− | The serializable classes are organized into 16 ''engines''. Each class is also subdivided into ''chunks''. A class is then not serialized in one go, but rather as a series of chunks. This allows Nadeo to easily extend classes in new TrackMania versions: instead of having to define a new class they can simply add more chunks to an existing one, and have older versions ignore these new chunk types. | + | The serializable classes are organized into ''engines''. Each class is also subdivided into ''chunks''. A class is then not serialized in one go, but rather as a series of chunks. This allows Nadeo to easily extend classes in new TrackMania versions: instead of having to define a new class they can simply add more chunks to an existing one, and have older versions ignore these new chunk types. |
| | | |
| The data in a .gbx file follows the pattern {{c|<chunk ID> <chunk data>}}. A ''chunk ID'' is a 32-bit number that identifies the engine, the class, and the chunk in that class. If you for example see the bytes <code>07 30 04 03</code> in the file, that would correspond to the integer 0x03043007, and be interpreted as follows: | | The data in a .gbx file follows the pattern {{c|<chunk ID> <chunk data>}}. A ''chunk ID'' is a 32-bit number that identifies the engine, the class, and the chunk in that class. If you for example see the bytes <code>07 30 04 03</code> in the file, that would correspond to the integer 0x03043007, and be interpreted as follows: |
Line 71: |
Line 71: |
| The file body contains further chunks of the main class instance, and may also contain auxiliary class instances. Reading the body is started by creating an in-memory instance of the class corresponding to the main class ID (instances are called ''nodes'' internally), and calling ReadNode on it: | | The file body contains further chunks of the main class instance, and may also contain auxiliary class instances. Reading the body is started by creating an in-memory instance of the class corresponding to the main class ID (instances are called ''nodes'' internally), and calling ReadNode on it: |
| | | |
− | ReadNode() | + | ReadNode()<ref>[[ManiaPlanet_internals#Object_system|CMwNod::Archive]]</ref> |
| { | | { |
| while (true) | | while (true) |
| { | | { |
− | chunkID = ReadUInt32(); | + | chunkID = ReadUInt32();<ref>[[ManiaPlanet_internals#CClassicArchive|CClassicArchive::ReadNat32]]</ref> |
| if (chunkID == 0xFACADE01) // no more chunks | | if (chunkID == 0xFACADE01) // no more chunks |
| { | | { |
− | OnNodLoaded(); | + | OnNodLoaded();<ref>[[ManiaPlanet_internals#Object_system|CMwNod::OnNodLoaded]]</ref> |
| return; | | return; |
| } | | } |
| | | |
− | chunkFlags = GetChunkInfo(chunkID); | + | chunkFlags = GetChunkInfo(chunkID);<ref>[[ManiaPlanet_internals#Object_system|CMwNod::GetChunkInfo]]</ref> |
| | | |
| if (chunkFlags == 0xFACADE01 || (chunkFlags & 0x11) == 0x10) | | if (chunkFlags == 0xFACADE01 || (chunkFlags & 0x11) == 0x10) |
Line 94: |
Line 94: |
| | | |
| chunkDataSize = ReadUInt32(); | | chunkDataSize = ReadUInt32(); |
− | SkipData(chunkDataSize); // skip unknown or obsolete chunk | + | SkipData(chunkDataSize);<ref>[[ManiaPlanet_internals#CClassicArchive|CClassicArchive::SkipData]]</ref> // skip unknown or obsolete chunk |
| } | | } |
| | | |
Line 105: |
Line 105: |
| } | | } |
| | | |
− | ReadChunk(chunkID); // read the chunk | + | ReadChunk(chunkID);<ref>[[ManiaPlanet_internals#Object_system|CMwNod::Chunk]]</ref> // read the chunk |
| } | | } |
| } | | } |
Line 123: |
Line 123: |
| * '''byte''', '''uint16''', '''int32''', '''uint32''', '''uint64''', '''uint128''', '''float''': regular little-endian encoding. | | * '''byte''', '''uint16''', '''int32''', '''uint32''', '''uint64''', '''uint128''', '''float''': regular little-endian encoding. |
| | | |
− | * '''vec2D''': | + | * '''vec2''': |
| ** float x | | ** float x |
| ** float y | | ** float y |
| | | |
− | * '''vec3D''': | + | * '''vec3''': |
| ** float x | | ** float x |
| ** float y | | ** float y |
Line 137: |
Line 137: |
| ** float b | | ** float b |
| | | |
− | * '''string''': | + | * '''string''':<ref>[[ManiaPlanet_internals#CClassicArchive|CClassicArchive::DoString]]</ref> |
| ** uint32 length | | ** uint32 length |
| ** byte chars[length] ({{wp|UTF-8}}, older files sometimes with {{wp|Byte order mark|BOM}}, not zero-terminated) | | ** byte chars[length] ({{wp|UTF-8}}, older files sometimes with {{wp|Byte order mark|BOM}}, not zero-terminated) |
| | | |
− | * '''lookbackstring''': a form of compression which allows to avoid repeating the same string multiple times. Every time a new string is encountered, it is added to a string list, and from then on this list entry is referenced instead of repeating the string another time. | + | * '''lookbackstring''':<ref>[[ManiaPlanet_internals#Id|CMwId::Archive]]</ref> a form of compression which allows to avoid repeating the same string multiple times. Every time a new string is encountered, it is added to a string list, and from then on this list entry is referenced instead of repeating the string another time. |
| ** if this is the first lookback string encountered: | | ** if this is the first lookback string encountered: |
| *** uint32 version (currently 3) | | *** uint32 version (currently 3) |
Line 152: |
Line 152: |
| ''Note'': Virtual Skipper 2 uses version 2 of the lookback strings. In this version, the string is always stored, the index always contains the position within the global name table, and the field with the version is also always present. | | ''Note'': Virtual Skipper 2 uses version 2 of the lookback strings. In this version, the string is always stored, the index always contains the position within the global name table, and the field with the version is also always present. |
| | | |
− | * '''fileref''': path to an external file, e.g. a skin. | + | * '''meta''':<ref>[[ManiaPlanet_internals#Identifier|SGameCtnIdentifier::Archive]]</ref> contains [[ManiaPlanet_internals#Identifier|meta]] information like the track environment, time of day, and author. |
| + | ** lookbackstring id |
| + | ** lookbackstring collection |
| + | ** lookbackstring author |
| + | |
| + | * '''fileref''':<ref>CSystemPackManager::ArchivePackDesc</ref> path to an external file, e.g. a skin. |
| ** byte version (currently 3) | | ** byte version (currently 3) |
| ** if version >= 3: | | ** if version >= 3: |
Line 160: |
Line 165: |
| *** string locatorUrl | | *** string locatorUrl |
| | | |
− | * '''meta''': contains [[ManiaPlanet_internals#Identifier|meta]] information like the track environment, time of day, and author. | + | * '''noderef''':<ref>[[ManiaPlanet_internals#CSystemArchiveNod|CSystemArchiveNod::DoNodPtr]]</ref> a reference to an auxiliary class instance. |
− | ** lookbackstring field1
| |
− | ** lookbackstring field2
| |
− | ** lookbackstring author
| |
− | | |
− | * '''noderef''': a reference to an auxiliary class instance.
| |
| ** uint32 index. if this is -1, the node reference is empty (null). | | ** uint32 index. if this is -1, the node reference is empty (null). |
| ** if the index is >= 0 and the node at the index has not been read yet: | | ** if the index is >= 0 and the node at the index has not been read yet: |
Line 217: |
Line 217: |
| 5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo) | | 5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo) |
| if version >= 1: | | if version >= 1: |
− | bool locked (used by Virtual Skipper to lock the map parameter) | + | bool locked (used by Virtual Skipper to lock the map parameters) |
| string password (weak xor encryption, no longer used in newer track files; see 03043029) | | string password (weak xor encryption, no longer used in newer track files; see 03043029) |
| if version >= 2: | | if version >= 2: |
| meta decoration (timeOfDay, environment, envirAuthor) (decoration envir can be different than collection envir) | | meta decoration (timeOfDay, environment, envirAuthor) (decoration envir can be different than collection envir) |
| if version >= 3: | | if version >= 3: |
− | vec2D mapOrigin | + | vec2 mapOrigin |
| if version >= 4: | | if version >= 4: |
− | vec2D mapTarget | + | vec2 mapTarget |
| if version >= 5: | | if version >= 5: |
| uint128 | | uint128 |
Line 275: |
Line 275: |
| 5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo) | | 5: (old)Rounds, 6: InProgress, 7: Campaign, 8: Multi, 9: Solo, 10: Site, 11: SoloNadeo, 12: MultiNadeo) |
| | | |
| + | '''03043012''' |
| + | string |
| + | |
| + | '''03043013''' |
| + | ReadChunk(0x0304301F) |
| + | |
| '''03043014''' (skippable) | | '''03043014''' (skippable) |
| uint32 | | uint32 |
Line 305: |
Line 311: |
| uint32 sizeY | | uint32 sizeY |
| uint32 sizeZ | | uint32 sizeZ |
− | uint32 needUnlock | + | bool needUnlock |
− | uint32 flagsAre32Bit | + | if chunkId != 03043013: |
| + | uint32 version |
| | | |
| uint32 numBlocks | | uint32 numBlocks |
Line 315: |
Line 322: |
| byte y | | byte y |
| byte z | | byte z |
− | uint16/uint32 flags | + | if version == 0: |
| + | uint16 flags |
| + | if version > 0: |
| + | uint32 flags |
| if (flags == 0xFFFFFFFF) | | if (flags == 0xFFFFFFFF) |
| continue (read the next block) | | continue (read the next block) |
Line 323: |
Line 333: |
| if (flags & 0x100000) | | if (flags & 0x100000) |
| noderef blockparameters | | noderef blockparameters |
| + | |
| ''Note:'' blocks with flags 0xFFFFFFFF should be skipped, they aren't counted in the numBlocks. | | ''Note:'' blocks with flags 0xFFFFFFFF should be skipped, they aren't counted in the numBlocks. |
| | | |
Line 339: |
Line 350: |
| | | |
| '''03043025''' | | '''03043025''' |
− | vec2D mapCoordOrigin | + | vec2 mapCoordOrigin |
− | vec2D mapCoordTarget | + | vec2 mapCoordTarget |
| | | |
| '''03043026''' | | '''03043026''' |
Line 349: |
Line 360: |
| if archiveGmCamVal: | | if archiveGmCamVal: |
| byte | | byte |
− | GmMat3 (vec3D x 3) | + | GmMat3 (vec3 x 3) |
− | vec3D | + | vec3 |
| float | | float |
| float | | float |
Line 370: |
Line 381: |
| uint32 version | | uint32 version |
| if version >= 5: | | if version >= 5: |
− | uint32 frames | + | uint32 frames // If version < 5 then frames = 1 |
| if version >= 2: | | if version >= 2: |
− | if version < 5: | + | for each frame: |
− | if version >= 4:
| |
− | uint32 size
| |
− | byte riff[size] // Avg lightmap webp file
| |
| uint32 size | | uint32 size |
− | byte jfif[size] // Intens/Avg lightmap jpeg file | + | byte image[size] // Image is JPEG/JFIF or WEBP/RIFF file format |
− | if version == 3: | + | if version >= 3: |
− | uint32 size
| |
− | byte jfif[size] // Intens lightmap jpeg file
| |
− | if version >= 5:
| |
− | for each frame:
| |
| uint32 size | | uint32 size |
− | byte riff[size] // Avg lightmap webp file | + | byte image[size] |
| + | if version >= 6: |
| uint32 size | | uint32 size |
− | byte jfif[size] // Intens lightmap jpeg file | + | byte image[size] |
| if size != 0: | | if size != 0: |
| uint32 uncompressedSize | | uint32 uncompressedSize |
| uint32 compressedSize | | uint32 compressedSize |
− | byte data[compressedSize] // Lightmap cache zip file | + | byte compressedData[compressedSize] // ZLIB compressed lightmap cache node |
| + | |
| + | '''03043040''' (skippable) ''"items"'' |
| + | |
| + | ''Note:'' This chunk resets the lookback string state. |
| + | |
| + | uint32 version |
| + | if version != 0: |
| + | uint32 |
| + | uint32 size |
| + | uint32 (10) |
| + | uint32 numItems |
| + | for each item: |
| + | noderef item (CGameCtnAnchoredObject) |
| + | uint32 |
| | | |
| '''03043044''' (skippable) | | '''03043044''' (skippable) |
| uint32 unknown (0) | | uint32 unknown (0) |
| uint32 size | | uint32 size |
− | uint32 flags | + | uint32 classID |
− | uint32 unknown (1, 2) | + | uint32 version |
− | uint32 count (number of metadata records)
| + | if version >= 2: |
− | for each count:
| + | uint32 count (number of metadata records) |
− | string varName
| + | for each count: |
− | uint32 varType
| + | string varName |
− | switch varType:
| + | uint32 varType |
− | case EType_Boolean:
| + | switch varType: |
− | bool
| + | case EType_Boolean: |
− | case EType_Integer:
| + | bool |
− | int32
| + | case EType_Integer: |
− | case EType_Real:
| + | int32 |
− | float
| + | case EType_Real: |
− | case EType_Text:
| + | float |
− | string
| + | case EType_Text: |
− | case EType_Int2:
| + | string |
− | int32
| + | case EType_Int2: |
− | int32
| + | int32 |
− | case EType_Int3:
| + | int32 |
− | int32
| + | case EType_Int3: |
− | int32
| + | int32 |
− | int32
| + | int32 |
− | case EType_Vec2:
| + | int32 |
− | float
| + | case EType_Vec2: |
− | float
| + | float |
− | case EType_Vec3:
| + | float |
− | float
| + | case EType_Vec3: |
− | float
| + | float |
− | float
| + | float |
− | case EType_Array:
| + | float |
− | uint32 typeKey
| + | case EType_Array: |
− | uint32 typeValue
| + | uint32 typeKey |
− | uint32 arrayElements
| + | uint32 typeValue |
− | for each arrayElements
| + | uint32 arrayElements |
− | switch typeKey:
| + | for each arrayElements |
− | case EType_Boolean:
| + | switch typeKey: |
− | bool
| + | case EType_Boolean: |
− | case EType_Integer:
| + | bool |
− | int32
| + | case EType_Integer: |
− | case EType_Real:
| + | int32 |
− | float
| + | case EType_Real: |
− | case EType_Text:
| + | float |
− | string
| + | case EType_Text: |
− | switch typeValue:
| + | string |
− | case EType_Boolean:
| + | switch typeValue: |
− | bool
| + | case EType_Boolean: |
− | case EType_Integer:
| + | bool |
− | int32
| + | case EType_Integer: |
− | case EType_Real:
| + | int32 |
− | float
| + | case EType_Real: |
− | case EType_Text:
| + | float |
− | string
| + | case EType_Text: |
− | case EType_Int2:
| + | string |
− | int32
| + | case EType_Int2: |
− | int32
| + | int32 |
− | case EType_Int3:
| + | int32 |
− | int32
| + | case EType_Int3: |
− | int32
| + | int32 |
− | int32
| + | int32 |
− | case EType_Vec2:
| + | int32 |
− | float
| + | case EType_Vec2: |
− | float
| + | float |
− | case EType_Vec3:
| + | float |
− | float
| + | case EType_Vec3: |
− | float
| + | float |
− | float
| + | float |
− | case EType_Array:
| + | float |
− | recursively read multidimensional arrays
| + | case EType_Array: |
| + | recursively read multidimensional arrays |
| | | |
− | <div class="mw-collapsible mw-collapsed">
| |
| The variable type is to be interpreted as follows: | | The variable type is to be interpreted as follows: |
− | <div class="mw-collapsible-content">
| |
| enum eScriptType | | enum eScriptType |
| { | | { |
Line 483: |
Line 501: |
| EType_Iso4, | | EType_Iso4, |
| EType_Ident, | | EType_Ident, |
− | EType_Int2 | + | EType_Int2, |
| + | EType_Struct |
| }; | | }; |
− | </div> | + | Maniaplanet 4.1 has changed the way script types and values are written. The code now does the following: |
− | </div>
| + | |
| + | * First write the list of all types (all types appear only once). |
| + | * For each value, write the index of the type in the list, and then write the value. |
| + | |
| + | Writing the types and values has not changed except for the addition of structures which are a plain list of members. |
| + | |
| + | Also note that the indices are written in the following form: |
| + | |
| + | * If the index is < 128, it is written directly into one byte (because this covers 99% of the cases). |
| + | * Otherwise, it is written in the first 7 bits of the first byte and in the following 2 bytes, a total of 23 bits (7+8+8). The 8th bit of the first byte is set to 1. |
| + | |
| + | Note that this scheme is also used to write string lengths. |
| | | |
| '''03043054''' (skippable) | | '''03043054''' (skippable) |
Line 492: |
Line 522: |
| uint32 | | uint32 |
| uint32 chunkSize | | uint32 chunkSize |
− | uint32 itemsCount (number of embedded items) | + | uint32 itemCount (number of embedded items) |
| + | meta items[itemCount] |
| uint32 zipSize (embedded items ZIP file size) | | uint32 zipSize (embedded items ZIP file size) |
| byte zipFile[zipSize] | | byte zipFile[zipSize] |
| + | uint32 textureCount |
| + | string textures[textureCount] |
| | | |
| '''21080001''' ''"VskDesc"'' | | '''21080001''' ''"VskDesc"'' |
Line 557: |
Line 590: |
| SCollectorStock archive[archiveCount] | | SCollectorStock archive[archiveCount] |
| meta (blockName, collection, author) | | meta (blockName, collection, author) |
− | uint32 | + | uint32 numPieces |
| | | |
| ===CGameCtnChallengeParameters (03 05B 000)=== | | ===CGameCtnChallengeParameters (03 05B 000)=== |
Line 646: |
Line 679: |
| | | |
| '''0305B00D''' | | '''0305B00D''' |
− | uint32 (-1?) | + | noderef raceValidateGhost (CGameCtnGhost) (usually -1) |
| | | |
− | '''0305B00E''' | + | '''0305B00E''' (skippable) |
− | (skippable) | + | string mapType |
− | uint32 | + | string mapStyle |
− | uint32 | |
| uint32 | | uint32 |
| | | |
Line 668: |
Line 700: |
| fileref packDesc | | fileref packDesc |
| fileref parentPackDesc | | fileref parentPackDesc |
| + | |
| + | '''03059003''' ''"TM2020"'' |
| + | uint32 version |
| + | fileref secondaryPackDesc |
| | | |
| ===CGameWaypointSpecialProperty (03 13B 000) === | | ===CGameWaypointSpecialProperty (03 13B 000) === |
| + | Mapped to the new GameData engine (2E) as class CGameWaypointSpecialProperty (2E009000). |
| + | |
| '''0313B000''' | | '''0313B000''' |
| uint32 version | | uint32 version |
Line 678: |
Line 716: |
| string tag | | string tag |
| uint32 order | | uint32 order |
| + | |
| + | ===CGameCtnAnchoredObject (03 101 000)=== |
| + | |
| + | '''03101002''' |
| + | uint32 version |
| + | meta (itemFile, collection, author) |
| + | vec3 pitchYawRoll |
| + | byte blockUnitX |
| + | byte blockUnitY |
| + | byte blockUnitZ |
| + | lookbackstring anchorTreeId |
| + | vec3 absolutePositionInMap |
| + | CGameWaypointSpecialProperty waypointSpecialProperty (-1 if not a waypoint, otherwise direct node) |
| + | if version >= 4: |
| + | uint16 flags |
| + | if version >= 5: |
| + | vec3 pivotPosition |
| + | if version >= 6: |
| + | float scale |
| + | if version >= 8: // TM 2020 |
| + | vec3 |
| + | vec3 |
| | | |
| ===CGameCtnReplayRecord (03 093 000)=== | | ===CGameCtnReplayRecord (03 093 000)=== |
Line 754: |
Line 814: |
| | | |
| A sample record looks as follows: | | A sample record looks as follows: |
− | vec3D position | + | vec3 position |
| uint16 angle (0..0xFFFF -> 0..pi) | | uint16 angle (0..0xFFFF -> 0..pi) |
| int16 axisHeading (-0x8000..0x7FFF -> -pi..pi) | | int16 axisHeading (-0x8000..0x7FFF -> -pi..pi) |
Line 772: |
Line 832: |
| ===CGameCtnGhost (03 092 000)=== | | ===CGameCtnGhost (03 092 000)=== |
| CGameCtnGhost is a subclass of CGameGhost. If you encounter an unknown chunk ID while reading a CGameCtnGhost instance, delegate it to CGameGhost. | | CGameCtnGhost is a subclass of CGameGhost. If you encounter an unknown chunk ID while reading a CGameCtnGhost instance, delegate it to CGameGhost. |
| + | |
| + | '''03092000''' (skippable) |
| + | uint32 |
| + | meta playerModel |
| + | vec3 |
| + | |
| + | uint32 numSkinRef |
| + | fileref skinRef[numSkinRef] |
| + | |
| + | uint32 |
| + | string ghostNickname |
| + | string ghostAvatarFile |
| + | uint32 |
| | | |
| '''03092005''' (skippable) | | '''03092005''' (skippable) |
Line 786: |
Line 859: |
| | | |
| '''0309200B''' (skippable) | | '''0309200B''' (skippable) |
− | uint32 num | + | uint32 numCheckpoints |
− | uint64[num] | + | for each checkpoint: |
| + | uint32 time |
| + | uint32 stuntsScore (usually 0 in TM2) |
| | | |
| '''0309200C''' | | '''0309200C''' |
Line 825: |
Line 900: |
| | | |
| '''03092019''' | | '''03092019''' |
− | uint32 eventsDuration | + | uint32 eventsDuration (if 0 then stop reading this chunk) |
| uint32 ignored | | uint32 ignored |
| uint32 numControlNames | | uint32 numControlNames |
Line 852: |
Line 927: |
| meta (name, collection, author) | | meta (name, collection, author) |
| lookbackstring version | | lookbackstring version |
− | string pagePath (slash-separated folder path where the block appears in the editor) | + | string pageName (slash-separated folder path where the block appears in the editor) |
| if version == 5: | | if version == 5: |
| lookbackstring | | lookbackstring |
Line 858: |
Line 933: |
| lookbackstring | | lookbackstring |
| if version >= 3: | | if version >= 3: |
− | uint32 flags | + | struct SCollectorDescFlags |
− | uint16 index (order of the blocks within pagePath) | + | { |
| + | uint32 __unused2__ : 1; |
| + | uint32 IsInternal : 1; |
| + | uint32 IsAdvanced : 1; |
| + | uint32 IconDesc : 5; // 0 = Unknown, 1 = NoIcon, 2 = BGRA_64x64, 3 = BGRA_128x128 |
| + | uint32 __unused__ : 24; |
| + | }; |
| + | uint16 catalogPosition (order of the blocks within pageName) |
| if version >= 7: | | if version >= 7: |
| string name | | string name |
| if version >= 8: | | if version >= 8: |
− | byte | + | byte prodState (0: Aborted, 1: GameBox, 2: DevBuild, 3: Release) |
| | | |
| '''0301A004''' ''"Icon"'' (header) | | '''0301A004''' ''"Icon"'' (header) |
Line 880: |
Line 962: |
| uint32 | | uint32 |
| uint32 | | uint32 |
| + | |
| + | '''0301A008''' |
| + | byte |
| + | string skinFile |
| | | |
| '''0301A009''' | | '''0301A009''' |
Line 908: |
Line 994: |
| | | |
| '''0301C000''' (header) | | '''0301C000''' (header) |
− | uint32 itemType (0: Undefined, 1: Ornament (formerly: StaticObject), 2: PickUp (formerly: DynaObject), 3: Character, 4: Vehicle, 5: Spot, 6: Cannon, 7: Group (Dev build), 8: Decal (Dev build), 9: Turret (Dev build), 10: Wagon (Dev build), 11: Block (Dev build)) | + | uint32 itemType (0: Undefined, 1: Ornament (formerly: StaticObject), 2: PickUp (formerly: DynaObject), 3: Character, 4: Vehicle, 5: Spot, 6: Cannon, 7: Group, 8: Decal, 9: Turret, 10: Wagon, 11: Block, 12: EntitySpawner |
| | | |
| '''0301C001''' (header) | | '''0301C001''' (header) |
Line 939: |
Line 1,025: |
| | | |
| '''0301C012''' | | '''0301C012''' |
− | vec3D groundPoint | + | vec3 groundPoint |
| float painterGroundMargin | | float painterGroundMargin |
| float orbitalCenterHeightFromGround | | float orbitalCenterHeightFromGround |
Line 946: |
Line 1,032: |
| | | |
| '''301C013''' | | '''301C013''' |
− | nodref audioEnvironmentInCar (CPlugAudioEnvironment; used for cars) | + | noderef audioEnvironmentInCar (CPlugAudioEnvironment; used for cars) |
| | | |
| '''301C014''' | | '''301C014''' |
Line 967: |
Line 1,053: |
| '''0301C019''' | | '''0301C019''' |
| int version | | int version |
− | nodref phyModel // CPlugSurface | + | noderef phyModel // CPlugSurface |
− | nodref visModel // CPlugSurface | + | noderef visModel // CPlugSurface |
| if version >= 1: | | if version >= 1: |
− | nodref visModelStatic // CPlugSolid2Model | + | noderef visModelStatic // CPlugSolid2Model |
| | | |
| ===CGameCtnDecoration (03 038 000)=== | | ===CGameCtnDecoration (03 038 000)=== |
Line 985: |
Line 1,071: |
| '''03033001''' ''"Desc"'' | | '''03033001''' ''"Desc"'' |
| byte version | | byte version |
− | lookbackstring environment | + | lookbackstring collection |
− | bool | + | bool needUnlock |
| if version >= 1: | | if version >= 1: |
| string iconEnv | | string iconEnv |
| string iconCollection | | string iconCollection |
| if version >= 2: | | if version >= 2: |
− | int32 | + | int32 sortIndex |
| if version >= 3: | | if version >= 3: |
− | lookbackstring terrain | + | lookbackstring defaultZone |
| if version >= 4: | | if version >= 4: |
| meta (vehicle, collection, author) | | meta (vehicle, collection, author) |
| if version >= 5: | | if version >= 5: |
− | string | + | string mapFid |
− | float | + | vec2 |
− | float | + | vec2 |
− | float
| + | if version == 5: |
− | float
| + | vec2 mapCoordElem |
− | if version <= 5: | + | if version == 6 || version == 7: |
− | float | + | vec2 mapCoordElem |
− | float
| + | vec2 mapCoordIcon |
− | if version <= 7: | |
− | float | |
− | float | |
| if version >= 7: | | if version >= 7: |
| string loadscreen | | string loadscreen |
| if version >= 8: | | if version >= 8: |
− | float | + | vec2 mapCoordElem |
− | float | + | vec2 mapCoordIcon |
− | float | + | vec2 mapCoordDesc |
− | float
| + | string longDesc |
− | float
| |
− | float
| |
− | string | |
| if version >= 9: | | if version >= 9: |
− | string name | + | string displayName |
| if version >= 10: | | if version >= 10: |
− | bool | + | bool isEditable |
| | | |
| '''03033002''' ''"CollectorFolders"'' | | '''03033002''' ''"CollectorFolders"'' |
| byte version | | byte version |
− | string dirName | + | string folderBlockInfo |
− | string dirName | + | string folderItem |
− | string dirName | + | string folderDecoration |
| if version == 1 || version == 2: | | if version == 1 || version == 2: |
− | string dirName | + | string folder |
| if version >= 2: | | if version >= 2: |
− | string dirName | + | string folderCardEventInfo |
| if version >= 3: | | if version >= 3: |
− | string dirName | + | string folderMacroBlockInfo |
| if version >= 4: | | if version >= 4: |
− | string dirName | + | string folderMacroDecals |
| | | |
| '''03033003''' ''"MenuIconsFolders"'' | | '''03033003''' ''"MenuIconsFolders"'' |
| byte version | | byte version |
− | string dirName | + | string folderMenusIcons |
| | | |
| ===CGameSkin (03 031 000)=== | | ===CGameSkin (03 031 000)=== |
Line 1,056: |
Line 1,136: |
| string file | | string file |
| if version >= 2: | | if version >= 2: |
− | bool mipMap | + | bool needMipMap |
| if version >= 4: | | if version >= 4: |
| string dirNameAlt | | string dirNameAlt |
| if version >= 5: | | if version >= 5: |
− | bool unknown | + | bool useDefaultSkin |
| | | |
| ===CGamePlayerProfile (03 08C 000)=== | | ===CGamePlayerProfile (03 08C 000)=== |
| '''0308C000''' ''"NetPlayerProfile"'' | | '''0308C000''' ''"NetPlayerProfile"'' |
− | string login | + | string onlineLogin |
| string onlineSupportKey | | string onlineSupportKey |
| + | |
| + | ===CGameCtnMediaClipGroup (03 07A 000)=== |
| + | '''0307A003''' |
| + | uint32 ignored (0xA) |
| + | uint32 numClips |
| + | for each clip: |
| + | noderef clip |
| + | uint32 numClips |
| + | for each clip: |
| + | vec3 referenceFramePosition (NaN if none) |
| + | uint32 referenceFrameRotation |
| + | uint32 triggerCondition (0: None, 1: Time < arg, 2: Time > arg, 3: Already triggered, 4: Speed < arg, 5: Speed > arg, 6: Not already triggered) |
| + | float triggerArgument |
| + | uint32 numTriggers |
| + | for each trigger: |
| + | vec3 position |
| + | |
| + | ===CGameCtnMediaClip (03 079 000)=== |
| + | '''03079002''' |
| + | uint32 |
| + | uint32 numTracks |
| + | for each track: |
| + | noderef mediaTrack |
| + | string clipName |
| + | uint32 |
| + | |
| + | '''03079003''' |
| + | uint32 |
| + | uint32 numTracks |
| + | for each track: |
| + | noderef mediaTrack |
| + | string clipName |
| + | |
| + | '''03079004''' (all fields are ignored) |
| + | uint32 |
| + | |
| + | '''03079005''' |
| + | uint32 ignored (0xA) |
| + | uint32 numTracks |
| + | for each track: |
| + | noderef mediaTrack |
| + | string clipName |
| + | |
| + | '''03079007''' |
| + | uint32 localPlayerClipEntIndex |
| + | |
| + | '''0307900A''' |
| + | bool stopWhenLeave |
| + | |
| + | '''0307900D''' |
| + | uint32 |
| + | uint32 version |
| + | uint32 numTracks |
| + | for each track: |
| + | noderef mediaTrack |
| + | string clipName |
| + | bool stopWhenLeave |
| + | bool |
| + | bool stopWhenRespawn |
| + | string |
| + | float |
| + | uint32 localPlayerClipEntIndex |
| + | |
| + | ===CGameCtnMediaTrack (03 078 000)=== |
| + | '''03078001''' |
| + | string trackName |
| + | uint32 ignored (0xA) |
| + | uint32 numTracks |
| + | for each track: |
| + | noderef mediaBlock |
| + | uint32 unknown |
| + | |
| + | '''03078004''' |
| + | bool keepPlaying |
| + | uint32 ignored (0) |
| + | |
| + | ===CControlEffectSimi (07 010 000)=== |
| + | '''07010003''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | vec2 position |
| + | float rotation (in rad) |
| + | float scaleX |
| + | float scaleY |
| + | float opacity |
| + | float depth |
| + | bool centered |
| + | |
| + | '''07010004''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | vec2 position |
| + | float rotation (in rad) |
| + | float scaleX |
| + | float scaleY |
| + | float opacity |
| + | float depth |
| + | float |
| + | float isContinousEffect |
| + | float |
| + | float |
| + | bool centered |
| + | uint32 colorBlendMode |
| + | bool isContinousEffect |
| + | |
| + | '''07010005''' |
| + | ReadChunk(0x07010004) |
| + | bool isInterpolated |
| + | |
| + | ===CGameCtnMediaBlock=== |
| + | |
| + | ====CGameCtnMediaBlockCameraPath (03 0A1 000)==== |
| + | '''030A1002''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | vec3 cameraPosition |
| + | float pitch (rad) |
| + | float yaw (rad) |
| + | float roll (rad) |
| + | float FOV |
| + | bool anchorRot |
| + | uint32 indexTargetPlayer (maxint: None, 0: Local player) |
| + | bool anchorVis |
| + | uint32 indexAnchorPlayer (maxint: None, 0: Local player) |
| + | vec3 targetPosition |
| + | float weight |
| + | float |
| + | float |
| + | float |
| + | float |
| + | |
| + | ====CGameCtnMediaBlockCameraCustom (03 0A2 000)==== |
| + | '''030A2005''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | uint32 interpolation (0: None, 1: Hermit, 2: Linear, 3: FixedTangent) |
| + | uint64 unused (0) |
| + | vec3 cameraPosition |
| + | float pitch (rad) |
| + | float yaw (rad) |
| + | float roll (rad) |
| + | float FOV |
| + | bool anchorRot |
| + | uint32 indexTargetPlayer (maxint: None, 0: Local player) |
| + | bool anchorVis |
| + | uint32 indexAnchorPlayer (maxint: None, 0: Local player) |
| + | vec3 targetPosition |
| + | float leftTangentX |
| + | float leftTangentY |
| + | float leftTangentZ |
| + | float rightTangentX |
| + | float rightTangentY |
| + | float rightTangentZ |
| + | |
| + | ====CGameCtnMediaBlockCameraEffectShake (03 0A4 000)==== |
| + | '''030A4000''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float intensity |
| + | float speed |
| + | |
| + | ====CGameCtnMediaBlockImage (03 0A5 000)==== |
| + | '''030A5000''' |
| + | noderef CControlEffectSimi |
| + | fileref image |
| + | |
| + | ====CGameCtnMediaBlockMusicEffect (03 0A6 000)==== |
| + | '''030A6001''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float musicVolume |
| + | float soundVolume |
| + | |
| + | ====CGameCtnMediaBlockSound (03 0A7 000)==== |
| + | '''030A7001''' |
| + | fileref sound |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float volume |
| + | float pan |
| + | |
| + | '''030A7002''' |
| + | uint32 playCount |
| + | bool isLooping |
| + | |
| + | '''030A7003''' |
| + | uint32 version |
| + | uint32 playCount |
| + | bool isLooping |
| + | bool isMusic |
| + | if version >= 1: |
| + | bool stopWithClip |
| + | if version >= 2: |
| + | bool audioToSpeech |
| + | int audioToSpeechTarget |
| + | |
| + | '''030A7004''' |
| + | fileref sound |
| + | uint32 ignored (1) |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float volume |
| + | float pan (unused) |
| + | vec3 soundTransmitorPosition |
| + | |
| + | ====CGameCtnMediaBlockText (03 0A8 000)==== |
| + | '''030A8001''' |
| + | string text |
| + | noderef CControlEffectSimi |
| + | |
| + | '''030A8002''' |
| + | color textColor (with in-game color selector format) |
| + | |
| + | ====CGameCtnMediaBlockTrails (03 0A9 000)==== |
| + | '''030A9000''' |
| + | float timeClipStart |
| + | float timeClipEnd |
| + | |
| + | ====CGameCtnMediaBlockTransitionFade (03 0AB 000)==== |
| + | '''030AB000''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float opacity |
| + | color transitionColor (with in-game color selector format) |
| + | float ignored (1.0) |
| + | |
| + | ====CGameCtnMediaBlockFxColors (03 080 000)==== |
| + | '''03080003''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float intensity |
| + | float blendZ (far) |
| + | float distance (near) |
| + | float distance (far) |
| + | additionnalParameters (near) |
| + | additionnalParameters (far) |
| + | |
| + | additionnalParameters format: |
| + | float inverse |
| + | float hue |
| + | float saturation |
| + | float brightness |
| + | float contrast |
| + | color |
| + | float ignored (1.0) |
| + | float ignored (1.0) |
| + | float ignored (1.0) |
| + | float ignored (0.0) |
| + | |
| + | ====CGameCtnMediaBlockFxBlurDepth (03 081 000)==== |
| + | '''03081001''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float lensSize |
| + | bool forceFocus |
| + | float focusZ |
| + | |
| + | ====CGameCtnMediaBlockFxBlurMotion (03 082 000)==== |
| + | '''03082000''' |
| + | float timeClipStart |
| + | float timeClipEnd |
| + | |
| + | ====CGameCtnMediaBlockFxBloom (03 083 000)==== |
| + | '''03083001''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float intensity |
| + | float sensitivity |
| + | |
| + | ====CGameControlCameraFree (03 084 000)==== |
| + | '''03084003''' |
| + | float timeClipStart |
| + | float timeClipEnd |
| + | lookbackstring cameraView |
| + | uint32 indexTargetPlayer (0: Local player) |
| + | |
| + | ====CGameCtnMediaBlockTime (03 085 000)==== |
| + | '''03085000''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float timeValue |
| + | float tangent |
| + | |
| + | ====CGameCtnMediaBlock3dStereo (03 024 000)==== |
| + | '''03024000''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float separation |
| + | float screenDist |
| + | |
| + | ====CGameCtnMediaBlockTriangles (03 029 000)==== |
| + | '''03029001''' |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | uint32 numKeys |
| + | uint32 numPoints |
| + | for each key: |
| + | for each point: |
| + | vec3 pointPosition |
| + | uint32 numPoints |
| + | for each point: |
| + | color pointColor (with in-game color selector format) |
| + | float opacity |
| + | uint32 numTriangles |
| + | for each triangle: (index of the 3 vertices forming the triangle) |
| + | uint32 vertex1 |
| + | uint32 vertex2 |
| + | uint32 vertex3 |
| + | uint32 ignored (1) |
| + | uint32 ignored (0) |
| + | uint32 ignored (0) |
| + | float ignored (1.0) |
| + | uint32 ignored (0) |
| + | uint64 ignored (0) |
| + | |
| + | ====CGameCtnMediaBlockGhost (03 0E5 000)==== |
| + | '''030E5001''' |
| + | float timeClipStart |
| + | float timeClipEnd |
| + | noderef ghostModel (CGameCtnGhost) |
| + | float startOffset |
| + | |
| + | '''030E5002''' |
| + | uint32 version |
| + | if version < 3: |
| + | float timeClipStart |
| + | float timeClipEnd |
| + | if version >= 3: |
| + | uint32 numKeys |
| + | for each key: |
| + | float timeStamp |
| + | float |
| + | noderef ghostModel (CGameCtnGhost) |
| + | float startOffset |
| + | bool noDamage |
| + | bool forceLight |
| + | bool forceHue |
| | | |
| ===CMwNod (01 001 000)=== | | ===CMwNod (01 001 000)=== |
Line 1,072: |
Line 1,504: |
| for each number: | | for each number: |
| string dirName | | string dirName |
| + | |
| + | == References to the actual functions == |
| + | <references /> |
| | | |
| == Applications and Libraries that can inspect/modify the file format == | | == Applications and Libraries that can inspect/modify the file format == |
Line 1,091: |
Line 1,526: |
| * [http://www.wolfgang-rolke.de/gbxdump/gbxlightmap.zip GbxLightMap download] - a Windows tool to extract the lightmaps from a given .Map.Gbx file (includes source code). | | * [http://www.wolfgang-rolke.de/gbxdump/gbxlightmap.zip GbxLightMap download] - a Windows tool to extract the lightmaps from a given .Map.Gbx file (includes source code). |
| * [http://www.wolfgang-rolke.de/gbxdump/gbxmetadata.zip GbxMetadata download] - a Windows tool that indicates the persistent attributes of a given .Map.Gbx file (includes source code). | | * [http://www.wolfgang-rolke.de/gbxdump/gbxmetadata.zip GbxMetadata download] - a Windows tool that indicates the persistent attributes of a given .Map.Gbx file (includes source code). |
| + | * [[File:Krzychor-campaign-maker.zip]] - a Windows tool that allows to create custom campaigns for TMNF/TMUF. Sources not included. |
| | | |
| [[Category:File formats]] | | [[Category:File formats]] |