Table of Contents
Miscellany
These are various odds and ends that do not fit into the earlier categories.
Version
Every level file begins with a uint32_t
version number. This seems to be used by the engine to guarantee compatibility between various level editor versions and the game engine version. More generally, it can be used to determine what sort of level is being read.
Here are the known (observed) values for the version header:
0x00000020
— Tomb Raider 1, Gold, Unfinished Business0x0000002D
— Tomb Raider 2, Gold0xFF180038
— Tomb Raider 3, Gold, Gold Title level0xFF080038
— Tomb Raider 3 (Title level on Normal)0xFF180034
— Tomb Raider 3 (VICT.TR2
that only contains palette and atlases)0x00345254
(TR4
) — Tomb Raider 4 and Tomb Raider 50x63345254
(TR4c
) — Tomb Raider 4 (demo versions)
Palette
This consists of 256 [tr_colour] structs, one for each palette entry. However, the individual colour values range from 0 to 63; they must be multiplied by 4 (or bitshifted by 2 to the left) to get the correct values. Palette is used for all 8-bit colour, such as 8-bit textures.
First entry in palette is treated as transparent colour used for textures with alpha testing. In later games, transparent colour was replaced by so-called “magenta transparency”, meaning that any pixel with red and blue values at maximum and green value at zero, is treated as completely transparent.
Object Textures
An object texture (or texture details in TRLE terms) keeps detailed information about each texture independently used in the game. While it’s not a texture image itself (these are kept inside texture atlases), it’s rather a reference to a particular texture in an atlas, kept with all other necessary information to display this texture.
Object Texture Vertex Structure
This sub-structure used by object textures specifies a vertex location in texture tile coordinates. The Xcoordinate and Ycoordinate are the actual coordinates of the vertex's pixel. If the object texture is used to specify a triangle, then the fourth vertex's values will all be zero.
struct tr_object_texture_vert // 4 bytes { ufixed16 Xcoordinate; ufixed16 Ycoordinate; };
Object Texture Structure (TR1-3)
It’s object texture structure itself. These, thee contents of ObjectTextures[]
, are used for specifying texture mapping for the world geometry and for mesh objects.
struct tr_object_texture // 20 bytes { uint16_t Attribute; uint16_t AtlasAndFlag; tr_object_texture_vert Vertices[4]; // The four corners of the texture };
AtlasAndFlag
is a combined field:
- Bits 0..14 specify the texture atlas to use. On PC, the value should be between 0 and 63 (inclusive).
- Bit 15: if set, it indicates that the texture is used on a triangle face.
Attribute
specifies transparency mode (i.e. blending mode) used for face with this texture applied. There are several ones available:
- 0 — Texture is all-opaque, and that transparency information is ignored.
- 1 — Texture uses alpha testing, i.e. it may contain opaque and completely transparent regions. In 8-bit colour, index 0 is the transparent colour, while in 16-bit colour, the top bit (0x8000) is the alpha channel (1 = opaque, 0 = transparent). In 32-bit textures, transparency is specified by full magenta colour value (RGB = 255,0,255) — i.e. pixel has to be magenta to be transparent.
- 2 — Texture uses alpha blending with additive operation. No depth sorting is done on alpha-blended textures.
- 3 — Not implemented properly in PC version, but on PlayStation this type produces alpha blending with inversion operation, thus converting all the bright zones to dark, and dark zones to bright. This blending mode was used for smooth textured shadows, footprints and black smoke sprites. There is a remnant of this blending mode in the form of entity type named smoke emitter black.
- 4 — Alpha-tested face without Z testing, i.e. depth information is ignored. Used for GUI elements (such as fonts) and skyboxes.
- 5 — Unused. Possibly was used in PlayStation versions.
- 6 — Wireframe mode. Used for “line particles”, such as gun sparks, water drops and laser beams. Possibly was also used for debug purposes.
- 7 — Forced alpha value. It’s ordinary alpha-tested face, but alpha value for this face is overridden with global variable. Used to “fade out” specific meshes, like vanishing enemy bodies or Semerkhet ghost in “Tomb of Semerkhet” level.
Object Texture Structure (TR4-5)
The structure introduced many new fields in TR4, partly related to new bump mapping feature.
For bump mapping, TR4 used fairly simple approach, which was actually not a true bump mapping, but multitexturing with additive operation. Therefore, bump maps were not normal maps mainly used for bump-mapping nowadays, but simple monochrome heightmaps automatically generated by level editor. This is a test screenshot comparison demonstrating same scene with and without bump mapping:
Bump mapping turned off | Bump mapping turned on |
Assignment of bump maps happened inside level editor, where each texture piece could be marked as either level 1 or level 2 of the bump map effect. When the level was converted, all texture pieces with bumpmaps were placed into separate texture atlases after all other texture atlases, followed by the same amount of texture atlases with auto-generated bump maps arranged in the same manner as the original texture atlases. The number of bump map atlases was kept in a separate variable as well (see TR4 Level Format section).
So, when the engine rendered a face with a texture marked as bump-mapped, it rendered the original texture first, then it jumped to the texture atlas plus the number of bump-mapped texture atlases, and rendered one more texture pass on this face using the texture from the resulting texture atlas and the same UV coordinates.
struct tr4_object_texture // 38 bytes { uint16_t Attribute; uint16_t AtlasAndFlag; uint16_t NewFlags; tr_object_texture_vert Vertices[4]; // The four corners of the texture uint32_t OriginalU; uint32_t OriginalV; uint32_t Width; // Actually width-1 uint32_t Height; // Actually height-1 };
NewFlags
is a bit field with flags:
- Bits 0..2 — Mapping correction. This value is used by internal
AdjustUV
function which crops the texture in specific way to prevent border bleeding issue happening because of texture atlas packing. Value meaning depends on texture face type (triangle or quad). For quads, only types0
and1
are actually used (0
being normal and1
being mirrored quad texture), while other types (2-7) produce same result as 0. For triangles, all possible values (0-7) are used for each possible right triangle type (including mirrored coordinates):
Triangle mapping correction types. Orange shapes indicate normal (non-mirrored) texture coordinates, while blue shapes indicate mirrored ones. Mirrored coordinates mean that they are placed in counterclockwise order. |
- Bits 9..10 — Specifies bump mapping level (see above), so can be either
00 = 0
(no bump mapping),01 = 1
(level 1) or10 = 2
(level 2). - Bit 15 — If set, the texture is for a triangle/quad from a room geometry. If not set, the texture is for a static mesh or model.
Width
and Height
are helper values which specify width and height for a given object texture.
OriginalU
and OriginalV
are unused values, which seem to identify original UV coordinates of object texture in TRLE texture page listings. These coordinates are getting messed up when level is compiled, so one shouldn’t bother about parsing them correctly.
There is also null uint16_t
filler in the end of each [tr4_object_texture].
Animated Textures
Animated textures describe sets of object textures that are cycled through to produce texture animations; they are a set of int16_t’s with the following format (not a “real” C/C++ structure):
int16_t NumAnimatedTextures virtual struct { int16_t NumTextureIDs; // Actually, this is the number of texture ID's - 1. int16_t TextureIDs[NumTextureIDs + 1]; // offsets into ObjectTextures[], in animation order. } AnimatedTextures[NumAnimatedTextures];
If a texture belongs to an animated-texture group, it will automatically be animated by the engine.
There are two types of animated textures — classic frames and UVRotate:
- Classic frames: These are ordinary animated textures, and the only type displayed prior to TR4. It is simply a list of textures that are cycled through in an endless loop; they are normally used as geographic elements of the levels (e.g. water surface, bubbling lava, Atlantean flesh walls), but practically, Tomb Raider engines are capable of applying animated textures to mesh geometry (this feature is primarily used in custom levels). The speed (interval) of animation is hardcoded, and varies from version to version. While in TR1-2 textures were animated relatively slowly, in TR3 onwards they were sped up.
- UV Rotate: Beginning from TR4, there is a new scheme for animated textures, called UVRotate. According to its name, it continuously shifts vertical texture coordinate while preserving texture size, which creates an effect of moving texture. For example, you can see it in action in TR4’s
angkor1.tr4
, room #76:
In foreground, you can see alpha-blended waterfall object animated with UVRotate. In background, UVRotate animation is also applied to room mesh. |
UVRotate mode is engaged by specifying UVRotate
command in level script entry, which takes rotation speed as an argument, where speed is amount of pixel shift per each frame, considering fixed 30 FPS framerate (speed value may be negative, and in such cases pixel shift occurs in reverse direction). If such command is found (and argument is not zero — for example, UVRotate = 4
), engine uses special variable value kept in level file, NumUVRotates
, to determine if animation range belongs to UVRotate mode or classic frames mode. Then, if it belongs to UVRotate mode, each frame of this range is treated as individual rotating texture.
The speed of animation for waterfall objects is not affected by UVRotate
script command. Instead, it is hardcoded value of 7.
Cameras and Sinks
This data block serves for two different purposes, albeit keeping the same structure for both. First purpose is to provide positions to switch the camera to using Camera trigger action, and the second purpose is to move Lara to specified position when she is underwater, and Underwater Current trigger action was used.
struct tr_camera // 16 bytes { int32_t x; int32_t y; int32_t z; int16_t Room; uint16_t Flag; };
X
, Y
and Z
values are coordinates of a given camera or sink. When used with camera, it is an origin point of a camera. When used with sink, it is a point, towards which Lara is pushed.
Room
value specifies the room where camera is placed. For sink cases, this value is used to define strength of the current which moves Lara underwater.
Flag
value for cameras specifies whether it’s possible to breakout from fixed camera angle. If first bit of this field is set, camera becomes persistent, and it’s not possible to bypass it with look or draw weapon buttons. For sinks, Flag
value contains Box index — which is used as pathfinding reference when Lara is pushed towards sink via underwater current trigger action.
Flyby Cameras
Flyby cameras are cinematic interludes, in which camera flies from one point to another using spline trajectory. Each point in such sequence is a single flyby camera, and current camera properties (position, direction, roll, FOV, speed, and some more) are calculated by interpolating corresponding values from such flyby camera points — for example, if camera 0 has speed value of 10, and camera 1 has speed value of 5, then speed will gradually change from 10 to 5 when moving from one to another.
struct tr4_flyby_camera // 40 bytes { int32_t x; // Camera position int32_t y; int32_t z; int32_t dx; // Camera angles (so called "look at" vector) int32_t dy; int32_t dz; uint8_t Sequence; uint8_t Index; uint16_t FOV; int16_t Roll; uint16_t Timer; uint16_t Speed; uint16_t Flags; uint32_t Room_ID; };
Sequence
is a number of flyby camera “chain” this particular camera belongs to. Maximum amount of flyby sequences in single level is 8 (however, this limit was raised to 64 in TREP).
Index
specifies order of the cameras in this particular sequence. Camera with index
0 will be first one in sequence, index
1 means camera will be second in sequence, and so on.
Room_ID
should be valid for a given flyby camera, so it will display properly, as well as have the ability to activate heavy triggers.
FOV
changes this particular camera’s field of view. The value is 182 times higher than the value entered in the TRLE.
Roll
changes roll factor of a particular camera. When this parameter is not zero, camera will rotate either left or right along roll axis, creating so-called “dutch angle”. The value is 182 times higher than the value entered in the TRLE.
Timer
field mainly used to stop camera movement for a given time (in game frames). As this parameter is temporal, it won’t be interpolated between two cameras.
Speed
specifies movement speed for this particular camera. The value is 655 times higher than the value entered in the TRLE.
Flags
is an array of bit flags specifying different camera options:
Hex | Bit | Description |
---|---|---|
0x0001 | 0 | Make a cut to flyby from Lara camera position. Without it, it’ll pan smoothly. |
0x0002 | 1 | Tracks specified entity position (from Entities[] array). |
Creates a vignette around the picture, giving impression of “subjective” camera. | ||
0x0004 | 2 | Infinitely loop sequence. |
0x0008 | 3 | Used only with first camera in a sequence: whole sequence is treated merely as a camera “rails”, and camera itself focuses on Lara, thus creating “tracking” camera. Best example is “tracking” view in ALEXHUB2.TR4 , rooms #23 and #31. |
0x0010 | 4 | Camera focuses on Lara’s last head position. |
For TR5, this flag is now used to hide Lara for this camera. | ||
0x0020 | 5 | Camera continuously focuses on Lara’s head, overriding own angle. |
0x0040 | 6 | Used only with last camera in a sequence: camera smoothly pans back to Lara camera position. |
0x0080 | 7 | When flyby arrives to this position, cuts to specific camera in same sequence. Next camera number is specified in Timer field of this camera. |
0x0100 | 8 | Stops camera movement for a given time (see Timer field). |
0x0200 | 9 | Disables look keypress breakout. |
0x0400 | 10 | Disables all Lara controls for all next camera points. Also engages widescreen bars to create cinematic feel. |
0x0800 | 11 | Overrides Bit 10 controls lock, enabling them back. Widescreen bars remain unaffected. |
0x1000 | 12 | Make screen fade-in. |
0x2000 | 13 | Make screen fade-out. |
0x4000 | 14 | Camera can activate heavy triggers, just like particular kinds of entities (boulders, pushables, etc.). When camera is moving right above heavy trigger sector, it will be activated. |
0x8000 | 15 | TRLE for TR5 says this flag is used to make camera one-shot, but it’s not true. Actual one-shot flag is placed in extra uint16_t field at 0x0100 for flyby camera TrigAction. |
Cinematic Frames
These are camera positionings and properties for cutscene frames. All the entity animations are specified separately, and they are not synced with actual camera positions.
switch (CutLevelID) { case 0: // CUT1.PHD levelPosX = 36668; // X pivot position levelPosZ = 63180; // Z pivot position levelRotY = -23312; // Y rotation trackID = 23; // Audio track index break; case 1: // CUT2.PHD levelPosX = 51962; levelPosZ = 53760; levelRotY = 16380; trackID = 25; break; case 2: // CUT3.PHD levelRotY = 0x4000; // Default rotation, 90 degrees FlipMap(); // Do a flipmap trackID = 24; break; case 3: // CUT4.PHD levelRotY = 0x4000; trackID = 22; break; }
levelPosX
, levelPosZ
and levelRotY
parameters are used, if defined, to set-up initial camera pivot position and Y axis rotation. If some of these parameters are not defined (which is the case for CUT3.PHD and CUT4.PHD), they are borrowed from X and Z position and Y rotation of entity with ID #77 (slot used for main cutscene actor, usually Lara). Also, same parameters are used as master model matrix (i. e. multiplied by them instead of using their own position and rotation) for models with IDs #77-79 (which are slots for cutscene actors).
struct tr_cinematic_frame // 16 bytes { int16_t targetX; // Camera look at position about X axis, int16_t targetY; // Camera look at position about Y axis int16_t target2; // Camera look at position about Z axis int16_t posZ; // Camera position about Z axis int16_t posY; // Camera position relative to something (see posZ) int16_t posX; // Camera position relative to something (see posZ) int16_t fov; int16_t roll; // Rotation about X axis };
All target
and pos
parameters, as well as roll
parameter, are encoded in the same manner as Angle
parameter for [tr_entity] structure.
LightMap
A 32*256 array of uint8_t
which is apparently for applying light to 8-bit colour, in some documentation called ColourMap
. The current palette index and lighting value are used to calcuate an index to this table, which is a table of palette indices.
The Tomb Raider series' software rendering, like that of most real-time-3D games, uses 8-bit colour for speed and low bulk; however, there is the serious problem of how to do lighting with 8-bit colour, because doing it directly is computationally expensive. The usual solution is to arrange the palettes' colours in ramps, which the engine then follows in the appropriate directions. However, the TR series' palettes generally lack such neat ramps.
But the TR series has a more general solution, one that does not require palettes to have colour ramps. It uses precalculated lighting tables, the ColourMap
objects. These contain translations of a colour value and a lighting value, listed by palette index. The translation goes as follows:
$n = ColourMap[256 \cdot k + i]$
where $i$ is the original palette index, $k$ is determined from the lighting value, and $n$ is the new palette index. The lighting index $k$ varies from $0$ to $31$, and the corresponding lighting value is $2 - k / 16$ for TR1 and $2 - (k + 1) / 16$ for TR2 and TR3.
This may be associated with the curious fact of the lighting values in the data files increasing in the “wrong” direction in TR1 and TR2, with $0$ being full brightness and greater values being darker.
Flipeffects
The Concept
As it was briefly mentioned earlier, flipeffect is a special pre-compiled routine which is called when some non-trivial event occurs.
The concept of flipeffect is somewhat similar to task, i.e. when some flipeffect is engaged, it could be flagged by engine to call every game frame (however, there are primarily one-shot flipeffects present). Such setup is needed for some complex flipeffect events, like flickering lights in TR1 Atlantis (see FLICKER_FX
description), which stops automatically after some time.
If flipeffect is flagged to execute every game frame, this flag can only be unset by own current flipeffect code (when its task is done — for this purpose, special internal flip timer is used to count how much time have passed since flipeffect activation) or replaced by any other flipeffect call (however, newly called flipeffect doesn’t necessarily overwrite current flipeffect flag, so you can have one-shot flipeffect executed with another one queued for continuous execution). Ergo, it’s not possible to queue more than one _continuous flipeffect at a time, but it’s possible to have one one-shot and another continuous flipeffect executed every game frame.
Complete Flipeffect List
In this chapter, we’ll try to describe each flipeffect for every TR engine version. Given the fact that flipeffect listing changed from version to version, yet retaining common ones, the easiest way to lay them down is to create a table with flipeffect indexes corresponding to each game version.
There are some guidelines to flipeffect table:
- It’s possible that same flipeffect goes under different names in different game versions. In this case, legacy flipeffect name will be preserved (for historical [sic] reasons), and description will point to a flipeffect with more recent name. Legacy flipeffect names would be colored in green.
- Flipeffect names are directly brought from native SDK or debug listings, where available (namely TR1, TR2, and TR4). When native names are wrong (which happens in TR4 and TR5 listings), new ones will be coined. New flipeffect names would be colored in purple.
- It’s possible that legacy flipeffect code could migrate to later engine version without changes, but could be broken due to missing code in another part of engine or changes in internal structures. In this case, flipeffect name would be colored in red.
- If there’s an entry in engine’s flipeffect list, but no actual code for it, it would be marked as (-).
- If actual flipeffect’s purpose is unknown, it would be marked as (?).
- If flipeffect ought to be continuous, it will be marked in bold.
On contrary, some flipeffects may require certain trigger action and/or certain trigger type to be called at the moment. In such case, if flipeffect is called via AnimCommand, resulting outcome is undefined in original engine.
Index | TR1 | TR2 | TR3 | TR4 | TR5 |
---|---|---|---|---|---|
0 | TURN180 | TURN180 | TURN180 | ROTATE_180 | ROTATE_180 |
1 | DINO_STOMP | FLOOR_SHAKE | FLOOR_SHAKE | FLOOR_SHAKE | FLOOR_SHAKE |
2 | LARA_NORMAL | LARA_NORMAL | LARA_NORMAL | FLOOD_FX | FLOOD_FX |
3 | LARA_BUBBLES | LARA_BUBBLES | LARA_BUBBLES | LARA_BUBBLES | LARA_BUBBLES |
4 | FINISH_LEVEL | FINISH_LEVEL | FINISH_LEVEL | FINISH_LEVEL | FINISH_LEVEL |
5 | EARTHQUAKE_FX | FLOOD_FX | FLOOD_FX | ACTIVATE_CAMERA | ACTIVATE_CAMERA |
6 | FLOOD_FX | CHANDELIER_FX | CHANDELIER_FX | ACTIVATE_KEY | ACTIVATE_KEY |
7 | RAISINGBLOCK_FX | RUBBLE_FX | RUBBLE_FX | RUBBLE_FX | RUBBLE_FX |
8 | STAIRS2SLOPE_FX | PISTON_FX | PISTON_FX | SWAP_CROWBAR | SWAP_CROWBAR |
9 | SAND_FX | CURTAIN_FX | CURTAIN_FX | - | - |
10 | POWERUP_FX | SETCHANGE_FX | SETCHANGE_FX | TIMER_FIELD_FX | TIMER_FIELD_FX |
11 | EXPLOSION_FX | EXPLOSION_FX | EXPLOSION_FX | EXPLOSION_FX | EXPLOSION_FX |
12 | LARA_HANDSFREE | LARA_HANDSFREE | LARA_HANDSFREE | LARA_HANDSFREE | LARA_HANDSFREE |
13 | FLIP_MAP | FLIP_MAP | FLIP_MAP | - | - |
14 | DRAW_RIGHTGUN | DRAW_RIGHTGUN | DRAW_RIGHTGUN | DRAW_RIGHTGUN | - |
15 | CHAINBLOCK_FX | DRAW_LEFTGUN | DRAW_LEFTGUN | DRAW_LEFTGUN | - |
16 | FLICKER_FX | - | SHOOT_RIGHTGUN | SHOOT_RIGHTGUN | SHOOT_RIGHTGUN |
17 | - | SHOOT_LEFTGUN | SHOOT_LEFTGUN | SHOOT_LEFTGUN |
|
18 | MESH_SWAP1 | MESH_SWAP1 | MESH_SWAP1 | - |
|
19 | MESH_SWAP2 | MESH_SWAP2 | MESH_SWAP2 | - |
|
20 | MESH_SWAP3 | MESH_SWAP3 | MESH_SWAP3 | - |
|
21 | INV_ON | INV_ON | INV_ON | INV_ON |
|
22 | INV_OFF | INV_OFF | INV_OFF | INV_OFF |
|
23 | DYN_ON | DYN_ON | - | - |
|
24 | DYN_OFF | DYN_OFF | - | - |
|
25 | STATUE_FX | STATUE_FX | - | - |
|
26 | RESET_HAIR | RESET_HAIR | RESET_HAIR | RESET_HAIR |
|
27 | BOILER_FX | BOILER_FX | - | - |
|
28 | ASSAULT_RESET | ASSAULT_RESET | SETFOG | SETFOG |
|
29 | ASSAULT_STOP | ASSAULT_STOP | GHOSTTRAP | - |
|
30 | ASSAULT_START | ASSAULT_START | LARALOCATION | LARALOCATION |
|
31 | ASSAULT_FINISHED | ASSAULT_FINISHED | CLEARSCARABS | RESET_TEST (?) |
|
32 | FOOTPRINT_FX | FOOTPRINT_FX | FOOTPRINT_FX |
||
33 | ASSAULT_PENALTY_8 | - | CLEAR_SPIDERS_PATCH (?) |
||
34 | RACETRACK_START | - | - |
||
35 | RACETRACK_RESET | - | - |
||
36 | RACETRACK_FINISHED | - | - |
||
37 | ASSAULT_PENALTY_30 | - | - |
||
38 | GYM_HINT_1 | - | - |
||
39 | GYM_HINT_2 | - | - |
||
40 | GYM_HINT_3 | - | - |
||
41 | GYM_HINT_4 | - | - |
||
42 | GYM_HINT_5 | - | - |
||
43 | GYM_HINT_6 | POURSWAP_ON | - |
||
44 | GYM_HINT_7 | POURSWAP_OFF | - |
||
45 | GYM_HINT_8 | LARALOCATIONPAD | LARALOCATIONPAD |
||
46 | GYM_HINT_9 | KILLACTIVEBADDIES | KILLACTIVEBADDIES |
||
47 | GYM_HINT_10 | TUT_HINT_1 |
|||
48 | GYM_HINT_11 | TUT_HINT_2 |
|||
49 | GYM_HINT_12 | TUT_HINT_3 |
|||
50 | GYM_HINT_13 | TUT_HINT_4 |
|||
51 | GYM_HINT_14 | TUT_HINT_5 |
|||
52 | GYM_HINT_15 | TUT_HINT_6 |
|||
53 | GYM_HINT_16 | TUT_HINT_7 |
|||
54 | GYM_HINT_17 | TUT_HINT_8 |
|||
55 | GYM_HINT_18 | TUT_HINT_9 |
|||
56 | GYM_HINT_19 | TUT_HINT_10 |
|||
57 | GYM_HINT_RESET | TUT_HINT_11 |
|||
58 | TUT_HINT_12 |
LARA_
prefix automatically take Lara character as an entity to work with. Also, most flipeffects with _FX
postfix are simple sound effect events.
ROTATE_180
— Rotates an entity 180 degrees around yaw axis and also around pitch axis for underwater cases. Mostly used in Lara roll animations. This flipeffect needs special approach if original animation frames are interpolated, because usually rotation is done on animation transition (e.g., frame 5 of Lara animation 48, which is second and final part of her roll movement). To prevent stray misaligned interpolated frames, this flipeffect must be performed only in the end of frame-to-frame interpolated sequence.TURN180
— Same asROTATE_180
.LARA_NORMAL
— Resets certain internal Lara parameters to default ones, including movement modes, FOV and camera position.FLOOR_SHAKE
— If entity producing this effect is in less than 8 sector range, send shake effect to camera. Shake effect is a variable which is inversely proportional to entity distance, and, when sent to camera, makes it shake with corresponding amplitude gradually fading out. If there are multiple FLOOR_SHAKE events constantly occuring nearby camera, shake effect won’t accumulate, but rather overwrite previous value.DINO_STOMP
— Same asFLOOR_SHAKE
.LARA_BUBBLES
— When underwater, emit bubble sound (ID #37) and produce bubble particle for Lara. Position of bubble is linked to model’s last mesh (which is headmesh in case of Lara).FINISH_LEVEL
— Same effect as TrigAction0x07
— immediately loads next level. For TR4, (which requires explicit level index to jump), current level index is increased and passed as level index to jump to.ACTIVATE_CAMERA
— If there is a trigger type Key (SubFunction0x03
) being queued at the moment, and there are any Camera TrigActions (0x01
) present inActionList
, these TrigActions will be forced to activate at a given frame of keyhole entity current animation, rather than at the ending frame of it. Works only for keyhole entities which have complex activation animations, not single-frame ones. It can be used to change camera POV before keyhole animation is finished.ACTIVATE_KEY
— Same as above, but works for Object TrigAction. That is, any entities to be activated fromActionList
will be activated at a given frame of keyhole entity current animation, rather than at the ending frame of it. Can be used to activate entities before actual keyhole animation is finished.LARA_HANDSFREE
— Functionally removes any weapon from Lara’s hands. If called during holstering or unholstering operation, immediately aborts it. Note that holstering animation won’t be automatically performed, and weapon model meshswaps won’t be swapped back to normal hands.DRAW_RIGHTGUN
— Swaps given entity’s mesh #10 index with same mesh’s index from PISTOLS_ANIM model (model ID #1 in all TR versions). Calling this effect again swaps mesh #10 back to native. Used primarily in cutscenes to create an illusion of Lara getting pistol in her right hand.DRAW_LEFTGUN
— Swaps given entity’s mesh #13 index with same mesh’s index from PISTOLS_ANIM model (model ID #1 in all TR versions). Calling this effect again swaps mesh #13 back to native. Used primarily in cutscenes to create an illusion of Lara getting pistol in her left hand.SHOOT_RIGHTGUN
— Activates given entity’s muzzle flash effect and dynamic light near mesh #10. Muzzle flash position and orientation, as well as effect duration and intensity is hardcoded. Used primarily in cutscenes.SHOOT_LEFTGUN
— Activates given entity’s muzzle flash effect and dynamic light near mesh #13. Muzzle flash position and orientation, as well as effect duration and intensity is hardcoded. Used primarily in cutscenes.MESH_SWAP1
— Swaps all given entity meshes with MESH_SWAP1 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.MESH_SWAP2
— Swaps all given entity meshes with MESH_SWAP2 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.MESH_SWAP3
— Swaps all given entity meshes with MESH_SWAP3 model meshes (model ID varies across TR versions). Each mesh is swapped only if source meshswap model mesh is not null, otherwise swap is ignored for a given mesh. Calling this flipeffect again swaps all meshes back to native. Used primarily in cutscenes.SWAP_CROWBAR
— Swaps given entity’s mesh #10 index with same mesh’s index from CROWBAR_ANIM model (either model ID #246 in TR4, or model ID #240 in TR5). Calling this flipeffect again swaps mesh #10 back to native. Used primarily in cutscenes to create an illusion of Lara getting crowbar in her hand.POURSWAP_ON
— Swaps given entity’s mesh #10 index with same mesh’s index from LARA_WATER_MESH model (TR4, modei ID #25). Used in Lara’s waterskin animations used in late TR4 levels with waterskin puzzle.POURSWAP_OFF
— Swaps given entity’s mesh #10 back to native. Used in Lara’s waterskin animations used in late TR4 levels with waterskin puzzle.INV_ON
— Hides given entity.INV_OFF
— Shows given entity, if it was hidden.DYN_ON
— Turns dynamic lights on for a given entity. Actual result is unclear.DYN_OFF
— Turns dynamic lights off for a given entity. Actual result is unclear.RESET_HAIR
— Presumably used to save Lara’s ponytail from potential stuck during cutscenes by resetting all hair parameters to “identity”.SETFOG
— When called by trigger action, changes global colour for volumetric fog effect. TakesTriggerSetup
Timer field as an index into hardcoded RGB table of colours (see this section for more info). If specified index is 100, engine temporarily turns off volumetric fog effect (possibly, this was used for debug purposes).GHOSTTRAP
— Kills all the living WRAITH3 entities (model ID #88 in TR4) this way: the wraith starts falling towards given entity. Reaching it or not, the wraith will die if it hits the floor of the room.CLEARSCARABS
— Removes all swarms of scarabs currently wandering in level.KILLACTIVEBADDIES
— Disable and remove all active NPCs from level.CLEAR_SPIDERS_PATCH
— Present only in TR5. It seems it’s same asKILLACTIVEBADDIES
, but some other processing is done. Never used in actual levels.RESET_TEST
— Present only in TR5. No visible or significant effect on gameplay. If there are any NPCs in level, then this flipeffect will fill certain memory zone with zero bytes. This flipeffect seems like last-minute fix-up for some memory leak bug. Used in RICH1.TRC level (The 13th Floor)LARALOCATION
— When activated, makes Guide NPC (TR4, model ID #37) or Von Croy NPC (TR4, model ID #39) to move to specific AI_FOLLOW object. TakesTriggerSetup
Timer field as an index to search for such OCB within AI objects array. When AI_FOLLOW AI object with same OCB index is found, NPC is then directed to this AI_FOLLOW object. This flipeffect also stores this index in additional global variable which is used to prevent NPC to get back to AI_FOLLOW objects with lower OCB indexes that were already passed — for example, if NPC already passed AI_FOLLOW with OCB 2, he won’t return to AI_FOLLOW with OCB 1, even if he hasn’t been there before.LARALOCATIONPAD
— Same action asLARALOCATION
, but with one difference - Timer field is checked for certain values to engage either specific soundtrack and/or cinematic dialogue with Von Croy NPC (for demonstration, look for Angkor Wat level walkthrough). This additional behaviour is hardcoded for TR4’s first level index only.ASSAULT_RESET
— Resets assault course clock (for ex., when Lara stepped out of assault course).ASSAULT_STOP
— Stops assault course clock.ASSAULT_START
— Starts assault course clock.ASSAULT_FINISHED
— Finishes assault course clock and fixes the record. Depending on record time, plays either unbeat record (“I’m sure you can do better”, track ID #24 in TR2) soundtrack or best record (“Gosh, that was my best time yet”, track ID #22 in TR2, #95 in TR3) soundtrack. Record time is hardcoded to 100 seconds in TR2 and to 180 seconds in TR3. In TR3, flipeffect also checks if all targets in shooting range were hit by Lara, and if not, applies penalty of 10 seconds for each unhit target. Also, TR3 lacks “unbeat record” soundtrack.ASSAULT_PENALTY_8
— 8-second penalty for losing track on assault course.ASSAULT_PENALTY_30
— 30-second penalty for losing track on assault course.RACETRACK_START
— Prepare racetrack timer for counting lap time. Only works when Lara is on a quadbike! As soon as quadbike leaves sector with this flipeffect, timer will start counting.RACETRACK_RESET
— Resets current lap time. Only works when Lara is on a quadbike!RACETRACK_FINISHED
— Finishes racetrack timer and fixes the record. Only works when Lara is on a quadbike!GYM_HINT_1-19
— Sequence of Lara’s voice hints on how to complete gym training. Reason why these are activated via flipeffects rather than normal soundtrack is they must be engaged in predefined order, e.g. voice hint #8 can’t play before #7 was played, and so on.GYM_HINT_RESET
— Resets gym training progress, so all voice hints will be played once again.TUT_HINT_1-12
— Sequence of Lara’s voice hints on how to complete tutorial on Streets of Rome (TR5). Setup is similar toGYM_HINT
flipeffects, but seems that there’s no reset flipeffect to restart tutorial.RAISINGBLOCK_FX
— Plays global sound with ID 117. Used in TR1, Palace Midas.CHAINBLOCK_FX
— Plays global sounds with ID 173 and ID 33 with predefined interval. Used in TR1, Tomb of Tihocan.EARTHQUAKE_FX
— Shakes screen violently and plays sounds with ID 99 and 70 globally with predefined intervals. Used in TR1, Palace Midas.STAIRS2SLOPE_FX
— Plays global sound with ID 119 with predefined delay. Used in TR1, City of Khamoon.SAND_FX
— Plays global sounds with ID 161, 118 and 155 with predefined intervals. Used in TR1, City of Khamoon.POWERUP_FX
— Plays global sound with ID 155 for 1 second. Presumably used in TR1, one of the Atlantis levels, but never appears on map.FLICKER_FX
— Flips alternate rooms back and forth several times with predefined intervals, creating illusion of flickering light. Used in TR1, first room of Atlantis.CHANDELIER_FX
— Plays global sound with ID 278 for 1 second. Used in TR2, Bartoli’s Hideout.BOILER_FX
— Plays global sound with ID 338. Used in TR2, Wreck of the Maria Doria.PISTON_FX
— Plays global sound with ID 190. Used in TR2, Living Quarters.CURTAIN_FX
— Plays global sound with ID 191. Used in TR2, Living Quarters.SET_CHANGE_FX
— Plays global sound with ID 330. Used in TR2, Opera House and Temple of Xian.STATUE_FX
— Plays global sound with ID 331. Used in TR2, Barkhang Monastery.RUBBLE_FX
— Plays global rumble sound FX and holds camera shake effect for some time, then finishes it with “shutting” sound. If there are any earthquake type objects in a level, engine engages same behaviour locally for these objects.TIMER_FIELD_FX
— If this flipeffect is called by trigger action, play global sound FX, takingTriggerSetup
Timer field as a sound ID.EXPLOSION_FX
— Plays global explosion sound (ID #105) and produce full-screen flash graphical FX (TR3-5) or camera shake effect (TR1-2).FLOOD_FX
— Plays global flooding sound (TR1 — ID #81, TR2 — ID #79, TR3 — ID #163, TR4 — ID #238). Implementation differs from version to version — in TR1 and TR2 looped waterfall sound is used (which is then stopped by an engine after 1 second), while in TR3 and TR4 one-shot sound is engaged.FOOTPRINT_FX
— Plays random footprint sound effect, taking current block's material index into consideration. On PlayStation, also applies footprint sprite under left or right Lara foot (target foot is selected based on packed flag which is stored in animcommand argument — look here for details).