{{indexmenu_n>8}}
====== 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 Business
* ''%%0x0000002D%%'' — Tomb Raider 2, Gold
* ''%%0xFF180038%%'' — Tomb Raider 3, Gold, Gold Title level
* ''%%0xFF080038%%'' — 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 5
* ''%%0x63345254%%'' (''TR4c'') — Tomb Raider 4 (demo versions)
Early TR4 demos (e.g. //September 15 demo//) have whole level file packed into a single zlib chunk. Therefore, there is no header.
TR5 version header is equal to TR4 version header. So there is no way to tell TR4 level from TR5 level judging only by this header — you need to check filename extension as well.
As it was noted, //retail// version of TR4 expects to load sound samples compressed in MS-ADPCM format, while //TRLE// version of TR4 loads uncompressed samples only. There is no way to tell //retail// version from //TRLE// version, as their version numbers are equal.
===== Palette =====
This consists of 256 [[trs:fundamentals#tr_colour|[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.
{{:icons:tr1.png?nolink|TR1 only}} 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.
{{anchor:tr_object_texture_vert}}
struct tr_object_texture_vert // 4 bytes
{
ufixed16 Xcoordinate;
ufixed16 Ycoordinate;
};
Actual texture coordinade format was unknown before the end of 2017, when //TE// developer MontyTRC uncovered that used format is similar to fixed-point format used for fractional values in animation structures, yet it uses 2 bytes instead of 4 (i.e. one byte for whole part and another for fractional part). However, since classic TR games built with native tools produced only whole coordinates (e.g. 64x64, 16x32, and so on) and there was no occurence of seeing fractional coordinates in levels, for many years it was believed that //low byte// in each field must always be of specific value (not 0 as expected, but either 1 or 255 which is probably caused by rounding error in Core's native conversion tools).
{{anchor:tr_object_texture}}
==== 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//: {{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} 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** — {{:icons:tr3.png?nolink|TR3 only}}{{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} Texture uses //alpha blending// with //additive operation//. No depth sorting is done on alpha-blended textures.
While blending modes 0, 1 and 2 were the only ones directly available for implementation in original level and animation editors, and therefore, only ones which can be encountered in object textures, there are actually several //internal blending modes//, which were primarily used for different sprite and particle types. These will be listed below:
* **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** — {{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} 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:
|{{:illustrations:bump-no.jpg?nolink|illustrations/bump-no.jpg}}|{{:illustrations:bump-yes.jpg?nolink|illustrations/bump-yes.jpg}}|
|//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 [[trs:file_formats#level_format_tr4|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.
{{anchor:tr4_object_texture}}
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 types ''0'' and ''1'' are actually used (''0'' being normal and ''1'' 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):
|{{:illustrations:mapping-correction.png?nolink|illustrations/mapping-correction.png}}|
|//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) or ''%%10 = 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.
{{:icons:tr5.png?nolink|TR5 only}} There is also null ''%%uint16_t%%'' filler in the end of each [[miscellany#tr4_object_texture|[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):
{{anchor:animated_textures}}
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:
|{{:illustrations:uvrotate.jpg?nolink|illustrations/uvrotate.jpg}} |
|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.
There is also special case when UVRotate texture mode is engaged. When a texture is applied to a model with specific ID (so-called //waterfall objects//), then it is also considered UVRotate animated texture, even if it doesn’t belong to animated texture range, //but only if it is a texture applied to a first face in the first mesh of the model//. If there are other textures applied to other faces of a waterfall object, they won’t be considered as UVRotate.
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.
{{anchor:tr_camera}}
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 [[trs:floordata#trigfunc_0x02|underwater current trigger action]].
===== Flyby Cameras =====
{{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} 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.
{{anchor:tr4_flyby_camera}}
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 | {{:icons:tr4.png?nolink|TR4 only}} Tracks specified entity position (from ''%%Entities[]%%'' array). |
^ ::: ^ ::: | {{:icons:tr5.png?nolink|TR5 only}} 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 | {{:icons:tr4.png?nolink|TR4 only}} Camera focuses on Lara’s last head position. |
^ ::: ^ ::: | {{:icons:tr5.png?nolink|TR5 only}} 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 | {{:icons:tr5.png?nolink|TR5 only}} Make screen fade-in. |
^ ''0x2000'' ^ 13 | {{:icons:tr5.png?nolink|TR5 only}} 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 | {{:icons:tr5.png?nolink|TR5 only}} 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.
{{:icons:tr1.png?nolink|TR1 only}} For each cutscene, game applies certain hardcoded set of parameters:
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).
{{anchor:tr_cinematic_frame}}
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 [[trs:meshes_models#tr_entity|[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.
{{anchor:flipeffects}}
===== Flipeffects =====
==== The Concept ====
As it was briefly mentioned [[trs:floordata#trigaction-0x09-flipeffect|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.
Continuous flipeffects are mostly present in TR1 and TR2. In TR3, only two “legacy” continuous flipeffects remained, and in TR4 and TR5 there are no continuous flipeffects at all. However, there’s still legacy code that checks if there’s any continuous flipeffect queued.
==== 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**.
As mentioned [[trs:mesh_construction_animation#animcommand-structure|here]], flipeffect could be called in two ways — either by an entity via //AnimCommand//, or by //trigger action//. However, there are certain flipeffect which strictly require caller entity ID to work with (see effect descriptions for that). In such case, if flipeffect is called by trigger action, //resulting outcome is undefined// in original engine. The most sane way to deal with this situation is to pass an ID of entity which activated given trigger.
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%%'' |
In original engines, all flipeffects which name begins with ''%%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 as ''%%ROTATE_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 as ''%%FLOOR_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 //TrigAction// ''%%0x07%%'' — 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.
* ''%%FLIP_MAP%%'' — Equal to [[trs:floordata#trigfunc_0x03|TrigAction ]]''[[trs:floordata#trigfunc_0x03|0x03]]''.
* ''%%ACTIVATE_CAMERA%%'' — If there is a trigger type //Key// (SubFunction ''%%0x03%%'') being queued at the moment, and there are any //Camera// TrigActions (''%%0x01%%'') present in ''%%ActionList%%'', 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 from ''%%ActionList%%'' 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. Takes ''%%TriggerSetup%%'' //Timer// field as an index into hardcoded RGB table of colours (see [[trs:room_geometry#fog_bulb|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 as ''%%KILLACTIVEBADDIES%%'', 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. Takes ''%%TriggerSetup%%'' //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 as ''%%LARALOCATION%%'', 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 to ''%%GYM_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. {{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} 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, taking ''%%TriggerSetup%%'' //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 — [[trs:mesh_construction_animation#animcommand-structure|look here]] for details).