Both sides previous revisionPrevious revisionNext revision | Previous revision |
trs:floordata [2017/02/02 19:56] – ↷ Links adapted because of a move operation stohrendorf | trs:floordata [2020/05/19 12:51] (current) – [Function 0x15] zdimension |
---|
| {{indexmenu_n>3}} |
| |
====== FloorData ====== | ====== FloorData ====== |
| |
Therefore, the //current [[trs:room_geometry#tr_room_sector|[tr_room_sector]]] offset// (not yet the FloorData pointer itself!) is calculated using this formula: | Therefore, the //current [[trs:room_geometry#tr_room_sector|[tr_room_sector]]] offset// (not yet the FloorData pointer itself!) is calculated using this formula: |
| |
$S_{Offset} = (((X_{current} - X_{room}) / 1024) \times n_{Zsectors}) + ((Z_{current} - Z_{room}) / 1024)$ | $S_{Offset} = \frac{X_{current} - X_{room}}{1024} \cdot n_{Zsectors} + \frac{Z_{current} - Z_{room}}{1024}$ |
| |
…where $X_{current}$ and $Z_{current}$ are current player positions, $X_{room}$ and $Z_{room}$ are corresponding [[trs:room_geometry#tr_room_info|tr_room_info.x]] and [[trs:room_geometry#tr_room_info|tr_room_info.z]] fields, and $n_{Zsectors}$ is [[trs:room_geometry#tr_room|tr_room.NumZsectors]] value. | …where $X_{current}$ and $Z_{current}$ are current player positions, $X_{room}$ and $Z_{room}$ are corresponding [[trs:room_geometry#tr_room_info|tr_room_info.x]] and [[trs:room_geometry#tr_room_info|tr_room_info.z]] fields, and $n_{Zsectors}$ is [[trs:room_geometry#tr_room|tr_room.NumZsectors]] value. |
</note> | </note> |
| |
| <note> |
| //Collisional floordata functions// should always come first in sequence, with floor collision function strictly being first and ceiling collision function strictly being second. The reason is hardcoded floordata collision parser which always expects these two functions to be first in sequence. |
| </note> |
| |
| |
^ Hex value ^ ''%%0x8000%%'' ^ ''%%0x7C00%%'' ^^^^^ ''%%0x03E0%%'' ^^^^^ ''%%0x001F%%'' ^^^^^ | ^ Hex value ^ ''%%0x8000%%'' ^ ''%%0x7C00%%'' ^^^^^ ''%%0x03E0%%'' ^^^^^ ''%%0x001F%%'' ^^^^^ |
^ Bit ^ 15 ^ 14 ^ 13 ^ 12 ^ 11 ^ 10 ^ 9 ^ 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ | ^ Bit ^ 15 ^ 14 ^ 13 ^ 12 ^ 11 ^ 10 ^ 9 ^ 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ |
^ Field | EndData | $H_{\triangle2}$ ||||| $H_{\triangle1}$ ||||| Function ||||| | ^ Field | ''%%EndData%%'' | $H_{\triangle2}$ ||||| $H_{\triangle1}$ ||||| ''%%Function%%'' ||||| |
| |
$H_{\triangle1}$ and $H_{\triangle2}$ are signed values, and replace ''%%FDSetup%%'''s ''%%SubFunction%%'' field. | $H_{\triangle1}$ and $H_{\triangle2}$ are signed values, and replace ''%%FDSetup%%'''s ''%%SubFunction%%'' field. |
=== The Triangulation Formula === | === The Triangulation Formula === |
| |
The idea behind this set up is dividing each sector rectangle into //two independent triangles//, and adjust each triangle height by combination of //corner// and //triangle// heights. To get each triangle’s individual corner height, you shoroom_geometryuld use this formula: | The idea behind this set up is dividing each sector rectangle into //two independent triangles//, and adjust each triangle height by combination of //corner// and //triangle// heights. To get each triangle’s individual corner height, you should use this formula: |
| |
$H_{\angle} = H_{floor} + (\max(\Delta C_{10}, \Delta C_{00}, \Delta C_{01}, \Delta C_{11}) - \Delta C_{n} \times 1024 )$ | $H_{\angle} = H_{floor} + (\max(\Delta C_{10}, \Delta C_{00}, \Delta C_{01}, \Delta C_{11}) - \Delta C_{n} \cdot 1024 )$ |
| |
…where $H_{\angle}$ is //absolute floor height// specified in [[trs:room_geometry#tr_room_sector|[tr_room_sector]]]'s ''%%Floor%%'' field, and $\Delta C_{n}$ is triangle’s individual corner height. | …where $H_{\angle}$ is //absolute floor height// specified in [[trs:room_geometry#tr_room_sector|[tr_room_sector]]]'s ''%%Floor%%'' field, and $\Delta C_{n}$ is triangle’s individual corner height. |
The way engine interprets //triangle height values// $H_{\triangle1}$ and $H_{\triangle2}$ is not exactly known — however, //meta2tr// understands them and uses them to create so-called //diagonal steps//, example of which is pictured on the left side. There is no case of diagonal steps in original games, but they may exist in levels edited with //meta2tr//. | The way engine interprets //triangle height values// $H_{\triangle1}$ and $H_{\triangle2}$ is not exactly known — however, //meta2tr// understands them and uses them to create so-called //diagonal steps//, example of which is pictured on the left side. There is no case of diagonal steps in original games, but they may exist in levels edited with //meta2tr//. |
| |
Overall, there are 12 different triangulation functions, which can be divided into two pairs of groups — one pair of groups is for floor, and another pair is for ceiling. Each pair is categorized by //split direction//, and each group is categorized if it’s floor or ceiling. In each group, there are three functions — first function denotes that //both// triangles in sector are solid, second and third functions denote that //one of triangles is a collisional vertical room_geometryportal//. When function denotes a vertical portal, target room of a portal is taken from [[trs:room_geometry#tr_room_sector|[tr_room_sector]]] structure — ''%%RoomBelow%%'' for floor functions, and ''%%RoomAbove%%'' for ceiling functions. | Overall, there are 12 different triangulation functions, which can be divided into two pairs of groups — one pair of groups is for floor, and another pair is for ceiling. Each pair is categorized by //split direction//, and each group is categorized if it’s floor or ceiling. In each group, there are three functions — first function denotes that //both// triangles in sector are solid, second and third functions denote that //one of triangles is a collisional vertical portal//. When function denotes a vertical portal, target room of a portal is taken from [[trs:room_geometry#tr_room_sector|[tr_room_sector]]] structure — ''%%RoomBelow%%'' for floor functions, and ''%%RoomAbove%%'' for ceiling functions. |
| |
Here is an example illustration depicting sectors with all possible floor triangulation functions. Ceiling triangulation happens in similar manner. | Here is an example illustration depicting sectors with all possible floor triangulation functions. Ceiling triangulation happens in similar manner. |
{{:icons:tr3.png?nolink|TR3 only}}{{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} This function has a different meaning in TR3 and TR4/5. | {{:icons:tr3.png?nolink|TR3 only}}{{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} This function has a different meaning in TR3 and TR4/5. |
| |
* In TR3, if Lara approaches sector with this FloorData function inside //minecart// vehicle, it will turn //left// 90 degrees, with a circle radius around 4 sectors (4096 units in world coordinates). | * In TR3, if Lara approaches sector with this FloorData function inside //minecart// vehicle, it will turn //left// 90 degrees, with a circle radius around 4 sectors (4096 units in world coordinates). If both this and ''0x15'' functions are set for a given sector, minecart will //stop// there. |
* In TR4 and TR5, this function is used together with special entity called //Trigger Triggerer//. The purpose of this entity is to perform //deferred triggering//. That is, if //trigger// FloorData function is placed in the same sector with function ''%%0x14%%'', trigger won’t be activated until there’s an activated //Trigger Triggerer// object in the same sector. This allows to create setups where player can cross trigger sector without activating it, until some other event occurs later in level. | * In TR4 and TR5, this function is used together with special entity called //Trigger Triggerer//. The purpose of this entity is to perform //deferred triggering//. That is, if //trigger// FloorData function is placed in the same sector with function ''%%0x14%%'', trigger won’t be activated until there’s an activated //Trigger Triggerer// object in the same sector. This allows to create setups where player can cross trigger sector without activating it, until some other event occurs later in level. |
| |
{{:icons:tr3.png?nolink|TR3 only}}{{:icons:tr4.png?nolink|TR4 only}} This function has a different meaning in TR3 and TR4. | {{:icons:tr3.png?nolink|TR3 only}}{{:icons:tr4.png?nolink|TR4 only}} This function has a different meaning in TR3 and TR4. |
| |
* In TR3, if Lara approaches sector with this FloorData function inside //minecart// vehicle, it will turn //right// 90 degrees, with a circle radius around 4 sectors (4096 units in world coordinates). | * In TR3, if Lara approaches sector with this FloorData function inside //minecart// vehicle, it will turn //right// 90 degrees, with a circle radius around 4 sectors (4096 units in world coordinates). If both this and ''0x14'' functions are set for a given sector, minecart will //stop// there. |
* In TR4, this function is used together with special entity called //Mapper//. If //Mechanical Beetle// is placed in sector with function ''%%0x15%%'' and inactive //Mapper// entity, it rotates in the same direction //Mapper// is pointing to, activates it, and then rolls forward, until next sector with function ''%%0x15%%'' is reached. Then it waits until Lara picks it up. | * In TR4, this function is used together with special entity called //Mapper//. If //Mechanical Beetle// is placed in sector with function ''%%0x15%%'' and inactive //Mapper// entity, it rotates in the same direction //Mapper// is pointing to, activates it, and then rolls forward, until next sector with function ''%%0x15%%'' is reached. Then it waits until Lara picks it up. |
| |
''%%ActionList%%'' entry format is: | ''%%ActionList%%'' entry format is: |
| |
|''%%Parameter%%'' |bits 0..9 (''%%0x03FF%%'') //-- Used bytes may vary//| | ^ Hex value ^ ''%%0x8000%%'' ^ ''%%0x7C00%%'' ^^^^^ ''%%0x03FF%%'' ^^^^^^^^^^ |
|''%%TrigAction%%''|bits 10..14 (''%%0x7C00%%'') | | ^ Bit ^ 15 ^ 14 ^ 13 ^ 12 ^ 11 ^ 10 ^ 9 ^ 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ |
|''%%ContBit%%'' |bit 15 (''%%0x8000%%'') | | ^ Field | ''%%ContBit%%'' | ''%%TrigAction%%'' ||||| ''%%Parameter%%'' — //used bytes may vary// |||||||||| |
| |
''%%TrigAction%%'' is a type of action to be performed. These will be listed seperately. | ''%%TrigAction%%'' is a type of action to be performed. These will be listed seperately. |
Camera trigger action //uses one extra ''%%uint16_t%%'' entry// after its own entry! Its format is: | Camera trigger action //uses one extra ''%%uint16_t%%'' entry// after its own entry! Its format is: |
| |
|''%%Timer%%'' |bits 0..7 (''%%0x00FF%%'') | | ^ Hex value ^ ''%%0x8000%%'' ^^ ''%%0x3E00%%'' ^^^^^ ''%%0x0100%%'' ^ ''%%0x0FF%%'' ^^^^^^^^ |
|''%%Once%%'' |bit 8 (''%%0x0100%%'') | | ^ Bit ^ 15 ^ 14 ^ 13 ^ 12 ^ 11 ^ 10 ^ 9 ^ 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ 3 ^ 2 ^ 1 ^ 0 ^ |
|''%%MoveTimer%%''|bits 9..13 (''%%0x3E00%%'')| | ^ Field | ''%%ContBit%%'' || ''%%MoveTimer%%'' ||||| ''%%Once%%'' | ''%%Timer%%'' |||||||| |
|''%%ContBit%%'' |bit 15 (''%%0x8000%%'') | | |
</note> | </note> |
| |
{{:icons:tr4.png?nolink|TR4 only}} In TR4, so called “hub system” was implemented, which allows Lara to jump between levels back and forth. For this reason, ''%%Parameter%%'' field must also explicitly specify level index to jump. | {{:icons:tr4.png?nolink|TR4 only}} In TR4, so called “hub system” was implemented, which allows Lara to jump between levels back and forth. For this reason, ''%%Parameter%%'' field must also explicitly specify level index to jump. |
| |
{{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} Also, since TR4 Lara can have multiple start positions for each level, so ''%%Timer%%'' field in ''%%TriggerSetup%%'' entry specifies an OCB of //lara start posision AI object// to warp Lara to. That is, if there’s an end level trigger with value ''%%3%%'' in ''%%Timer%%'' field, it means that Lara will be warped to first //start position AI object// with number 3 specified in its OCB. For more info on AI objects, refer to [[trs:npc_behaviour#ai-objects|this section]]. | {{:icons:tr4.png?nolink|TR4 only}}{{:icons:tr5.png?nolink|TR5 only}} Also, since TR4 Lara can have multiple start positions for each level, so ''%%Timer%%'' field in ''%%TriggerSetup%%'' entry specifies an index of //lara start posision AI object// in AI objects array to warp Lara to. That is, if there’s an end level trigger with value ''%%3%%'' in ''%%Timer%%'' field, it means that Lara will be warped to third //start position AI object// in AI objects array. For more info on AI objects, refer to [[trs:npc_behaviour#ai-objects|this section]]. |
| |
==== TrigAction 0x08 — Play Soundtrack ==== | ==== TrigAction 0x08 — Play Soundtrack ==== |