Merge branch 'develop'

This commit is contained in:
Jakub 2024-11-03 12:35:58 +00:00
commit d81fce22ad
503 changed files with 17812 additions and 11349 deletions

View file

@ -1,12 +1,94 @@
# Changelog # Changelog
Here you will find the full changelog of TEN's releases from Version 1.0 and up The dates are in European standard format where date is presented as **YYYY-MM-DD**.
TombEngine releases are located in this repository (alongside with Tomb Editor): https://github.com/TombEngine/TombEditorReleases
The dates are in European standard format where date is presented as **YYYY-MM-DD** ## Version 1.5 - xxxx-xx-xx
### Bug fixes
* Fixed original issue with classic switch off trigger incorrectly activating some trigger actions.
* Fixed moveable status after antitriggering.
* Fixed leveljump vehicle transfer.
* Fixed weapons not properly hitting enemies.
* Fixed falling through dynamic bridges that are moving upwards.
* Fixed Laserhead teleporting Lara and making her invisible on death.
* Fixed pick-ups from Sarcophagus objects.
* Fixed issue with Lara not rotating together with bridges while picking up items.
* Fixed ghost collision with objects with zero bounds.
* Fixed several binocular bugs.
* Fixed faulty death sectors.
* Fixed shimmy softlocks around static meshes with soft collision.
* Fixed incorrect swing ledge grabs with steep grab angles.
* Fixed incorrect climbing out of water on bridge objects and in front of static meshes.
* Fixed incorrect diving animation when swandiving from a high place.
* Fixed room clipping when flyby path goes out of room bounds.
* Fixed camera rotating with the player's hips when climbing out of water.
* Fixed camera behaviour on sloped surfaces after player's death.
* Fixed camera position after loading a savegame.
* Fixed broken ropes after loading a savegame.
* Fixed AI for TR2 Skidoo driver and Worker with shotgun.
* Fixed Ember Emitter crashing when ocb is between -1 and -10.
* Fixed Electric Cleaner and Squishy Block not detecting collision with certain block heights.
* Fixed Squishy Blocks crashing the level.
* Fixed Larson and Pierre pathfinding.
* Fixed Dart Emitters failing with antitrigger.
* Fixed Homing Dart Emitter spawning darts continously when player is on its trigger.
* Fixed Four Blade Trap floor and ceiling collision.
* Fixed Joby Spikes collision and deformation.
* Fixed Sentry Gun joint rotation.
* Fixed Teeth Spikes not triggering the player impale animation.
* Fixed TR4 Mine crash with OCB 1 when triggered.
* Fixed cases where Atlantean Mutant's bombs cause the game to crash.
* Fixed torch flame delay when the player throws or drops a torch.
* Fixed display sprites and display strings rendering in the inventory background.
* Fixed young Lara hair drawing. https://tombengine.com/docs/level-settings/#young_lara
### Features/Amendments
* Added high framerate mode (also known as 60 FPS mode).
* Added a customisable global lensflare effect. https://tombengine.com/docs/level-settings/#lensflare
* Added a customisable starry sky and meteor effect. https://tombengine.com/docs/level-settings/#stars
* Added the ability to display "Lara's Home" entry in the main menu.
* Added the ability to change pickup item count by modifying item hit points.
* Added F12 as alternative to PrtSc for screenshots.
* Added ability to invoke load game dialog after death by pressing any key.
* Added visible mouse pointer in windowed mode.
* Added portal debug mode.
* Added new sound conditions: Quicksand and Underwater.
- Quicksand - sound effect plays when a moveable is in quicksand.
- Underwater - sound plays when the camera is submerged.
* Added TR3 Seal Mutant. https://tombengine.com/docs/ocb-and-setup-instructions/#sealmutant
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Seal_Mutant.wad2
* Added TR4 Enemy Jeep. https://tombengine.com/docs/ocb-and-setup-instructions/#enemy_jeep
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TR4_Enemy_Jeep.wad2
* Changed TR5 Rome Hammer to not hurt player whilst deactivated.
* Changed TR2 Statue with blade damage from 20 to 200.
* Changed sound effect that is triggered when using the `level.rumble` feature in a level (ID 359 in the soundmap).
* Changed hardcoded sound for Raising Block 1/2 back to the ID used in TRLE (ID 149).
* Enhanced TR2 Rolling Spindle detection to avoid them going down through pits.
* Enhanced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns (Puzzle Item 5 by default).
* Enhanced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots (by default 32 in Dart Emitter, and 24 in Homing-Dart Emitter).
* Enhanced Raptor behaviour and handling. https://tombengine.com/docs/ocb-and-setup-instructions/#raptor
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Raptor.wad2
* Removed original limit of 32 active Flame Emitters.
### Lua API changes
* Added Flow.EnableHomeLevel() function.
* Added Flow.IsStringPresent() function.
* Added Flow.LensFlare() and Flow.Starfield() classes.
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
* Added Input.KeyClearAll() function.
* Added Moveable.GetJointRotation() and optional 'offset' parameter for Moveable.GetJointPosition().
* Added Moveable.GetTargetState() function.
* Added Room:GetRoomNumber() function.
* Removed anims.monkeyAutoJump. It is now a player menu configuration.
* Fixed Volume:GetActive() method.
## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21 ## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21
### Bug Fixes ### Bug fixes
* Fixed drawing of display sprites in title level. * Fixed drawing of display sprites in title level.
* Fixed drawing of smoke sprites and various other sprites. * Fixed drawing of smoke sprites and various other sprites.
* Fixed drawing of transparent surfaces when debris are present in scene. * Fixed drawing of transparent surfaces when debris are present in scene.
@ -49,7 +131,7 @@ The dates are in European standard format where date is presented as **YYYY-MM-D
## [Version 1.3](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7) - 2024-01-06 ## [Version 1.3](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7) - 2024-01-06
### Bug Fixes ### Bug fixes
* Fixed crash if title logo is removed from Textures folder. * Fixed crash if title logo is removed from Textures folder.
* Fixed crash if unknown player state ID is encountered. * Fixed crash if unknown player state ID is encountered.
* Fixed bug with OCB 2 on pushables, and some other pushable bugs. * Fixed bug with OCB 2 on pushables, and some other pushable bugs.
@ -105,7 +187,7 @@ The dates are in European standard format where date is presented as **YYYY-MM-D
## [Version 1.2](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.9) - 2023-11-11 ## [Version 1.2](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.9) - 2023-11-11
### Bug Fixes ### Bug fixes
* Fix burning torch not working properly if there are more than 256 objects in a level. * Fix burning torch not working properly if there are more than 256 objects in a level.
* Fix grenade and rocket projectiles smoke offset in certain directions. * Fix grenade and rocket projectiles smoke offset in certain directions.
* Fix projectiles flying through animating objects. * Fix projectiles flying through animating objects.
@ -133,24 +215,24 @@ The dates are in European standard format where date is presented as **YYYY-MM-D
### Features/Amendments ### Features/Amendments
* Improve head-on wall collision. * Improve head-on wall collision.
* Overhaul pushables: * Overhaul pushables:
- Separate climbable and non-climbable pushable object slots. - Separate climbable and non-climbable pushable object slots.
- Add new pushable OCB to manipulate pushable properties. - Add new pushable OCB to manipulate pushable properties.
- Add new animations for pushing pushables off edgees (TR1-3 and TR4-5 versions). - Add new animations for pushing pushables off edgees (TR1-3 and TR4-5 versions).
- Fix pushables not working with raising blocks. - Fix pushables not working with raising blocks.
- Fix miscellaneous pushable bugs. - Fix miscellaneous pushable bugs.
* Overhaul look-around feature: * Overhaul look-around feature:
- Allow for more consistent and wider viewing angles while crawling, crouching, and hanging. - Allow for more consistent and wider viewing angles while crawling, crouching, and hanging.
- Improve look camera movement and control. - Improve look camera movement and control.
- Re-enable looking while performing up jump, backward jump, or backward crawl. - Re-enable looking while performing up jump, backward jump, or backward crawl.
- Add functionality to rotate slowly when holding Walk while using binoculars or lasersight. - Add functionality to rotate slowly when holding Walk while using binoculars or lasersight.
* Add target highlighter system with toggle in Sound and Gameplay settings. * Add target highlighter system with toggle in Sound and Gameplay settings.
* Add sprint slide state 191. * Add sprint slide state 191.
* Add swinging blade. * Add swinging blade.
* Add crumbling platform and add new OCBs for behaviour: * Add crumbling platform and add new OCBs for behaviour:
- OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds. - OCB 0: Default behaviour. When the player steps on the platform, it will shake and crumble after 1.2 seconds.
- OCB > 0: When the player steps on the platform, it will crumble after the number of frames set in the OCB. - OCB > 0: When the player steps on the platform, it will crumble after the number of frames set in the OCB.
- A positive value results in activation via player collision. - A positive value results in activation via player collision.
- A negative value requires a trigger to activate. - A negative value requires a trigger to activate.
* Add basic mouse input handling. Allows for binding of mouse inputs in control settings. * Add basic mouse input handling. Allows for binding of mouse inputs in control settings.
* Add settings for Mouse Sensitivity and Mouse Smoothing (not used in-game yet). * Add settings for Mouse Sensitivity and Mouse Smoothing (not used in-game yet).
@ -182,7 +264,7 @@ The dates are in European standard format where date is presented as **YYYY-MM-D
## [Version 1.1.0](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.8) - 2023-07-29 ## [Version 1.1.0](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.8) - 2023-07-29
### Bug Fixes ### Bug fixes
* Fix enemies shooting Lara through static meshes and moveables. * Fix enemies shooting Lara through static meshes and moveables.
* Fix skeletons and mummies not being affected by explosive weapons. * Fix skeletons and mummies not being affected by explosive weapons.
* Fix crash on loading if static meshes with IDs above maximum are present. * Fix crash on loading if static meshes with IDs above maximum are present.
@ -393,7 +475,7 @@ The dates are in European standard format where date is presented as **YYYY-MM-D
## [Version 1.0.6](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.4) - 2023-01-29 ## [Version 1.0.6](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.4) - 2023-01-29
### Bug FIxes ### Bug fixes
* Fix major pathfinding bug which could have caused lots of issues with enemy behaviour. * Fix major pathfinding bug which could have caused lots of issues with enemy behaviour.
* Fix potential random crashes due to incorrect rendering behaviour. * Fix potential random crashes due to incorrect rendering behaviour.
* Fix savegame crash for disabled enemies with partially set activation mask. * Fix savegame crash for disabled enemies with partially set activation mask.

View file

@ -12,7 +12,7 @@ new_type("luautil", "5 Lua utility modules", true)
not_luadoc = true not_luadoc = true
local version = "1.4" local version = "1.5"
project = "TombEngine" project = "TombEngine"
title = "TombEngine " .. version .. " Lua API" title = "TombEngine " .. version .. " Lua API"
description = "TombEngine " .. version .. " scripting interface" description = "TombEngine " .. version .. " scripting interface"

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -129,6 +131,10 @@ scripts too.</p>
<td class="summary">Enable or disable level selection in title flyby.</td> <td class="summary">Enable or disable level selection in title flyby.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#EnableHomeLevel">EnableHomeLevel(enabled)</a></td>
<td class="summary">Enable or disable Home Level entry in the main menu.</td>
</tr>
<tr>
<td class="name" ><a href="#EnableLoadSave">EnableLoadSave(enabled)</a></td> <td class="name" ><a href="#EnableLoadSave">EnableLoadSave(enabled)</a></td>
<td class="summary">Enable or disable saving and loading of savegames.</td> <td class="summary">Enable or disable saving and loading of savegames.</td>
</tr> </tr>
@ -137,7 +143,7 @@ scripts too.</p>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" ><a href="#EnableFlyCheat">EnableFlyCheat(enabled)</a></td> <td class="name" ><a href="#EnableFlyCheat">EnableFlyCheat(enabled)</a></td>
<td class="summary">Enable or disable DOZY mode (fly cheat).</td> <td class="summary">Enable or disable the fly cheat.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#EnablePointFilter">EnablePointFilter(enabled)</a></td> <td class="name" ><a href="#EnablePointFilter">EnablePointFilter(enabled)</a></td>
@ -230,6 +236,10 @@ scripts too.</p>
<td class="summary">Get translated string.</td> <td class="summary">Get translated string.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#IsStringPresent">IsStringPresent(string)</a></td>
<td class="summary">Check if translated string is present.</td>
</tr>
<tr>
<td class="name" ><a href="#SetLanguageNames">SetLanguageNames(table)</a></td> <td class="name" ><a href="#SetLanguageNames">SetLanguageNames(table)</a></td>
<td class="summary">Set language names for translations.</td> <td class="summary">Set language names for translations.</td>
</tr> </tr>
@ -363,11 +373,11 @@ Must be true or false
</dd> </dd>
<dt> <dt>
<a name = "EnableLoadSave"></a> <a name = "EnableHomeLevel"></a>
<strong>EnableLoadSave(enabled)</strong> <strong>EnableHomeLevel(enabled)</strong>
</dt> </dt>
<dd> <dd>
Enable or disable saving and loading of savegames. Enable or disable Home Level entry in the main menu. ()
@ -375,7 +385,29 @@ Must be true or false
<ul> <ul>
<li><span class="parameter">enabled</span> <li><span class="parameter">enabled</span>
<span class="types"><span class="type">bool</span></span> <span class="types"><span class="type">bool</span></span>
true or false. True or false.
</li>
</ul>
</dd>
<dt>
<a name = "EnableLoadSave"></a>
<strong>EnableLoadSave(enabled)</strong>
</dt>
<dd>
Enable or disable saving and loading of savegames. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">enabled</span>
<span class="types"><span class="type">bool</span></span>
True or false.
</li> </li>
</ul> </ul>
@ -393,8 +425,7 @@ Must be true or false
<strong>EnableFlyCheat(enabled)</strong> <strong>EnableFlyCheat(enabled)</strong>
</dt> </dt>
<dd> <dd>
Enable or disable DOZY mode (fly cheat). Enable or disable the fly cheat. ()
Must be true or false
@ -402,7 +433,7 @@ Must be true or false
<ul> <ul>
<li><span class="parameter">enabled</span> <li><span class="parameter">enabled</span>
<span class="types"><span class="type">bool</span></span> <span class="types"><span class="type">bool</span></span>
true or false True or false.
</li> </li>
</ul> </ul>
@ -902,6 +933,28 @@ You will not need to call them manually.
</dd>
<dt>
<a name = "IsStringPresent"></a>
<strong>IsStringPresent(string)</strong>
</dt>
<dd>
Check if translated string is present.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">string</span>
<span class="types"><span class="type">key</span></span>
key for translated string
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "SetLanguageNames"></a> <a name = "SetLanguageNames"></a>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -129,6 +131,10 @@
<td class="summary">Clear an action key.</td> <td class="summary">Clear an action key.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#KeyClearAll">KeyClearAll()</a></td>
<td class="summary">Clear all action keys.</td>
</tr>
<tr>
<td class="name" ><a href="#GetMouseDisplayPosition">GetMouseDisplayPosition()</a></td> <td class="name" ><a href="#GetMouseDisplayPosition">GetMouseDisplayPosition()</a></td>
<td class="summary">Get the display position of the cursor in percent.</td> <td class="summary">Get the display position of the cursor in percent.</td>
</tr> </tr>
@ -254,6 +260,21 @@
</dd>
<dt>
<a name = "KeyClearAll"></a>
<strong>KeyClearAll()</strong>
</dt>
<dd>
Clear all action keys.
</dd> </dd>
<dt> <dt>
<a name = "GetMouseDisplayPosition"></a> <a name = "GetMouseDisplayPosition"></a>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -124,6 +126,18 @@
<td class="name" ><a href="#SetItemCount">SetItemCount(objectID, count)</a></td> <td class="name" ><a href="#SetItemCount">SetItemCount(objectID, count)</a></td>
<td class="summary">Set the amount of an item in the player's inventory.</td> <td class="summary">Set the amount of an item in the player's inventory.</td>
</tr> </tr>
<tr>
<td class="name" ><a href="#GetUsedItem">GetUsedItem()</a></td>
<td class="summary">Get last item used in the player's inventory.</td>
</tr>
<tr>
<td class="name" ><a href="#SetUsedItem">SetUsedItem(objectID)</a></td>
<td class="summary">Set last item used in the player's inventory.</td>
</tr>
<tr>
<td class="name" ><a href="#ClearUsedItem">ClearUsedItem()</a></td>
<td class="summary">Clear last item used in the player's inventory.</td>
</tr>
</table> </table>
<br/> <br/>
@ -245,6 +259,70 @@
</dd>
<dt>
<a name = "GetUsedItem"></a>
<strong>GetUsedItem()</strong>
</dt>
<dd>
Get last item used in the player's inventory.
This value will be valid only for a single frame after exiting inventory, after which Lara says "No".
Therefore, this function must be preferably used either in OnLoop or OnUseItem events.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../4 enums/Objects.ObjID.html#">ObjID</a></span>
Last item used in the inventory.
</ol>
</dd>
<dt>
<a name = "SetUsedItem"></a>
<strong>SetUsedItem(objectID)</strong>
</dt>
<dd>
Set last item used in the player's inventory.
You will be able to specify only objects which already exist in the inventory.
Will only be valid for the next frame. If not processed by the game, Lara will say "No".
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">objectID</span>
<span class="types"><a class="type" href="../4 enums/Objects.ObjID.html#">ObjID</a></span>
Object ID of the item to select from inventory.
</li>
</ul>
</dd>
<dt>
<a name = "ClearUsedItem"></a>
<strong>ClearUsedItem()</strong>
</dt>
<dd>
Clear last item used in the player's inventory.
When this function is used in OnUseItem level function, it allows to override existing item functionality.
For items without existing functionality, this function is needed to avoid Lara saying "No" after using it.
</dd> </dd>
</dl> </dl>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -263,7 +265,8 @@ LOAD
SAVE SAVE
START START
END END
LOOP</pre> LOOP
USEITEM</pre>
<h3>Parameters:</h3> <h3>Parameters:</h3>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -109,7 +111,7 @@
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" ><a href="#ShowString">ShowString(str, time)</a></td> <td class="name" ><a href="#ShowString">ShowString(str, time, autoDelete)</a></td>
<td class="summary">Show some text on-screen.</td> <td class="summary">Show some text on-screen.</td>
</tr> </tr>
<tr> <tr>
@ -131,7 +133,7 @@
<dl class="function"> <dl class="function">
<dt> <dt>
<a name = "ShowString"></a> <a name = "ShowString"></a>
<strong>ShowString(str, time)</strong> <strong>ShowString(str, time, autoDelete)</strong>
</dt> </dt>
<dd> <dd>
Show some text on-screen. Show some text on-screen.
@ -151,6 +153,13 @@ If not given, the string will have an "infinite" life, and will show
until <a href="../1 modules/Strings.html#HideString">HideString</a> is called or until the level is finished. until <a href="../1 modules/Strings.html#HideString">HideString</a> is called or until the level is finished.
Default: nil (i.e. infinite) Default: nil (i.e. infinite)
</li> </li>
<li><span class="parameter">autoDelete</span>
<span class="types"><span class="type">bool</span></span>
should be string automatically deleted after timeout is reached.
If not given, the string will remain allocated even after timeout is reached, and can be
shown again without re-initialization.
Default: false
</li>
</ul> </ul>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <here>Flow.Animations</here></li> <li> <here>Flow.Animations</here></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <here>Flow.Fog</here></li> <li> <here>Flow.Fog</here></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <here>Flow.InventoryItem</here></li> <li> <here>Flow.InventoryItem</here></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -0,0 +1,397 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>TombEngine</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>1 Modules</h2>
<ul class="nowrap">
<li> <a href="../1 modules/Effects.html">Effects</a></li>
<li> <a href="../1 modules/Flow.html">Flow</a></li>
<li> <a href="../1 modules/Input.html">Input</a></li>
<li> <a href="../1 modules/Inventory.html">Inventory</a></li>
<li> <a href="../1 modules/Logic.html">Logic</a></li>
<li> <a href="../1 modules/Objects.html">Objects</a></li>
<li> <a href="../1 modules/Sound.html">Sound</a></li>
<li> <a href="../1 modules/Strings.html">Strings</a></li>
<li> <a href="../1 modules/Util.html">Util</a></li>
<li> <a href="../1 modules/View.html">View</a></li>
</ul>
<h2>2 Classes</h2>
<ul class="nowrap">
<li> <a href="../2 classes/View.DisplaySprite.html">View.DisplaySprite</a></li>
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <here>Flow.LensFlare</here></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
<li> <a href="../2 classes/Objects.Moveable.html">Objects.Moveable</a></li>
<li> <a href="../2 classes/Objects.Room.html">Objects.Room</a></li>
<li> <a href="../2 classes/Objects.Sink.html">Objects.Sink</a></li>
<li> <a href="../2 classes/Objects.SoundSource.html">Objects.SoundSource</a></li>
<li> <a href="../2 classes/Objects.Static.html">Objects.Static</a></li>
<li> <a href="../2 classes/Objects.Volume.html">Objects.Volume</a></li>
<li> <a href="../2 classes/Strings.DisplayString.html">Strings.DisplayString</a></li>
</ul>
<h2>3 Primitive Classes</h2>
<ul class="nowrap">
<li> <a href="../3 primitive classes/Color.html">Color</a></li>
<li> <a href="../3 primitive classes/Rotation.html">Rotation</a></li>
<li> <a href="../3 primitive classes/Vec2.html">Vec2</a></li>
<li> <a href="../3 primitive classes/Vec3.html">Vec3</a></li>
</ul>
<h2>4 Enums</h2>
<ul class="nowrap">
<li> <a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li> <a href="../4 enums/Effects.EffectID.html">Effects.EffectID</a></li>
<li> <a href="../4 enums/Flow.GameStatus.html">Flow.GameStatus</a></li>
<li> <a href="../4 enums/Input.ActionID.html">Input.ActionID</a></li>
<li> <a href="../4 enums/Objects.AmmoType.html">Objects.AmmoType</a></li>
<li> <a href="../4 enums/Objects.MoveableStatus.html">Objects.MoveableStatus</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li>
<li> <a href="../4 enums/Objects.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
<li> <a href="../4 enums/Sound.SoundTrackType.html">Sound.SoundTrackType</a></li>
<li> <a href="../4 enums/Util.LogLevel.html">Util.LogLevel</a></li>
<li> <a href="../4 enums/View.AlignMode.html">View.AlignMode</a></li>
<li> <a href="../4 enums/View.CameraType.html">View.CameraType</a></li>
<li> <a href="../4 enums/View.PostProcessMode.html">View.PostProcessMode</a></li>
<li> <a href="../4 enums/View.ScaleMode.html">View.ScaleMode</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li> <a href="../5 lua utility modules/EventSequence.html">EventSequence</a></li>
<li> <a href="../5 lua utility modules/Timer.html">Timer</a></li>
</ul>
</div>
<div id="content">
<h1>Class <code>Flow.LensFlare</code></h1>
<p>Represents a lens flare.</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#LensFlare">LensFlare(Pitch, Yaw, Color.)</a></td>
<td class="summary">Create a LensFlare object.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:GetEnabled">LensFlare:GetEnabled()</a></td>
<td class="summary">Get the lens flare's enabled status.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:GetSunSpriteID">LensFlare:GetSunSpriteID()</a></td>
<td class="summary">Get the sun's sprite ID.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:GetPitch">LensFlare:GetPitch()</a></td>
<td class="summary">Get the lens flare's pitch angle in degrees.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:GetYaw">LensFlare:GetYaw()</a></td>
<td class="summary">Get the lens flare's yaw angle in degrees.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:SetColor">LensFlare:SetColor()</a></td>
<td class="summary">Get the lens flare's color.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:SetSunSpriteID">LensFlare:SetSunSpriteID(New)</a></td>
<td class="summary">Set the lens flare's sun sprite ID.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:SetPitch">LensFlare:SetPitch(New)</a></td>
<td class="summary">Set the lens flare's pitch angle.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:SetYaw">LensFlare:SetYaw(New)</a></td>
<td class="summary">Set the lens flare's yaw angle.</td>
</tr>
<tr>
<td class="name" ><a href="#LensFlare:SetColor">LensFlare:SetColor(New)</a></td>
<td class="summary">Set the lens flare's color.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "LensFlare"></a>
<strong>LensFlare(Pitch, Yaw, Color.)</strong>
</dt>
<dd>
Create a LensFlare object. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">Pitch</span>
<span class="types"><span class="type">float</span></span>
angle in degrees.
</li>
<li><span class="parameter">Yaw</span>
<span class="types"><span class="type">float</span></span>
angle in degrees.
</li>
<li><span class="parameter">Color.</span>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../2 classes/Flow.LensFlare.html#LensFlare">LensFlare</a></span>
A new LensFlare object.
</ol>
</dd>
<dt>
<a name = "LensFlare:GetEnabled"></a>
<strong>LensFlare:GetEnabled()</strong>
</dt>
<dd>
Get the lens flare's enabled status. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
Lens flare's enabled status.
</ol>
</dd>
<dt>
<a name = "LensFlare:GetSunSpriteID"></a>
<strong>LensFlare:GetSunSpriteID()</strong>
</dt>
<dd>
Get the sun's sprite ID. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
Sprite ID.
</ol>
</dd>
<dt>
<a name = "LensFlare:GetPitch"></a>
<strong>LensFlare:GetPitch()</strong>
</dt>
<dd>
Get the lens flare's pitch angle in degrees. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">float</span></span>
Pitch angle in degrees.
</ol>
</dd>
<dt>
<a name = "LensFlare:GetYaw"></a>
<strong>LensFlare:GetYaw()</strong>
</dt>
<dd>
Get the lens flare's yaw angle in degrees. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">float</span></span>
Yaw angle in degrees.
</ol>
</dd>
<dt>
<a name = "LensFlare:SetColor"></a>
<strong>LensFlare:SetColor()</strong>
</dt>
<dd>
Get the lens flare's color. ()
</dd>
<dt>
<a name = "LensFlare:SetSunSpriteID"></a>
<strong>LensFlare:SetSunSpriteID(New)</strong>
</dt>
<dd>
Set the lens flare's sun sprite ID. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">int</span></span>
sprite ID.
</li>
</ul>
</dd>
<dt>
<a name = "LensFlare:SetPitch"></a>
<strong>LensFlare:SetPitch(New)</strong>
</dt>
<dd>
Set the lens flare's pitch angle. (float)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">float</span></span>
pitch angle in degrees.
</li>
</ul>
</dd>
<dt>
<a name = "LensFlare:SetYaw"></a>
<strong>LensFlare:SetYaw(New)</strong>
</dt>
<dd>
Set the lens flare's yaw angle. (float)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">float</span></span>
yaw angle in degrees.
</li>
</ul>
</dd>
<dt>
<a name = "LensFlare:SetColor"></a>
<strong>LensFlare:SetColor(New)</strong>
</dt>
<dd>
Set the lens flare's color. (Color)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
color.
</li>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="https://github.com/hispidence/TEN-LDoc">TEN-LDoc</a> (a fork of <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a>)</i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <here>Flow.Level</here></li> <li> <here>Flow.Level</here></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -106,10 +108,6 @@
<h2><a href="#Members">Members</a></h2> <h2><a href="#Members">Members</a></h2>
<table class="function_list"> <table class="function_list">
<tr>
<td class="name" ><a href="#nameKey">nameKey</a></td>
<td class="summary">(string) string key for the level's (localised) name.</td>
</tr>
<tr> <tr>
<td class="name" ><a href="#scriptFile">scriptFile</a></td> <td class="name" ><a href="#scriptFile">scriptFile</a></td>
<td class="summary">(string) Level-specific Lua script file.</td> <td class="summary">(string) Level-specific Lua script file.</td>
@ -135,6 +133,14 @@
<td class="summary">(<a href="../2 classes/Flow.SkyLayer.html#">Flow.SkyLayer</a>) Secondary sky layer</td> <td class="summary">(<a href="../2 classes/Flow.SkyLayer.html#">Flow.SkyLayer</a>) Secondary sky layer</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#starfield">starfield</a></td>
<td class="summary">(<a href="../2 classes/Flow.Starfield.html#">Flow.Starfield</a>) Starfield.</td>
</tr>
<tr>
<td class="name" ><a href="#lensFlare">lensFlare</a></td>
<td class="summary">(<a href="../2 classes/Flow.LensFlare.html#">Flow.LensFlare</a>) Global lens flare .</td>
</tr>
<tr>
<td class="name" ><a href="#fog">fog</a></td> <td class="name" ><a href="#fog">fog</a></td>
<td class="summary">(<a href="../2 classes/Flow.Fog.html#">Flow.Fog</a>) omni fog RGB color and distance.</td> <td class="summary">(<a href="../2 classes/Flow.Fog.html#">Flow.Fog</a>) omni fog RGB color and distance.</td>
</tr> </tr>
@ -198,22 +204,6 @@
<h2 class="section-header "><a name="Members"></a>Members</h2> <h2 class="section-header "><a name="Members"></a>Members</h2>
<dl class="function"> <dl class="function">
<dt>
<a name = "nameKey"></a>
<strong>nameKey</strong>
</dt>
<dd>
(string) string key for the level's (localised) name.
Corresponds to an entry in strings.lua.
</dd>
<dt> <dt>
<a name = "scriptFile"></a> <a name = "scriptFile"></a>
<strong>scriptFile</strong> <strong>scriptFile</strong>
@ -307,6 +297,36 @@
</dd>
<dt>
<a name = "starfield"></a>
<strong>starfield</strong>
</dt>
<dd>
(<a href="../2 classes/Flow.Starfield.html#">Flow.Starfield</a>) Starfield.
</dd>
<dt>
<a name = "lensFlare"></a>
<strong>lensFlare</strong>
</dt>
<dd>
(<a href="../2 classes/Flow.LensFlare.html#">Flow.LensFlare</a>) Global lens flare .
</dd> </dd>
<dt> <dt>
<a name = "fog"></a> <a name = "fog"></a>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <here>Flow.Mirror</here></li> <li> <here>Flow.Mirror</here></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <here>Flow.Settings</here></li> <li> <here>Flow.Settings</here></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <here>Flow.SkyLayer</here></li> <li> <here>Flow.SkyLayer</here></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -154,13 +156,14 @@
<dd> <dd>
(int) cloud speed. </p> (int) cloud speed. </p>
<p>Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from <pre><code> Values can be between [-32768, 32767], with positive numbers resulting in a sky that scrolls from
west to east, and negative numbers resulting in one that travels east to west.</p> west to east, and negative numbers resulting in one that travels east to west.
<p>Please note that speeds outside of the range of about [-1000, 1000] will cause the
sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
Less is more. City of The Dead, for example, uses a speed value of 16.
Please note that speeds outside of the range of about [-1000, 1000] will cause the
sky to scroll so fast that it will no longer appear as a coherent stream of clouds.
Less is more. City of The Dead, for example, uses a speed value of 16.
</code></pre>
<p>

View file

@ -0,0 +1,454 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div> <!-- id="product" -->
<div id="main">
<!-- Menu -->
<div id="navigation">
<br/>
<h1>TombEngine</h1>
<ul>
<li><a href="../index.html">Index</a></li>
</ul>
<h2>1 Modules</h2>
<ul class="nowrap">
<li> <a href="../1 modules/Effects.html">Effects</a></li>
<li> <a href="../1 modules/Flow.html">Flow</a></li>
<li> <a href="../1 modules/Input.html">Input</a></li>
<li> <a href="../1 modules/Inventory.html">Inventory</a></li>
<li> <a href="../1 modules/Logic.html">Logic</a></li>
<li> <a href="../1 modules/Objects.html">Objects</a></li>
<li> <a href="../1 modules/Sound.html">Sound</a></li>
<li> <a href="../1 modules/Strings.html">Strings</a></li>
<li> <a href="../1 modules/Util.html">Util</a></li>
<li> <a href="../1 modules/View.html">View</a></li>
</ul>
<h2>2 Classes</h2>
<ul class="nowrap">
<li> <a href="../2 classes/View.DisplaySprite.html">View.DisplaySprite</a></li>
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <here>Flow.Starfield</here></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
<li> <a href="../2 classes/Objects.Moveable.html">Objects.Moveable</a></li>
<li> <a href="../2 classes/Objects.Room.html">Objects.Room</a></li>
<li> <a href="../2 classes/Objects.Sink.html">Objects.Sink</a></li>
<li> <a href="../2 classes/Objects.SoundSource.html">Objects.SoundSource</a></li>
<li> <a href="../2 classes/Objects.Static.html">Objects.Static</a></li>
<li> <a href="../2 classes/Objects.Volume.html">Objects.Volume</a></li>
<li> <a href="../2 classes/Strings.DisplayString.html">Strings.DisplayString</a></li>
</ul>
<h2>3 Primitive Classes</h2>
<ul class="nowrap">
<li> <a href="../3 primitive classes/Color.html">Color</a></li>
<li> <a href="../3 primitive classes/Rotation.html">Rotation</a></li>
<li> <a href="../3 primitive classes/Vec2.html">Vec2</a></li>
<li> <a href="../3 primitive classes/Vec3.html">Vec3</a></li>
</ul>
<h2>4 Enums</h2>
<ul class="nowrap">
<li> <a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li> <a href="../4 enums/Effects.EffectID.html">Effects.EffectID</a></li>
<li> <a href="../4 enums/Flow.GameStatus.html">Flow.GameStatus</a></li>
<li> <a href="../4 enums/Input.ActionID.html">Input.ActionID</a></li>
<li> <a href="../4 enums/Objects.AmmoType.html">Objects.AmmoType</a></li>
<li> <a href="../4 enums/Objects.MoveableStatus.html">Objects.MoveableStatus</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li>
<li> <a href="../4 enums/Objects.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
<li> <a href="../4 enums/Sound.SoundTrackType.html">Sound.SoundTrackType</a></li>
<li> <a href="../4 enums/Util.LogLevel.html">Util.LogLevel</a></li>
<li> <a href="../4 enums/View.AlignMode.html">View.AlignMode</a></li>
<li> <a href="../4 enums/View.CameraType.html">View.CameraType</a></li>
<li> <a href="../4 enums/View.PostProcessMode.html">View.PostProcessMode</a></li>
<li> <a href="../4 enums/View.ScaleMode.html">View.ScaleMode</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li> <a href="../5 lua utility modules/EventSequence.html">EventSequence</a></li>
<li> <a href="../5 lua utility modules/Timer.html">Timer</a></li>
</ul>
</div>
<div id="content">
<h1>Class <code>Flow.Starfield</code></h1>
<p>Represents a starfield.</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#Starfield">Starfield(starCount)</a></td>
<td class="summary">Create a starfield object with only stars.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield">Starfield(starCount, meteorCount)</a></td>
<td class="summary">Create a starfield object with stars and meteors.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetStarsEnabled">Starfield:GetStarsEnabled()</a></td>
<td class="summary">Get the starfield's enabled status of stars.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetMeteorsEnabled">Starfield:GetMeteorsEnabled()</a></td>
<td class="summary">Get the starfield's enabled status of meteors.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetStarCount">Starfield:GetStarCount()</a></td>
<td class="summary">Get the starfield's number of stars.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetMeteorCount">Starfield:GetMeteorCount()</a></td>
<td class="summary">Get the starfield's number of meteors.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetMeteorSpawnDensity">Starfield:GetMeteorSpawnDensity()</a></td>
<td class="summary">Get the starfield's meteor spawn density.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:GetMeteorVelocity">Starfield:GetMeteorVelocity()</a></td>
<td class="summary">Get the starfield's meteor velocity.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:SetStarCount">Starfield:SetStarCount(New)</a></td>
<td class="summary">Set the starfield's number of stars (6000 max).</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:SetMeteorCount">Starfield:SetMeteorCount(New)</a></td>
<td class="summary">Set the starfield's number of meteors (100 max).</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:SetMeteorSpawnDensity">Starfield:SetMeteorSpawnDensity(New)</a></td>
<td class="summary">Set the starfield's meteor spawn density.</td>
</tr>
<tr>
<td class="name" ><a href="#Starfield:SetMeteorVelocity">Starfield:SetMeteorVelocity(New)</a></td>
<td class="summary">Set the starfield's meteor velocity.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "Starfield"></a>
<strong>Starfield(starCount)</strong>
</dt>
<dd>
Create a starfield object with only stars. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">starCount</span>
<span class="types"><span class="type">int</span></span>
Star count.
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../2 classes/Flow.Starfield.html#Starfield">Starfield</a></span>
A new Starfield object.
</ol>
</dd>
<dt>
<a name = "Starfield"></a>
<strong>Starfield(starCount, meteorCount)</strong>
</dt>
<dd>
Create a starfield object with stars and meteors. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">starCount</span>
<span class="types"><span class="type">int</span></span>
Star count (6000 max).
</li>
<li><span class="parameter">meteorCount</span>
<span class="types"><span class="type">int</span></span>
Meteor count (100 max).
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../2 classes/Flow.Starfield.html#Starfield">Starfield</a></span>
A new Starfield object.
</ol>
</dd>
<dt>
<a name = "Starfield:GetStarsEnabled"></a>
<strong>Starfield:GetStarsEnabled()</strong>
</dt>
<dd>
Get the starfield's enabled status of stars. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
Stars enabled status.
</ol>
</dd>
<dt>
<a name = "Starfield:GetMeteorsEnabled"></a>
<strong>Starfield:GetMeteorsEnabled()</strong>
</dt>
<dd>
Get the starfield's enabled status of meteors. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
Meteors enabled status.
</ol>
</dd>
<dt>
<a name = "Starfield:GetStarCount"></a>
<strong>Starfield:GetStarCount()</strong>
</dt>
<dd>
Get the starfield's number of stars. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
Count.
</ol>
</dd>
<dt>
<a name = "Starfield:GetMeteorCount"></a>
<strong>Starfield:GetMeteorCount()</strong>
</dt>
<dd>
Get the starfield's number of meteors. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
Count.
</ol>
</dd>
<dt>
<a name = "Starfield:GetMeteorSpawnDensity"></a>
<strong>Starfield:GetMeteorSpawnDensity()</strong>
</dt>
<dd>
Get the starfield's meteor spawn density. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
Spawn density.
</ol>
</dd>
<dt>
<a name = "Starfield:GetMeteorVelocity"></a>
<strong>Starfield:GetMeteorVelocity()</strong>
</dt>
<dd>
Get the starfield's meteor velocity. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">float</span></span>
Velocity.
</ol>
</dd>
<dt>
<a name = "Starfield:SetStarCount"></a>
<strong>Starfield:SetStarCount(New)</strong>
</dt>
<dd>
Set the starfield's number of stars (6000 max). (int)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">int</span></span>
count.
</li>
</ul>
</dd>
<dt>
<a name = "Starfield:SetMeteorCount"></a>
<strong>Starfield:SetMeteorCount(New)</strong>
</dt>
<dd>
Set the starfield's number of meteors (100 max). (int)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">int</span></span>
count.
</li>
</ul>
</dd>
<dt>
<a name = "Starfield:SetMeteorSpawnDensity"></a>
<strong>Starfield:SetMeteorSpawnDensity(New)</strong>
</dt>
<dd>
Set the starfield's meteor spawn density. (int)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">int</span></span>
spawn density.
</li>
</ul>
</dd>
<dt>
<a name = "Starfield:SetMeteorVelocity"></a>
<strong>Starfield:SetMeteorVelocity(New)</strong>
</dt>
<dd>
Set the starfield's meteor velocity. (float)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">New</span>
<span class="types"><span class="type">int</span></span>
velocity.
</li>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="https://github.com/hispidence/TEN-LDoc">TEN-LDoc</a> (a fork of <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a>)</i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <here>Objects.AIObject</here></li> <li> <here>Objects.AIObject</here></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <here>Objects.Camera</here></li> <li> <here>Objects.Camera</here></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <here>Objects.LaraObject</here></li> <li> <here>Objects.LaraObject</here></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -108,7 +110,7 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" ><a href="#Moveable">Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits)</a></td> <td class="name" ><a href="#Moveable">Moveable(object, name, position, rotation, roomNumber, animNumber, frameNumber, hp, OCB, AIBits)</a></td>
<td class="summary">Used to generate a new moveable dynamically at runtime.</td> <td class="summary">Used to generate a new moveable dynamically at runtime.</td>
</tr> </tr>
<tr> <tr>
@ -120,11 +122,11 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
<td class="summary">Shatter item.</td> <td class="summary">Shatter item.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Moveable:SetEffect">Moveable:SetEffect(effect, timeout)</a></td> <td class="name" ><a href="#Moveable:SetEffect">Moveable:SetEffect(effect[, timeout])</a></td>
<td class="summary">Set effect to moveable</td> <td class="summary">Set effect to moveable</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Moveable:SetCustomEffect">Moveable:SetCustomEffect(Color1, Color2, timeout)</a></td> <td class="name" ><a href="#Moveable:SetCustomEffect">Moveable:SetCustomEffect(Color1, Color2[, timeout])</a></td>
<td class="summary">Set custom colored burn effect to moveable</td> <td class="summary">Set custom colored burn effect to moveable</td>
</tr> </tr>
<tr> <tr>
@ -152,6 +154,10 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
<td class="summary">Retrieve the index of the current state.</td> <td class="summary">Retrieve the index of the current state.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Moveable:GetTargetState">Moveable:GetTargetState()</a></td>
<td class="summary">Retrieve the index of the target state.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SetState">Moveable:SetState(index)</a></td> <td class="name" ><a href="#Moveable:SetState">Moveable:SetState(index)</a></td>
<td class="summary">Set the object's state to the one specified by the given index.</td> <td class="summary">Set the object's state to the one specified by the given index.</td>
</tr> </tr>
@ -225,10 +231,14 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
<td class="summary">Determine whether the moveable is active or not</td> <td class="summary">Determine whether the moveable is active or not</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Moveable:GetJointPosition">Moveable:GetJointPosition(index)</a></td> <td class="name" ><a href="#Moveable:GetJointPosition">Moveable:GetJointPosition(index[, offset])</a></td>
<td class="summary">Get the object's joint position</td> <td class="summary">Get the object's joint position</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Moveable:GetJointRotation">Moveable:GetJointRotation(index)</a></td>
<td class="summary">Get the object's joint rotation</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetRotation">Moveable:GetRotation()</a></td> <td class="name" ><a href="#Moveable:GetRotation">Moveable:GetRotation()</a></td>
<td class="summary">Get the moveable's rotation</td> <td class="summary">Get the moveable's rotation</td>
</tr> </tr>
@ -390,7 +400,7 @@ pickups, and Lara herself (see also <a href="../2 classes/Objects.LaraObject.htm
<dl class="function"> <dl class="function">
<dt> <dt>
<a name = "Moveable"></a> <a name = "Moveable"></a>
<strong>Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits)</strong> <strong>Moveable(object, name, position, rotation, roomNumber, animNumber, frameNumber, hp, OCB, AIBits)</strong>
</dt> </dt>
<dd> <dd>
Used to generate a new moveable dynamically at runtime. <br/> Used to generate a new moveable dynamically at runtime. <br/>
@ -418,9 +428,9 @@ most can just be ignored (see usage).
<span class="types"><a class="type" href="../3 primitive classes/Rotation.html#">Rotation</a></span> <span class="types"><a class="type" href="../3 primitive classes/Rotation.html#">Rotation</a></span>
rotation rotation about x, y, and z axes (default Rotation(0, 0, 0)) rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
</li> </li>
<li><span class="parameter">roomID</span> <li><span class="parameter">roomNumber</span>
<span class="types"><span class="type">int</span></span> <span class="types"><span class="type">int</span></span>
room ID item is in (default: calculated automatically) the room number the moveable is in (default: calculated automatically).
</li> </li>
<li><span class="parameter">animNumber</span> <li><span class="parameter">animNumber</span>
<span class="types"><span class="type">int</span></span> <span class="types"><span class="type">int</span></span>
@ -494,7 +504,7 @@ most can just be ignored (see usage).
</dd> </dd>
<dt> <dt>
<a name = "Moveable:SetEffect"></a> <a name = "Moveable:SetEffect"></a>
<strong>Moveable:SetEffect(effect, timeout)</strong> <strong>Moveable:SetEffect(effect[, timeout])</strong>
</dt> </dt>
<dd> <dd>
Set effect to moveable Set effect to moveable
@ -509,7 +519,8 @@ most can just be ignored (see usage).
</li> </li>
<li><span class="parameter">timeout</span> <li><span class="parameter">timeout</span>
<span class="types"><span class="type">float</span></span> <span class="types"><span class="type">float</span></span>
time (in seconds) after which effect turns off (optional). time (in seconds) after which effect turns off.
(<em>optional</em>)
</li> </li>
</ul> </ul>
@ -520,7 +531,7 @@ most can just be ignored (see usage).
</dd> </dd>
<dt> <dt>
<a name = "Moveable:SetCustomEffect"></a> <a name = "Moveable:SetCustomEffect"></a>
<strong>Moveable:SetCustomEffect(Color1, Color2, timeout)</strong> <strong>Moveable:SetCustomEffect(Color1, Color2[, timeout])</strong>
</dt> </dt>
<dd> <dd>
Set custom colored burn effect to moveable Set custom colored burn effect to moveable
@ -539,7 +550,8 @@ most can just be ignored (see usage).
</li> </li>
<li><span class="parameter">timeout</span> <li><span class="parameter">timeout</span>
<span class="types"><span class="type">float</span></span> <span class="types"><span class="type">float</span></span>
time (in seconds) after which effect turns off (optional). time (in seconds) after which effect turns off.
(<em>optional</em>)
</li> </li>
</ul> </ul>
@ -681,6 +693,28 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
</dd>
<dt>
<a name = "Moveable:GetTargetState"></a>
<strong>Moveable:GetTargetState()</strong>
</dt>
<dd>
Retrieve the index of the target state.
This corresponds to the state the object is trying to get into, which is sometimes different from the active state.
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
the index of the target state
</ol>
</dd> </dd>
<dt> <dt>
<a name = "Moveable:SetState"></a> <a name = "Moveable:SetState"></a>
@ -1096,7 +1130,7 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
</dd> </dd>
<dt> <dt>
<a name = "Moveable:GetJointPosition"></a> <a name = "Moveable:GetJointPosition"></a>
<strong>Moveable:GetJointPosition(index)</strong> <strong>Moveable:GetJointPosition(index[, offset])</strong>
</dt> </dt>
<dd> <dd>
Get the object's joint position Get the object's joint position
@ -1109,13 +1143,46 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
<span class="types"><span class="type">int</span></span> <span class="types"><span class="type">int</span></span>
of a joint to get position of a joint to get position
</li> </li>
<li><span class="parameter">offset</span>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
a pre-rotation offset to the joint
(<em>optional</em>)
</li>
</ul> </ul>
<h3>Returns:</h3> <h3>Returns:</h3>
<ol> <ol>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span> <span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
a copy of the moveable's position a copy of the moveable's joint position
</ol>
</dd>
<dt>
<a name = "Moveable:GetJointRotation"></a>
<strong>Moveable:GetJointRotation(index)</strong>
</dt>
<dd>
Get the object's joint rotation
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a joint to get rotation
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Rotation.html#">Rotation</a></span>
a calculated copy of the moveable's joint rotation
</ol> </ol>
@ -1359,7 +1426,10 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
<h3>Usage:</h3> <h3>Usage:</h3>
<ul> <ul>
<pre class="example">LevelFuncs.objCollided = <span class="keyword">function</span>(obj1, obj2) <pre class="example"><span class="comment">-- obj1 is the collision moveable
</span><span class="comment">-- obj2 is the collider moveable
</span>
LevelFuncs.objCollided = <span class="keyword">function</span>(obj1, obj2)
<span class="global">print</span>(obj1:GetName() .. <span class="string">" collided with "</span> .. obj2:GetName()) <span class="global">print</span>(obj1:GetName() .. <span class="string">" collided with "</span> .. obj2:GetName())
<span class="keyword">end</span> <span class="keyword">end</span>
baddy:SetOnCollidedWithObject(LevelFuncs.objCollided)</pre> baddy:SetOnCollidedWithObject(LevelFuncs.objCollided)</pre>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -100,7 +102,7 @@
<div id="content"> <div id="content">
<h1>Class <code>Objects.Room</code></h1> <h1>Class <code>Objects.Room</code></h1>
<p>Rooms</p> <p>Room object.</p>
<p> <p>
</p> </p>
@ -109,8 +111,12 @@
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" ><a href="#Room:GetActive">Room:GetActive()</a></td> <td class="name" ><a href="#Room:GetRoomNumber">Room:GetRoomNumber()</a></td>
<td class="summary">Determine whether the room is active or not</td> <td class="summary">Get the room's number.</td>
</tr>
<tr>
<td class="name" ><a href="#Room:GetName">Room:GetName()</a></td>
<td class="summary">Get the room's unique string identifier.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:GetColor">Room:GetColor()</a></td> <td class="name" ><a href="#Room:GetColor">Room:GetColor()</a></td>
@ -121,28 +127,28 @@
<td class="summary">Get the room's reverb type.</td> <td class="summary">Get the room's reverb type.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:SetReverbType">Room:SetReverbType(new)</a></td> <td class="name" ><a href="#Room:SetName">Room:SetName(name)</a></td>
<td class="summary">Set the room's unique string identifier.</td>
</tr>
<tr>
<td class="name" ><a href="#Room:SetReverbType">Room:SetReverbType(Reverb)</a></td>
<td class="summary">Set the room's reverb type.</td> <td class="summary">Set the room's reverb type.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:GetName">Room:GetName()</a></td> <td class="name" ><a href="#Room:SetFlag">Room:SetFlag(flagID, Boolean)</a></td>
<td class="summary">Get the room's unique string identifier.</td> <td class="summary">Set the room's specified flag.</td>
</tr>
<tr>
<td class="name" ><a href="#Room:SetName">Room:SetName(name)</a></td>
<td class="summary">Set the room's name (its unique string identifier).</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:GetFlag">Room:GetFlag(flagID)</a></td> <td class="name" ><a href="#Room:GetFlag">Room:GetFlag(flagID)</a></td>
<td class="summary">Get the room's specified flag value (true or false).</td> <td class="summary">Get the room's specified flag value (true or false).</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:SetFlag">Room:SetFlag(flagID, the)</a></td> <td class="name" ><a href="#Room:IsTagPresent">Room:IsTagPresent(tag)</a></td>
<td class="summary">Set the room's specified flag value.</td> <td class="summary">Check if the specified tag is set for the room.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#Room:IsTagPresent">Room:IsTagPresent(tag)</a></td> <td class="name" ><a href="#Room:GetActive">Room:GetActive()</a></td>
<td class="summary">Checks if specified tag is set for this room.</td> <td class="summary">Check if the room is active.</td>
</tr> </tr>
</table> </table>
@ -154,11 +160,11 @@
<dl class="function"> <dl class="function">
<dt> <dt>
<a name = "Room:GetActive"></a> <a name = "Room:GetRoomNumber"></a>
<strong>Room:GetActive()</strong> <strong>Room:GetRoomNumber()</strong>
</dt> </dt>
<dd> <dd>
Determine whether the room is active or not Get the room's number. ()
@ -166,8 +172,29 @@
<h3>Returns:</h3> <h3>Returns:</h3>
<ol> <ol>
<span class="types"><span class="type">bool</span></span> <span class="types"><span class="type">int</span></span>
true if the room is active Room number.
</ol>
</dd>
<dt>
<a name = "Room:GetName"></a>
<strong>Room:GetName()</strong>
</dt>
<dd>
Get the room's unique string identifier. ()
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
Room name.
</ol> </ol>
@ -179,7 +206,7 @@
<strong>Room:GetColor()</strong> <strong>Room:GetColor()</strong>
</dt> </dt>
<dd> <dd>
Get the room's ambient light color. Get the room's ambient light color. ()
@ -188,7 +215,7 @@
<ol> <ol>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span> <span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
ambient light color of the room Ambient light color.
</ol> </ol>
@ -200,7 +227,7 @@
<strong>Room:GetReverbType()</strong> <strong>Room:GetReverbType()</strong>
</dt> </dt>
<dd> <dd>
Get the room's reverb type. Get the room's reverb type. ()
@ -209,50 +236,7 @@
<ol> <ol>
<span class="types"><a class="type" href="../4 enums/Objects.RoomReverb.html#">RoomReverb</a></span> <span class="types"><a class="type" href="../4 enums/Objects.RoomReverb.html#">RoomReverb</a></span>
room's reverb type Reverb type.
</ol>
</dd>
<dt>
<a name = "Room:SetReverbType"></a>
<strong>Room:SetReverbType(new)</strong>
</dt>
<dd>
Set the room's reverb type.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">new</span>
<span class="types"><a class="type" href="../4 enums/Objects.RoomReverb.html#">RoomReverb</a></span>
reverb type of the room
</li>
</ul>
</dd>
<dt>
<a name = "Room:GetName"></a>
<strong>Room:GetName()</strong>
</dt>
<dd>
Get the room's unique string identifier.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
the room's name
</ol> </ol>
@ -264,7 +248,7 @@
<strong>Room:SetName(name)</strong> <strong>Room:SetName(name)</strong>
</dt> </dt>
<dd> <dd>
Set the room's name (its unique string identifier). Set the room's unique string identifier. ()
@ -272,7 +256,55 @@
<ul> <ul>
<li><span class="parameter">name</span> <li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
The room's new name New name.
</li>
</ul>
</dd>
<dt>
<a name = "Room:SetReverbType"></a>
<strong>Room:SetReverbType(Reverb)</strong>
</dt>
<dd>
Set the room's reverb type. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">Reverb</span>
<span class="types"><a class="type" href="../4 enums/Objects.RoomReverb.html#">RoomReverb</a></span>
type.
</li>
</ul>
</dd>
<dt>
<a name = "Room:SetFlag"></a>
<strong>Room:SetFlag(flagID, Boolean)</strong>
</dt>
<dd>
Set the room's specified flag. ()
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">flagID</span>
<span class="types"><a class="type" href="../4 enums/Objects.RoomFlagID.html#">RoomFlagID</a></span>
Room flag ID.
</li>
<li><span class="parameter">Boolean</span>
<span class="types"><span class="type">bool</span></span>
to set the flag to.
</li> </li>
</ul> </ul>
@ -286,7 +318,7 @@
<strong>Room:GetFlag(flagID)</strong> <strong>Room:GetFlag(flagID)</strong>
</dt> </dt>
<dd> <dd>
Get the room's specified flag value (true or false). Get the room's specified flag value (true or false). ()
@ -294,39 +326,7 @@
<ul> <ul>
<li><span class="parameter">flagID</span> <li><span class="parameter">flagID</span>
<span class="types"><a class="type" href="../4 enums/Objects.RoomFlagID.html#">RoomFlagID</a></span> <span class="types"><a class="type" href="../4 enums/Objects.RoomFlagID.html#">RoomFlagID</a></span>
The room's flag ID Room flag ID.
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
the room's specified flag value
</ol>
</dd>
<dt>
<a name = "Room:SetFlag"></a>
<strong>Room:SetFlag(flagID, the)</strong>
</dt>
<dd>
Set the room's specified flag value.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">flagID</span>
<span class="types"><a class="type" href="../4 enums/Objects.RoomFlagID.html#">RoomFlagID</a></span>
The room's flag ID
</li>
<li><span class="parameter">the</span>
<span class="types"><span class="type">bool</span></span>
room's new flag value
</li> </li>
</ul> </ul>
@ -340,7 +340,7 @@
<strong>Room:IsTagPresent(tag)</strong> <strong>Room:IsTagPresent(tag)</strong>
</dt> </dt>
<dd> <dd>
Checks if specified tag is set for this room. Check if the specified tag is set for the room. ()
@ -348,7 +348,7 @@
<ul> <ul>
<li><span class="parameter">tag</span> <li><span class="parameter">tag</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
A text tag to check (case sensitive) Text tag to check (case sensitive).
</li> </li>
</ul> </ul>
@ -356,7 +356,28 @@
<ol> <ol>
<span class="types"><span class="type">bool</span></span> <span class="types"><span class="type">bool</span></span>
true if tag is present, false if not Boolean of the tag's presence.
</ol>
</dd>
<dt>
<a name = "Room:GetActive"></a>
<strong>Room:GetActive()</strong>
</dt>
<dd>
Check if the room is active. ()
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
Boolean of the room's active status.
</ol> </ol>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -178,7 +180,7 @@
<strong>DisplaySprite(ID, int, pos, rot, scale[, color])</strong> <strong>DisplaySprite(ID, int, pos, rot, scale[, color])</strong>
</dt> </dt>
<dd> <dd>
Create a DisplaySprite object. Create a DisplaySprite object. ()

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -100,27 +102,27 @@
<div id="content"> <div id="content">
<h1>Primitive Class <code>Color</code></h1> <h1>Primitive Class <code>Color</code></h1>
<p>An RGBA or RGB color.</p> <p>Represents an RGBA or RGB color.</p>
<p>Components are specified in bytes; all values are clamped to [0, 255].</p> <p> Components are specified in bytes. All values are clamped to the range [0, 255].</p>
<h2><a href="#Members">Members</a></h2> <h2><a href="#Members">Members</a></h2>
<table class="function_list"> <table class="function_list">
<tr> <tr>
<td class="name" ><a href="#r">r</a></td> <td class="name" ><a href="#r">r</a></td>
<td class="summary">(int) red component</td> <td class="summary">(int) Red component.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#g">g</a></td> <td class="name" ><a href="#g">g</a></td>
<td class="summary">(int) green component</td> <td class="summary">(int) Green component.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#b">b</a></td> <td class="name" ><a href="#b">b</a></td>
<td class="summary">(int) blue component</td> <td class="summary">(int) Blue component.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#a">a</a></td> <td class="name" ><a href="#a">a</a></td>
<td class="summary">(int) alpha component (255 = opaque, 0 = invisible)</td> <td class="summary">(int) Alpha component (0 = invisible, 255 = opaque).</td>
</tr> </tr>
</table> </table>
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
@ -129,12 +131,6 @@
<td class="name" ><a href="#Color">Color(R, G, B)</a></td> <td class="name" ><a href="#Color">Color(R, G, B)</a></td>
<td class="summary"> <td class="summary">
</td>
</tr>
<tr>
<td class="name" ><a href="#Color">Color(R, G, B, A)</a></td>
<td class="summary">
</td> </td>
</tr> </tr>
<tr> <tr>
@ -157,7 +153,7 @@
<strong>r</strong> <strong>r</strong>
</dt> </dt>
<dd> <dd>
(int) red component (int) Red component.
@ -172,7 +168,7 @@
<strong>g</strong> <strong>g</strong>
</dt> </dt>
<dd> <dd>
(int) green component (int) Green component.
@ -187,7 +183,7 @@
<strong>b</strong> <strong>b</strong>
</dt> </dt>
<dd> <dd>
(int) blue component (int) Blue component.
@ -202,7 +198,7 @@
<strong>a</strong> <strong>a</strong>
</dt> </dt>
<dd> <dd>
(int) alpha component (255 = opaque, 0 = invisible) (int) Alpha component (0 = invisible, 255 = opaque).
@ -253,48 +249,6 @@
</dd>
<dt>
<a name = "Color"></a>
<strong>Color(R, G, B, A)</strong>
</dt>
<dd>
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">R</span>
<span class="types"><span class="type">int</span></span>
red component
</li>
<li><span class="parameter">G</span>
<span class="types"><span class="type">int</span></span>
green component
</li>
<li><span class="parameter">B</span>
<span class="types"><span class="type">int</span></span>
blue component
</li>
<li><span class="parameter">A</span>
<span class="types"><span class="type">int</span></span>
alpha component (255 is opaque, 0 is invisible)
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
A new Color object.
</ol>
</dd> </dd>
<dt> <dt>
<a name = "__tostring"></a> <a name = "__tostring"></a>
@ -311,7 +265,7 @@
<ul> <ul>
<li><span class="parameter">color</span> <li><span class="parameter">color</span>
<span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span> <span class="types"><a class="type" href="../3 primitive classes/Color.html#">Color</a></span>
this color This color.
</li> </li>
</ul> </ul>
@ -319,7 +273,7 @@
<ol> <ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span> <span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
A string showing the r, g, b, and a values of the color A string representing the r, g, b, and a values of the color.
</ol> </ol>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -101,7 +103,7 @@
<h1>Primitive Class <code>Rotation</code></h1> <h1>Primitive Class <code>Rotation</code></h1>
<p>Represents a degree-based 3D rotation.</p> <p>Represents a degree-based 3D rotation.</p>
<p>All values are clamped to the range [0.0, 360.0].</p> <p> All values are clamped to the range [0.0, 360.0].</p>
<h2><a href="#Members">Members</a></h2> <h2><a href="#Members">Members</a></h2>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -171,7 +173,8 @@ LARA_PETROL_MESH
LARA_DIRT_MESH LARA_DIRT_MESH
LARA_CROWBAR_ANIM LARA_CROWBAR_ANIM
LARA_TORCH_ANIM LARA_TORCH_ANIM
HAIR HAIR_PRIMARY
HAIR_SECONDARY
SNOWMOBILE_LARA_ANIMS SNOWMOBILE_LARA_ANIMS
SNOWMOBILE SNOWMOBILE
QUAD_LARA_ANIMS QUAD_LARA_ANIMS
@ -357,7 +360,7 @@ WASP_MUTANT
SKATEBOARD SKATEBOARD
SKATEBOARD_KID SKATEBOARD_KID
WINSTON WINSTON
ARMY_WINSTON SEAL_MUTANT
SPRINGBOARD SPRINGBOARD
ROLLING_SPINDLE ROLLING_SPINDLE
DISK_SHOOTER DISK_SHOOTER
@ -943,6 +946,7 @@ MESHSWAP_ROMAN_GOD1
MESHSWAP_ROMAN_GOD2 MESHSWAP_ROMAN_GOD2
MESHSWAP_MONKEY_MEDIPACK MESHSWAP_MONKEY_MEDIPACK
MESHSWAP_MONKEY_KEY MESHSWAP_MONKEY_KEY
MESHSWAP_WINSTON_ARMY_OUTFIT
ANIMATING1 ANIMATING1
ANIMATING2 ANIMATING2
ANIMATING3 ANIMATING3
@ -1104,6 +1108,10 @@ HEALTH_BAR_TEXTURE
AIR_BAR_TEXTURE AIR_BAR_TEXTURE
DASH_BAR_TEXTURE DASH_BAR_TEXTURE
SFX_BAR_TEXTURE SFX_BAR_TEXTURE
SPEEDOMETER
CUSTOM_BAR_GRAPHIC
CUSTOM_AMMO_GRAPHIC
PANEL_BORDER PANEL_BORDER
PANEL_MIDDLE PANEL_MIDDLE
PANEL_CORNER PANEL_CORNER

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="../ldoc.css" type="text/css" /> <link rel="stylesheet" href="../ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="../2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="../2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="../2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="../2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="../2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="../2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="../2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="../2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="../2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="../2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="../2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="../2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>

View file

@ -3,7 +3,7 @@
<html> <html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head> <head>
<title>TombEngine 1.4 Lua API</title> <title>TombEngine 1.5 Lua API</title>
<link rel="stylesheet" href="ldoc.css" type="text/css" /> <link rel="stylesheet" href="ldoc.css" type="text/css" />
</head> </head>
<body> <body>
@ -49,10 +49,12 @@
<li> <a href="2 classes/Flow.Animations.html">Flow.Animations</a></li> <li> <a href="2 classes/Flow.Animations.html">Flow.Animations</a></li>
<li> <a href="2 classes/Flow.Fog.html">Flow.Fog</a></li> <li> <a href="2 classes/Flow.Fog.html">Flow.Fog</a></li>
<li> <a href="2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li> <li> <a href="2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></li>
<li> <a href="2 classes/Flow.LensFlare.html">Flow.LensFlare</a></li>
<li> <a href="2 classes/Flow.Level.html">Flow.Level</a></li> <li> <a href="2 classes/Flow.Level.html">Flow.Level</a></li>
<li> <a href="2 classes/Flow.Mirror.html">Flow.Mirror</a></li> <li> <a href="2 classes/Flow.Mirror.html">Flow.Mirror</a></li>
<li> <a href="2 classes/Flow.Settings.html">Flow.Settings</a></li> <li> <a href="2 classes/Flow.Settings.html">Flow.Settings</a></li>
<li> <a href="2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li> <li> <a href="2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></li>
<li> <a href="2 classes/Flow.Starfield.html">Flow.Starfield</a></li>
<li> <a href="2 classes/Objects.AIObject.html">Objects.AIObject</a></li> <li> <a href="2 classes/Objects.AIObject.html">Objects.AIObject</a></li>
<li> <a href="2 classes/Objects.Camera.html">Objects.Camera</a></li> <li> <a href="2 classes/Objects.Camera.html">Objects.Camera</a></li>
<li> <a href="2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li> <li> <a href="2 classes/Objects.LaraObject.html">Objects.LaraObject</a></li>
@ -100,7 +102,7 @@
<div id="content"> <div id="content">
<h2>TombEngine 1.4 scripting interface</h2> <h2>TombEngine 1.5 scripting interface</h2>
<p>Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse.</p> <p>Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse.</p>
<p>At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on <a href="https://www.tombengine.com">the TombEngine website</a>.</p> <p>At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on <a href="https://www.tombengine.com">the TombEngine website</a>.</p>
@ -183,6 +185,10 @@ local door = GetMoveableByName("door_type4_14")
<td class="name" ><a href="2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></td> <td class="name" ><a href="2 classes/Flow.InventoryItem.html">Flow.InventoryItem</a></td>
<td class="summary">Represents the properties of an object as it appears in the inventory.</td> <td class="summary">Represents the properties of an object as it appears in the inventory.</td>
</tr> </tr>
<tr>
<td class="name" ><a href="2 classes/Flow.LensFlare.html">Flow.LensFlare</a></td>
<td class="summary">Represents a lens flare.</td>
</tr>
<tr> <tr>
<td class="name" ><a href="2 classes/Flow.Level.html">Flow.Level</a></td> <td class="name" ><a href="2 classes/Flow.Level.html">Flow.Level</a></td>
<td class="summary">Stores level metadata.</td> <td class="summary">Stores level metadata.</td>
@ -199,6 +205,10 @@ local door = GetMoveableByName("door_type4_14")
<td class="name" ><a href="2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></td> <td class="name" ><a href="2 classes/Flow.SkyLayer.html">Flow.SkyLayer</a></td>
<td class="summary">Describes a layer of moving clouds.</td> <td class="summary">Describes a layer of moving clouds.</td>
</tr> </tr>
<tr>
<td class="name" ><a href="2 classes/Flow.Starfield.html">Flow.Starfield</a></td>
<td class="summary">Represents a starfield.</td>
</tr>
<tr> <tr>
<td class="name" ><a href="2 classes/Objects.AIObject.html">Objects.AIObject</a></td> <td class="name" ><a href="2 classes/Objects.AIObject.html">Objects.AIObject</a></td>
<td class="summary">AI object</td> <td class="summary">AI object</td>
@ -217,7 +227,7 @@ local door = GetMoveableByName("door_type4_14")
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="2 classes/Objects.Room.html">Objects.Room</a></td> <td class="name" ><a href="2 classes/Objects.Room.html">Objects.Room</a></td>
<td class="summary">Rooms</td> <td class="summary">Room object.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="2 classes/Objects.Sink.html">Objects.Sink</a></td> <td class="name" ><a href="2 classes/Objects.Sink.html">Objects.Sink</a></td>
@ -244,7 +254,7 @@ local door = GetMoveableByName("door_type4_14")
<table class="module_list"> <table class="module_list">
<tr> <tr>
<td class="name" ><a href="3 primitive classes/Color.html">Color</a></td> <td class="name" ><a href="3 primitive classes/Color.html">Color</a></td>
<td class="summary">An RGBA or RGB color.</td> <td class="summary">Represents an RGBA or RGB color.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="3 primitive classes/Rotation.html">Rotation</a></td> <td class="name" ><a href="3 primitive classes/Rotation.html">Rotation</a></td>

View file

@ -2,13 +2,12 @@
![Logo](https://github.com/MontyTRC89/TombEngine/assets/80340234/f22c9ca9-7159-467f-b8ad-7bb32274a278) ![Logo](https://github.com/MontyTRC89/TombEngine/assets/80340234/f22c9ca9-7159-467f-b8ad-7bb32274a278)
In the year 2000, Core Design granted us a great gift: their TR4-based Level Editor, which allowed people to create custom levels. It was, unfortunately, quite limited, hence why over the decades it was upgraded massively with fan patcher projects such as Tomb Raider Engine Patcher (TREP) and Tomb Raider Next Generation (TRNG). TombEngine (TEN) is an open-source, custom level engine which aims to abolish limits and fix bugs of the classic Tomb Raider games, introduce new features while refining old ones, and provide user-friendly level creation process. Current support includes:
TombEngine (TEN) is a new, open-source engine which aims to abolish all limits, fix bugs from the original games, introduce new features while refining old ones, and provide for a refined, user-friendly level creation process. Current support includes:
- Lua (as the native scripting language) - Lua (as the native scripting language)
- All objects from the classic series (1-5) - Many objects from the original series (1-5)
- Many more exciting gameplay functionalities such as diagonal shimmying and expanded crawlspace flexibility - Support for high framerate, antialiasing, mipmapping and SSAO
- An enlarged 2D map, allowing for the creation of massive levels (imagine one big level may previously have been split into five!) - Full diagonal geometry support
- Uncapped map size
- A streamlined player control scheme. - A streamlined player control scheme.
If you would like to participate in TEN discussion with other TEN devs whether it is contributing, bugs or general discussion, then join this discord server: https://discord.gg/h5tUYFmres If you would like to participate in TEN discussion with other TEN devs whether it is contributing, bugs or general discussion, then join this discord server: https://discord.gg/h5tUYFmres
@ -22,19 +21,21 @@ To compile TEN, ensure you have installed:
Steps: Steps:
1) Clone the repository to your GitHub Desktop 1) Clone the repository to your GitHub Desktop
2) Launch TombEngine.sln and compile 2) Open TombEngine.sln
3) Once compiled, create a separate folder to serve as your main TEN directory 4) Compile the solution
4) Copy everything inside the Build folder to the main TEN directory 5) Once compiled, create a separate folder to serve as your main TEN directory (or create test TEN project using TombIDE)
5) Copy the Scripts folder to your main TEN directory 6) Copy everything inside the Build folder to the main TEN directory
6) Ensure you have the necessary level data and texture files as well 7) Ensure you have the necessary level data and texture files as well
7) In the case Windows warns about missing DLLs, (bass.dll, etc.) copy the missing DLL files found inside the Libs folder to your main TEN directory. 8) In the case Windows warns about missing DLLs, (bass.dll, etc.) copy the missing DLL files found inside the Libs folder to your main TEN directory.
Visual Studio may also warn about NuGet packages. To fix: Visual Studio may also warn about NuGet packages. To fix:
1) Delete the Packages folder 1) Delete the Packages folder
2) Go back to Microsoft Visual Studio 2) Go back to Microsoft Visual Studio
3) Right-click on the TombEngine solution in the Solution Explorer tab and select "Restore NuGet Packages" 3) Right-click on the TombEngine solution in the Solution Explorer tab and select "Restore NuGet Packages"
4) Compile again and once done, you should be able to compile a level with TombEditor and run it in TEN. 4) If it doesn't help, manually install `directxtk_desktop_2019` and `Microsoft.XAudio2.Redist` packages via NuGet Package Manager
Once done, you should be able to build a level with TombEditor and run it in TEN.
# Disclaimer # Disclaimer
We do not and have never worked for Core Design, Eidos Interactive, or Square Enix. This is a hobby project. Tomb Raider is a registered trademark of Square Enix; TombEngine is not be sold. The code is open-source to encourage contributions and to be used for study purposes. We are not responsible for illegal uses of this source code. This source code is released as-is and continues to be maintained by non-paid contributors in their free time. This is a community project which is not affiliated with Core Design, Eidos Interactive, or Square Enix. Tomb Raider is a registered trademark of Square Enix; TombEngine is not be sold. The code is open-source to encourage contributions and to be used for study purposes. We are not responsible for illegal uses of this source code. This source code is released as-is and continues to be maintained by non-paid contributors in their free time.

View file

@ -11,7 +11,6 @@ local anims = Flow.Animations.new()
anims.crawlExtended = true anims.crawlExtended = true
anims.crouchRoll = true anims.crouchRoll = true
anims.crawlspaceSwandive = true anims.crawlspaceSwandive = true
anims.monkeyAutoJump = false
anims.overhangClimb = false anims.overhangClimb = false
anims.slideExtended = false anims.slideExtended = false
anims.sprintJump = false anims.sprintJump = false

View file

@ -58,7 +58,7 @@ local strings =
-- Level name strings -- Level name strings
lara_home = { "Lara's Home" }, home_level = { "Home Level" },
test_level = { "Test Level" }, test_level = { "Test Level" },
title = { "Title" }, title = { "Title" },
} }

View file

@ -51,7 +51,8 @@ local strings =
ammo_used = { "Ammo Used" }, ammo_used = { "Ammo Used" },
antialiasing = { "Antialiasing" }, antialiasing = { "Antialiasing" },
apply = { "Apply" }, apply = { "Apply" },
automatic_targeting = { "Automatic Targeting" }, auto_monkey_swing_jump = { "Auto Monkey Jump" },
auto_targeting = { "Auto Targeting" },
back = { "Back" }, back = { "Back" },
cancel = { "Cancel" }, cancel = { "Cancel" },
caustics = { "Underwater Caustics" }, caustics = { "Underwater Caustics" },
@ -74,13 +75,17 @@ local strings =
exit_to_title = { "Exit to Title" }, exit_to_title = { "Exit to Title" },
general_actions = { "General Actions" }, general_actions = { "General Actions" },
high = { "High" }, high = { "High" },
high_framerate = { "High Framerate" },
level_secrets_found = { "Secrets Found in Level" }, level_secrets_found = { "Secrets Found in Level" },
load_game = { "Load Game" }, load_game = { "Load Game" },
low = { "Low" }, low = { "Low" },
medium = { "Medium" }, medium = { "Medium" },
menu_actions = { "Menu Actions" }, menu_actions = { "Menu Actions" },
menu_option_looping = { "Menu Option Looping" },
menu_option_looping_all_menus = { "All Menus" },
menu_option_looping_disabled = { "Disabled" },
menu_option_looping_save_load_only = { "Save/Load Only" },
mouse_sensitivity = { "Mouse Sensitivity" }, mouse_sensitivity = { "Mouse Sensitivity" },
mouse_smoothing = { "Mouse Smoothing" },
music_volume = { "Music Volume" }, music_volume = { "Music Volume" },
new_game = { "New Game" }, new_game = { "New Game" },
none = { "None" }, none = { "None" },

View file

@ -331,21 +331,21 @@ namespace TEN::Gui
void CombineRevolverLasersight(ItemInfo* item, bool flag) void CombineRevolverLasersight(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
if (flag) if (flag)
{ {
lara->Inventory.HasLasersight = true; player.Inventory.HasLasersight = true;
lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false; player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = false;
} }
else else
{ {
lara->Inventory.HasLasersight = false; player.Inventory.HasLasersight = false;
lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true; player.Weapons[(int)LaraWeaponType::Revolver].HasLasersight = true;
} }
if (lara->Control.HandStatus != HandStatus::Free && if (player.Control.HandStatus != HandStatus::Free &&
lara->Control.Weapon.GunType == LaraWeaponType::Revolver) player.Control.Weapon.GunType == LaraWeaponType::Revolver)
{ {
UndrawPistolMesh(*item, LaraWeaponType::Revolver, true); UndrawPistolMesh(*item, LaraWeaponType::Revolver, true);
DrawPistolMeshes(*item, LaraWeaponType::Revolver); DrawPistolMeshes(*item, LaraWeaponType::Revolver);
@ -354,21 +354,21 @@ namespace TEN::Gui
void CombineCrossbowLasersight(ItemInfo* item, bool flag) void CombineCrossbowLasersight(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
if (flag) if (flag)
{ {
lara->Inventory.HasLasersight = true; player.Inventory.HasLasersight = true;
lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false; player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = false;
} }
else else
{ {
lara->Inventory.HasLasersight = false; player.Inventory.HasLasersight = false;
lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true; player.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight = true;
} }
if (lara->Control.HandStatus != HandStatus::Free && if (player.Control.HandStatus != HandStatus::Free &&
lara->Control.Weapon.GunType == LaraWeaponType::Crossbow) player.Control.Weapon.GunType == LaraWeaponType::Crossbow)
{ {
UndrawShotgunMeshes(*item, LaraWeaponType::Crossbow); UndrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
DrawShotgunMeshes(*item, LaraWeaponType::Crossbow); DrawShotgunMeshes(*item, LaraWeaponType::Crossbow);
@ -377,21 +377,21 @@ namespace TEN::Gui
void CombineHKLasersight(ItemInfo* item, bool flag) void CombineHKLasersight(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
if (flag) if (flag)
{ {
lara->Inventory.HasLasersight = true; player.Inventory.HasLasersight = true;
lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = false; player.Weapons[(int)LaraWeaponType::HK].HasLasersight = false;
} }
else else
{ {
lara->Inventory.HasLasersight = false; player.Inventory.HasLasersight = false;
lara->Weapons[(int)LaraWeaponType::HK].HasLasersight = true; player.Weapons[(int)LaraWeaponType::HK].HasLasersight = true;
} }
if (lara->Control.HandStatus != HandStatus::Free && if (player.Control.HandStatus != HandStatus::Free &&
lara->Control.Weapon.GunType == LaraWeaponType::HK) player.Control.Weapon.GunType == LaraWeaponType::HK)
{ {
UndrawShotgunMeshes(*item, LaraWeaponType::HK); UndrawShotgunMeshes(*item, LaraWeaponType::HK);
DrawShotgunMeshes(*item, LaraWeaponType::HK); DrawShotgunMeshes(*item, LaraWeaponType::HK);
@ -400,514 +400,514 @@ namespace TEN::Gui
void CombinePuzzleItem1(ItemInfo* item, bool flag) void CombinePuzzleItem1(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[0] = false; player.Inventory.PuzzlesCombo[0] = false;
lara->Inventory.PuzzlesCombo[1] = false; player.Inventory.PuzzlesCombo[1] = false;
lara->Inventory.Puzzles[0] = true; player.Inventory.Puzzles[0] = true;
} }
void CombinePuzzleItem2(ItemInfo* item, bool flag) void CombinePuzzleItem2(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[2] = false; player.Inventory.PuzzlesCombo[2] = false;
lara->Inventory.PuzzlesCombo[3] = false; player.Inventory.PuzzlesCombo[3] = false;
lara->Inventory.Puzzles[1] = true; player.Inventory.Puzzles[1] = true;
} }
void CombinePuzzleItem3(ItemInfo* item, bool flag) void CombinePuzzleItem3(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[4] = false; player.Inventory.PuzzlesCombo[4] = false;
lara->Inventory.PuzzlesCombo[5] = false; player.Inventory.PuzzlesCombo[5] = false;
lara->Inventory.Puzzles[2] = true; player.Inventory.Puzzles[2] = true;
} }
void CombinePuzzleItem4(ItemInfo* item, bool flag) void CombinePuzzleItem4(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[6] = false; player.Inventory.PuzzlesCombo[6] = false;
lara->Inventory.PuzzlesCombo[7] = false; player.Inventory.PuzzlesCombo[7] = false;
lara->Inventory.Puzzles[3] = true; player.Inventory.Puzzles[3] = true;
} }
void CombinePuzzleItem5(ItemInfo* item, bool flag) void CombinePuzzleItem5(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[8] = false; player.Inventory.PuzzlesCombo[8] = false;
lara->Inventory.PuzzlesCombo[9] = false; player.Inventory.PuzzlesCombo[9] = false;
lara->Inventory.Puzzles[4] = true; player.Inventory.Puzzles[4] = true;
} }
void CombinePuzzleItem6(ItemInfo* item, bool flag) void CombinePuzzleItem6(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[10] = false; player.Inventory.PuzzlesCombo[10] = false;
lara->Inventory.PuzzlesCombo[11] = false; player.Inventory.PuzzlesCombo[11] = false;
lara->Inventory.Puzzles[5] = true; player.Inventory.Puzzles[5] = true;
} }
void CombinePuzzleItem7(ItemInfo* item, bool flag) void CombinePuzzleItem7(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[12] = false; player.Inventory.PuzzlesCombo[12] = false;
lara->Inventory.PuzzlesCombo[13] = false; player.Inventory.PuzzlesCombo[13] = false;
lara->Inventory.Puzzles[6] = true; player.Inventory.Puzzles[6] = true;
} }
void CombinePuzzleItem8(ItemInfo* item, bool flag) void CombinePuzzleItem8(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[14] = false; player.Inventory.PuzzlesCombo[14] = false;
lara->Inventory.PuzzlesCombo[15] = false; player.Inventory.PuzzlesCombo[15] = false;
lara->Inventory.Puzzles[7] = true; player.Inventory.Puzzles[7] = true;
} }
void CombinePuzzleItem9(ItemInfo* item, bool flag) void CombinePuzzleItem9(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[16] = false; player.Inventory.PuzzlesCombo[16] = false;
lara->Inventory.PuzzlesCombo[17] = false; player.Inventory.PuzzlesCombo[17] = false;
lara->Inventory.Puzzles[8] = true; player.Inventory.Puzzles[8] = true;
} }
void CombinePuzzleItem10(ItemInfo* item, bool flag) void CombinePuzzleItem10(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[18] = false; player.Inventory.PuzzlesCombo[18] = false;
lara->Inventory.PuzzlesCombo[19] = false; player.Inventory.PuzzlesCombo[19] = false;
lara->Inventory.Puzzles[9] = true; player.Inventory.Puzzles[9] = true;
} }
void CombinePuzzleItem11(ItemInfo* item, bool flag) void CombinePuzzleItem11(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[20] = false; player.Inventory.PuzzlesCombo[20] = false;
lara->Inventory.PuzzlesCombo[21] = false; player.Inventory.PuzzlesCombo[21] = false;
lara->Inventory.Puzzles[10] = true; player.Inventory.Puzzles[10] = true;
} }
void CombinePuzzleItem12(ItemInfo* item, bool flag) void CombinePuzzleItem12(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[22] = false; player.Inventory.PuzzlesCombo[22] = false;
lara->Inventory.PuzzlesCombo[23] = false; player.Inventory.PuzzlesCombo[23] = false;
lara->Inventory.Puzzles[11] = true; player.Inventory.Puzzles[11] = true;
} }
void CombinePuzzleItem13(ItemInfo* item, bool flag) void CombinePuzzleItem13(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[24] = false; player.Inventory.PuzzlesCombo[24] = false;
lara->Inventory.PuzzlesCombo[25] = false; player.Inventory.PuzzlesCombo[25] = false;
lara->Inventory.Puzzles[12] = true; player.Inventory.Puzzles[12] = true;
} }
void CombinePuzzleItem14(ItemInfo* item, bool flag) void CombinePuzzleItem14(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[26] = false; player.Inventory.PuzzlesCombo[26] = false;
lara->Inventory.PuzzlesCombo[27] = false; player.Inventory.PuzzlesCombo[27] = false;
lara->Inventory.Puzzles[13] = true; player.Inventory.Puzzles[13] = true;
} }
void CombinePuzzleItem15(ItemInfo* item, bool flag) void CombinePuzzleItem15(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[28] = false; player.Inventory.PuzzlesCombo[28] = false;
lara->Inventory.PuzzlesCombo[29] = false; player.Inventory.PuzzlesCombo[29] = false;
lara->Inventory.Puzzles[14] = true; player.Inventory.Puzzles[14] = true;
} }
void CombinePuzzleItem16(ItemInfo* item, bool flag) void CombinePuzzleItem16(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.PuzzlesCombo[30] = false; player.Inventory.PuzzlesCombo[30] = false;
lara->Inventory.PuzzlesCombo[31] = false; player.Inventory.PuzzlesCombo[31] = false;
lara->Inventory.Puzzles[15] = true; player.Inventory.Puzzles[15] = true;
} }
void CombineKeyItem1(ItemInfo* item, bool flag) void CombineKeyItem1(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[0] = true; player.Inventory.Keys[0] = true;
lara->Inventory.KeysCombo[0] = false; player.Inventory.KeysCombo[0] = false;
lara->Inventory.KeysCombo[1] = false; player.Inventory.KeysCombo[1] = false;
} }
void CombineKeyItem2(ItemInfo* item, bool flag) void CombineKeyItem2(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[1] = true; player.Inventory.Keys[1] = true;
lara->Inventory.KeysCombo[2] = false; player.Inventory.KeysCombo[2] = false;
lara->Inventory.KeysCombo[3] = false; player.Inventory.KeysCombo[3] = false;
} }
void CombineKeyItem3(ItemInfo* item, bool flag) void CombineKeyItem3(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[2] = true; player.Inventory.Keys[2] = true;
lara->Inventory.KeysCombo[4] = false; player.Inventory.KeysCombo[4] = false;
lara->Inventory.KeysCombo[5] = false; player.Inventory.KeysCombo[5] = false;
} }
void CombineKeyItem4(ItemInfo* item, bool flag) void CombineKeyItem4(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[3] = true; player.Inventory.Keys[3] = true;
lara->Inventory.KeysCombo[6] = false; player.Inventory.KeysCombo[6] = false;
lara->Inventory.KeysCombo[7] = false; player.Inventory.KeysCombo[7] = false;
} }
void CombineKeyItem5(ItemInfo* item, bool flag) void CombineKeyItem5(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[4] = true; player.Inventory.Keys[4] = true;
lara->Inventory.KeysCombo[8] = false; player.Inventory.KeysCombo[8] = false;
lara->Inventory.KeysCombo[9] = false; player.Inventory.KeysCombo[9] = false;
} }
void CombineKeyItem6(ItemInfo* item, bool flag) void CombineKeyItem6(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[5] = true; player.Inventory.Keys[5] = true;
lara->Inventory.KeysCombo[10] = false; player.Inventory.KeysCombo[10] = false;
lara->Inventory.KeysCombo[11] = false; player.Inventory.KeysCombo[11] = false;
} }
void CombineKeyItem7(ItemInfo* item, bool flag) void CombineKeyItem7(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[6] = true; player.Inventory.Keys[6] = true;
lara->Inventory.KeysCombo[12] = false; player.Inventory.KeysCombo[12] = false;
lara->Inventory.KeysCombo[13] = false; player.Inventory.KeysCombo[13] = false;
} }
void CombineKeyItem8(ItemInfo* item, bool flag) void CombineKeyItem8(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[7] = true; player.Inventory.Keys[7] = true;
lara->Inventory.KeysCombo[14] = false; player.Inventory.KeysCombo[14] = false;
lara->Inventory.KeysCombo[15] = false; player.Inventory.KeysCombo[15] = false;
} }
void CombineKeyItem9(ItemInfo* item, bool flag) void CombineKeyItem9(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[8] = true; player.Inventory.Keys[8] = true;
lara->Inventory.KeysCombo[16] = false; player.Inventory.KeysCombo[16] = false;
lara->Inventory.KeysCombo[17] = false; player.Inventory.KeysCombo[17] = false;
} }
void CombineKeyItem10(ItemInfo* item, bool flag) void CombineKeyItem10(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[9] = true; player.Inventory.Keys[9] = true;
lara->Inventory.KeysCombo[18] = false; player.Inventory.KeysCombo[18] = false;
lara->Inventory.KeysCombo[19] = false; player.Inventory.KeysCombo[19] = false;
} }
void CombineKeyItem11(ItemInfo* item, bool flag) void CombineKeyItem11(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[10] = true; player.Inventory.Keys[10] = true;
lara->Inventory.KeysCombo[20] = false; player.Inventory.KeysCombo[20] = false;
lara->Inventory.KeysCombo[21] = false; player.Inventory.KeysCombo[21] = false;
} }
void CombineKeyItem12(ItemInfo* item, bool flag) void CombineKeyItem12(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[11] = true; player.Inventory.Keys[11] = true;
lara->Inventory.KeysCombo[22] = false; player.Inventory.KeysCombo[22] = false;
lara->Inventory.KeysCombo[23] = false; player.Inventory.KeysCombo[23] = false;
} }
void CombineKeyItem13(ItemInfo* item, bool flag) void CombineKeyItem13(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[12] = true; player.Inventory.Keys[12] = true;
lara->Inventory.KeysCombo[24] = false; player.Inventory.KeysCombo[24] = false;
lara->Inventory.KeysCombo[25] = false; player.Inventory.KeysCombo[25] = false;
} }
void CombineKeyItem14(ItemInfo* item, bool flag) void CombineKeyItem14(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[13] = true; player.Inventory.Keys[13] = true;
lara->Inventory.KeysCombo[26] = false; player.Inventory.KeysCombo[26] = false;
lara->Inventory.KeysCombo[27] = false; player.Inventory.KeysCombo[27] = false;
} }
void CombineKeyItem15(ItemInfo* item, bool flag) void CombineKeyItem15(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[14] = true; player.Inventory.Keys[14] = true;
lara->Inventory.KeysCombo[28] = false; player.Inventory.KeysCombo[28] = false;
lara->Inventory.KeysCombo[29] = false; player.Inventory.KeysCombo[29] = false;
} }
void CombineKeyItem16(ItemInfo* item, bool flag) void CombineKeyItem16(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Keys[15] = true; player.Inventory.Keys[15] = true;
lara->Inventory.KeysCombo[30] = false; player.Inventory.KeysCombo[30] = false;
lara->Inventory.KeysCombo[31] = false; player.Inventory.KeysCombo[31] = false;
} }
void CombinePickupItem1(ItemInfo* item, bool flag) void CombinePickupItem1(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[0] = true; player.Inventory.Pickups[0] = true;
lara->Inventory.PickupsCombo[0] = false; player.Inventory.PickupsCombo[0] = false;
lara->Inventory.PickupsCombo[1] = false; player.Inventory.PickupsCombo[1] = false;
} }
void CombinePickupItem2(ItemInfo* item, bool flag) void CombinePickupItem2(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[1] = true; player.Inventory.Pickups[1] = true;
lara->Inventory.PickupsCombo[2] = false; player.Inventory.PickupsCombo[2] = false;
lara->Inventory.PickupsCombo[3] = false; player.Inventory.PickupsCombo[3] = false;
} }
void CombinePickupItem3(ItemInfo* item, bool flag) void CombinePickupItem3(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[2] = true; player.Inventory.Pickups[2] = true;
lara->Inventory.PickupsCombo[4] = false; player.Inventory.PickupsCombo[4] = false;
lara->Inventory.PickupsCombo[5] = false; player.Inventory.PickupsCombo[5] = false;
} }
void CombinePickupItem4(ItemInfo* item, bool flag) void CombinePickupItem4(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[3] = true; player.Inventory.Pickups[3] = true;
lara->Inventory.PickupsCombo[6] = false; player.Inventory.PickupsCombo[6] = false;
lara->Inventory.PickupsCombo[7] = false; player.Inventory.PickupsCombo[7] = false;
} }
void CombinePickupItem5(ItemInfo* item, bool flag) void CombinePickupItem5(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[4] = true; player.Inventory.Pickups[4] = true;
lara->Inventory.PickupsCombo[8] = false; player.Inventory.PickupsCombo[8] = false;
lara->Inventory.PickupsCombo[9] = false; player.Inventory.PickupsCombo[9] = false;
} }
void CombinePickupItem6(ItemInfo* item, bool flag) void CombinePickupItem6(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[5] = true; player.Inventory.Pickups[5] = true;
lara->Inventory.PickupsCombo[10] = false; player.Inventory.PickupsCombo[10] = false;
lara->Inventory.PickupsCombo[11] = false; player.Inventory.PickupsCombo[11] = false;
} }
void CombinePickupItem7(ItemInfo* item, bool flag) void CombinePickupItem7(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[6] = true; player.Inventory.Pickups[6] = true;
lara->Inventory.PickupsCombo[12] = false; player.Inventory.PickupsCombo[12] = false;
lara->Inventory.PickupsCombo[13] = false; player.Inventory.PickupsCombo[13] = false;
} }
void CombinePickupItem8(ItemInfo* item, bool flag) void CombinePickupItem8(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[7] = true; player.Inventory.Pickups[7] = true;
lara->Inventory.PickupsCombo[14] = false; player.Inventory.PickupsCombo[14] = false;
lara->Inventory.PickupsCombo[15] = false; player.Inventory.PickupsCombo[15] = false;
} }
void CombinePickupItem9(ItemInfo* item, bool flag) void CombinePickupItem9(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[8] = true; player.Inventory.Pickups[8] = true;
lara->Inventory.PickupsCombo[16] = false; player.Inventory.PickupsCombo[16] = false;
lara->Inventory.PickupsCombo[17] = false; player.Inventory.PickupsCombo[17] = false;
} }
void CombinePickupItem10(ItemInfo* item, bool flag) void CombinePickupItem10(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[9] = true; player.Inventory.Pickups[9] = true;
lara->Inventory.PickupsCombo[18] = false; player.Inventory.PickupsCombo[18] = false;
lara->Inventory.PickupsCombo[19] = false; player.Inventory.PickupsCombo[19] = false;
} }
void CombinePickupItem11(ItemInfo* item, bool flag) void CombinePickupItem11(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[10] = true; player.Inventory.Pickups[10] = true;
lara->Inventory.PickupsCombo[20] = false; player.Inventory.PickupsCombo[20] = false;
lara->Inventory.PickupsCombo[21] = false; player.Inventory.PickupsCombo[21] = false;
} }
void CombinePickupItem12(ItemInfo* item, bool flag) void CombinePickupItem12(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[11] = true; player.Inventory.Pickups[11] = true;
lara->Inventory.PickupsCombo[22] = false; player.Inventory.PickupsCombo[22] = false;
lara->Inventory.PickupsCombo[23] = false; player.Inventory.PickupsCombo[23] = false;
} }
void CombinePickupItem13(ItemInfo* item, bool flag) void CombinePickupItem13(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[12] = true; player.Inventory.Pickups[12] = true;
lara->Inventory.PickupsCombo[24] = false; player.Inventory.PickupsCombo[24] = false;
lara->Inventory.PickupsCombo[25] = false; player.Inventory.PickupsCombo[25] = false;
} }
void CombinePickupItem14(ItemInfo* item, bool flag) void CombinePickupItem14(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[13] = true; player.Inventory.Pickups[13] = true;
lara->Inventory.PickupsCombo[26] = false; player.Inventory.PickupsCombo[26] = false;
lara->Inventory.PickupsCombo[27] = false; player.Inventory.PickupsCombo[27] = false;
} }
void CombinePickupItem15(ItemInfo* item, bool flag) void CombinePickupItem15(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[14] = true; player.Inventory.Pickups[14] = true;
lara->Inventory.PickupsCombo[28] = false; player.Inventory.PickupsCombo[28] = false;
lara->Inventory.PickupsCombo[29] = false; player.Inventory.PickupsCombo[29] = false;
} }
void CombinePickupItem16(ItemInfo* item, bool flag) void CombinePickupItem16(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Pickups[15] = true; player.Inventory.Pickups[15] = true;
lara->Inventory.PickupsCombo[30] = false; player.Inventory.PickupsCombo[30] = false;
lara->Inventory.PickupsCombo[31] = false; player.Inventory.PickupsCombo[31] = false;
} }
void CombineExamine1(ItemInfo* item, bool flag) void CombineExamine1(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[0] = true; player.Inventory.Examines[0] = true;
lara->Inventory.ExaminesCombo[0] = false; player.Inventory.ExaminesCombo[0] = false;
lara->Inventory.ExaminesCombo[1] = false; player.Inventory.ExaminesCombo[1] = false;
} }
void CombineExamine2(ItemInfo* item, bool flag) void CombineExamine2(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[1] = true; player.Inventory.Examines[1] = true;
lara->Inventory.ExaminesCombo[2] = false; player.Inventory.ExaminesCombo[2] = false;
lara->Inventory.ExaminesCombo[3] = false; player.Inventory.ExaminesCombo[3] = false;
} }
void CombineExamine3(ItemInfo* item, bool flag) void CombineExamine3(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[2] = true; player.Inventory.Examines[2] = true;
lara->Inventory.ExaminesCombo[4] = false; player.Inventory.ExaminesCombo[4] = false;
lara->Inventory.ExaminesCombo[5] = false; player.Inventory.ExaminesCombo[5] = false;
} }
void CombineExamine4(ItemInfo* item, bool flag) void CombineExamine4(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[3] = true; player.Inventory.Examines[3] = true;
lara->Inventory.ExaminesCombo[6] = false; player.Inventory.ExaminesCombo[6] = false;
lara->Inventory.ExaminesCombo[7] = false; player.Inventory.ExaminesCombo[7] = false;
} }
void CombineExamine5(ItemInfo* item, bool flag) void CombineExamine5(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[4] = true; player.Inventory.Examines[4] = true;
lara->Inventory.ExaminesCombo[8] = false; player.Inventory.ExaminesCombo[8] = false;
lara->Inventory.ExaminesCombo[9] = false; player.Inventory.ExaminesCombo[9] = false;
} }
void CombineExamine6(ItemInfo* item, bool flag) void CombineExamine6(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[5] = true; player.Inventory.Examines[5] = true;
lara->Inventory.ExaminesCombo[10] = false; player.Inventory.ExaminesCombo[10] = false;
lara->Inventory.ExaminesCombo[11] = false; player.Inventory.ExaminesCombo[11] = false;
} }
void CombineExamine7(ItemInfo* item, bool flag) void CombineExamine7(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[6] = true; player.Inventory.Examines[6] = true;
lara->Inventory.ExaminesCombo[12] = false; player.Inventory.ExaminesCombo[12] = false;
lara->Inventory.ExaminesCombo[13] = false; player.Inventory.ExaminesCombo[13] = false;
} }
void CombineExamine8(ItemInfo* item, bool flag) void CombineExamine8(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.Examines[7] = true; player.Inventory.Examines[7] = true;
lara->Inventory.ExaminesCombo[14] = false; player.Inventory.ExaminesCombo[14] = false;
lara->Inventory.ExaminesCombo[15] = false; player.Inventory.ExaminesCombo[15] = false;
} }
void CombineClockWorkBeetle(ItemInfo* item, bool flag) void CombineClockWorkBeetle(ItemInfo* item, bool flag)
{ {
auto* lara = GetLaraInfo(item); auto& player = GetLaraInfo(*item);
lara->Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle. player.Inventory.BeetleComponents |= BEETLECOMP_FLAG_BEETLE; // Get beetle.
lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1. player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_1; // Remove combo 1.
lara->Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2. player.Inventory.BeetleComponents &= BEETLECOMP_FLAG_COMBO_2; // Remove combo 2.
} }
} }

View file

@ -2,6 +2,8 @@
#include "Game/Hud/PickupSummary.h" #include "Game/Hud/PickupSummary.h"
#include "Game/pickup/pickup.h" #include "Game/pickup/pickup.h"
#include "Game/pickup/pickup_ammo.h"
#include "Game/pickup/pickup_consumable.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer.h" #include "Renderer/Renderer.h"
#include "Specific/clock.h" #include "Specific/clock.h"
@ -39,6 +41,8 @@ namespace TEN::Hud
constexpr auto ROT_RATE = ANGLE(360.0f / (LIFE_MAX * FPS)); constexpr auto ROT_RATE = ANGLE(360.0f / (LIFE_MAX * FPS));
constexpr auto ROT = EulerAngles(0, ROT_RATE, 0); constexpr auto ROT = EulerAngles(0, ROT_RATE, 0);
StoreInterpolationData();
// Move offscreen. // Move offscreen.
if (Life <= 0.0f && isHead) if (Life <= 0.0f && isHead)
{ {
@ -122,6 +126,21 @@ namespace TEN::Hud
pickup.StringScalar = 0.0f; pickup.StringScalar = 0.0f;
} }
void PickupSummaryController::AddDisplayPickup(const ItemInfo& item)
{
// NOTE: Ammo and consumables are a special case, as internal amount differs from pickup amount.
int ammoCount = GetDefaultAmmoCount(item.ObjectNumber);
int consumableCount = GetDefaultConsumableCount(item.ObjectNumber);
int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT;
if (ammoCount != NO_VALUE)
count = ammoCount;
if (consumableCount != NO_VALUE)
count = consumableCount;
AddDisplayPickup(item.ObjectNumber, item.Pose.Position.ToVector3(), (item.HitPoints > 0) ? item.HitPoints : count);
}
void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count) void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count)
{ {
// Project 3D position to 2D origin. // Project 3D position to 2D origin.
@ -196,7 +215,7 @@ namespace TEN::Hud
DisplayPickup& PickupSummaryController::GetNewDisplayPickup() DisplayPickup& PickupSummaryController::GetNewDisplayPickup()
{ {
assertion(_displayPickups.size() <= DISPLAY_PICKUP_COUNT_MAX, "Display pickup overflow."); TENAssert(_displayPickups.size() <= DISPLAY_PICKUP_COUNT_MAX, "Display pickup overflow.");
// Add and return new display pickup. // Add and return new display pickup.
if (_displayPickups.size() < DISPLAY_PICKUP_COUNT_MAX) if (_displayPickups.size() < DISPLAY_PICKUP_COUNT_MAX)
@ -213,12 +232,15 @@ namespace TEN::Hud
_displayPickups.erase( _displayPickups.erase(
std::remove_if( std::remove_if(
_displayPickups.begin(), _displayPickups.end(), _displayPickups.begin(), _displayPickups.end(),
[](const DisplayPickup& pickup) { return ((pickup.Life <= 0.0f) && pickup.IsOffscreen()); }), [](const DisplayPickup& pickup)
{
return ((pickup.Life <= 0.0f) && pickup.IsOffscreen());
}),
_displayPickups.end()); _displayPickups.end());
} }
void PickupSummaryController::DrawDebug() const void PickupSummaryController::DrawDebug() const
{ {
g_Renderer.PrintDebugMessage("Display pickups in summary: %d", _displayPickups.size()); PrintDebugMessage("Display pickups in summary: %d", _displayPickups.size());
} }
} }

View file

@ -25,24 +25,41 @@ namespace TEN::Hud
float StringScale = 0.0f; float StringScale = 0.0f;
float StringScalar = 0.0f; float StringScalar = 0.0f;
Vector2 PrevPosition = Vector2::Zero;
EulerAngles PrevOrientation = EulerAngles::Identity;
float PrevScale = 0.0f;
float PrevOpacity = 0.0f;
bool IsOffscreen() const; bool IsOffscreen() const;
void Update(bool isHead); void Update(bool isHead);
void StoreInterpolationData()
{
PrevPosition = Position;
PrevOrientation = Orientation;
PrevScale = Scale;
PrevOpacity = Opacity;
}
}; };
class PickupSummaryController class PickupSummaryController
{ {
private: private:
// Constants // Constants
static constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64; static constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64;
static constexpr auto DISPLAY_PICKUP_COUNT_ARG_DEFAULT = 1; static constexpr auto DISPLAY_PICKUP_COUNT_ARG_DEFAULT = 1;
// Members // Members
std::vector<DisplayPickup> _displayPickups = {}; std::vector<DisplayPickup> _displayPickups = {};
public: public:
// Utilities // Utilities
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector2& origin, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT); void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector2& origin, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT); void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
void AddDisplayPickup(const ItemInfo& item);
void Update(); void Update();
void Draw() const; void Draw() const;
@ -50,6 +67,7 @@ namespace TEN::Hud
private: private:
// Helpers // Helpers
std::vector<Vector2> GetStackPositions() const; std::vector<Vector2> GetStackPositions() const;
DisplayPickup& GetNewDisplayPickup(); DisplayPickup& GetNewDisplayPickup();
void ClearInactiveDisplayPickups(); void ClearInactiveDisplayPickups();

View file

@ -3,11 +3,12 @@
#include "Game/effects/DisplaySprite.h" #include "Game/effects/DisplaySprite.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer.h"
#include "Specific/clock.h" #include "Specific/clock.h"
#include "Renderer/Renderer.h"
using namespace TEN::Effects::DisplaySprite; using namespace TEN::Effects::DisplaySprite;
using namespace TEN::Math; using namespace TEN::Math;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
namespace TEN::Hud namespace TEN::Hud
@ -30,6 +31,8 @@ namespace TEN::Hud
return; return;
} }
StoreInterpolationData();
// Update life and updated value status. // Update life and updated value status.
_life = std::clamp(_life + (_hasValueUpdated ? 1.0f : -1.0f), 0.0f, LIFE_MAX * FPS); _life = std::clamp(_life + (_hasValueUpdated ? 1.0f : -1.0f), 0.0f, LIFE_MAX * FPS);
_hasValueUpdated = false; _hasValueUpdated = false;
@ -46,7 +49,7 @@ namespace TEN::Hud
void SpeedometerController::Draw() const void SpeedometerController::Draw() const
{ {
constexpr auto POS = Vector2(DISPLAY_SPACE_RES.x - (DISPLAY_SPACE_RES.x / 6), DISPLAY_SPACE_RES.y - (DISPLAY_SPACE_RES.y / 10)); constexpr auto POS = Vector2(DISPLAY_SPACE_RES.x - (DISPLAY_SPACE_RES.x / 6), DISPLAY_SPACE_RES.y - (DISPLAY_SPACE_RES.y / 10));
constexpr auto ORIENT_OFFSET = ANGLE(90.0f); constexpr auto POINTER_ANGLE_OFFSET = ANGLE(90.0f);
constexpr auto SCALE = Vector2(0.35f); constexpr auto SCALE = Vector2(0.35f);
constexpr auto DIAL_ELEMENT_SPRITE_ID = 0; constexpr auto DIAL_ELEMENT_SPRITE_ID = 0;
constexpr auto POINTER_ELEMENT_SPRITE_ID = 1; constexpr auto POINTER_ELEMENT_SPRITE_ID = 1;
@ -58,19 +61,22 @@ namespace TEN::Hud
if (_life <= 0.0f) if (_life <= 0.0f)
return; return;
auto color = Color(1.0f, 1.0f, 1.0f, _opacity); short pointerAngle = (short)Lerp(_prevPointerAngle, _pointerAngle, g_Renderer.GetInterpolationFactor());
auto color = Color(1.0f, 1.0f, 1.0f, Lerp(_prevOpacity, _opacity, g_Renderer.GetInterpolationFactor()));
// Draw dial. // Draw dial.
AddDisplaySprite( AddDisplaySprite(
ID_SPEEDOMETER, DIAL_ELEMENT_SPRITE_ID, ID_SPEEDOMETER, DIAL_ELEMENT_SPRITE_ID,
POS, 0, SCALE, color, POS, 0, SCALE, color,
DIAL_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend); DIAL_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
DisplaySpritePhase::Draw);
// Draw pointer. // Draw pointer.
AddDisplaySprite( AddDisplaySprite(
ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID, ID_SPEEDOMETER, POINTER_ELEMENT_SPRITE_ID,
POS, _pointerAngle + ORIENT_OFFSET, SCALE, color, POS, pointerAngle + POINTER_ANGLE_OFFSET, SCALE, color,
POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend); POINTER_PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BlendMode::AlphaBlend,
DisplaySpritePhase::Draw);
} }
void SpeedometerController::Clear() void SpeedometerController::Clear()
@ -80,10 +86,10 @@ namespace TEN::Hud
void SpeedometerController::DrawDebug() const void SpeedometerController::DrawDebug() const
{ {
g_Renderer.PrintDebugMessage("SPEEDOMETER DEBUG"); PrintDebugMessage("SPEEDOMETER DEBUG");
g_Renderer.PrintDebugMessage("Value: %.3f", _value); PrintDebugMessage("Value: %.3f", _value);
g_Renderer.PrintDebugMessage("Pointer angle: %.3f", _pointerAngle); PrintDebugMessage("Pointer angle: %.3f", _pointerAngle);
g_Renderer.PrintDebugMessage("Opacity: %.3f", _opacity); PrintDebugMessage("Opacity: %.3f", _opacity);
g_Renderer.PrintDebugMessage("Life: %.3f", _life / FPS); PrintDebugMessage("Life: %.3f", _life / FPS);
} }
} }

View file

@ -6,9 +6,11 @@ namespace TEN::Hud
{ {
private: private:
// Constants // Constants
static constexpr auto LIFE_MAX = 0.75f; static constexpr auto LIFE_MAX = 0.75f;
// Members // Members
bool _hasValueUpdated = false; bool _hasValueUpdated = false;
float _value = 0.0f; float _value = 0.0f;
@ -16,8 +18,18 @@ namespace TEN::Hud
float _opacity = 0.0f; float _opacity = 0.0f;
float _life = 0.0f; float _life = 0.0f;
short _prevPointerAngle = 0;
float _prevOpacity = 0.0f;
void StoreInterpolationData()
{
_prevPointerAngle = _pointerAngle;
_prevOpacity = _opacity;
}
public: public:
// Utilities // Utilities
void UpdateValue(float value); void UpdateValue(float value);
void Update(); void Update();

View file

@ -26,6 +26,7 @@ namespace TEN::Hud
{ {
private: private:
// Members // Members
StatusBar _airBar = {}; StatusBar _airBar = {};
StatusBar _exposureBar = {}; StatusBar _exposureBar = {};
StatusBar _healthBar = {}; StatusBar _healthBar = {};
@ -35,6 +36,7 @@ namespace TEN::Hud
public: public:
// Utilities // Utilities
void Initialize(const ItemInfo& item); void Initialize(const ItemInfo& item);
void Update(const ItemInfo& item); void Update(const ItemInfo& item);
void Draw(const ItemInfo& item) const; void Draw(const ItemInfo& item) const;
@ -42,12 +44,14 @@ namespace TEN::Hud
private: private:
// Update helpers // Update helpers
void UpdateAirBar(const ItemInfo& item); void UpdateAirBar(const ItemInfo& item);
void UpdateExposureBar(const ItemInfo& item); void UpdateExposureBar(const ItemInfo& item);
void UpdateHealthBar(const ItemInfo& item); void UpdateHealthBar(const ItemInfo& item);
void UpdateStaminaBar(const ItemInfo& item); void UpdateStaminaBar(const ItemInfo& item);
// Draw helpers // Draw helpers
void DrawStatusBar(float value, float criticalValue, const RendererHudBar& rHudBar, GAME_OBJECT_ID textureID, int frame, bool isPoisoned) const; void DrawStatusBar(float value, float criticalValue, const RendererHudBar& rHudBar, GAME_OBJECT_ID textureID, int frame, bool isPoisoned) const;
void DrawAirBar() const; void DrawAirBar() const;
void DrawExposureBar() const; void DrawExposureBar() const;

View file

@ -74,6 +74,9 @@ namespace TEN::Hud
constexpr auto ORIENT_LERP_ALPHA = 0.1f; constexpr auto ORIENT_LERP_ALPHA = 0.1f;
constexpr auto RADIUS_LERP_ALPHA = 0.2f; constexpr auto RADIUS_LERP_ALPHA = 0.2f;
if (Position.has_value())
StoreInterpolationData();
// Update active status. // Update active status.
IsActive = isActive; IsActive = isActive;
@ -133,30 +136,36 @@ namespace TEN::Hud
constexpr auto STATIC_ELEMENT_SPRITE_ID = 0; constexpr auto STATIC_ELEMENT_SPRITE_ID = 0;
constexpr auto SEGMENT_ELEMENT_SPRITE_ID = 1; constexpr auto SEGMENT_ELEMENT_SPRITE_ID = 1;
constexpr auto PRIORITY = 0; // TODO: Check later. May interfere with Lua display sprites. -- Sezz 2023.10.06 constexpr auto PRIORITY = 0; // TODO: Check later. May interfere with Lua display sprites. -- Sezz 2023.10.06
constexpr auto ALIGN_MODE = DisplaySpriteAlignMode::Center;
constexpr auto SCALE_MODE = DisplaySpriteScaleMode::Fill;
constexpr auto BLEND_MODE = BlendMode::Additive;
if (!Position.has_value()) if (!Position.has_value())
return; return;
auto pos0 = Vector2::Lerp(PrevPosition, *Position, g_Renderer.GetInterpolationFactor());
short orient0 = PrevOrientation + Geometry::GetShortestAngle(PrevOrientation, Orientation) * g_Renderer.GetInterpolationFactor();
float scale = Lerp(PrevScale, Scale, g_Renderer.GetInterpolationFactor());
auto color = Color::Lerp(PrevColor, Color, g_Renderer.GetInterpolationFactor());
// Draw main static element. // Draw main static element.
AddDisplaySprite( AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID, SPRITE_SEQUENCE_OBJECT_ID, STATIC_ELEMENT_SPRITE_ID,
*Position, Orientation, Vector2(Scale), Color, pos0, orient0, Vector2(scale), color,
PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE); PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
BlendMode::Additive, DisplaySpritePhase::Draw);
// Draw animated outer segment elements. // Draw animated outer segment elements.
for (const auto& segment : Segments) for (int i = 0; i < Segments.size(); i++)
{ {
auto pos = *Position + segment.PosOffset; const auto& segment = Segments[i];
short orient = Orientation + segment.OrientOffset; const auto& prevSegment = PrevSegments[i];
auto scale = Vector2(Scale / 2);
auto pos1 = pos0 + Vector2::Lerp(prevSegment.PosOffset, segment.PosOffset, g_Renderer.GetInterpolationFactor());
short orient1 = orient0 + (prevSegment.OrientOffset + (Geometry::GetShortestAngle(prevSegment.OrientOffset, segment.OrientOffset) * g_Renderer.GetInterpolationFactor()));
AddDisplaySprite( AddDisplaySprite(
SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID, SPRITE_SEQUENCE_OBJECT_ID, SEGMENT_ELEMENT_SPRITE_ID,
pos, orient, scale, Color, pos1, orient1, Vector2(scale / 2), color,
PRIORITY, ALIGN_MODE, SCALE_MODE, BLEND_MODE); PRIORITY, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fill,
BlendMode::Additive, DisplaySpritePhase::Draw);
} }
} }
@ -175,23 +184,23 @@ namespace TEN::Hud
// Loop over player targets. // Loop over player targets.
auto itemNumbers = std::vector<int>{}; auto itemNumbers = std::vector<int>{};
for (const auto* itemPtr : player.TargetList) for (const auto* item : player.TargetList)
{ {
if (itemPtr == nullptr) if (item == nullptr)
continue; continue;
// Collect item number. // Collect item number.
if (itemPtr->HitPoints != NOT_TARGETABLE) if (item->HitPoints != NOT_TARGETABLE)
itemNumbers.push_back(itemPtr->Index); itemNumbers.push_back(item->Index);
// Find crosshair at item number key. // Find crosshair at item number key.
auto it = _crosshairs.find(itemPtr->Index); auto it = _crosshairs.find(item->Index);
if (it == _crosshairs.end()) if (it == _crosshairs.end())
continue; continue;
// Set crosshair as primary or peripheral. // Set crosshair as primary or peripheral.
auto& crosshair = it->second; auto& crosshair = it->second;
if (player.TargetEntity != nullptr && itemPtr->Index == player.TargetEntity->Index) if (player.TargetEntity != nullptr && item->Index == player.TargetEntity->Index)
{ {
crosshair.SetPrimary(); crosshair.SetPrimary();
} }
@ -350,9 +359,9 @@ namespace TEN::Hud
for (const auto& [itemNumber, crosshair] : _crosshairs) for (const auto& [itemNumber, crosshair] : _crosshairs)
crosshair.IsPrimary ? primaryCount++ : peripheralCount++; crosshair.IsPrimary ? primaryCount++ : peripheralCount++;
g_Renderer.PrintDebugMessage("TARGET HIGHLIGHTER DEBUG"); PrintDebugMessage("TARGET HIGHLIGHTER DEBUG");
g_Renderer.PrintDebugMessage(g_Configuration.EnableTargetHighlighter ? "Enabled" : "Disabled"); PrintDebugMessage(g_Configuration.EnableTargetHighlighter ? "Enabled" : "Disabled");
g_Renderer.PrintDebugMessage("Primary crosshairs: %d", primaryCount); PrintDebugMessage("Primary crosshairs: %d", primaryCount);
g_Renderer.PrintDebugMessage("Peripheral crosshairs: %d", peripheralCount); PrintDebugMessage("Peripheral crosshairs: %d", peripheralCount);
} }
} }

View file

@ -15,11 +15,13 @@ namespace TEN::Hud
public: public:
// Constants // Constants
static constexpr auto COLOR_RED = Color(1.0f, 0.2f, 0.2f); static constexpr auto COLOR_RED = Color(1.0f, 0.2f, 0.2f);
static constexpr auto COLOR_GRAY = Color(0.7f, 0.7f, 0.7f, 0.7f); static constexpr auto COLOR_GRAY = Color(0.7f, 0.7f, 0.7f, 0.7f);
static constexpr auto SEGMENT_COUNT = 4; static constexpr auto SEGMENT_COUNT = 4;
// Members // Members
bool IsActive = false; bool IsActive = false;
bool IsPrimary = false; bool IsPrimary = false;
@ -34,37 +36,59 @@ namespace TEN::Hud
std::array<SegmentData, SEGMENT_COUNT> Segments = {}; std::array<SegmentData, SEGMENT_COUNT> Segments = {};
Vector2 PrevPosition = Vector2::Zero;
short PrevOrientation = 0;
float PrevScale = 0.0f;
Vector4 PrevColor = Vector4::Zero;
std::array<SegmentData, SEGMENT_COUNT> PrevSegments = {};
// Getters // Getters
float GetScale(float cameraDist) const; float GetScale(float cameraDist) const;
float GetRadius() const; float GetRadius() const;
Vector2 GetPositionOffset(short orientOffset) const; Vector2 GetPositionOffset(short orientOffset) const;
// Setters // Setters
void SetPrimary(); void SetPrimary();
void SetPeripheral(); void SetPeripheral();
// Utilities // Utilities
void Update(const Vector3& targetPos, bool isActive, bool doPulse); void Update(const Vector3& targetPos, bool isActive, bool doPulse);
void Draw() const; void Draw() const;
void StoreInterpolationData()
{
PrevPosition = *Position;
PrevOrientation = Orientation;
PrevScale = Scale;
PrevColor = Color;
PrevSegments = Segments;
}
}; };
class TargetHighlighterController class TargetHighlighterController
{ {
private: private:
// Members // Members
std::unordered_map<int, CrosshairData> _crosshairs = {}; // Key = item number. std::unordered_map<int, CrosshairData> _crosshairs = {}; // Key = item number.
public: public:
// Utilities // Utilities
void Update(const ItemInfo& playerItem); void Update(const ItemInfo& playerItem);
void Draw() const; void Draw() const;
void Clear(); void Clear();
private: private:
// Update helpers // Update helpers
void Update(const std::vector<int>& itemNumbers); void Update(const std::vector<int>& itemNumbers);
// Object helpers // Object helpers
CrosshairData& GetNewCrosshair(int itemNumber); CrosshairData& GetNewCrosshair(int itemNumber);
void AddCrosshair(int itemNumber, const Vector3& targetPos); void AddCrosshair(int itemNumber, const Vector3& targetPos);
void ClearInactiveCrosshairs(); void ClearInactiveCrosshairs();

View file

@ -3,6 +3,7 @@
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/collision/floordata.h" #include "Game/collision/floordata.h"
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/items.h" #include "Game/items.h"
@ -14,6 +15,7 @@
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Input; using namespace TEN::Input;
namespace TEN::Entities::Player namespace TEN::Entities::Player
@ -35,8 +37,8 @@ namespace TEN::Entities::Player
const auto& player = GetLaraInfo(item); const auto& player = GetLaraInfo(item);
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision. auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 1) Test if player is already aligned with floor. // 1) Test if player is already aligned with floor.
if (relFloorHeight == 0) if (relFloorHeight == 0)
@ -61,8 +63,8 @@ namespace TEN::Entities::Player
constexpr auto UPPER_FLOOR_BOUND_DOWN = CLICK(0.75f); constexpr auto UPPER_FLOOR_BOUND_DOWN = CLICK(0.75f);
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision. auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Height offset required for correct bridge collision.
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// Determine appropriate floor bounds. // Determine appropriate floor bounds.
int lowerFloorBound = isGoingUp ? LOWER_FLOOR_BOUND_UP : LOWER_FLOOR_BOUND_DOWN; int lowerFloorBound = isGoingUp ? LOWER_FLOOR_BOUND_UP : LOWER_FLOOR_BOUND_DOWN;
@ -167,30 +169,30 @@ namespace TEN::Entities::Player
int playerHeight = isCrawling ? LARA_HEIGHT_CRAWL : coll.Setup.Height; int playerHeight = isCrawling ? LARA_HEIGHT_CRAWL : coll.Setup.Height;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, setup.HeadingAngle, OFFSET_RADIUS(playerRadius), -playerHeight); auto pointColl = GetPointCollision(item, setup.HeadingAngle, OFFSET_RADIUS(playerRadius), -playerHeight);
int vPos = item.Pose.Position.y; int vPos = item.Pose.Position.y;
int vPosTop = vPos - playerHeight; int vPosTop = vPos - playerHeight;
// Calculate slope aspect delta angle. // Calculate slope aspect delta angle.
short aspectAngle = Geometry::GetSurfaceAspectAngle(pointColl.FloorNormal); short aspectAngle = Geometry::GetSurfaceAspectAngle(pointColl.GetFloorNormal());
short aspectAngleDelta = Geometry::GetShortestAngle(setup.HeadingAngle, aspectAngle); short aspectAngleDelta = Geometry::GetShortestAngle(setup.HeadingAngle, aspectAngle);
// 1) Check for slippery slope below floor (if applicable). // 1) Check for illegal slope below floor (if applicable).
if (setup.TestSlipperySlopeBelow && if (setup.TestSteepFloorBelow &&
(pointColl.Position.FloorSlope && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX)) (pointColl.IsSteepFloor() && abs(aspectAngleDelta) <= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{ {
return false; return false;
} }
// 1) Check for slippery slope above floor (if applicable). // 1) Check for illegal slope above floor (if applicable).
if (setup.TestSlipperySlopeAbove && if (setup.TestSteepFloorAbove &&
(pointColl.Position.FloorSlope && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX)) (pointColl.IsSteepFloor() && abs(aspectAngleDelta) >= SLOPE_ASPECT_ANGLE_DELTA_MAX))
{ {
return false; return false;
} }
// 3) Check for death floor (if applicable). // 3) Check for death floor (if applicable).
if (setup.TestDeathFloor && pointColl.Block->Flags.Death) if (setup.TestDeathFloor && pointColl.GetSector().Flags.Death && pointColl.GetFloorBridgeItemNumber() == NO_VALUE)
return false; return false;
// LOS setup at upper floor bound. // LOS setup at upper floor bound.
@ -200,9 +202,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z, item.Pose.Position.z,
item.RoomNumber); item.RoomNumber);
auto target0 = GameVector( auto target0 = GameVector(
pointColl.Coordinates.x, pointColl.GetPosition().x,
(vPos + setup.UpperFloorBound) - 1, (vPos + setup.UpperFloorBound) - 1,
pointColl.Coordinates.z, pointColl.GetPosition().z,
item.RoomNumber); item.RoomNumber);
// LOS setup at lowest ceiling bound (player height). // LOS setup at lowest ceiling bound (player height).
@ -212,9 +214,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z, item.Pose.Position.z,
item.RoomNumber); item.RoomNumber);
auto target1 = GameVector( auto target1 = GameVector(
pointColl.Coordinates.x, pointColl.GetPosition().x,
vPosTop + 1, vPosTop + 1,
pointColl.Coordinates.z, pointColl.GetPosition().z,
item.RoomNumber); item.RoomNumber);
// Calculate LOS direction. // Calculate LOS direction.
@ -232,9 +234,9 @@ namespace TEN::Entities::Player
if (!LOS(&origin0, &target0) || !LOS(&origin1, &target1)) if (!LOS(&origin0, &target0) || !LOS(&origin1, &target1))
return false; return false;
int relFloorHeight = pointColl.Position.Floor - vPos; int relFloorHeight = pointColl.GetFloorHeight() - vPos;
int relCeilHeight = pointColl.Position.Ceiling - vPos; int relCeilHeight = pointColl.GetCeilingHeight() - vPos;
int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor); int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 6) Assess point collision. // 6) Assess point collision.
if (relFloorHeight <= setup.LowerFloorBound && // Floor height is above lower floor bound. if (relFloorHeight <= setup.LowerFloorBound && // Floor height is above lower floor bound.
@ -400,12 +402,12 @@ namespace TEN::Entities::Player
return false; return false;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); // NOTE: Offset required for correct bridge collision. auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2); // NOTE: Offset required for correct bridge collision.
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 2) Assess point collision. // 2) Assess point collision.
if (abs(relFloorHeight) <= ABS_FLOOR_BOUND && // Floor height is within upper/lower floor bounds. if (abs(relFloorHeight) <= ABS_FLOOR_BOUND && // Floor height is within upper/lower floor bounds.
pointColl.Position.FloorSlope) // Floor is a slippery slope. pointColl.IsSteepFloor()) // Floor is a slippery slope.
{ {
return true; return true;
} }
@ -432,8 +434,8 @@ namespace TEN::Entities::Player
float radius = TestState(item.Animation.ActiveState, CROUCH_STATES) ? LARA_RADIUS_CRAWL : LARA_RADIUS; float radius = TestState(item.Animation.ActiveState, CROUCH_STATES) ? LARA_RADIUS_CRAWL : LARA_RADIUS;
// Get center point collision. // Get center point collision.
auto pointCollCenter = GetCollision(&item, 0, 0.0f, -LARA_HEIGHT / 2); auto pointCollCenter = GetPointCollision(item, 0, 0.0f, -LARA_HEIGHT / 2);
int floorToCeilHeightCenter = abs(pointCollCenter.Position.Ceiling - pointCollCenter.Position.Floor); int floorToCeilHeightCenter = abs(pointCollCenter.GetCeilingHeight() - pointCollCenter.GetFloorHeight());
// Assess center point collision. // Assess center point collision.
if (floorToCeilHeightCenter < LARA_HEIGHT || // Floor-to-ceiling height isn't too wide. if (floorToCeilHeightCenter < LARA_HEIGHT || // Floor-to-ceiling height isn't too wide.
@ -445,9 +447,9 @@ namespace TEN::Entities::Player
// TODO: Check whether < or <= and > or >=. // TODO: Check whether < or <= and > or >=.
// Get front point collision. // Get front point collision.
auto pointCollFront = GetCollision(&item, item.Pose.Orientation.y, radius, -coll.Setup.Height); auto pointCollFront = GetPointCollision(item, item.Pose.Orientation.y, radius, -coll.Setup.Height);
int floorToCeilHeightFront = abs(pointCollFront.Position.Ceiling - pointCollFront.Position.Floor); int floorToCeilHeightFront = abs(pointCollFront.GetCeilingHeight() - pointCollFront.GetFloorHeight());
int relFloorHeightFront = abs(pointCollFront.Position.Floor - pointCollCenter.Position.Floor); int relFloorHeightFront = abs(pointCollFront.GetFloorHeight() - pointCollCenter.GetFloorHeight());
// Assess front point collision. // Assess front point collision.
if (relFloorHeightFront <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds. if (relFloorHeightFront <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds.
@ -458,9 +460,9 @@ namespace TEN::Entities::Player
} }
// Get back point collision. // Get back point collision.
auto pointCollBack = GetCollision(&item, item.Pose.Orientation.y, -radius, -coll.Setup.Height); auto pointCollBack = GetPointCollision(item, item.Pose.Orientation.y, -radius, -coll.Setup.Height);
int floorToCeilHeightBack = abs(pointCollBack.Position.Ceiling - pointCollBack.Position.Floor); int floorToCeilHeightBack = abs(pointCollBack.GetCeilingHeight() - pointCollBack.GetFloorHeight());
int relFloorHeightBack = abs(pointCollBack.Position.Floor - pointCollCenter.Position.Floor); int relFloorHeightBack = abs(pointCollBack.GetFloorHeight() - pointCollCenter.GetFloorHeight());
// Assess back point collision. // Assess back point collision.
if (relFloorHeightBack <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds. if (relFloorHeightBack <= CRAWL_STEPUP_HEIGHT && // Floor is within upper/lower floor bounds.
@ -526,22 +528,22 @@ namespace TEN::Entities::Player
// TODO: Extend point collision struct to also find water depths. // TODO: Extend point collision struct to also find water depths.
float dist = 0.0f; float dist = 0.0f;
auto pointColl0 = GetCollision(&item); auto pointColl0 = GetPointCollision(item);
// 3) Test continuity of path. // 3) Test continuity of path.
while (dist < PROBE_DIST_MAX) while (dist < PROBE_DIST_MAX)
{ {
// Get point collision. // Get point collision.
dist += STEP_DIST; dist += STEP_DIST;
auto pointColl1 = GetCollision(&item, item.Pose.Orientation.y, dist, -LARA_HEIGHT_CRAWL); auto pointColl1 = GetPointCollision(item, item.Pose.Orientation.y, dist, -LARA_HEIGHT_CRAWL);
int floorHeightDelta = abs(pointColl0.Position.Floor - pointColl1.Position.Floor); int floorHeightDelta = abs(pointColl0.GetFloorHeight() - pointColl1.GetFloorHeight());
int floorToCeilHeight = abs(pointColl1.Position.Ceiling - pointColl1.Position.Floor); int floorToCeilHeight = abs(pointColl1.GetCeilingHeight() - pointColl1.GetFloorHeight());
// Assess point collision. // Assess point collision.
if (floorHeightDelta > FLOOR_BOUND || // Avoid floor height delta beyond crawl stepup threshold. if (floorHeightDelta > FLOOR_BOUND || // Avoid floor height delta beyond crawl stepup threshold.
floorToCeilHeight <= FLOOR_TO_CEIL_HEIGHT_MAX || // Avoid narrow spaces. floorToCeilHeight <= FLOOR_TO_CEIL_HEIGHT_MAX || // Avoid narrow spaces.
pointColl1.Position.FloorSlope) // Avoid slippery floor slopes. pointColl1.IsSteepFloor()) // Avoid slippery floor slopes.
{ {
return false; return false;
} }
@ -580,8 +582,8 @@ namespace TEN::Entities::Player
constexpr auto UPPER_CEIL_BOUND = -MONKEY_STEPUP_HEIGHT; constexpr auto UPPER_CEIL_BOUND = -MONKEY_STEPUP_HEIGHT;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY); int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
// Assess point collision. // Assess point collision.
if (relCeilHeight <= LOWER_CEIL_BOUND && // Ceiling height is above lower ceiling bound. if (relCeilHeight <= LOWER_CEIL_BOUND && // Ceiling height is above lower ceiling bound.
@ -604,14 +606,14 @@ namespace TEN::Entities::Player
return true; return true;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
// 2) Test for slippery ceiling slope and check if overhang climb is disabled. // 2) Test for slippery ceiling slope and check if overhang climb is disabled.
if (pointColl.Position.CeilingSlope && !g_GameFlow->HasOverhangClimb()) if (pointColl.IsSteepCeiling() && !g_GameFlow->HasOverhangClimb())
return true; return true;
// 3) Assess point collision. // 3) Assess point collision.
int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY); int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
if (abs(relCeilHeight) > ABS_CEIL_BOUND) // Ceiling height is within lower/upper ceiling bound. if (abs(relCeilHeight) > ABS_CEIL_BOUND) // Ceiling height is within lower/upper ceiling bound.
return true; return true;
@ -630,9 +632,9 @@ namespace TEN::Entities::Player
return false; return false;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_MONKEY); int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_MONKEY);
int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor); int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 2) Assess collision with ceiling. // 2) Assess collision with ceiling.
if (relCeilHeight < 0 && if (relCeilHeight < 0 &&
@ -658,14 +660,14 @@ namespace TEN::Entities::Player
constexpr auto PLAYER_HEIGHT = LARA_HEIGHT_MONKEY; constexpr auto PLAYER_HEIGHT = LARA_HEIGHT_MONKEY;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, setup.HeadingAngle, OFFSET_RADIUS(coll.Setup.Radius)); auto pointColl = GetPointCollision(item, setup.HeadingAngle, OFFSET_RADIUS(coll.Setup.Radius));
// 1) Test if ceiling is monkey swing. // 1) Test if ceiling is monkey swing.
if (!pointColl.BottomBlock->Flags.Monkeyswing) if (!pointColl.GetBottomSector().Flags.Monkeyswing)
return false; return false;
// 2) Test for ceiling slippery slope. // 2) Test for illegal ceiling.
if (pointColl.Position.CeilingSlope) if (pointColl.IsSteepCeiling())
return false; return false;
int vPos = item.Pose.Position.y; int vPos = item.Pose.Position.y;
@ -678,9 +680,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z, item.Pose.Position.z,
item.RoomNumber); item.RoomNumber);
auto target0 = GameVector( auto target0 = GameVector(
pointColl.Coordinates.x, pointColl.GetPosition().x,
vPos - 1, vPos - 1,
pointColl.Coordinates.z, pointColl.GetPosition().z,
item.RoomNumber); item.RoomNumber);
// Raycast setup at lower ceiling bound. // Raycast setup at lower ceiling bound.
@ -690,9 +692,9 @@ namespace TEN::Entities::Player
item.Pose.Position.z, item.Pose.Position.z,
item.RoomNumber); item.RoomNumber);
auto target1 = GameVector( auto target1 = GameVector(
pointColl.Coordinates.x, pointColl.GetPosition().x,
(vPosTop + setup.LowerCeilingBound) + 1, (vPosTop + setup.LowerCeilingBound) + 1,
pointColl.Coordinates.z, pointColl.GetPosition().z,
item.RoomNumber); item.RoomNumber);
// Prepare data for static object LOS. // Prepare data for static object LOS.
@ -712,9 +714,9 @@ namespace TEN::Entities::Player
// TODO: Assess static object geometry ray collision. // TODO: Assess static object geometry ray collision.
int relFloorHeight = pointColl.Position.Floor - vPos; int relFloorHeight = pointColl.GetFloorHeight() - vPos;
int relCeilHeight = pointColl.Position.Ceiling - vPosTop; int relCeilHeight = pointColl.GetCeilingHeight() - vPosTop;
int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor); int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// 4) Assess point collision. // 4) Assess point collision.
if (relFloorHeight > 0 && // Floor is within highest floor bound (player base). if (relFloorHeight > 0 && // Floor is within highest floor bound (player base).
@ -782,8 +784,8 @@ namespace TEN::Entities::Player
return false; return false;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, 0, 0, -coll.Setup.Height / 2); auto pointColl = GetPointCollision(item, 0, 0, -coll.Setup.Height / 2);
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
// 2) Assess point collision. // 2) Assess point collision.
if (relFloorHeight > UPPER_FLOOR_BOUND) // Floor height is below upper floor bound. if (relFloorHeight > UPPER_FLOOR_BOUND) // Floor height is below upper floor bound.
@ -805,11 +807,11 @@ namespace TEN::Entities::Player
return true; return true;
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
int vPos = item.Pose.Position.y; int vPos = item.Pose.Position.y;
// 3) Assess point collision. // 3) Assess point collision.
if ((pointColl.Position.Floor - vPos) <= projVerticalVel) // Floor height is above projected vertical position. if ((pointColl.GetFloorHeight() - vPos) <= projVerticalVel) // Floor height is above projected vertical position.
return true; return true;
return false; return false;
@ -848,9 +850,9 @@ namespace TEN::Entities::Player
return false;*/ return false;*/
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, setup.HeadingAngle, setup.Distance, -coll.Setup.Height); auto pointColl = GetPointCollision(item, setup.HeadingAngle, setup.Distance, -coll.Setup.Height);
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y; int relCeilHeight = pointColl.GetCeilingHeight() - item.Pose.Position.y;
// 4) Assess point collision. // 4) Assess point collision.
if (relFloorHeight >= -STEPUP_HEIGHT && // Floor is within highest floor bound. if (relFloorHeight >= -STEPUP_HEIGHT && // Floor is within highest floor bound.
@ -923,11 +925,11 @@ namespace TEN::Entities::Player
return IsRunJumpQueueableState(item.Animation.TargetState); return IsRunJumpQueueableState(item.Animation.TargetState);
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item, item.Pose.Orientation.y, BLOCK(1), -coll.Setup.Height); auto pointColl = GetPointCollision(item, item.Pose.Orientation.y, BLOCK(1), -coll.Setup.Height);
int lowerCeilingBound = (LOWER_CEIL_BOUND_BASE - coll.Setup.Height); int lowerCeilingBound = (LOWER_CEIL_BOUND_BASE - coll.Setup.Height);
int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; int relFloorHeight = pointColl.GetFloorHeight() - item.Pose.Position.y;
int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y; int relCeilHeight = pointColl.GetCeilingHeight() - item.Pose.Position.y;
// 2) Assess point collision for possible running jump ahead. // 2) Assess point collision for possible running jump ahead.
if (relCeilHeight < lowerCeilingBound || // Ceiling height is above lower ceiling bound. if (relCeilHeight < lowerCeilingBound || // Ceiling height is above lower ceiling bound.
@ -993,7 +995,7 @@ namespace TEN::Entities::Player
// TODO: Broken on diagonal slides? // TODO: Broken on diagonal slides?
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
//short aspectAngle = GetLaraSlideHeadingAngle(item, coll); //short aspectAngle = GetLaraSlideHeadingAngle(item, coll);
//short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetSurfaceNormal(pointColl.FloorTilt, true)); //short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetSurfaceNormal(pointColl.FloorTilt, true));
@ -1002,8 +1004,8 @@ namespace TEN::Entities::Player
bool CanCrawlspaceDive(const ItemInfo& item, const CollisionInfo& coll) bool CanCrawlspaceDive(const ItemInfo& item, const CollisionInfo& coll)
{ {
auto pointColl = GetCollision(&item, coll.Setup.ForwardAngle, coll.Setup.Radius, -coll.Setup.Height); auto pointColl = GetPointCollision(item, coll.Setup.ForwardAngle, coll.Setup.Radius, -coll.Setup.Height);
return (abs(pointColl.Position.Ceiling - pointColl.Position.Floor) < LARA_HEIGHT || IsInLowSpace(item, coll)); return (abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight()) < LARA_HEIGHT || IsInLowSpace(item, coll));
} }
bool CanPerformLedgeJump(const ItemInfo& item, const CollisionInfo& coll) bool CanPerformLedgeJump(const ItemInfo& item, const CollisionInfo& coll)
@ -1031,8 +1033,8 @@ namespace TEN::Entities::Player
// TODO: Assess static object geometry ray collision. // TODO: Assess static object geometry ray collision.
// Get point collision. // Get point collision.
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
int relCeilHeight = pointColl.Position.Ceiling - (item.Pose.Position.y - LARA_HEIGHT_STRETCH); int relCeilHeight = pointColl.GetCeilingHeight() - (item.Pose.Position.y - LARA_HEIGHT_STRETCH);
// 3) Assess point collision. // 3) Assess point collision.
if (relCeilHeight >= -coll.Setup.Height) // Ceiling height is below upper ceiling bound. if (relCeilHeight >= -coll.Setup.Height) // Ceiling height is below upper ceiling bound.
@ -1045,10 +1047,10 @@ namespace TEN::Entities::Player
{ {
const auto& player = GetLaraInfo(item); const auto& player = GetLaraInfo(item);
auto pointColl = GetCollision(&item); auto pointColl = GetPointCollision(item);
if (player.Control.Tightrope.CanDismount && // Dismount is allowed. if (player.Control.Tightrope.CanDismount && // Dismount is allowed.
pointColl.Position.Floor == item.Pose.Position.y) // Floor is level with player. pointColl.GetFloorHeight() == item.Pose.Position.y) // Floor is level with player.
{ {
return true; return true;
} }

View file

@ -8,9 +8,9 @@ namespace TEN::Entities::Player
int LowerFloorBound = 0; int LowerFloorBound = 0;
int UpperFloorBound = 0; int UpperFloorBound = 0;
bool TestSlipperySlopeBelow = true; bool TestSteepFloorBelow = true;
bool TestSlipperySlopeAbove = true; bool TestSteepFloorAbove = true;
bool TestDeathFloor = true; bool TestDeathFloor = true;
}; };
struct MonkeySwingMovementSetupData struct MonkeySwingMovementSetupData

View file

@ -71,7 +71,7 @@ namespace TEN::Entities::Player
PlayerBehaviorStateRoutines[LS_PUSHABLE_PUSH] = std::pair(lara_as_pushable_push, lara_default_col); PlayerBehaviorStateRoutines[LS_PUSHABLE_PUSH] = std::pair(lara_as_pushable_push, lara_default_col);
PlayerBehaviorStateRoutines[LS_PUSHABLE_PULL] = std::pair(lara_as_pushable_pull, lara_default_col); PlayerBehaviorStateRoutines[LS_PUSHABLE_PULL] = std::pair(lara_as_pushable_pull, lara_default_col);
PlayerBehaviorStateRoutines[LS_PUSHABLE_GRAB] = std::pair(lara_as_pushable_grab, lara_default_col); PlayerBehaviorStateRoutines[LS_PUSHABLE_GRAB] = std::pair(lara_as_pushable_grab, lara_default_col);
PlayerBehaviorStateRoutines[LS_PICKUP] = std::pair(lara_as_pickup, lara_default_col); PlayerBehaviorStateRoutines[LS_PICKUP] = std::pair(lara_as_pickup, lara_col_pickup);
PlayerBehaviorStateRoutines[LS_SWITCH_DOWN] = std::pair(lara_as_switch_on, lara_default_col); PlayerBehaviorStateRoutines[LS_SWITCH_DOWN] = std::pair(lara_as_switch_on, lara_default_col);
PlayerBehaviorStateRoutines[LS_SWITCH_UP] = std::pair(lara_as_switch_off, lara_default_col); PlayerBehaviorStateRoutines[LS_SWITCH_UP] = std::pair(lara_as_switch_off, lara_default_col);
PlayerBehaviorStateRoutines[LS_INSERT_KEY] = std::pair(lara_as_use_key, lara_default_col); PlayerBehaviorStateRoutines[LS_INSERT_KEY] = std::pair(lara_as_use_key, lara_default_col);
@ -99,7 +99,7 @@ namespace TEN::Entities::Player
PlayerBehaviorStateRoutines[LS_TEST_3] = std::pair(lara_void_func, lara_void_func); PlayerBehaviorStateRoutines[LS_TEST_3] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_WADE_FORWARD] = std::pair(lara_as_wade_forward, lara_col_wade_forward); PlayerBehaviorStateRoutines[LS_WADE_FORWARD] = std::pair(lara_as_wade_forward, lara_col_wade_forward);
PlayerBehaviorStateRoutines[LS_UNDERWATER_ROLL] = std::pair(lara_as_underwater_roll_180, lara_col_underwater_roll_180); PlayerBehaviorStateRoutines[LS_UNDERWATER_ROLL] = std::pair(lara_as_underwater_roll_180, lara_col_underwater_roll_180);
PlayerBehaviorStateRoutines[LS_PICKUP_FLARE] = std::pair(lara_as_pickup_flare, lara_default_col); PlayerBehaviorStateRoutines[LS_PICKUP_FLARE] = std::pair(lara_as_pickup_flare, lara_col_pickup);
PlayerBehaviorStateRoutines[LS_JUMP_ROLL_180] = std::pair(lara_void_func, lara_void_func); PlayerBehaviorStateRoutines[LS_JUMP_ROLL_180] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_KICK] = std::pair(lara_void_func, lara_void_func); PlayerBehaviorStateRoutines[LS_KICK] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_ZIP_LINE] = std::pair(lara_as_zip_line, lara_void_func); PlayerBehaviorStateRoutines[LS_ZIP_LINE] = std::pair(lara_as_zip_line, lara_void_func);

View file

@ -24,6 +24,7 @@
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/floordata.h" #include "Game/collision/floordata.h"
#include "Game/collision/Point.h"
#include "Game/control/flipeffect.h" #include "Game/control/flipeffect.h"
#include "Game/control/volume.h" #include "Game/control/volume.h"
#include "Game/effects/Hair.h" #include "Game/effects/Hair.h"
@ -47,6 +48,7 @@
#include "Specific/winmain.h" #include "Specific/winmain.h"
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Control::Volumes; using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Hair; using namespace TEN::Effects::Hair;
using namespace TEN::Effects::Items; using namespace TEN::Effects::Items;
@ -57,8 +59,8 @@ using namespace TEN::Gui;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
LaraInfo Lara = {}; LaraInfo Lara = {};
ItemInfo* LaraItem; ItemInfo* LaraItem = nullptr;
CollisionInfo LaraCollision = {}; CollisionInfo LaraCollision = {};
void LaraControl(ItemInfo* item, CollisionInfo* coll) void LaraControl(ItemInfo* item, CollisionInfo* coll)
@ -152,7 +154,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
} }
else if (item->Animation.ActiveState == LS_FREEFALL_DIVE) else if (item->Animation.ActiveState == LS_FREEFALL_DIVE)
{ {
SetAnimation(item, LA_SWANDIVE_DIVE); SetAnimation(item, LA_SWANDIVE_FREEFALL_DIVE);
item->Animation.Velocity.y /= 2; item->Animation.Velocity.y /= 2;
item->Pose.Orientation.x = ANGLE(-85.0f); item->Pose.Orientation.x = ANGLE(-85.0f);
player.Control.HandStatus = HandStatus::Free; player.Control.HandStatus = HandStatus::Free;
@ -207,7 +209,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
// pre-TR5 bug where player would keep submerged until root mesh was above water level. // pre-TR5 bug where player would keep submerged until root mesh was above water level.
isWaterOnHeadspace = TestEnvironment( isWaterOnHeadspace = TestEnvironment(
ENV_FLAG_WATER, item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, ENV_FLAG_WATER, item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z,
GetCollision(item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, item->RoomNumber).RoomNumber); GetPointCollision(*item, 0, 0, -CLICK(1)).GetRoomNumber());
if (water.WaterDepth == NO_HEIGHT || abs(water.HeightFromWater) >= CLICK(1) || isWaterOnHeadspace || if (water.WaterDepth == NO_HEIGHT || abs(water.HeightFromWater) >= CLICK(1) || isWaterOnHeadspace ||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE || item->Animation.AnimNumber == LA_ONWATER_DIVE) item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE || item->Animation.AnimNumber == LA_ONWATER_DIVE)
@ -333,7 +335,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (DebugMode) if (DebugMode)
{ {
DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box); DrawNearbyPathfinding(GetPointCollision(*item).GetBottomSector().PathfindingBoxID);
DrawNearbySectorFlags(*item); DrawNearbySectorFlags(*item);
} }
} }
@ -354,14 +356,13 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
coll->Setup.BlockMonkeySwingEdge = false; coll->Setup.BlockMonkeySwingEdge = false;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = true; coll->Setup.EnableSpasm = true;
coll->Setup.ForceSolidStatics = false;
coll->Setup.PrevPosition = item->Pose.Position; coll->Setup.PrevPosition = item->Pose.Position;
coll->Setup.PrevAnimObjectID = item->Animation.AnimObjectID; coll->Setup.PrevAnimObjectID = item->Animation.AnimObjectID;
coll->Setup.PrevAnimNumber = item->Animation.AnimNumber; coll->Setup.PrevAnimNumber = item->Animation.AnimNumber;
coll->Setup.PrevFrameNumber = item->Animation.FrameNumber; coll->Setup.PrevFrameNumber = item->Animation.FrameNumber;
coll->Setup.PrevState = item->Animation.ActiveState; coll->Setup.PrevState = item->Animation.ActiveState;
UpdateLaraRoom(item, -LARA_HEIGHT / 2);
// Handle look-around. // Handle look-around.
if (((IsHeld(In::Look) && CanPlayerLookAround(*item)) || if (((IsHeld(In::Look) && CanPlayerLookAround(*item)) ||
(player.Control.Look.IsUsingBinoculars || player.Control.Look.IsUsingLasersight)) && (player.Control.Look.IsUsingBinoculars || player.Control.Look.IsUsingLasersight)) &&
@ -376,6 +377,8 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
} }
player.Control.Look.Mode = LookMode::None; player.Control.Look.Mode = LookMode::None;
UpdateLaraRoom(item, -LARA_HEIGHT / 2);
// Process vehicles. // Process vehicles.
if (HandleLaraVehicle(item, coll)) if (HandleLaraVehicle(item, coll))
return; return;
@ -424,6 +427,7 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
coll->Setup.BlockMonkeySwingEdge = false; coll->Setup.BlockMonkeySwingEdge = false;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
coll->Setup.ForceSolidStatics = false;
coll->Setup.PrevPosition = item->Pose.Position; coll->Setup.PrevPosition = item->Pose.Position;
// Handle look-around. // Handle look-around.
@ -496,6 +500,7 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
coll->Setup.BlockMonkeySwingEdge = false; coll->Setup.BlockMonkeySwingEdge = false;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
coll->Setup.ForceSolidStatics = false;
coll->Setup.PrevPosition = item->Pose.Position; coll->Setup.PrevPosition = item->Pose.Position;
// Handle look-around. // Handle look-around.
@ -626,6 +631,7 @@ void UpdateLara(ItemInfo* item, bool isTitle)
// Control player. // Control player.
InItemControlLoop = true; InItemControlLoop = true;
LaraControl(item, &LaraCollision); LaraControl(item, &LaraCollision);
HandlePlayerFlyCheat(*item); HandlePlayerFlyCheat(*item);
InItemControlLoop = false; InItemControlLoop = false;
@ -634,17 +640,11 @@ void UpdateLara(ItemInfo* item, bool isTitle)
if (isTitle) if (isTitle)
ActionMap = actionMap; ActionMap = actionMap;
if (g_Gui.GetInventoryItemChosen() != NO_VALUE)
{
g_Gui.SetInventoryItemChosen(NO_VALUE);
SayNo();
}
// Update player animations. // Update player animations.
g_Renderer.UpdateLaraAnimations(true); g_Renderer.UpdateLaraAnimations(true);
// Update player effects. // Update player effects.
HairEffect.Update(*item, g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young); HairEffect.Update(*item);
HandlePlayerWetnessDrips(*item); HandlePlayerWetnessDrips(*item);
HandlePlayerDiveBubbles(*item); HandlePlayerDiveBubbles(*item);
ProcessEffects(item); ProcessEffects(item);

View file

@ -93,8 +93,8 @@ constexpr auto WADE_WATER_DEPTH = STEPUP_HEIGHT;
constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f); constexpr auto SWIM_WATER_DEPTH = CLICK(2.75f);
constexpr auto SLOPE_DIFFERENCE = 60; constexpr auto SLOPE_DIFFERENCE = 60;
extern LaraInfo Lara; extern LaraInfo Lara;
extern ItemInfo* LaraItem; extern ItemInfo* LaraItem;
extern CollisionInfo LaraCollision; extern CollisionInfo LaraCollision;
void LaraControl(ItemInfo* item, CollisionInfo* coll); void LaraControl(ItemInfo* item, CollisionInfo* coll);

View file

@ -39,17 +39,7 @@ void lara_void_func(ItemInfo* item, CollisionInfo* coll)
void lara_default_col(ItemInfo* item, CollisionInfo* coll) void lara_default_col(ItemInfo* item, CollisionInfo* coll)
{ {
auto& player = GetLaraInfo(*item); LaraDefaultCollision(item, coll);
player.Control.MoveAngle = item->Pose.Orientation.y;
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
coll->Setup.BlockFloorSlopeDown = true;
coll->Setup.BlockFloorSlopeUp = true;
coll->Setup.ForwardAngle = player.Control.MoveAngle;
GetCollisionInfo(coll, item);
LaraResetGravityStatus(item, coll);
} }
// Boulder death. // Boulder death.

View file

@ -3,7 +3,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/sphere.h" #include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
@ -14,6 +14,7 @@
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Input; using namespace TEN::Input;
constexpr auto LADDER_TEST_MARGIN = 8; constexpr auto LADDER_TEST_MARGIN = 8;
@ -327,8 +328,8 @@ void lara_col_climb_idle(ItemInfo* item, CollisionInfo* coll)
// HACK: Prevent climbing inside sloped ceilings. Breaks overhang even more, but that shouldn't matter since we'll be doing it over. -- Sezz 2022.05.13 // HACK: Prevent climbing inside sloped ceilings. Breaks overhang even more, but that shouldn't matter since we'll be doing it over. -- Sezz 2022.05.13
int y = item->Pose.Position.y - (coll->Setup.Height + CLICK(0.5f)); int y = item->Pose.Position.y - (coll->Setup.Height + CLICK(0.5f));
auto probe = GetCollision(item, 0, 0, -(coll->Setup.Height + CLICK(0.5f))); auto probe = GetPointCollision(*item, 0, 0, -(coll->Setup.Height + CLICK(0.5f)));
if ((probe.Position.Ceiling - y) < 0) if ((probe.GetCeilingHeight() - y) < 0)
{ {
item->Animation.TargetState = LS_LADDER_UP; item->Animation.TargetState = LS_LADDER_UP;
item->Pose.Position.y += yShift; item->Pose.Position.y += yShift;
@ -416,7 +417,7 @@ void lara_as_climb_stepoff_right(ItemInfo* item, CollisionInfo* coll)
short GetClimbFlags(int x, int y, int z, short roomNumber) short GetClimbFlags(int x, int y, int z, short roomNumber)
{ {
return GetClimbFlags(GetCollision(x, y, z, roomNumber).BottomBlock); return GetClimbFlags(&GetPointCollision(Vector3i(x, y, z), roomNumber).GetBottomSector());
} }
short GetClimbFlags(FloorInfo* floor) short GetClimbFlags(FloorInfo* floor)
@ -787,13 +788,13 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
int y = item->Pose.Position.y + yOffset; int y = item->Pose.Position.y + yOffset;
int z = item->Pose.Position.z + zOffset; int z = item->Pose.Position.z + zOffset;
auto probeUp = GetCollision(x, y - CLICK(0.5f), z, item->RoomNumber); auto probeUp = GetPointCollision(Vector3i(x, y - CLICK(0.5f), z), item->RoomNumber);
auto probeDown = GetCollision(x, y, z, item->RoomNumber); auto probeDown = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
if (!lara->Control.CanClimbLadder && !TestLaraNearClimbableWall(item, probeDown.BottomBlock)) if (!lara->Control.CanClimbLadder && !TestLaraNearClimbableWall(item, &probeDown.GetBottomSector()))
return 0; return 0;
int height = probeUp.Position.Floor; int height = probeUp.GetFloorHeight();
if (height == NO_HEIGHT) if (height == NO_HEIGHT)
return 0; return 0;
@ -805,7 +806,7 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
if (height < 0) if (height < 0)
*shift = height; *shift = height;
int ceiling = probeDown.Position.Ceiling - y; int ceiling = probeDown.GetCeilingHeight() - y;
if (ceiling > LADDER_CLIMB_SHIFT) if (ceiling > LADDER_CLIMB_SHIFT)
return 0; return 0;
@ -822,8 +823,8 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
int dz = zFront + z; int dz = zFront + z;
int dx = xFront + x; int dx = xFront + x;
auto probeFront = GetCollision(dx, y, dz, item->RoomNumber); auto probeFront = GetPointCollision(Vector3i(dx, y, dz), item->RoomNumber);
height = probeFront.Position.Floor; height = probeFront.GetFloorHeight();
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
height -= y; height -= y;
@ -839,9 +840,9 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
*shift = height; *shift = height;
} }
auto probeTop = GetCollision(x, y + itemHeight, z, item->RoomNumber); auto probeTop = GetPointCollision(Vector3i(x, y + itemHeight, z), item->RoomNumber);
auto probeTopFront = GetCollision(dx, y + itemHeight, dz, probeTop.RoomNumber); auto probeTopFront = GetPointCollision(Vector3i(dx, y + itemHeight, dz), probeTop.GetRoomNumber());
ceiling = probeTopFront.Position.Ceiling; ceiling = probeTopFront.GetCeilingHeight();
if (ceiling == NO_HEIGHT) if (ceiling == NO_HEIGHT)
return 1; return 1;
@ -862,7 +863,7 @@ int LaraTestClimb(ItemInfo* item, int xOffset, int yOffset, int zOffset, int xFr
return 1; return 1;
} }
ceiling = probeFront.Position.Ceiling - y; ceiling = probeFront.GetCeilingHeight() - y;
if (ceiling >= CLICK(2)) if (ceiling >= CLICK(2))
return 1; return 1;
@ -895,16 +896,16 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
*shift = 0; *shift = 0;
// Test center. // Test center.
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
int vPos = item->Pose.Position.y - CLICK(4); int vPos = item->Pose.Position.y - CLICK(4);
if ((pointColl.Position.Ceiling - vPos) > LADDER_CLIMB_SHIFT) if ((pointColl.GetCeilingHeight() - vPos) > LADDER_CLIMB_SHIFT)
return 0; return 0;
pointColl = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber); pointColl = GetPointCollision(probePos, item->RoomNumber);
int ceiling = (CLICK(1) - probePos.y) + pointColl.Position.Ceiling; int ceiling = (CLICK(1) - probePos.y) + pointColl.GetCeilingHeight();
pointColl = GetCollision(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z, pointColl.RoomNumber); pointColl = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z), pointColl.GetRoomNumber());
int height = pointColl.Position.Floor; int height = pointColl.GetFloorHeight();
if (height == NO_HEIGHT) if (height == NO_HEIGHT)
{ {
@ -933,10 +934,10 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
if (height > 0 && height > *shift) if (height > 0 && height > *shift)
*shift = height; *shift = height;
pointColl = GetCollision(probePos.x, probePos.y + CLICK(2), probePos.z, item->RoomNumber); pointColl = GetPointCollision(Vector3i(probePos.x, probePos.y + CLICK(2), probePos.z), item->RoomNumber);
pointColl = GetCollision(probePos.x + probeOffset.x, probePos.y + CLICK(2), probePos.z + probeOffset.z, pointColl.RoomNumber); pointColl = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y + CLICK(2), probePos.z + probeOffset.z), pointColl.GetRoomNumber());
ceiling = pointColl.Position.Ceiling - probePos.y; ceiling = pointColl.GetCeilingHeight() - probePos.y;
if (ceiling <= height) if (ceiling <= height)
return 1; return 1;
@ -947,7 +948,7 @@ int LaraTestClimbUpPos(ItemInfo* item, int front, int right, int* shift, int* le
} }
else else
{ {
ceiling = GetCollision(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z, pointColl.RoomNumber).Position.Ceiling - probePos.y; ceiling = GetPointCollision(Vector3i(probePos.x + probeOffset.x, probePos.y, probePos.z + probeOffset.z), pointColl.GetRoomNumber()).GetCeilingHeight() - probePos.y;
if (ceiling < CLICK(2)) if (ceiling < CLICK(2))
{ {
if ((height - ceiling) <= LARA_HEIGHT) if ((height - ceiling) <= LARA_HEIGHT)

View file

@ -4,6 +4,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
#include "Game/items.h" #include "Game/items.h"
@ -19,9 +20,15 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Scripting/Include/ScriptInterfaceLevel.h" #include "Scripting/Include/ScriptInterfaceLevel.h"
using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player; using namespace TEN::Entities::Player;
using namespace TEN::Input; using namespace TEN::Input;
constexpr auto DEFLECT_STRAIGHT_ANGLE = ANGLE(5.0f);
constexpr auto DEFLECT_DIAGONAL_ANGLE = ANGLE(12.0f);
constexpr auto DEFLECT_STRAIGHT_ANGLE_CRAWL = ANGLE(2.0f);
constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = ANGLE(5.0f);
// ----------------------------- // -----------------------------
// COLLISION TEST FUNCTIONS // COLLISION TEST FUNCTIONS
// For State Control & Collision // For State Control & Collision
@ -43,12 +50,12 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CollisionType::Left) if (coll->CollisionType == CollisionType::Left)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
} }
else if (coll->CollisionType == CollisionType::Right) else if (coll->CollisionType == CollisionType::Right)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
} }
else if (coll->LastBridgeItemNumber != NO_VALUE) else if (coll->LastBridgeItemNumber != NO_VALUE)
{ {
@ -118,11 +125,11 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
switch (coll->CollisionType) switch (coll->CollisionType)
{ {
case CollisionType::Left: case CollisionType::Left:
item->Pose.Orientation.y += ANGLE(DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y += DEFLECT_STRAIGHT_ANGLE;
break; break;
case CollisionType::Right: case CollisionType::Right:
item->Pose.Orientation.y -= ANGLE(DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y -= DEFLECT_STRAIGHT_ANGLE;
break; break;
case CollisionType::Top: case CollisionType::Top:
@ -154,11 +161,11 @@ void LaraSlideEdgeJump(ItemInfo* item, CollisionInfo* coll)
switch (coll->CollisionType) switch (coll->CollisionType)
{ {
case CollisionType::Left: case CollisionType::Left:
item->Pose.Orientation.y += ANGLE(DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y += DEFLECT_STRAIGHT_ANGLE;
break; break;
case CollisionType::Right: case CollisionType::Right:
item->Pose.Orientation.y -= ANGLE(DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y -= DEFLECT_STRAIGHT_ANGLE;
break; break;
case CollisionType::Top: case CollisionType::Top:
@ -196,12 +203,12 @@ bool LaraDeflectEdgeCrawl(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CollisionType::Left) if (coll->CollisionType == CollisionType::Left)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL); item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL;
} }
else if (coll->CollisionType == CollisionType::Right) else if (coll->CollisionType == CollisionType::Right)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL); item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL;
} }
return false; return false;
@ -227,12 +234,12 @@ bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CollisionType::Left) if (coll->CollisionType == CollisionType::Left)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y += coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
} }
else if (coll->CollisionType == CollisionType::Right) else if (coll->CollisionType == CollisionType::Right)
{ {
ShiftItem(item, coll); ShiftItem(item, coll);
item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE); item->Pose.Orientation.y -= coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE;
} }
return false; return false;
@ -489,19 +496,32 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
item->Pose.Orientation.y -= ANGLE(5.0f); item->Pose.Orientation.y -= ANGLE(5.0f);
} }
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
int waterHeight = GetWaterHeight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); if ((pointColl.GetFloorHeight() - item->Pose.Position.y) < SWIM_WATER_DEPTH)
if ((pointColl.Position.Floor - item->Pose.Position.y) < SWIM_WATER_DEPTH)
{ {
TestPlayerWaterStepOut(item, coll); TestPlayerWaterStepOut(item, coll);
} }
else if ((waterHeight - item->Pose.Position.y) <= -LARA_HEADROOM) else if ((pointColl.GetWaterTopHeight() - item->Pose.Position.y) <= -LARA_HEADROOM)
{ {
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
} }
} }
void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll)
{
auto& player = GetLaraInfo(*item);
player.Control.MoveAngle = item->Pose.Orientation.y;
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
coll->Setup.BlockFloorSlopeDown = true;
coll->Setup.BlockFloorSlopeUp = true;
coll->Setup.ForwardAngle = player.Control.MoveAngle;
GetCollisionInfo(coll, item);
LaraResetGravityStatus(item, coll);
}
void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll) void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);

View file

@ -3,11 +3,6 @@
struct ItemInfo; struct ItemInfo;
struct CollisionInfo; struct CollisionInfo;
constexpr auto DEFLECT_STRAIGHT_ANGLE = 5.0f;
constexpr auto DEFLECT_DIAGONAL_ANGLE = 12.0f;
constexpr auto DEFLECT_STRAIGHT_ANGLE_CRAWL = 2.0f;
constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = 5.0f;
// ----------------------------- // -----------------------------
// COLLISION TEST FUNCTIONS // COLLISION TEST FUNCTIONS
// For State Control & Collision // For State Control & Collision
@ -30,6 +25,7 @@ void GetLaraDeadlyBounds();
void LaraJumpCollision(ItemInfo* item, CollisionInfo* coll, short moveAngle); void LaraJumpCollision(ItemInfo* item, CollisionInfo* coll, short moveAngle);
void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll); void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll);
void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll); void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll);
void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll);
void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll); void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll);

View file

@ -4,7 +4,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/sphere.h" #include "Game/collision/Sphere.h"
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/control/lot.h" #include "Game/control/lot.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
@ -31,6 +31,7 @@
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
using namespace TEN::Collision::Sphere;
using namespace TEN::Entities::Generic; using namespace TEN::Entities::Generic;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Math; using namespace TEN::Math;
@ -842,32 +843,38 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
auto target = origin + (directionNorm * weapon.TargetDist); auto target = origin + (directionNorm * weapon.TargetDist);
auto ray = Ray(origin, directionNorm); auto ray = Ray(origin, directionNorm);
int num = GetSpheres(&targetEntity, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
int bestJointIndex = NO_VALUE;
float bestDistance = INFINITY;
for (int i = 0; i < num; i++)
{
auto sphere = BoundingSphere(Vector3(CreatureSpheres[i].x, CreatureSpheres[i].y, CreatureSpheres[i].z), CreatureSpheres[i].r);
float distance = 0.0f;
if (ray.Intersects(sphere, distance))
{
if (distance < bestDistance)
{
bestDistance = distance;
bestJointIndex = i;
}
}
}
player.Control.Weapon.HasFired = true; player.Control.Weapon.HasFired = true;
player.Control.Weapon.Fired = true; player.Control.Weapon.Fired = true;
auto vOrigin = GameVector(pos); auto vOrigin = GameVector(pos);
short roomNumber = laraItem.RoomNumber; short roomNumber = laraItem.RoomNumber;
GetFloor(pos.x, pos.y, pos.z, &roomNumber); GetFloor(pos.x, pos.y, pos.z, &roomNumber);
vOrigin.RoomNumber = roomNumber; vOrigin.RoomNumber = roomNumber;
if (bestJointIndex < 0) if (&targetEntity == nullptr)
{
auto vTarget = GameVector(target);
GetTargetOnLOS(&vOrigin, &vTarget, false, true);
return FireWeaponType::Miss;
}
auto spheres = targetEntity.GetSpheres();
int closestJointIndex = NO_VALUE;
float closestDist = INFINITY;
for (int i = 0; i < spheres.size(); i++)
{
float dist = 0.0f;
if (ray.Intersects(spheres[i], dist))
{
if (dist < closestDist)
{
closestDist = dist;
closestJointIndex = i;
}
}
}
if (closestJointIndex < 0)
{ {
auto vTarget = GameVector(target); auto vTarget = GameVector(target);
GetTargetOnLOS(&vOrigin, &vTarget, false, true); GetTargetOnLOS(&vOrigin, &vTarget, false, true);
@ -876,13 +883,13 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo& targetEntity, Ite
else else
{ {
SaveGame::Statistics.Game.AmmoHits++; SaveGame::Statistics.Game.AmmoHits++;
target = origin + (directionNorm * bestDistance); target = origin + (directionNorm * closestDist);
auto vTarget = GameVector(target); auto vTarget = GameVector(target);
// NOTE: It seems that entities hit by the player in the normal way must have GetTargetOnLOS return false. // NOTE: It seems that entities hit by the player in the normal way must have GetTargetOnLOS return false.
// It's strange, but this replicates original behaviour until we fully understand what is happening. // It's strange, but this replicates original behaviour until we fully understand what is happening.
if (!GetTargetOnLOS(&vOrigin, &vTarget, false, true)) if (!GetTargetOnLOS(&vOrigin, &vTarget, false, true))
HitTarget(&laraItem, &targetEntity, &vTarget, weapon.Damage, false, bestJointIndex); HitTarget(&laraItem, &targetEntity, &vTarget, weapon.Damage, false, closestJointIndex);
return FireWeaponType::PossibleHit; return FireWeaponType::PossibleHit;
} }

View file

@ -4,6 +4,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
#include "Game/effects/chaffFX.h" #include "Game/effects/chaffFX.h"
@ -18,6 +19,7 @@
#include "Specific/clock.h" #include "Specific/clock.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Math; using namespace TEN::Math;
constexpr auto FLARE_LIFE_MAX = 60.0f * FPS; constexpr auto FLARE_LIFE_MAX = 60.0f * FPS;
@ -258,7 +260,7 @@ void DrawFlare(ItemInfo& laraItem)
SoundEffect( SoundEffect(
SFX_TR4_FLARE_IGNITE_DRY, SFX_TR4_FLARE_IGNITE_DRY,
&laraItem.Pose, &laraItem.Pose,
TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land); TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::ShallowWater : SoundEnvironment::Land);
} }
DoFlareInHand(laraItem, player.Flare.Life); DoFlareInHand(laraItem, player.Flare.Life);
@ -323,7 +325,7 @@ void CreateFlare(ItemInfo& laraItem, GAME_OBJECT_ID objectID, bool isThrown)
flareItem.Pose.Position = pos; flareItem.Pose.Position = pos;
int floorHeight = GetCollision(pos.x, pos.y, pos.z, laraItem.RoomNumber).Position.Floor; int floorHeight = GetPointCollision(pos, laraItem.RoomNumber).GetFloorHeight();
auto isCollided = !GetCollidedObjects(flareItem, true, true).IsEmpty(); auto isCollided = !GetCollidedObjects(flareItem, true, true).IsEmpty();
bool hasLanded = false; bool hasLanded = false;

View file

@ -146,10 +146,10 @@ void lara_col_hang(ItemInfo* item, CollisionInfo* coll)
if (item->Animation.AnimNumber == LA_REACH_TO_HANG || if (item->Animation.AnimNumber == LA_REACH_TO_HANG ||
item->Animation.AnimNumber == LA_HANG_IDLE) item->Animation.AnimNumber == LA_HANG_IDLE)
{ {
TestForObjectOnLedge(item, coll);
if (IsHeld(In::Forward)) if (IsHeld(In::Forward))
{ {
TestForObjectOnLedge(item, coll);
if (coll->Front.Floor > -(CLICK(3.5f) - 46) && if (coll->Front.Floor > -(CLICK(3.5f) - 46) &&
TestValidLedge(item, coll) && !coll->HitStatic) TestValidLedge(item, coll) && !coll->HitStatic)
{ {

View file

@ -7,6 +7,7 @@
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h" #include "Game/collision/floordata.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/control/volume.h" #include "Game/control/volume.h"
#include "Game/items.h" #include "Game/items.h"
@ -21,7 +22,6 @@
#include "Game/savegame.h" #include "Game/savegame.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer.h"
#include "Scripting/Include/ScriptInterfaceLevel.h" #include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Sound/sound.h" #include "Sound/sound.h"
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
@ -37,6 +37,7 @@
#include "Objects/TR4/Vehicles/motorbike.h" #include "Objects/TR4/Vehicles/motorbike.h"
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Control::Volumes; using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Bubble; using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip; using namespace TEN::Effects::Drip;
@ -44,7 +45,6 @@ using namespace TEN::Entities::Player;
using namespace TEN::Gui; using namespace TEN::Gui;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Math; using namespace TEN::Math;
using namespace TEN::Renderer;
// ----------------------------- // -----------------------------
// HELPER FUNCTIONS // HELPER FUNCTIONS
@ -160,9 +160,9 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
const auto& vehicleItem = g_Level.Items[player.Context.Vehicle]; const auto& vehicleItem = g_Level.Items[player.Context.Vehicle];
if (vehicleItem.ObjectNumber == ID_UPV) if (vehicleItem.ObjectNumber == ID_UPV)
{ {
auto pointColl = GetCollision(&item, 0, 0, CLICK(1)); auto pointColl = GetPointCollision(item, 0, 0, CLICK(1));
water.IsCold = (water.IsCold || TestEnvironment(ENV_FLAG_COLD, pointColl.RoomNumber)); water.IsCold = (water.IsCold || TestEnvironment(ENV_FLAG_COLD, pointColl.GetRoomNumber()));
if (water.IsCold) if (water.IsCold)
{ {
player.Status.Exposure--; player.Status.Exposure--;
@ -276,50 +276,7 @@ void HandlePlayerStatusEffects(ItemInfo& item, WaterStatus waterStatus, PlayerWa
} }
} }
static void UsePlayerMedipack(ItemInfo& item) static LaraWeaponType GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
{
auto& player = GetLaraInfo(item);
// Can't use medipack; return early.
if (item.HitPoints <= 0 ||
(item.HitPoints >= LARA_HEALTH_MAX && player.Status.Poison == 0))
{
return;
}
bool hasUsedMedipack = false;
if (IsClicked(In::SmallMedipack) &&
player.Inventory.TotalSmallMedipacks != 0)
{
hasUsedMedipack = true;
item.HitPoints += LARA_HEALTH_MAX / 2;
if (item.HitPoints > LARA_HEALTH_MAX)
item.HitPoints = LARA_HEALTH_MAX;
if (player.Inventory.TotalSmallMedipacks != -1)
player.Inventory.TotalSmallMedipacks--;
}
else if (IsClicked(In::LargeMedipack) &&
player.Inventory.TotalLargeMedipacks != 0)
{
hasUsedMedipack = true;
item.HitPoints = LARA_HEALTH_MAX;
if (player.Inventory.TotalLargeMedipacks != -1)
player.Inventory.TotalLargeMedipacks--;
}
if (hasUsedMedipack)
{
player.Status.Poison = 0;
SaveGame::Statistics.Game.HealthUsed++;
SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always);
}
}
static std::optional<LaraWeaponType> GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev)
{ {
static const auto SCROLL_WEAPON_TYPES = std::vector<LaraWeaponType> static const auto SCROLL_WEAPON_TYPES = std::vector<LaraWeaponType>
{ {
@ -334,15 +291,15 @@ static std::optional<LaraWeaponType> GetPlayerScrolledWeaponType(const ItemInfo&
LaraWeaponType::RocketLauncher LaraWeaponType::RocketLauncher
}; };
auto getNextIndex = [getPrev](unsigned int index) auto getNextIndex = [getPrev](int index)
{ {
return (index + (getPrev ? ((unsigned int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (unsigned int)SCROLL_WEAPON_TYPES.size(); return (index + (getPrev ? ((int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (int)SCROLL_WEAPON_TYPES.size();
}; };
auto& player = GetLaraInfo(item); auto& player = GetLaraInfo(item);
// Get vector index for current weapon type. // Get vector index for current weapon type.
auto currentIndex = std::optional<unsigned int>(std::nullopt); auto currentIndex = NO_VALUE;
for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++) for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++)
{ {
if (SCROLL_WEAPON_TYPES[i] == currentWeaponType) if (SCROLL_WEAPON_TYPES[i] == currentWeaponType)
@ -352,13 +309,13 @@ static std::optional<LaraWeaponType> GetPlayerScrolledWeaponType(const ItemInfo&
} }
} }
// Invalid current weapon type; return nullopt. // Invalid current weapon type; return None type.
if (!currentIndex.has_value()) if (currentIndex == NO_VALUE)
return std::nullopt; return LaraWeaponType::None;
// Get next valid weapon type in sequence. // Get next valid weapon type in sequence.
unsigned int nextIndex = getNextIndex(*currentIndex); int nextIndex = getNextIndex(currentIndex);
while (nextIndex != *currentIndex) while (nextIndex != currentIndex)
{ {
auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex]; auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex];
if (player.Weapons[(int)nextWeaponType].Present) if (player.Weapons[(int)nextWeaponType].Present)
@ -367,8 +324,8 @@ static std::optional<LaraWeaponType> GetPlayerScrolledWeaponType(const ItemInfo&
nextIndex = getNextIndex(nextIndex); nextIndex = getNextIndex(nextIndex);
} }
// No valid weapon type; return nullopt. // No valid weapon type; return None type.
return std::nullopt; return LaraWeaponType::None;
} }
void HandlePlayerQuickActions(ItemInfo& item) void HandlePlayerQuickActions(ItemInfo& item)
@ -376,17 +333,21 @@ void HandlePlayerQuickActions(ItemInfo& item)
auto& player = GetLaraInfo(item); auto& player = GetLaraInfo(item);
// Handle medipacks. // Handle medipacks.
if (IsClicked(In::SmallMedipack) || IsClicked(In::LargeMedipack)) if (IsClicked(In::SmallMedipack))
UsePlayerMedipack(item); {
g_Gui.UseItem(item, GAME_OBJECT_ID::ID_SMALLMEDI_ITEM);
}
else if (IsClicked(In::LargeMedipack))
{
g_Gui.UseItem(item, GAME_OBJECT_ID::ID_BIGMEDI_ITEM);
}
// Handle weapon scroll request. // Handle weapon scroll request.
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon)) if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
{ {
bool getPrev = IsClicked(In::PreviousWeapon); auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, IsClicked(In::PreviousWeapon));
auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, getPrev); if (weaponType != LaraWeaponType::None)
player.Control.Weapon.RequestGunType = weaponType;
if (weaponType.has_value())
player.Control.Weapon.RequestGunType = *weaponType;
} }
// Handle weapon requests. // Handle weapon requests.
@ -419,7 +380,7 @@ void HandlePlayerQuickActions(ItemInfo& item)
// TODO: 10th possible weapon, probably grapple gun. // TODO: 10th possible weapon, probably grapple gun.
/*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present) /*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::;*/ player.Control.Weapon.RequestGunType = LaraWeaponType::;*/
} }
bool CanPlayerLookAround(const ItemInfo& item) bool CanPlayerLookAround(const ItemInfo& item)
@ -1029,7 +990,7 @@ void HandlePlayerAirBubbles(ItemInfo* item)
{ {
constexpr auto BUBBLE_COUNT_MAX = 3; constexpr auto BUBBLE_COUNT_MAX = 3;
SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water); SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::ShallowWater);
const auto& level = *g_GameFlow->GetLevel(CurrentLevel); const auto& level = *g_GameFlow->GetLevel(CurrentLevel);
@ -1083,6 +1044,8 @@ void HandlePlayerElevationChange(ItemInfo* item, CollisionInfo* coll)
if (CanStepUp(*item, *coll)) if (CanStepUp(*item, *coll))
{ {
item->Animation.TargetState = LS_STEP_UP; item->Animation.TargetState = LS_STEP_UP;
item->DisableInterpolation = true;
if (GetStateDispatch(item, GetAnimData(*item))) if (GetStateDispatch(item, GetAnimData(*item)))
{ {
item->Pose.Position.y += coll->Middle.Floor; item->Pose.Position.y += coll->Middle.Floor;
@ -1250,20 +1213,14 @@ LaraInfo*& GetLaraInfo(ItemInfo* item)
PlayerWaterData GetPlayerWaterData(ItemInfo& item) PlayerWaterData GetPlayerWaterData(ItemInfo& item)
{ {
bool isWater = TestEnvironment(ENV_FLAG_WATER, &item); auto pointColl = GetPointCollision(item);
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, &item); int heightFromWater = (pointColl.GetWaterTopHeight() == NO_HEIGHT) ?
bool isCold = TestEnvironment(ENV_FLAG_COLD, &item); NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.GetFloorHeight()) - pointColl.GetWaterTopHeight());
int waterDepth = GetWaterDepth(&item);
int waterHeight = GetWaterHeight(&item);
auto pointColl = GetCollision(item);
int heightFromWater = (waterHeight == NO_HEIGHT) ? NO_HEIGHT : (std::min(item.Pose.Position.y, pointColl.Position.Floor) - waterHeight);
return PlayerWaterData return PlayerWaterData
{ {
isWater, isSwamp, isCold, TestEnvironment(ENV_FLAG_WATER, &item), TestEnvironment(ENV_FLAG_SWAMP, &item), TestEnvironment(ENV_FLAG_COLD, &item),
waterDepth, waterHeight, heightFromWater pointColl.GetWaterBottomHeight(), pointColl.GetWaterTopHeight(), heightFromWater
}; };
} }
@ -1322,20 +1279,20 @@ static short GetLegacySlideHeadingAngle(const Vector3& floorNormal)
short GetPlayerSlideHeadingAngle(ItemInfo* item, CollisionInfo* coll) short GetPlayerSlideHeadingAngle(ItemInfo* item, CollisionInfo* coll)
{ {
short headingAngle = coll->Setup.ForwardAngle; short headingAngle = coll->Setup.ForwardAngle;
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
// Ground is flat. // Ground is flat.
if (pointColl.FloorTilt == Vector2::Zero) if (pointColl.GetFloorNormal() == -Vector3::UnitY)
return coll->Setup.ForwardAngle; return coll->Setup.ForwardAngle;
// Return slide heading angle. // Return slide heading angle.
if (g_GameFlow->HasSlideExtended()) if (g_GameFlow->HasSlideExtended())
{ {
return Geometry::GetSurfaceAspectAngle(pointColl.FloorNormal); return Geometry::GetSurfaceAspectAngle(pointColl.GetFloorNormal());
} }
else else
{ {
return GetLegacySlideHeadingAngle(pointColl.FloorNormal); return GetLegacySlideHeadingAngle(pointColl.GetFloorNormal());
} }
} }
@ -1510,7 +1467,7 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / BLOCK(8); auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / BLOCK(8);
auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / BLOCK(8); auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / BLOCK(8);
auto vol = ((mul1 + mul2) * 5.0f) + 0.5f; auto vol = ((mul1 + mul2) * 5.0f) + 0.5f;
SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::Water, 1.0f + (mul1 + mul2), vol); SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::ShallowWater, 1.0f + (mul1 + mul2), vol);
} }
} }
@ -1524,7 +1481,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
if (g_GameFlow->HasSlideExtended()) if (g_GameFlow->HasSlideExtended())
{ {
auto probe = GetCollision(item); auto probe = GetPointCollision(*item);
short minSlideAngle = ANGLE(33.75f); short minSlideAngle = ANGLE(33.75f);
//short steepness = Geometry::GetSurfaceSlopeAngle(probe.FloorTilt); //short steepness = Geometry::GetSurfaceSlopeAngle(probe.FloorTilt);
//short direction = Geometry::GetSurfaceAspectAngle(probe.FloorTilt); //short direction = Geometry::GetSurfaceAspectAngle(probe.FloorTilt);
@ -1533,7 +1490,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
//int slideVelocity = std::min<int>(minVelocity + 10 * (steepness * velocityMultiplier), LARA_TERMINAL_VELOCITY); //int slideVelocity = std::min<int>(minVelocity + 10 * (steepness * velocityMultiplier), LARA_TERMINAL_VELOCITY);
//short deltaAngle = abs((short)(direction - item->Pose.Orientation.y)); //short deltaAngle = abs((short)(direction - item->Pose.Orientation.y));
//g_Renderer.PrintDebugMessage("%d", slideVelocity); //PrintDebugMessage("%d", slideVelocity);
//lara->ExtraVelocity.x += slideVelocity; //lara->ExtraVelocity.x += slideVelocity;
//lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness); //lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
@ -1545,7 +1502,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
void AlignLaraToSurface(ItemInfo* item, float alpha) void AlignLaraToSurface(ItemInfo* item, float alpha)
{ {
// Determine relative orientation adhering to floor normal. // Determine relative orientation adhering to floor normal.
auto floorNormal = GetCollision(item).FloorNormal; auto floorNormal = GetPointCollision(*item).GetFloorNormal();
auto orient = Geometry::GetRelOrientToNormal(item->Pose.Orientation.y, floorNormal); auto orient = Geometry::GetRelOrientToNormal(item->Pose.Orientation.y, floorNormal);
// Apply extra rotation according to alpha. // Apply extra rotation according to alpha.

View file

@ -1,6 +1,7 @@
#include "framework.h" #include "framework.h"
#include "Game/Lara/lara_initialise.h" #include "Game/Lara/lara_initialise.h"
#include "Game/collision/Point.h"
#include "Game/Hud/Hud.h" #include "Game/Hud/Hud.h"
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
@ -12,12 +13,17 @@
#include "Game/Lara/PlayerStateMachine.h" #include "Game/Lara/PlayerStateMachine.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Objects/TR2/Vehicles/skidoo.h" #include "Objects/TR2/Vehicles/skidoo.h"
#include "Objects/TR2/Vehicles/speedboat.h"
#include "Objects/TR3/Vehicles/kayak.h" #include "Objects/TR3/Vehicles/kayak.h"
#include "Objects/TR3/Vehicles/minecart.h"
#include "Objects/TR3/Vehicles/quad_bike.h" #include "Objects/TR3/Vehicles/quad_bike.h"
#include "Objects/TR3/Vehicles/rubber_boat.h"
#include "Objects/TR3/Vehicles/upv.h"
#include "Objects/TR4/Vehicles/jeep.h" #include "Objects/TR4/Vehicles/jeep.h"
#include "Objects/TR4/Vehicles/motorbike.h" #include "Objects/TR4/Vehicles/motorbike.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player; using namespace TEN::Entities::Player;
using namespace TEN::Hud; using namespace TEN::Hud;
@ -120,6 +126,9 @@ void InitializeLaraAnims(ItemInfo* item)
player.LeftArm.Locked = false; player.LeftArm.Locked = false;
player.RightArm.Locked = false; player.RightArm.Locked = false;
if (PlayerVehicleObjectID != GAME_OBJECT_ID::ID_NO_OBJECT)
return;
if (TestEnvironment(ENV_FLAG_WATER, item)) if (TestEnvironment(ENV_FLAG_WATER, item))
{ {
SetAnimation(item, LA_UNDERWATER_IDLE); SetAnimation(item, LA_UNDERWATER_IDLE);
@ -131,8 +140,8 @@ void InitializeLaraAnims(ItemInfo* item)
player.Control.WaterStatus = WaterStatus::Dry; player.Control.WaterStatus = WaterStatus::Dry;
// Allow player to start in crawl idle anim if start position is too low. // Allow player to start in crawl idle anim if start position is too low.
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
if (abs(pointColl.Position.Ceiling - pointColl.Position.Floor) < LARA_HEIGHT) if (abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight()) < LARA_HEIGHT)
{ {
SetAnimation(item, LA_CRAWL_IDLE); SetAnimation(item, LA_CRAWL_IDLE);
player.Control.IsLow = player.Control.IsLow =
@ -173,7 +182,7 @@ void InitializeLaraStartPosition(ItemInfo& playerItem)
playerItem.Location.Height = playerItem.Pose.Position.y; playerItem.Location.Height = playerItem.Pose.Position.y;
} }
static void InitializePlayerVehicle(ItemInfo& playerItem) void InitializePlayerVehicle(ItemInfo& playerItem)
{ {
if (PlayerVehicleObjectID == GAME_OBJECT_ID::ID_NO_OBJECT) if (PlayerVehicleObjectID == GAME_OBJECT_ID::ID_NO_OBJECT)
return; return;
@ -185,7 +194,6 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
// Restore vehicle. // Restore vehicle.
TENLog("Transferring vehicle " + GetObjectName(PlayerVehicleObjectID) + " from the previous level."); TENLog("Transferring vehicle " + GetObjectName(PlayerVehicleObjectID) + " from the previous level.");
vehicle->Pose = playerItem.Pose; vehicle->Pose = playerItem.Pose;
ItemNewRoom(vehicle->Index, playerItem.RoomNumber);
SetLaraVehicle(&playerItem, vehicle); SetLaraVehicle(&playerItem, vehicle);
playerItem.Animation = PlayerAnim; playerItem.Animation = PlayerAnim;
@ -195,6 +203,7 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
{ {
case GAME_OBJECT_ID::ID_KAYAK: case GAME_OBJECT_ID::ID_KAYAK:
InitializeKayak(vehicle->Index); InitializeKayak(vehicle->Index);
KayakPaddleTake(GetKayakInfo(&g_Level.Items[vehicle->Index]), &playerItem);
break; break;
case GAME_OBJECT_ID::ID_MOTORBIKE: case GAME_OBJECT_ID::ID_MOTORBIKE:
@ -213,9 +222,38 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
InitializeSkidoo(vehicle->Index); InitializeSkidoo(vehicle->Index);
break; break;
case GAME_OBJECT_ID::ID_MINECART:
MinecartWrenchTake(GetMinecartInfo(&g_Level.Items[vehicle->Index]), &playerItem);
break;
case GAME_OBJECT_ID::ID_SPEEDBOAT:
InitializeSpeedboat(vehicle->Index);
DoSpeedboatMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
break;
case GAME_OBJECT_ID::ID_RUBBER_BOAT:
InitializeRubberBoat(vehicle->Index);
DoRubberBoatMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
break;
case GAME_OBJECT_ID::ID_UPV:
DoUPVMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
GetUPVInfo(&g_Level.Items[vehicle->Index])->Flags = UPVFlags::UPV_FLAG_CONTROL;
break;
default: default:
break; break;
} }
// HACK: Reset activity status because boats need to be on active item linked list.
if (vehicle->ObjectNumber == GAME_OBJECT_ID::ID_RUBBER_BOAT ||
vehicle->ObjectNumber == GAME_OBJECT_ID::ID_SPEEDBOAT)
{
RemoveActiveItem(vehicle->Index, false);
AddActiveItem(vehicle->Index);
g_Level.Items[vehicle->Index].Status = ITEM_ACTIVE;
}
} }
void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup) void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup)
@ -258,9 +296,6 @@ void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup)
// Restore hit points. // Restore hit points.
item->HitPoints = PlayerHitPoints; item->HitPoints = PlayerHitPoints;
// Restore vehicle.
InitializePlayerVehicle(*item);
} }
void InitializeLaraDefaultInventory(ItemInfo& item) void InitializeLaraDefaultInventory(ItemInfo& item)

View file

@ -9,3 +9,4 @@ void InitializeLaraAnims(ItemInfo* item);
void InitializeLaraStartPosition(ItemInfo& playerItem); void InitializeLaraStartPosition(ItemInfo& playerItem);
void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup); void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup);
void InitializeLaraDefaultInventory(ItemInfo& item); void InitializeLaraDefaultInventory(ItemInfo& item);
void InitializePlayerVehicle(ItemInfo& playerItem);

View file

@ -64,7 +64,7 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
{ {
DoLaraFallDamage(item); DoLaraFallDamage(item);
if (item->HitPoints <= 0) USE_FEATURE_IF_CPP20([[unlikely]]) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else if (IsHeld(In::Forward) && !IsHeld(In::Walk) && else if (IsHeld(In::Forward) && !IsHeld(In::Walk) &&
player.Control.WaterStatus != WaterStatus::Wade) player.Control.WaterStatus != WaterStatus::Wade)
@ -146,7 +146,7 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -202,7 +202,7 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -414,7 +414,7 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -468,7 +468,7 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -523,7 +523,7 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -576,7 +576,7 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
{ {
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -673,7 +673,7 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -749,7 +749,7 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_CROUCH_IDLE; item->Animation.TargetState = LS_CROUCH_IDLE;
TranslateItem(item, coll->Setup.ForwardAngle, CLICK(0.5f)); // HACK: Move forward to avoid standing up or falling out on an edge. TranslateItem(item, coll->Setup.ForwardAngle, CLICK(0.5f)); // HACK: Move forward to avoid standing up or falling out on an edge.
} }
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);
@ -823,7 +823,7 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_DEATH; item->Animation.TargetState = LS_DEATH;
Rumble(0.5f, 0.2f); Rumble(0.5f, 0.2f);
} }
else USE_FEATURE_IF_CPP20([[likely]]) else
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
SetLaraLand(item, coll); SetLaraLand(item, coll);

View file

@ -8,6 +8,7 @@
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/PlayerContext.h" #include "Game/Lara/PlayerContext.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Game/Lara/lara_collide.h"
#include "Game/Lara/lara_helpers.h" #include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_tests.h" #include "Game/Lara/lara_tests.h"
#include "Objects/Generic/Object/rope.h" #include "Objects/Generic/Object/rope.h"
@ -45,6 +46,12 @@ void lara_as_pickup(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = GetNextAnimState(item); item->Animation.TargetState = GetNextAnimState(item);
} }
void lara_col_pickup(ItemInfo* item, CollisionInfo* coll)
{
LaraDefaultCollision(item, coll);
ShiftItem(item, coll);
}
// State: LS_PICKUP_FLARE (67) // State: LS_PICKUP_FLARE (67)
// Collision: lara_default_col() // Collision: lara_default_col()
void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll) void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll)

View file

@ -14,6 +14,7 @@ struct CollisionInfo;
void lara_as_pickup(ItemInfo* item, CollisionInfo* coll); void lara_as_pickup(ItemInfo* item, CollisionInfo* coll);
void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll); void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll);
void lara_col_pickup(ItemInfo* item, CollisionInfo* coll);
// ------ // ------
// SWITCH // SWITCH

View file

@ -4,6 +4,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/Point.h"
#include "Game/control/box.h" #include "Game/control/box.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/control/los.h" #include "Game/control/los.h"
@ -31,6 +32,7 @@
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Effects::Bubble; using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip; using namespace TEN::Effects::Drip;
using namespace TEN::Effects::Environment; using namespace TEN::Effects::Environment;
@ -426,7 +428,7 @@ void FireShotgun(ItemInfo& laraItem)
player.RightArm.GunFlash = Weapons[(int)LaraWeaponType::Shotgun].FlashTime; player.RightArm.GunFlash = Weapons[(int)LaraWeaponType::Shotgun].FlashTime;
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land); SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, TestEnvironment(ENV_FLAG_WATER, &laraItem) ? SoundEnvironment::ShallowWater : SoundEnvironment::Land);
SoundEffect(Weapons[(int)LaraWeaponType::Shotgun].SampleNum, &laraItem.Pose); SoundEffect(Weapons[(int)LaraWeaponType::Shotgun].SampleNum, &laraItem.Pose);
Rumble(0.5f, 0.2f); Rumble(0.5f, 0.2f);
@ -600,7 +602,7 @@ bool FireHarpoon(ItemInfo& laraItem, const std::optional<Pose>& pose)
auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77)); auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77));
harpoonItem.RoomNumber = laraItem.RoomNumber; harpoonItem.RoomNumber = laraItem.RoomNumber;
int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, harpoonItem.RoomNumber).Position.Floor; int floorHeight = GetPointCollision(jointPos, harpoonItem.RoomNumber).GetFloorHeight();
if (floorHeight >= jointPos.y) if (floorHeight >= jointPos.y)
{ {
harpoonItem.Pose.Position = jointPos; harpoonItem.Pose.Position = jointPos;
@ -693,7 +695,7 @@ void FireGrenade(ItemInfo& laraItem)
grenadeItem.Pose.Position = jointPos; grenadeItem.Pose.Position = jointPos;
auto smokePos = jointPos; auto smokePos = jointPos;
int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, grenadeItem.RoomNumber).Position.Floor; int floorHeight = GetPointCollision(jointPos, grenadeItem.RoomNumber).GetFloorHeight();
if (floorHeight < jointPos.y) if (floorHeight < jointPos.y)
{ {
grenadeItem.Pose.Position.x = laraItem.Pose.Position.x; grenadeItem.Pose.Position.x = laraItem.Pose.Position.x;
@ -1027,9 +1029,11 @@ void FireCrossbow(ItemInfo& laraItem, const std::optional<Pose>& pose)
boltItem.RoomNumber = laraItem.RoomNumber; boltItem.RoomNumber = laraItem.RoomNumber;
int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, boltItem.RoomNumber).Position.Floor; int floorHeight = GetPointCollision(jointPos, boltItem.RoomNumber).GetFloorHeight();
if (floorHeight >= jointPos.y) if (floorHeight >= jointPos.y)
{
boltItem.Pose.Position = jointPos; boltItem.Pose.Position = jointPos;
}
else else
{ {
boltItem.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z); boltItem.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z);
@ -1418,20 +1422,20 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type)
return true; return true;
} }
bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll) bool TestProjectileNewRoom(ItemInfo& item, PointCollisionData& pointColl)
{ {
// Check if projectile changed room. // Check if projectile changed room.
if (item.RoomNumber == coll.RoomNumber) if (item.RoomNumber == pointColl.GetRoomNumber())
return false; return false;
// If currently in water and previously on land, spawn ripple. // If currently in water and previously on land, spawn ripple.
if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) != TestEnvironment(ENV_FLAG_WATER, coll.RoomNumber)) if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) != TestEnvironment(ENV_FLAG_WATER, pointColl.GetRoomNumber()))
{ {
const auto& player = GetLaraInfo(item); const auto& player = GetLaraInfo(item);
int floorDiff = abs(coll.Position.Floor - item.Pose.Position.y); int floorDiff = abs(pointColl.GetFloorHeight() - item.Pose.Position.y);
int ceilingDiff = abs(coll.Position.Ceiling - item.Pose.Position.y); int ceilingDiff = abs(pointColl.GetCeilingHeight() - item.Pose.Position.y);
int yPoint = (floorDiff > ceilingDiff) ? coll.Position.Ceiling : coll.Position.Floor; int yPoint = (floorDiff > ceilingDiff) ? pointColl.GetCeilingHeight() : pointColl.GetFloorHeight();
if (player.Control.Weapon.GunType != LaraWeaponType::GrenadeLauncher && player.Control.Weapon.GunType != LaraWeaponType::RocketLauncher) if (player.Control.Weapon.GunType != LaraWeaponType::GrenadeLauncher && player.Control.Weapon.GunType != LaraWeaponType::RocketLauncher)
{ {
@ -1447,7 +1451,7 @@ bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll)
} }
} }
ItemNewRoom(item.Index, coll.RoomNumber); ItemNewRoom(item.Index, pointColl.GetRoomNumber());
return true; return true;
} }
@ -1475,7 +1479,7 @@ void ExplodeProjectile(ItemInfo& item, const Vector3i& prevPos)
void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& prevPos, ProjectileType type, int damage) void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& prevPos, ProjectileType type, int damage)
{ {
auto pointColl = GetCollision(&projectile); auto pointColl = GetPointCollision(projectile);
bool hasHit = false; bool hasHit = false;
bool hasHitNotByEmitter = false; bool hasHitNotByEmitter = false;
@ -1485,8 +1489,8 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
// For non-grenade projectiles, check for room collision. // For non-grenade projectiles, check for room collision.
if (type < ProjectileType::Grenade) if (type < ProjectileType::Grenade)
{ {
if (pointColl.Position.Floor < projectile.Pose.Position.y || if (pointColl.GetFloorHeight() < projectile.Pose.Position.y ||
pointColl.Position.Ceiling > projectile.Pose.Position.y) pointColl.GetCeilingHeight() > projectile.Pose.Position.y)
{ {
hasHit = hasHitNotByEmitter = true; hasHit = hasHitNotByEmitter = true;
} }
@ -1559,7 +1563,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
break; break;
// Run through statics. // Run through statics.
for (auto* staticPtr : collObjects.StaticPtrs) for (auto* staticPtr : collObjects.Statics)
{ {
hasHit = hasHitNotByEmitter = doShatter = true; hasHit = hasHitNotByEmitter = doShatter = true;
doExplosion = isExplosive; doExplosion = isExplosive;
@ -1580,7 +1584,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
} }
// Run through items. // Run through items.
for (auto* itemPtr : collObjects.ItemPtrs) for (auto* itemPtr : collObjects.Items)
{ {
// Object was already affected by collision, skip it. // Object was already affected by collision, skip it.
if (std::find(affectedObjects.begin(), affectedObjects.end(), itemPtr->Index) != affectedObjects.end()) if (std::find(affectedObjects.begin(), affectedObjects.end(), itemPtr->Index) != affectedObjects.end())

View file

@ -39,6 +39,7 @@ void HarpoonBoltControl(short itemNumber);
void FireGrenade(ItemInfo& laraItem); void FireGrenade(ItemInfo& laraItem);
void GrenadeControl(short itemNumber); void GrenadeControl(short itemNumber);
void FireRocket(ItemInfo& laraItem); void FireRocket(ItemInfo& laraItem);
void FireRocket(ItemInfo& laraItem);
void RocketControl(short itemNumber); void RocketControl(short itemNumber);
void FireCrossbow(ItemInfo& laraItem, const std::optional<Pose>& pose = std::nullopt); void FireCrossbow(ItemInfo& laraItem, const std::optional<Pose>& pose = std::nullopt);
void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVector* target); void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVector* target);

View file

@ -2,8 +2,9 @@
#include "Game/Lara/lara_overhang.h" #include "Game/Lara/lara_overhang.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Game/Lara/lara_climb.h" #include "Game/Lara/lara_climb.h"
@ -16,6 +17,8 @@
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic; using namespace TEN::Entities::Generic;
using namespace TEN::Input; using namespace TEN::Input;
@ -324,14 +327,14 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
auto up = Vector3i(item->Pose.Position.x - slopeData.Offset.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z - slopeData.Offset.z); auto up = Vector3i(item->Pose.Position.x - slopeData.Offset.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z - slopeData.Offset.z);
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z); auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
auto probeUp = GetCollision(up.x, up.y, up.z, item->RoomNumber); auto probeUp = GetPointCollision(up, item->RoomNumber);
auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber); auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_OVERHANG_LADDER_SLOPE_CONCAVE) if (item->Animation.AnimNumber == LA_OVERHANG_LADDER_SLOPE_CONCAVE)
return; return;
item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST; item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
// Drop down if action not pressed. // Drop down if action not pressed.
if (!IsHeld(In::Action)) if (!IsHeld(In::Action))
@ -351,13 +354,13 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Forward)) if (IsHeld(In::Forward))
{ {
// Test for ledge over slope. // Test for ledge over slope.
short tempRoom = probeUp.Block->GetNextRoomNumber(up.x, up.z, false).value_or(NO_VALUE); short tempRoom = probeUp.GetSector().GetNextRoomNumber(up.x, up.z, false).value_or(NO_VALUE);
if (tempRoom != NO_VALUE) if (tempRoom != NO_VALUE)
{ {
auto probeLedge = GetCollision(now.x, now.y - CLICK(3), now.z, tempRoom); auto probeLedge = GetPointCollision(Vector3i(now.x, now.y - CLICK(3), now.z), tempRoom);
if ((probeLedge.Position.Floor - probeLedge.Position.Ceiling) >= CLICK(3) && if ((probeLedge.GetFloorHeight() - probeLedge.GetCeilingHeight()) >= CLICK(3) &&
abs((item->Pose.Position.y - (CLICK(2.5f) + 48)) - probeLedge.Position.Floor) < 64) abs((item->Pose.Position.y - (CLICK(2.5f) + 48)) - probeLedge.GetFloorHeight()) < 64)
{ {
AlignToEdge(item, FORWARD_ALIGNMENT); AlignToEdge(item, FORWARD_ALIGNMENT);
SetAnimation(item, LA_OVERHANG_LEDGE_VAULT_START); // Ledge climb-up from slope. SetAnimation(item, LA_OVERHANG_LEDGE_VAULT_START); // Ledge climb-up from slope.
@ -365,32 +368,32 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
} }
// Test for slope to overhead ladder transition (convex). // Test for slope to overhead ladder transition (convex).
if (GetClimbFlags(probeUp.BottomBlock) & slopeData.ClimbOrient && if (GetClimbFlags(&probeUp.GetBottomSector()) & slopeData.ClimbOrient &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4))) InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4)))
{ {
if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there. //if (GetPointCollision(probeUp.Block, up.x, up.y, up.z).GetCeilingHeight() - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there.
{ //{
AlignToEdge(item, FORWARD_ALIGNMENT); // AlignToEdge(item, FORWARD_ALIGNMENT);
SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START); // SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
} //}
} }
// Test for monkey at next position. // Test for monkey at next position.
if (probeUp.BottomBlock->Flags.Monkeyswing) if (probeUp.GetBottomSector().Flags.Monkeyswing)
{ {
int yDelta = probeUp.Position.Ceiling - probeNow.Position.Ceiling; int yDelta = probeUp.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height; // Height variable for bridge ceiling functions. int height; // Height variable for bridge ceiling functions.
// Test for upwards slope to climb. // Test for upwards slope to climb.
short bridge = FindBridge(4, item->Pose.Orientation.y, up, &height, -CLICK(2.5f), -CLICK(1.5f)); short bridge = FindBridge(4, item->Pose.Orientation.y, up, &height, -CLICK(2.5f), -CLICK(1.5f));
if (yDelta >= -CLICK(1.25f) && yDelta <= -CLICK(0.75f) && (SlopeCheck(probeUp.CeilingTilt, slopeData.Goal) || bridge >= 0)) if (yDelta >= -CLICK(1.25f) && yDelta <= -CLICK(0.75f) && (SlopeCheck(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0))
{ {
// Do one more check for wall/ceiling step 2 * offX / Z further to avoid lara sinking her head in wall/step. // Do one more check for wall/ceiling step 2 * offX / Z further to avoid lara sinking her head in wall/step.
auto probeWall = GetCollision((up.x - slopeData.Offset.x), (up.y - CLICK(1)), (up.z - slopeData.Offset.z), item->RoomNumber); auto probeWall = GetPointCollision(Vector3i((up.x - slopeData.Offset.x), (up.y - CLICK(1)), (up.z - slopeData.Offset.z)), item->RoomNumber);
if (!probeWall.Block->IsWall((up.x - slopeData.Offset.x), (up.z - slopeData.Offset.z)) && if (!probeWall.GetSector().IsWall((up.x - slopeData.Offset.x), (up.z - slopeData.Offset.z)) &&
(probeNow.Position.Ceiling - probeWall.Position.Ceiling) > CLICK(0.5f)) // No wall or downward ceiling step. (probeNow.GetCeilingHeight() - probeWall.GetCeilingHeight()) > CLICK(0.5f)) // No wall or downward ceiling step.
{ {
TranslateItem(item, 0, -CLICK(1), -CLICK(1)); TranslateItem(item, 0, -CLICK(1), -CLICK(1));
SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_UP_LEFT : LA_OVERHANG_CLIMB_UP_RIGHT); SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_UP_LEFT : LA_OVERHANG_CLIMB_UP_RIGHT);
@ -405,7 +408,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
// HACK: because of the different calculations of bridge height in TR4 and TEN, we need to lower yDiff tolerance to 0.9f. // HACK: because of the different calculations of bridge height in TR4 and TEN, we need to lower yDiff tolerance to 0.9f.
if (yDelta > -CLICK(0.9f) && yDelta <= -CLICK(0.5f) && if (yDelta > -CLICK(0.9f) && yDelta <= -CLICK(0.5f) &&
((abs(probeUp.CeilingTilt.x) <= 2 && abs(probeUp.CeilingTilt.y) <= 2) || bridge >= 0)) ((abs(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2().x) <= 2 && abs(GetSurfaceTilt(probeUp.GetCeilingNormal(), false).ToVector2().y) <= 2) || bridge >= 0))
{ {
SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONCAVE); // Slope to overhead monkey transition (concave). SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONCAVE); // Slope to overhead monkey transition (concave).
} }
@ -413,30 +416,30 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
} }
else if (IsHeld(In::Back)) else if (IsHeld(In::Back))
{ {
if ((GetClimbFlags(GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) && //if ((GetClimbFlags(GetPointCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).BottomBlock) & slopeData.ClimbOrient) &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(1))) // InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(1)))
{ //{
AlignToEdge(item, BACKWARD_ALIGNMENT); // AlignToEdge(item, BACKWARD_ALIGNMENT);
SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONCAVE); // Slope to underlying ladder transition (concave). // SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONCAVE); // Slope to underlying ladder transition (concave).
return; // return;
} //}
if (probeDown.BottomBlock->Flags.Monkeyswing) if (probeDown.GetBottomSector().Flags.Monkeyswing)
{ {
int height; int height;
int yDiff = probeDown.Position.Ceiling - probeNow.Position.Ceiling; int yDiff = probeDown.GetCeilingHeight() - probeNow.GetCeilingHeight();
// Test for flat monkey (abs(slope) < 2). // Test for flat monkey (abs(slope) < 2).
short bridge = FindBridge(0, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2)); short bridge = FindBridge(0, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2));
if (bridge < 0) if (bridge < 0)
bridge = FindBridge(1, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2)); bridge = FindBridge(1, slopeData.GoalOrient, down, &height, -CLICK(3), -CLICK(2));
if ((abs(yDiff) < CLICK(1) && abs(probeDown.CeilingTilt.x) <= 2 && abs(probeDown.CeilingTilt.y) <= 2) || bridge >= 0) if ((abs(yDiff) < CLICK(1) && abs(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x) <= 2 && abs(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().y) <= 2) || bridge >= 0)
SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONVEX); // Force slope to underlying monkey transition (convex) SetAnimation(item, LA_OVERHANG_SLOPE_MONKEY_CONVEX); // Force slope to underlying monkey transition (convex)
// Test for downward slope to climb. // Test for downward slope to climb.
bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(2.5f), -CLICK(1.5f)); bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(2.5f), -CLICK(1.5f));
if (yDiff >= CLICK(0.75f) && yDiff <= CLICK(1.25f) && (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0)) if (yDiff >= CLICK(0.75f) && yDiff <= CLICK(1.25f) && (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0))
{ {
SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_DOWN_LEFT : LA_OVERHANG_CLIMB_DOWN_RIGHT); SetAnimation(item, item->Animation.AnimNumber == LA_OVERHANG_IDLE_LEFT ? LA_OVERHANG_CLIMB_DOWN_LEFT : LA_OVERHANG_CLIMB_DOWN_RIGHT);
return; return;
@ -491,9 +494,9 @@ void lara_col_slopehang(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position; auto now = item->Pose.Position;
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST; item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
// Drop down if action not pressed. // Drop down if action not pressed.
if (!IsHeld(In::Action)) if (!IsHeld(In::Action))
@ -528,16 +531,16 @@ void lara_col_slopehang(ItemInfo* item, CollisionInfo* coll)
direction = ANGLE(90.0f); direction = ANGLE(90.0f);
} }
auto probeShimmy = GetCollision(shimmy.x, shimmy.y, shimmy.z, item->RoomNumber); auto probeShimmy = GetPointCollision(shimmy, item->RoomNumber);
if (probeShimmy.BottomBlock->Flags.Monkeyswing) if (probeShimmy.GetBottomSector().Flags.Monkeyswing)
{ {
int yDiff = probeShimmy.Position.Ceiling - probeNow.Position.Ceiling; int yDiff = probeShimmy.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height; int height;
short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f)); short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f));
if ((SlopeCheck(probeShimmy.CeilingTilt, slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0) if ((SlopeCheck(GetSurfaceTilt(probeShimmy.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
SetAnimation(item, direction < 0 ? LA_OVERHANG_SHIMMY_LEFT : LA_OVERHANG_SHIMMY_RIGHT); SetAnimation(item, direction < 0 ? LA_OVERHANG_SHIMMY_LEFT : LA_OVERHANG_SHIMMY_RIGHT);
} }
} }
@ -567,9 +570,9 @@ void lara_col_slopeshimmy(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position; auto now = item->Pose.Position;
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
item->Pose.Position.y = probeNow.Position.Ceiling + HEIGHT_ADJUST; item->Pose.Position.y = probeNow.GetCeilingHeight() + HEIGHT_ADJUST;
auto shimmy = item->Pose.Position; auto shimmy = item->Pose.Position;
if (item->Animation.AnimNumber == LA_OVERHANG_SHIMMY_LEFT) if (item->Animation.AnimNumber == LA_OVERHANG_SHIMMY_LEFT)
@ -583,17 +586,17 @@ void lara_col_slopeshimmy(ItemInfo* item, CollisionInfo* coll)
shimmy.z -= slopeData.Offset.x / 2; shimmy.z -= slopeData.Offset.x / 2;
} }
auto probeShimmy = GetCollision(shimmy.x, shimmy.y, shimmy.z, item->RoomNumber); auto probeShimmy = GetPointCollision(shimmy, item->RoomNumber);
bool cancelShimmy = true; bool cancelShimmy = true;
if (probeShimmy.BottomBlock->Flags.Monkeyswing) if (probeShimmy.GetBottomSector().Flags.Monkeyswing)
{ {
int yDiff = probeShimmy.Position.Ceiling - probeNow.Position.Ceiling; int yDiff = probeShimmy.GetCeilingHeight() - probeNow.GetCeilingHeight();
int height; int height;
short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f)); short bridge = FindBridge(4, slopeData.GoalOrient, shimmy, &height, -CLICK(2.5f), -CLICK(1.5f));
if ((SlopeCheck(probeShimmy.CeilingTilt, slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0) if ((SlopeCheck(GetSurfaceTilt(probeShimmy.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) && abs(yDiff) < 64) || bridge >= 0)
cancelShimmy = false; cancelShimmy = false;
} }
@ -836,16 +839,16 @@ void SlopeHangExtra(ItemInfo* item, CollisionInfo* coll)
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z); auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber); auto probeDown = GetPointCollision(down, item->RoomNumber);
int ceilDist = item->Pose.Position.y - probeDown.Position.Ceiling; int ceilDist = item->Pose.Position.y - probeDown.GetCeilingHeight();
if (item->Animation.TargetState == LS_LADDER_IDLE) // Prevent going from hang to climb mode if slope is under ladder. if (item->Animation.TargetState == LS_LADDER_IDLE) // Prevent going from hang to climb mode if slope is under ladder.
{ {
if (ceilDist >= CLICK(1) && ceilDist < CLICK(2)) if (ceilDist >= CLICK(1) && ceilDist < CLICK(2))
{ {
if ((probeDown.CeilingTilt.x / 3) == (slopeData.Goal.x / 3) || if ((GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x / 3) == (slopeData.Goal.x / 3) ||
(probeDown.CeilingTilt.y / 3) == (slopeData.Goal.y / 3)) (GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().y / 3) == (slopeData.Goal.y / 3))
{ {
item->Animation.TargetState = LS_HANG; item->Animation.TargetState = LS_HANG;
if (IsHeld(In::Forward)) if (IsHeld(In::Forward))
@ -861,8 +864,8 @@ void SlopeHangExtra(ItemInfo* item, CollisionInfo* coll)
{ {
if (ceilDist < CLICK(1)) if (ceilDist < CLICK(1))
{ {
if ((probeDown.CeilingTilt.x / 3) == (goal.x / 3) || if ((GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().x / 3) == (goal.x / 3) ||
(probeDown.CeilingTilt.z / 3) == (goal.y / 3)) (GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2().z / 3) == (goal.y / 3))
{ {
SetAnimation(item, LA_REACH_TO_HANG, 21); SetAnimation(item, LA_REACH_TO_HANG, 21);
} }
@ -881,19 +884,19 @@ void SlopeReachExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position; auto now = item->Pose.Position;
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
int ceilDist = item->Pose.Position.y - probeNow.Position.Ceiling; int ceilDist = item->Pose.Position.y - probeNow.GetCeilingHeight();
if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist <= CLICK(3.5f)) if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
{ {
int height; int height;
short bridge = FindBridge(4, slopeData.GoalOrient, now, &height, -CLICK(4), -CLICK(2.5f)); short bridge = FindBridge(4, slopeData.GoalOrient, now, &height, -CLICK(4), -CLICK(2.5f));
if (abs(probeNow.CeilingTilt.x) > 2 || abs(probeNow.CeilingTilt.y) > 2 || bridge >= 0) if (abs(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2().x) > 2 || abs(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2().y) > 2 || bridge >= 0)
{ {
bool disableGrab = true; bool disableGrab = true;
if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0) if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{ {
if (abs(OrientDelta(item->Pose.Orientation.y, slopeData.GoalOrient)) < ANGLE(33.75f)) if (abs(OrientDelta(item->Pose.Orientation.y, slopeData.GoalOrient)) < ANGLE(33.75f))
disableGrab = false; disableGrab = false;
@ -916,17 +919,17 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position; auto now = item->Pose.Position;
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z); auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber); auto probeDown = GetPointCollision(down, item->RoomNumber);
// Block for ladder to overhead slope transition. // Block for ladder to overhead slope transition.
if (item->Animation.AnimNumber == LA_LADDER_IDLE) if (item->Animation.AnimNumber == LA_LADDER_IDLE)
{ {
if (IsHeld(In::Forward)) if (IsHeld(In::Forward))
{ {
int ceilDist = probeNow.Position.Ceiling - item->Pose.Position.y; int ceilDist = probeNow.GetCeilingHeight() - item->Pose.Position.y;
if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist >= -CLICK(4) && ceilDist <= -CLICK(3)) if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist >= -CLICK(4) && ceilDist <= -CLICK(3))
{ {
short facing = item->Pose.Orientation.y + ANGLE(45.0f); short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f); facing &= ANGLE(270.0f);
@ -934,9 +937,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
int height; int height;
short bridge = FindBridge(4, facing, now, &height, -CLICK(4), -CLICK(3)); short bridge = FindBridge(4, facing, now, &height, -CLICK(4), -CLICK(3));
if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0) if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{ {
item->Pose.Position.y = probeNow.Position.Ceiling + 900; item->Pose.Position.y = probeNow.GetCeilingHeight() + 900;
SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONCAVE); // Ladder to overhead slope transition (concave). SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONCAVE); // Ladder to overhead slope transition (concave).
} }
} }
@ -944,9 +947,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Back)) if (IsHeld(In::Back))
{ {
int ceilDist = probeDown.Position.Ceiling - item->Pose.Position.y; int ceilDist = probeDown.GetCeilingHeight() - item->Pose.Position.y;
if (probeDown.BottomBlock->Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1)) if (probeDown.GetBottomSector().Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
{ {
short facing = item->Pose.Orientation.y + ANGLE(45.0f); short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f); facing &= ANGLE(270.0f);
@ -954,9 +957,9 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
int height; int height;
short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f)); short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f));
if (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0) if (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{ {
item->Pose.Position.y = probeDown.Position.Ceiling - 156; item->Pose.Position.y = probeDown.GetCeilingHeight() - 156;
SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONVEX); // Ladder to underlying slope transition (convex). SetAnimation(item, LA_OVERHANG_LADDER_SLOPE_CONVEX); // Ladder to underlying slope transition (convex).
} }
} }
@ -967,12 +970,12 @@ void SlopeClimbExtra(ItemInfo* item, CollisionInfo* coll)
// Extends LS_LADDER_IDLE (56) // Extends LS_LADDER_IDLE (56)
bool LadderMonkeyExtra(ItemInfo* item, CollisionInfo* coll) bool LadderMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
{ {
auto probe = GetCollision(item); auto probe = GetPointCollision(*item);
if (probe.Position.CeilingSlope) if (probe.IsSteepCeiling())
return false; return false;
if (probe.BottomBlock->Flags.Monkeyswing && (item->Pose.Position.y - coll->Setup.Height - CLICK(0.5f) <= probe.Position.Ceiling)) if (probe.GetBottomSector().Flags.Monkeyswing && (item->Pose.Position.y - coll->Setup.Height - CLICK(0.5f) <= probe.GetCeilingHeight()))
{ {
item->Animation.TargetState = LS_MONKEY_IDLE; item->Animation.TargetState = LS_MONKEY_IDLE;
return true; return true;
@ -991,15 +994,15 @@ void SlopeClimbDownExtra(ItemInfo* item, CollisionInfo* coll)
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z); auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber); auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_LADDER_DOWN) // Make Lara stop before underlying slope ceiling at correct height. if (item->Animation.AnimNumber == LA_LADDER_DOWN) // Make Lara stop before underlying slope ceiling at correct height.
{ {
if (IsHeld(In::Back)) if (IsHeld(In::Back))
{ {
int ceilDist = probeDown.Position.Ceiling - item->Pose.Position.y; int ceilDist = probeDown.GetCeilingHeight() - item->Pose.Position.y;
if (probeDown.BottomBlock->Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1)) if (probeDown.GetBottomSector().Flags.Monkeyswing && ceilDist >= 0 && ceilDist <= CLICK(1))
{ {
short facing = item->Pose.Orientation.y + ANGLE(45.0f); short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= ANGLE(270.0f); facing &= ANGLE(270.0f);
@ -1007,9 +1010,9 @@ void SlopeClimbDownExtra(ItemInfo* item, CollisionInfo* coll)
int height; int height;
short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f)); short bridge = FindBridge(4, facing, down, &height, -CLICK(0.5f), -CLICK(0.25f));
if (SlopeCheck(probeDown.CeilingTilt, slopeData.Goal) || bridge >= 0) if (SlopeCheck(GetSurfaceTilt(probeDown.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{ {
item->Pose.Position.y = probeDown.Position.Ceiling - 156; item->Pose.Position.y = probeDown.GetCeilingHeight() - 156;
item->Animation.TargetState = LS_LADDER_IDLE; item->Animation.TargetState = LS_LADDER_IDLE;
} }
} }
@ -1054,14 +1057,14 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
auto now = item->Pose.Position; auto now = item->Pose.Position;
auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z); auto down = Vector3i(item->Pose.Position.x + slopeData.Offset.x, item->Pose.Position.y + CLICK(1), item->Pose.Position.z + slopeData.Offset.z);
auto probeNow = GetCollision(now.x, now.y, now.z, item->RoomNumber); auto probeNow = GetPointCollision(now, item->RoomNumber);
auto probeDown = GetCollision(down.x, down.y, down.z, item->RoomNumber); auto probeDown = GetPointCollision(down, item->RoomNumber);
if (item->Animation.AnimNumber == LA_REACH_TO_MONKEY && !GetFrameIndex(item, 0)) // Manage proper grabbing of monkey slope on forward jump. if (item->Animation.AnimNumber == LA_REACH_TO_MONKEY && !GetFrameIndex(item, 0)) // Manage proper grabbing of monkey slope on forward jump.
{ {
int ceilDist = item->Pose.Position.y - probeNow.Position.Ceiling; int ceilDist = item->Pose.Position.y - probeNow.GetCeilingHeight();
if (probeNow.BottomBlock->Flags.Monkeyswing && ceilDist <= CLICK(3.5f)) if (probeNow.GetBottomSector().Flags.Monkeyswing && ceilDist <= CLICK(3.5f))
{ {
short facing = item->Pose.Orientation.y + ANGLE(45.0f); short facing = item->Pose.Orientation.y + ANGLE(45.0f);
facing &= 0xC000; facing &= 0xC000;
@ -1069,12 +1072,12 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
int height; int height;
short bridge = FindBridge(4, facing, now, &height, -CLICK(3.5f), -CLICK(2.5f)); short bridge = FindBridge(4, facing, now, &height, -CLICK(3.5f), -CLICK(2.5f));
if (SlopeCheck(probeNow.CeilingTilt, slopeData.Goal) || bridge >= 0) if (SlopeCheck(GetSurfaceTilt(probeNow.GetCeilingNormal(), false).ToVector2(), slopeData.Goal) || bridge >= 0)
{ {
lara->Context.NextCornerPos.Orientation.z = AlignToGrab(item); lara->Context.NextCornerPos.Orientation.z = AlignToGrab(item);
int ceiling = GetCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).Position.Ceiling; /*int ceiling = GetPointCollision(probeNow.Block, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z).GetCeilingHeight();
item->Pose.Position.y = ceiling + HEIGHT_ADJUST; item->Pose.Position.y = ceiling + HEIGHT_ADJUST;*/
SetAnimation(item, LA_OVERHANG_HANG_SWING); SetAnimation(item, LA_OVERHANG_HANG_SWING);
} }
@ -1083,16 +1086,16 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
if (IsHeld(In::Forward)) // Monkey to slope transitions. if (IsHeld(In::Forward)) // Monkey to slope transitions.
{ {
if (probeNow.BottomBlock->Flags.Monkeyswing && if (probeNow.GetBottomSector().Flags.Monkeyswing &&
((item->Animation.AnimNumber == LA_REACH_TO_MONKEY && GetFrameIndex(item, 0) >= 54) || item->Animation.AnimNumber == LA_MONKEY_IDLE)) ((item->Animation.AnimNumber == LA_REACH_TO_MONKEY && GetFrameIndex(item, 0) >= 54) || item->Animation.AnimNumber == LA_MONKEY_IDLE))
{ {
if (abs(OrientDelta(slopeData.GoalOrient, item->Pose.Orientation.y)) <= ANGLE(30.0f) && if (abs(OrientDelta(slopeData.GoalOrient, item->Pose.Orientation.y)) <= ANGLE(30.0f) &&
InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(0.5f))) InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, 0, CLICK(0.5f)))
{ {
if (probeDown.BottomBlock->Flags.Monkeyswing) /*if (probeDown.BottomBlock->Flags.Monkeyswing)
{ {
int ceiling = GetCollision(probeDown.Block, down.x, now.y, down.z).Position.Ceiling; int ceiling = GetPointCollision(probeDown.Block, down.x, now.y, down.z).GetCeilingHeight();
int yDiff = ceiling - probeNow.Position.Ceiling; int yDiff = ceiling - probeNow.GetCeilingHeight();
int height; int height;
short bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(7) >> 1, -CLICK(5) >> 1); short bridge = FindBridge(4, slopeData.GoalOrient, down, &height, -CLICK(7) >> 1, -CLICK(5) >> 1);
@ -1113,7 +1116,7 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
return; return;
//item->Pose.Position.y = ceiling + 914; //item->Pose.Position.y = ceiling + 914;
} }
} }*/
} }
} }
@ -1122,19 +1125,19 @@ void SlopeMonkeyExtra(ItemInfo* item, CollisionInfo* coll)
// Additional overhang ladder tests. // Additional overhang ladder tests.
int y = item->Pose.Position.y - coll->Setup.Height; int y = item->Pose.Position.y - coll->Setup.Height;
auto probe = GetCollision(down.x, item->Pose.Position.y - coll->Setup.Height, down.z, item->RoomNumber); auto probe = GetPointCollision(Vector3i(down.x, item->Pose.Position.y - coll->Setup.Height, down.z), item->RoomNumber);
if (probe.BottomBlock->Flags.IsWallClimbable(GetClimbDirectionFlags(item->Pose.Orientation.y + ANGLE(180.0f))) && if (probe.GetBottomSector().Flags.IsWallClimbable(GetClimbDirectionFlags(item->Pose.Orientation.y + ANGLE(180.0f))) &&
probe.Position.Floor >= (item->Pose.Position.y - CLICK(1)) && probe.GetFloorHeight() >= (item->Pose.Position.y - CLICK(1)) &&
probe.Position.Ceiling <= (y - CLICK(1))) probe.GetCeilingHeight() <= (y - CLICK(1)))
{ {
// Primary checks succeeded, now do C-shaped secondary probing. // Primary checks succeeded, now do C-shaped secondary probing.
probe = GetCollision(down.x, y, down.z, probe.RoomNumber); probe = GetPointCollision(Vector3i(down.x, y, down.z), probe.GetRoomNumber());
probe = GetCollision(down.x, y - CLICK(2), down.z, probe.RoomNumber); probe = GetPointCollision(Vector3i(down.x, y - CLICK(2), down.z), probe.GetRoomNumber());
probe = GetCollision(now.x, y - CLICK(2), now.z, probe.RoomNumber); probe = GetPointCollision(Vector3i(now.x, y - CLICK(2), now.z), probe.GetRoomNumber());
if (probe.Position.Floor <= (y - CLICK(1)) || if (probe.GetFloorHeight() <= (y - CLICK(1)) ||
probe.Position.Ceiling >= (y - CLICK(1))) probe.GetCeilingHeight() >= (y - CLICK(1)))
{ {
if (item->Animation.TargetState != LS_LADDER_IDLE) if (item->Animation.TargetState != LS_LADDER_IDLE)
{ {

View file

@ -1025,7 +1025,7 @@ public:
Ammo& operator --() Ammo& operator --()
{ {
assertion(Count > 0, "Ammo count is already 0."); TENAssert(Count > 0, "Ammo count is already 0.");
--Count; --Count;
return *this; return *this;
} }

View file

@ -273,6 +273,5 @@ void lara_as_surface_climb_out(ItemInfo* item, CollisionInfo* coll)
player.Control.Look.Mode = LookMode::None; player.Control.Look.Mode = LookMode::None;
coll->Setup.EnableObjectPush = false; coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.flags = CF_FOLLOW_CENTER; Camera.flags = CF_FOLLOW_CENTER; // Forces the camera to follow Lara instead of snapping.
Camera.laraNode = LM_HIPS; // Forces the camera to follow Lara instead of snapping.
} }

View file

@ -3,6 +3,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/lara_collide.h" #include "Game/Lara/lara_collide.h"
@ -14,6 +15,7 @@
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
using namespace TEN::Collision::Point;
using namespace TEN::Input; using namespace TEN::Input;
// ----------------------------- // -----------------------------
@ -187,7 +189,7 @@ void lara_col_underwater_death(ItemInfo* item, CollisionInfo* coll)
item->HitPoints = -1; item->HitPoints = -1;
lara->Control.HandStatus = HandStatus::Busy; lara->Control.HandStatus = HandStatus::Busy;
int waterHeight = GetWaterHeight(item); int waterHeight = GetPointCollision(*item).GetWaterTopHeight();
if (waterHeight < (item->Pose.Position.y - (CLICK(0.4f) - 2)) && if (waterHeight < (item->Pose.Position.y - (CLICK(0.4f) - 2)) &&
waterHeight != NO_HEIGHT) waterHeight != NO_HEIGHT)
{ {

View file

@ -5,6 +5,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/collision/collide_item.h" #include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/control/control.h" #include "Game/control/control.h"
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/items.h" #include "Game/items.h"
@ -16,16 +17,16 @@
#include "Game/Lara/lara_helpers.h" #include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_monkey.h" #include "Game/Lara/lara_monkey.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer.h" #include "Specific/configuration.h"
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Point;
using namespace TEN::Entities::Player; using namespace TEN::Entities::Player;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Math; using namespace TEN::Math;
using namespace TEN::Renderer;
using namespace TEN::Utils; using namespace TEN::Utils;
// ----------------------------- // -----------------------------
@ -46,18 +47,18 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int y = item->Pose.Position.y - coll->Setup.Height; int y = item->Pose.Position.y - coll->Setup.Height;
// Get frontal collision data // Get frontal collision data
auto frontLeft = GetCollision(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber); auto frontLeft = GetPointCollision(Vector3i(item->Pose.Position.x + xl, y, item->Pose.Position.z + zl), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
auto frontRight = GetCollision(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber); auto frontRight = GetPointCollision(Vector3i(item->Pose.Position.x + xr, y, item->Pose.Position.z + zr), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber);
// If any of the frontal collision results intersects item bounds, return false, because there is material intersection. // If any of the frontal collision results intersects item bounds, return false, because there is material intersection.
// This check helps to filter out cases when Lara is formally facing corner but ledge check returns true because probe distance is fixed. // This check helps to filter out cases when Lara is formally facing corner but ledge check returns true because probe distance is fixed.
if (frontLeft.Position.Floor < (item->Pose.Position.y - CLICK(0.5f)) || frontRight.Position.Floor < (item->Pose.Position.y - CLICK(0.5f))) if (frontLeft.GetFloorHeight() < (item->Pose.Position.y - CLICK(0.5f)) || frontRight.GetFloorHeight() < (item->Pose.Position.y - CLICK(0.5f)))
return false; return false;
if (frontLeft.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height) || frontRight.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height)) if (frontLeft.GetCeilingHeight() >(item->Pose.Position.y - coll->Setup.Height) || frontRight.GetCeilingHeight() > (item->Pose.Position.y - coll->Setup.Height))
return false; return false;
//g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats); //DrawDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats);
//g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RendererDebugPage::CollisionStats); //DrawDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RendererDebugPage::CollisionStats);
// Determine ledge probe embed offset. // Determine ledge probe embed offset.
// We use 0.2f radius extents here for two purposes. First - we can't guarantee that shifts weren't already applied // We use 0.2f radius extents here for two purposes. First - we can't guarantee that shifts weren't already applied
@ -66,8 +67,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
int zf = phd_cos(coll->NearestLedgeAngle) * (coll->Setup.Radius * 1.2f); int zf = phd_cos(coll->NearestLedgeAngle) * (coll->Setup.Radius * 1.2f);
// Get floor heights at both points // Get floor heights at both points
auto left = GetCollision(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).Position.Floor; auto left = GetPointCollision(Vector3i(item->Pose.Position.x + xf + xl, y, item->Pose.Position.z + zf + zl), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).GetFloorHeight();
auto right = GetCollision(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr, GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).Position.Floor; auto right = GetPointCollision(Vector3i(item->Pose.Position.x + xf + xr, y, item->Pose.Position.z + zf + zr), GetRoomVector(item->Location, Vector3i(item->Pose.Position.x, y, item->Pose.Position.z)).RoomNumber).GetFloorHeight();
// If specified, limit vertical search zone only to nearest height // If specified, limit vertical search zone only to nearest height
if (heightLimit && (abs(left - y) > CLICK(0.5f) || abs(right - y) > CLICK(0.5f))) if (heightLimit && (abs(left - y) > CLICK(0.5f) || abs(right - y) > CLICK(0.5f)))
@ -140,6 +141,7 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT; coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0; coll->Setup.LowerCeilingBound = 0;
coll->Setup.ForwardAngle = lara->Control.MoveAngle; coll->Setup.ForwardAngle = lara->Control.MoveAngle;
coll->Setup.ForceSolidStatics = true;
// When Lara is about to move, use larger embed offset for stabilizing diagonal shimmying) // When Lara is about to move, use larger embed offset for stabilizing diagonal shimmying)
int embedOffset = 4; int embedOffset = 4;
@ -214,7 +216,7 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
z += testShift.y; z += testShift.y;
} }
if (TestLaraNearClimbableWall(item, GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).BottomBlock)) if (TestLaraNearClimbableWall(item, &GetPointCollision(Vector3i(x, item->Pose.Position.y, z), item->RoomNumber).GetBottomSector()))
{ {
if (!TestLaraHangOnClimbableWall(item, coll)) if (!TestLaraHangOnClimbableWall(item, coll))
verticalShift = 0; // Ignore vertical shift if ladder is encountered next block verticalShift = 0; // Ignore vertical shift if ladder is encountered next block
@ -450,7 +452,7 @@ bool TestLaraClimbIdle(ItemInfo* item, CollisionInfo* coll)
bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor) bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor)
{ {
if (floor == nullptr) if (floor == nullptr)
floor = GetCollision(item).BottomBlock; floor = &GetPointCollision(*item).GetBottomSector();
return ((256 << (GetQuadrant(item->Pose.Orientation.y))) & GetClimbFlags(floor)); return ((256 << (GetQuadrant(item->Pose.Orientation.y))) & GetClimbFlags(floor));
} }
@ -523,7 +525,7 @@ bool TestLaraValidHangPosition(ItemInfo* item, CollisionInfo* coll)
// Get incoming ledge height and own Lara's upper bound. // Get incoming ledge height and own Lara's upper bound.
// First one will be negative while first one is positive. // First one will be negative while first one is positive.
// Difference between two indicates difference in height between ledges. // Difference between two indicates difference in height between ledges.
auto frontFloor = GetCollision(item, lara->Control.MoveAngle, coll->Setup.Radius + CLICK(0.5f), -LARA_HEIGHT).Position.Floor; auto frontFloor = GetPointCollision(*item, lara->Control.MoveAngle, coll->Setup.Radius + CLICK(0.5f), -LARA_HEIGHT).GetFloorHeight();
auto laraUpperBound = item->Pose.Position.y - coll->Setup.Height; auto laraUpperBound = item->Pose.Position.y - coll->Setup.Height;
// If difference is above 1/2 click, return false (ledge is out of reach). // If difference is above 1/2 click, return false (ledge is out of reach).
@ -582,7 +584,7 @@ CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAng
item->Pose = cornerResult.RealPositionResult; item->Pose = cornerResult.RealPositionResult;
lara->Context.NextCornerPos.Position = Vector3i( lara->Context.NextCornerPos.Position = Vector3i(
item->Pose.Position.x, item->Pose.Position.x,
GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius + 16, -(coll->Setup.Height + CLICK(0.5f))).Position.Floor + abs(bounds.Y1), GetPointCollision(*item, item->Pose.Orientation.y, coll->Setup.Radius + 16, -(coll->Setup.Height + CLICK(0.5f))).GetFloorHeight() + abs(bounds.Y1),
item->Pose.Position.z item->Pose.Position.z
); );
lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y; lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y;
@ -640,7 +642,7 @@ CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAng
// Store next position // Store next position
item->Pose = cornerResult.RealPositionResult; item->Pose = cornerResult.RealPositionResult;
lara->Context.NextCornerPos.Position.x = item->Pose.Position.x; lara->Context.NextCornerPos.Position.x = item->Pose.Position.x;
lara->Context.NextCornerPos.Position.y = GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius * 1.25f, -(abs(bounds.Y1) + LARA_HEADROOM)).Position.Floor + abs(bounds.Y1); lara->Context.NextCornerPos.Position.y = GetPointCollision(*item, item->Pose.Orientation.y, coll->Setup.Radius * 1.25f, -(abs(bounds.Y1) + LARA_HEADROOM)).GetFloorHeight() + abs(bounds.Y1);
lara->Context.NextCornerPos.Position.z = item->Pose.Position.z; lara->Context.NextCornerPos.Position.z = item->Pose.Position.z;
lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y; lara->Context.NextCornerPos.Orientation.y = item->Pose.Orientation.y;
lara->Control.MoveAngle = item->Pose.Orientation.y; lara->Control.MoveAngle = item->Pose.Orientation.y;
@ -742,14 +744,16 @@ CornerTestResult TestItemAtNextCornerPosition(ItemInfo* item, CollisionInfo* col
bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll) bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); int vPos = item->Pose.Position.y;
auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius) + item->Animation.Velocity.z);
int y = item->Pose.Position.y; // 1) Test for wall.
auto probe = GetCollision(item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius)); if (pointColl.GetFloorHeight() == NO_HEIGHT)
return false;
if ((probe.Position.Floor - y) > 0 && // 2) Test leg space.
(probe.Position.Ceiling - y) < -CLICK(1.6f) && if ((pointColl.GetFloorHeight() - vPos) > 0 &&
probe.Position.Floor != NO_HEIGHT) (pointColl.GetCeilingHeight() - vPos) < -CLICK(1.6f))
{ {
return true; return true;
} }
@ -852,32 +856,22 @@ bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance)
int LaraFloorFront(ItemInfo* item, short angle, int distance) int LaraFloorFront(ItemInfo* item, short angle, int distance)
{ {
return LaraCollisionFront(item, angle, distance).Position.Floor; auto pointColl = GetPointCollision(*item, angle, distance, -LARA_HEIGHT);
if (pointColl.GetFloorHeight() == NO_HEIGHT)
return pointColl.GetFloorHeight();
return (pointColl.GetFloorHeight() - item->Pose.Position.y);
} }
int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height) int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height)
{ {
return LaraCeilingCollisionFront(item, angle, distance, height).Position.Ceiling; auto pointColl = GetPointCollision(*item, angle, distance, -height);
}
CollisionResult LaraCollisionFront(ItemInfo* item, short angle, int distance) if (pointColl.GetCeilingHeight() == NO_HEIGHT)
{ return pointColl.GetCeilingHeight();
auto probe = GetCollision(item, angle, distance, -LARA_HEIGHT);
if (probe.Position.Floor != NO_HEIGHT) return ((pointColl.GetCeilingHeight() + height) - item->Pose.Position.y);
probe.Position.Floor -= item->Pose.Position.y;
return probe;
}
CollisionResult LaraCeilingCollisionFront(ItemInfo* item, short angle, int distance, int height)
{
auto probe = GetCollision(item, angle, distance, -height);
if (probe.Position.Ceiling != NO_HEIGHT)
probe.Position.Ceiling += height - item->Pose.Position.y;
return probe;
} }
bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll) bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
@ -885,17 +879,17 @@ bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
auto& player = GetLaraInfo(*item); auto& player = GetLaraInfo(*item);
// Get point collision. // Get point collision.
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
int vPos = item->Pose.Position.y; int vPos = item->Pose.Position.y;
if (coll->CollisionType == CollisionType::Front || if (coll->CollisionType == CollisionType::Front ||
pointColl.Position.FloorSlope || pointColl.IsSteepFloor() ||
(pointColl.Position.Floor - vPos) <= 0) (pointColl.GetFloorHeight() - vPos) <= 0)
{ {
return false; return false;
} }
if ((pointColl.Position.Floor - vPos) >= -CLICK(0.5f)) if ((pointColl.GetFloorHeight() - vPos) >= -CLICK(0.5f))
{ {
SetAnimation(item, LA_STAND_IDLE); SetAnimation(item, LA_STAND_IDLE);
} }
@ -905,7 +899,7 @@ bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
} }
item->Pose.Position.y = pointColl.Position.Floor; item->Pose.Position.y = pointColl.GetFloorHeight();
UpdateLaraRoom(item, -(STEPUP_HEIGHT - 3)); UpdateLaraRoom(item, -(STEPUP_HEIGHT - 3));
ResetPlayerLean(item); ResetPlayerLean(item);
@ -933,22 +927,39 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
if (coll->Middle.Ceiling > -STEPUP_HEIGHT) if (coll->Middle.Ceiling > -STEPUP_HEIGHT)
return false; return false;
int frontFloor = coll->Front.Floor + LARA_HEIGHT_TREAD; // HACK: Probe at incremetal height steps to account for room stacks. -- Sezz 2024.10.28
if (coll->Front.Bridge == NO_VALUE && int frontFloor = NO_HEIGHT;
(frontFloor <= -CLICK(2) || if (coll->Front.Bridge != NO_VALUE)
frontFloor > CLICK(1.25f) - 4))
{ {
return false; auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.2f), -BLOCK(0.5f));
frontFloor = (pointColl.GetFloorHeight() - item->Pose.Position.y);
}
else
{
int yOffset = CLICK(1.25f);
while (yOffset > -CLICK(2))
{
auto pointColl = GetPointCollision(*item, item->Pose.Orientation.y, BLOCK(0.2f), yOffset);
frontFloor = pointColl.GetFloorHeight() - item->Pose.Position.y;
if (frontFloor > -CLICK(2) &&
frontFloor <= (CLICK(1.25f) - 4))
{
break;
}
yOffset -= CLICK(0.5f);
}
} }
// Extra bridge check. // Extra bridge check.
if (coll->Front.Bridge != NO_VALUE) if (coll->Front.Bridge != NO_VALUE)
{ {
int bridgeBorder = GetBridgeBorder(g_Level.Items[coll->Front.Bridge], false) - item->Pose.Position.y; frontFloor = GetBridgeBorder(g_Level.Items[coll->Front.Bridge], false) - item->Pose.Position.y;
frontFloor = bridgeBorder - CLICK(0.5f); int bridgeBorder = frontFloor - CLICK(0.5f);
if (frontFloor <= -CLICK(2) || if (bridgeBorder <= -CLICK(2) ||
frontFloor > CLICK(1.25f) - 4) bridgeBorder > CLICK(1.25f) - 4)
{ {
return false; return false;
} }
@ -961,8 +972,8 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
if (coll->HitStatic) if (coll->HitStatic)
return false; return false;
auto probe = GetCollision(item, coll->Setup.ForwardAngle, CLICK(2), -CLICK(1)); auto probe = GetPointCollision(*item, coll->Setup.ForwardAngle, CLICK(2), -CLICK(1));
int headroom = probe.Position.Floor - probe.Position.Ceiling; int headroom = probe.GetFloorHeight() - probe.GetCeilingHeight();
if (frontFloor <= -CLICK(1)) if (frontFloor <= -CLICK(1))
{ {
@ -1095,21 +1106,19 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
{ {
auto& player = GetLaraInfo(*item); auto& player = GetLaraInfo(*item);
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(*item);
int waterDepth = GetWaterDepth(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, pointColl.RoomNumber);
if (waterDepth == NO_HEIGHT) if (pointColl.GetWaterBottomHeight() == NO_HEIGHT)
{ {
item->Animation.Velocity.y = 0.0f; item->Animation.Velocity.y = 0.0f;
item->Pose.Position = coll->Setup.PrevPosition; item->Pose.Position = coll->Setup.PrevPosition;
} }
else if (pointColl.GetWaterBottomHeight() <= (LARA_HEIGHT - (LARA_HEADROOM / 2)))
else if (waterDepth <= (LARA_HEIGHT - (LARA_HEADROOM / 2)))
{ {
SetAnimation(item, LA_UNDERWATER_TO_STAND); SetAnimation(item, LA_UNDERWATER_TO_STAND);
ResetPlayerLean(item); ResetPlayerLean(item);
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
item->Pose.Position.y = pointColl.Position.Floor; item->Pose.Position.y = pointColl.GetFloorHeight();
item->Animation.IsAirborne = false; item->Animation.IsAirborne = false;
item->Animation.Velocity.y = 0.0f; item->Animation.Velocity.y = 0.0f;
item->Animation.Velocity.z = 0.0f; item->Animation.Velocity.z = 0.0f;
@ -1202,12 +1211,12 @@ std::optional<VaultTestResult> TestLaraVaultTolerance(ItemInfo* item, CollisionI
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
int distance = OFFSET_RADIUS(coll->Setup.Radius); int distance = OFFSET_RADIUS(coll->Setup.Radius);
auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height); auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
auto probeMiddle = GetCollision(item); auto probeMiddle = GetPointCollision(*item);
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item); bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item);
bool swampTooDeep = testSetup.CheckSwampDepth ? (isSwamp && lara->Context.WaterSurfaceDist < -CLICK(3)) : isSwamp; bool swampTooDeep = testSetup.CheckSwampDepth ? (isSwamp && lara->Context.WaterSurfaceDist < -CLICK(3)) : isSwamp;
int y = isSwamp ? item->Pose.Position.y : probeMiddle.Position.Floor; // HACK: Avoid cheese when in the midst of performing a step. Can be done better. @Sezz 2022.04.08 int y = isSwamp ? item->Pose.Position.y : probeMiddle.GetFloorHeight(); // HACK: Avoid cheese when in the midst of performing a step. Can be done better. @Sezz 2022.04.08
// Check swamp depth (if applicable). // Check swamp depth (if applicable).
if (swampTooDeep) if (swampTooDeep)
@ -1220,27 +1229,27 @@ std::optional<VaultTestResult> TestLaraVaultTolerance(ItemInfo* item, CollisionI
// Raise y position of point/room probe by increments of CLICK(0.5f) to find potential vault ledge. // Raise y position of point/room probe by increments of CLICK(0.5f) to find potential vault ledge.
int yOffset = testSetup.LowerFloorBound; int yOffset = testSetup.LowerFloorBound;
while (((probeFront.Position.Ceiling - y) > -coll->Setup.Height || // Ceiling is below Lara's height... while (((probeFront.GetCeilingHeight() - y) > -coll->Setup.Height || // Ceiling is below Lara's height...
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMin || // OR clamp is too small abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) <= testSetup.ClampMin || // OR clamp is too small
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMax) && // OR clamp is too large (future-proofing; not possible right now). abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) > testSetup.ClampMax) && // OR clamp is too large (future-proofing; not possible right now).
yOffset > (testSetup.UpperFloorBound - coll->Setup.Height)) // Offset is not too high. yOffset > (testSetup.UpperFloorBound - coll->Setup.Height)) // Offset is not too high.
{ {
probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, yOffset); probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, yOffset);
yOffset -= std::max<int>(CLICK(0.5f), testSetup.ClampMin); yOffset -= std::max<int>(CLICK(0.5f), testSetup.ClampMin);
} }
// Discard walls. // Discard walls.
if (probeFront.Position.Floor == NO_HEIGHT) if (probeFront.GetFloorHeight() == NO_HEIGHT)
return std::nullopt; return std::nullopt;
// Assess point/room collision. // Assess point/room collision.
if ((probeFront.Position.Floor - y) < testSetup.LowerFloorBound && // Within lower floor bound. if ((probeFront.GetFloorHeight() - y) < testSetup.LowerFloorBound && // Within lower floor bound.
(probeFront.Position.Floor - y) >= testSetup.UpperFloorBound && // Within upper floor bound. (probeFront.GetFloorHeight() - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) > testSetup.ClampMin && // Within clamp min. abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) > testSetup.ClampMin && // Within clamp min.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) <= testSetup.ClampMax && // Within clamp max. abs(probeFront.GetCeilingHeight() - probeFront.GetFloorHeight()) <= testSetup.ClampMax && // Within clamp max.
abs(probeMiddle.Position.Ceiling - probeFront.Position.Floor) >= testSetup.GapMin) // Gap is optically permissive. abs(probeMiddle.GetCeilingHeight() - probeFront.GetFloorHeight()) >= testSetup.GapMin) // Gap is optically permissive.
{ {
return VaultTestResult{ probeFront.Position.Floor }; return VaultTestResult{ probeFront.GetFloorHeight() };
} }
return std::nullopt; return std::nullopt;
@ -1390,20 +1399,20 @@ std::optional<VaultTestResult> TestLaraLadderAutoJump(ItemInfo* item, CollisionI
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
int distance = OFFSET_RADIUS(coll->Setup.Radius); int distance = OFFSET_RADIUS(coll->Setup.Radius);
auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height); auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
auto probeMiddle = GetCollision(item); auto probeMiddle = GetPointCollision(*item);
// Check ledge angle. // Check ledge angle.
if (!TestValidLedgeAngle(item, coll)) if (!TestValidLedgeAngle(item, coll))
return std::nullopt; return std::nullopt;
if (lara->Control.CanClimbLadder && // Ladder sector flag set. if (lara->Control.CanClimbLadder && // Ladder sector flag set.
(probeMiddle.Position.Ceiling - y) <= -CLICK(6.5f) && // Within lowest middle ceiling bound. (Synced with TestLaraLadderMount()) (probeMiddle.GetCeilingHeight() - y) <= -CLICK(6.5f) && // Within lowest middle ceiling bound. (Synced with TestLaraLadderMount())
((probeFront.Position.Floor - y) <= -CLICK(6.5f) || // Floor height is appropriate, OR ((probeFront.GetFloorHeight() - y) <= -CLICK(6.5f) || // Floor height is appropriate, OR
(probeFront.Position.Ceiling - y) > -CLICK(6.5f)) && // Ceiling height is appropriate. (Synced with TestLaraLadderMount()) (probeFront.GetCeilingHeight() - y) > -CLICK(6.5f)) && // Ceiling height is appropriate. (Synced with TestLaraLadderMount())
coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall. coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall.
{ {
return VaultTestResult{ probeMiddle.Position.Ceiling, false, true, true }; return VaultTestResult{ probeMiddle.GetCeilingHeight(), false, true, true };
} }
return std::nullopt; return std::nullopt;
@ -1415,18 +1424,18 @@ std::optional<VaultTestResult> TestLaraLadderMount(ItemInfo* item, CollisionInfo
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
int distance = OFFSET_RADIUS(coll->Setup.Radius); int distance = OFFSET_RADIUS(coll->Setup.Radius);
auto probeFront = GetCollision(item, coll->NearestLedgeAngle, distance, -coll->Setup.Height); auto probeFront = GetPointCollision(*item, coll->NearestLedgeAngle, distance, -coll->Setup.Height);
auto probeMiddle = GetCollision(item); auto probeMiddle = GetPointCollision(*item);
// Check ledge angle. // Check ledge angle.
if (!TestValidLedgeAngle(item, coll)) if (!TestValidLedgeAngle(item, coll))
return std::nullopt; return std::nullopt;
if (lara->Control.CanClimbLadder && // Ladder sector flag set. if (lara->Control.CanClimbLadder && // Ladder sector flag set.
(probeMiddle.Position.Ceiling - y) <= -CLICK(4.5f) && // Within lower middle ceiling bound. (probeMiddle.GetCeilingHeight() - y) <= -CLICK(4.5f) && // Within lower middle ceiling bound.
(probeMiddle.Position.Ceiling - y) > -CLICK(6.5f) && // Within upper middle ceiling bound. (probeMiddle.GetCeilingHeight() - y) > -CLICK(6.5f) && // Within upper middle ceiling bound.
(probeMiddle.Position.Floor - y) > -CLICK(6.5f) && // Within upper middle floor bound. (Synced with TestLaraAutoJump()) (probeMiddle.GetFloorHeight() - y) > -CLICK(6.5f) && // Within upper middle floor bound. (Synced with TestLaraAutoJump())
(probeFront.Position.Ceiling - y) <= -CLICK(4.5f) && // Within lowest front ceiling bound. (probeFront.GetCeilingHeight() - y) <= -CLICK(4.5f) && // Within lowest front ceiling bound.
coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall. coll->NearestLedgeDistance <= coll->Setup.Radius) // Appropriate distance from wall.
{ {
return VaultTestResult{ NO_HEIGHT, true, true, false }; return VaultTestResult{ NO_HEIGHT, true, true, false };
@ -1435,18 +1444,18 @@ std::optional<VaultTestResult> TestLaraLadderMount(ItemInfo* item, CollisionInfo
return std::nullopt; return std::nullopt;
} }
std::optional<VaultTestResult> TestLaraMonkeyAutoJump(ItemInfo* item, CollisionInfo* coll) std::optional<VaultTestResult> TestLaraAutoMonkeySwingJump(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
auto probe = GetCollision(item); auto probe = GetPointCollision(*item);
if (lara->Control.CanMonkeySwing && // Monkey swing sector flag set. if (lara->Control.CanMonkeySwing && // Monkey swing sector flag set.
(probe.Position.Ceiling - y) < -LARA_HEIGHT_MONKEY && // Within lower ceiling bound. (probe.GetCeilingHeight() - y) < -LARA_HEIGHT_MONKEY && // Within lower ceiling bound.
(probe.Position.Ceiling - y) >= -CLICK(7)) // Within upper ceiling bound. (probe.GetCeilingHeight() - y) >= -CLICK(7)) // Within upper ceiling bound.
{ {
return VaultTestResult{ probe.Position.Ceiling, false, false, true }; return VaultTestResult{ probe.GetCeilingHeight(), false, false, true };
} }
return std::nullopt; return std::nullopt;
@ -1538,8 +1547,8 @@ std::optional<VaultTestResult> TestLaraVault(ItemInfo* item, CollisionInfo* coll
// In this case, they fail due to a reliance on ShiftItem(). @Sezz 2021.02.05 // In this case, they fail due to a reliance on ShiftItem(). @Sezz 2021.02.05
// Auto jump to monkey swing. // Auto jump to monkey swing.
vaultResult = TestLaraMonkeyAutoJump(item, coll); vaultResult = TestLaraAutoMonkeySwingJump(item, coll);
if (vaultResult.has_value() && g_GameFlow->HasMonkeyAutoJump()) if (vaultResult.has_value() && g_Configuration.EnableAutoMonkeySwingJump)
{ {
vaultResult->TargetState = LS_AUTO_JUMP; vaultResult->TargetState = LS_AUTO_JUMP;
if (!HasStateDispatch(item, vaultResult->TargetState)) if (!HasStateDispatch(item, vaultResult->TargetState))
@ -1606,15 +1615,15 @@ bool TestAndDoLaraLadderClimb(ItemInfo* item, CollisionInfo* coll)
CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo* coll, CrawlVaultTestSetup testSetup) CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo* coll, CrawlVaultTestSetup testSetup)
{ {
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
auto probeA = GetCollision(item, item->Pose.Orientation.y, testSetup.CrossDist, -LARA_HEIGHT_CRAWL); // Crossing. auto probeA = GetPointCollision(*item, item->Pose.Orientation.y, testSetup.CrossDist, -LARA_HEIGHT_CRAWL); // Crossing.
auto probeB = GetCollision(item, item->Pose.Orientation.y, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination. auto probeB = GetPointCollision(*item, item->Pose.Orientation.y, testSetup.DestDist, -LARA_HEIGHT_CRAWL); // Approximate destination.
auto probeMiddle = GetCollision(item); auto probeMiddle = GetPointCollision(*item);
bool isSlope = testSetup.CheckSlope ? probeB.Position.FloorSlope : false; bool isSlope = testSetup.CheckSlope ? probeB.IsSteepFloor() : false;
bool isDeath = testSetup.CheckDeath ? probeB.Block->Flags.Death : false; bool isDeath = testSetup.CheckDeath ? probeB.GetSector().Flags.Death : false;
// Discard walls. // Discard walls.
if (probeA.Position.Floor == NO_HEIGHT || probeB.Position.Floor == NO_HEIGHT) if (probeA.GetFloorHeight() == NO_HEIGHT || probeB.GetFloorHeight() == NO_HEIGHT)
return CrawlVaultTestResult{ false }; return CrawlVaultTestResult{ false };
// Check for slope or death sector (if applicable). // Check for slope or death sector (if applicable).
@ -1622,14 +1631,14 @@ CrawlVaultTestResult TestLaraCrawlVaultTolerance(ItemInfo* item, CollisionInfo*
return CrawlVaultTestResult{ false }; return CrawlVaultTestResult{ false };
// Assess point/room collision. // Assess point/room collision.
if ((probeA.Position.Floor - y) <= testSetup.LowerFloorBound && // Within lower floor bound. if ((probeA.GetFloorHeight() - y) <= testSetup.LowerFloorBound && // Within lower floor bound.
(probeA.Position.Floor - y) >= testSetup.UpperFloorBound && // Within upper floor bound. (probeA.GetFloorHeight() - y) >= testSetup.UpperFloorBound && // Within upper floor bound.
abs(probeA.Position.Ceiling - probeA.Position.Floor) > testSetup.ClampMin && // Crossing clamp limit. abs(probeA.GetCeilingHeight() - probeA.GetFloorHeight()) > testSetup.ClampMin && // Crossing clamp limit.
abs(probeB.Position.Ceiling - probeB.Position.Floor) > testSetup.ClampMin && // Destination clamp limit. abs(probeB.GetCeilingHeight() - probeB.GetFloorHeight()) > testSetup.ClampMin && // Destination clamp limit.
abs(probeMiddle.Position.Ceiling - probeA.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going up). abs(probeMiddle.GetCeilingHeight() - probeA.GetFloorHeight()) >= testSetup.GapMin && // Gap is optically permissive (going up).
abs(probeA.Position.Ceiling - probeMiddle.Position.Floor) >= testSetup.GapMin && // Gap is optically permissive (going down). abs(probeA.GetCeilingHeight() - probeMiddle.GetFloorHeight()) >= testSetup.GapMin && // Gap is optically permissive (going down).
abs(probeA.Position.Floor - probeB.Position.Floor) <= testSetup.FloorBound && // Crossing/destination floor height difference suggests continuous crawl surface. abs(probeA.GetFloorHeight() - probeB.GetFloorHeight()) <= testSetup.FloorBound && // Crossing/destination floor height difference suggests continuous crawl surface.
(probeA.Position.Ceiling - y) < -testSetup.GapMin) // Ceiling height is permissive. (probeA.GetCeilingHeight() - y) < -testSetup.GapMin) // Ceiling height is permissive.
{ {
return CrawlVaultTestResult{ true }; return CrawlVaultTestResult{ true };
} }
@ -1718,7 +1727,7 @@ CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll)
{ {
if (IsHeld(In::Crouch) && TestLaraCrawlDownStep(item, coll).Success) if (IsHeld(In::Crouch) && TestLaraCrawlDownStep(item, coll).Success)
crawlVaultResult.TargetState = LS_CRAWL_STEP_DOWN; crawlVaultResult.TargetState = LS_CRAWL_STEP_DOWN;
else USE_FEATURE_IF_CPP20([[likely]]) else
crawlVaultResult.TargetState = LS_CRAWL_EXIT_STEP_DOWN; crawlVaultResult.TargetState = LS_CRAWL_EXIT_STEP_DOWN;
crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState); crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState);
@ -1731,7 +1740,7 @@ CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll)
{ {
if (IsHeld(In::Walk)) if (IsHeld(In::Walk))
crawlVaultResult.TargetState = LS_CRAWL_EXIT_FLIP; crawlVaultResult.TargetState = LS_CRAWL_EXIT_FLIP;
else USE_FEATURE_IF_CPP20([[likely]]) else
crawlVaultResult.TargetState = LS_CRAWL_EXIT_JUMP; crawlVaultResult.TargetState = LS_CRAWL_EXIT_JUMP;
crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState); crawlVaultResult.Success = HasStateDispatch(item, crawlVaultResult.TargetState);
@ -1763,14 +1772,14 @@ bool TestLaraCrawlToHang(ItemInfo* item, CollisionInfo* coll)
{ {
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
int distance = CLICK(1.2f); int distance = CLICK(1.2f);
auto probe = GetCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), distance, -LARA_HEIGHT_CRAWL); auto probe = GetPointCollision(*item, item->Pose.Orientation.y + ANGLE(180.0f), distance, -LARA_HEIGHT_CRAWL);
bool objectCollided = TestLaraObjectCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), CLICK(1.2f), -LARA_HEIGHT_CRAWL); bool objectCollided = TestLaraObjectCollision(item, item->Pose.Orientation.y + ANGLE(180.0f), CLICK(1.2f), -LARA_HEIGHT_CRAWL);
if (!objectCollided && // No obstruction. if (!objectCollided && // No obstruction.
(probe.Position.Floor - y) >= LARA_HEIGHT_STRETCH && // Highest floor bound. (probe.GetFloorHeight() - y) >= LARA_HEIGHT_STRETCH && // Highest floor bound.
(probe.Position.Ceiling - y) <= -CLICK(0.75f) && // Gap is optically permissive. (probe.GetCeilingHeight() - y) <= -CLICK(0.75f) && // Gap is optically permissive.
probe.Position.Floor != NO_HEIGHT) probe.GetFloorHeight() != NO_HEIGHT)
{ {
return true; return true;
} }
@ -1801,9 +1810,9 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
auto sphere = BoundingSphere(spherePos, poleProbeCollRadius); auto sphere = BoundingSphere(spherePos, poleProbeCollRadius);
auto offsetSphere = BoundingSphere(spherePos + sphereOffset2D, poleProbeCollRadius); auto offsetSphere = BoundingSphere(spherePos + sphereOffset2D, poleProbeCollRadius);
//g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats); //DrawDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
for (const auto* itemPtr : collObjects.ItemPtrs) for (const auto* itemPtr : collObjects.Items)
{ {
if (itemPtr->ObjectNumber != ID_POLEROPE) if (itemPtr->ObjectNumber != ID_POLEROPE)
continue; continue;
@ -1811,7 +1820,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
auto poleBox = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose); auto poleBox = GameBoundingBox(itemPtr).ToBoundingOrientedBox(itemPtr->Pose);
poleBox.Extents = poleBox.Extents + Vector3(coll->Setup.Radius, 0.0f, coll->Setup.Radius); poleBox.Extents = poleBox.Extents + Vector3(coll->Setup.Radius, 0.0f, coll->Setup.Radius);
//g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats); //DrawDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere)) if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere))
{ {

View file

@ -34,8 +34,6 @@ bool TestLaraFacingCorner(const ItemInfo* item, short headingAngle, float dist);
bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance); bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance);
int LaraFloorFront(ItemInfo* item, short angle, int distance); int LaraFloorFront(ItemInfo* item, short angle, int distance);
int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height); int LaraCeilingFront(ItemInfo* item, short angle, int distance, int height);
CollisionResult LaraCollisionFront(ItemInfo* item, short angle, int distance);
CollisionResult LaraCeilingCollisionFront(ItemInfo* item, short angle, int distance, int height);
bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll); bool TestPlayerWaterStepOut(ItemInfo* item, CollisionInfo* coll);
bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll); bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll);
@ -58,7 +56,7 @@ std::optional<VaultTestResult> TestLaraVault3StepsToCrouch(ItemInfo* item, Colli
std::optional<VaultTestResult> TestLaraLedgeAutoJump(ItemInfo* item, CollisionInfo* coll); std::optional<VaultTestResult> TestLaraLedgeAutoJump(ItemInfo* item, CollisionInfo* coll);
std::optional<VaultTestResult> TestLaraLadderAutoJump(ItemInfo* item, CollisionInfo* coll); std::optional<VaultTestResult> TestLaraLadderAutoJump(ItemInfo* item, CollisionInfo* coll);
std::optional<VaultTestResult> TestLaraLadderMount(ItemInfo* item, CollisionInfo* coll); std::optional<VaultTestResult> TestLaraLadderMount(ItemInfo* item, CollisionInfo* coll);
std::optional<VaultTestResult> TestLaraMonkeyAutoJump(ItemInfo* item, CollisionInfo* coll); std::optional<VaultTestResult> TestLaraAutoMonkeySwingJump(ItemInfo* item, CollisionInfo* coll);
std::optional<VaultTestResult> TestLaraVault(ItemInfo* item, CollisionInfo* coll); std::optional<VaultTestResult> TestLaraVault(ItemInfo* item, CollisionInfo* coll);
bool TestAndDoLaraLadderClimb(ItemInfo* item, CollisionInfo* coll); bool TestAndDoLaraLadderClimb(ItemInfo* item, CollisionInfo* coll);

View file

@ -79,7 +79,14 @@ ObjectInfo& ObjectHandler::GetFirstAvailableObject()
// NOTE: JointRotationFlags allows bones to be rotated with CreatureJoint(). // NOTE: JointRotationFlags allows bones to be rotated with CreatureJoint().
void ObjectInfo::SetBoneRotationFlags(int boneID, int flags) void ObjectInfo::SetBoneRotationFlags(int boneID, int flags)
{ {
g_Level.Bones[boneIndex + (boneID * 4)] |= flags; int index = boneIndex + (boneID * 4);
if (index < 0 || index >= g_Level.Bones.size())
{
TENLog("Failed to set rotation flag for bone ID " + std::to_string(boneID), LogLevel::Warning);
return;
}
g_Level.Bones[index] |= flags;
} }
void ObjectInfo::SetHitEffect(HitEffect hitEffect) void ObjectInfo::SetHitEffect(HitEffect hitEffect)
@ -127,7 +134,7 @@ void InitializeGameFlags()
ZeroMemory(FlipMap, MAX_FLIPMAP * sizeof(int)); ZeroMemory(FlipMap, MAX_FLIPMAP * sizeof(int));
ZeroMemory(FlipStats, MAX_FLIPMAP * sizeof(bool)); ZeroMemory(FlipStats, MAX_FLIPMAP * sizeof(bool));
FlipEffect = -1; FlipEffect = NO_VALUE;
FlipStatus = false; FlipStatus = false;
Camera.underwater = false; Camera.underwater = false;
} }

View file

@ -16,16 +16,16 @@ constexpr auto MAX_STATICS = 1000;
enum JointRotationFlags enum JointRotationFlags
{ {
ROT_X = (1 << 2), ROT_X = 1 << 2,
ROT_Y = (1 << 3), ROT_Y = 1 << 3,
ROT_Z = (1 << 4) ROT_Z = 1 << 4
}; };
// Unused. // Unused.
enum ShatterFlags enum ShatterFlags
{ {
NoCollision = (1 << 0), NoCollision = 1 << 0,
Shatterable = (1 << 1) Shatterable = 1 << 1
}; };
// Custom LOT definition for Creature. Used in InitializeSlot() in lot.cpp. // Custom LOT definition for Creature. Used in InitializeSlot() in lot.cpp.
@ -39,10 +39,11 @@ enum class LotType
HumanPlusJump, HumanPlusJump,
HumanPlusJumpAndMonkey, HumanPlusJumpAndMonkey,
Flyer, Flyer,
Blockable, // For large creatures such as trex and shiva. Blockable, // For large creatures such as trex and shiva.
Spider, // Only 2 block vault allowed. Spider, // Only 2 block vault allowed.
Ape, // Only 2 block vault allowed. Ape, // Only 2 block vault allowed.
SnowmobileGun // Only 1 block vault allowed and 4 block drop max. SnowmobileGun, // Only 1 block vault allowed and 4 block drop max.
EnemyJeep
}; };
enum class HitEffect enum class HitEffect

View file

@ -3,6 +3,7 @@
#include "Game/camera.h" #include "Game/camera.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/control/box.h" #include "Game/control/box.h"
#include "Game/control/flipeffect.h" #include "Game/control/flipeffect.h"
#include "Game/items.h" #include "Game/items.h"
@ -15,6 +16,7 @@
#include "Sound/sound.h" #include "Sound/sound.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Point;
using namespace TEN::Entities::Generic; using namespace TEN::Entities::Generic;
using namespace TEN::Math; using namespace TEN::Math;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
@ -60,6 +62,8 @@ static void PerformAnimCommands(ItemInfo& item, bool isFrameBased)
{ {
UpdateItemRoom(item.Index); UpdateItemRoom(item.Index);
} }
item.DisableInterpolation = true;
} }
commandDataPtr += 3; commandDataPtr += 3;
@ -110,49 +114,95 @@ static void PerformAnimCommands(ItemInfo& item, bool isFrameBased)
break; break;
case AnimCommandType::SoundEffect: case AnimCommandType::SoundEffect:
if (isFrameBased && item.Animation.FrameNumber == commandDataPtr[0]) {
int frameNumber = commandDataPtr[0];
if (isFrameBased && item.Animation.FrameNumber == frameNumber)
{ {
if (!Objects[item.ObjectNumber].waterCreature) // Get sound ID and sound environment flag from packed data.
{ int soundID = commandDataPtr[1] & 0xFFF; // Exclude last 4 bits for sound ID.
bool playInWater = (commandDataPtr[1] & 0x8000) != 0; int soundEnvFlag = commandDataPtr[1] & 0xF000; // Keep only last 4 bits for sound environment flag.
bool playOnLand = (commandDataPtr[1] & 0x4000) != 0;
bool playAlways = (playInWater && playOnLand) || (!playInWater && !playOnLand);
if (item.IsLara()) // FAILSAFE.
{ if (item.RoomNumber == NO_VALUE)
auto& player = GetLaraInfo(item);
if (playAlways ||
(playOnLand && (player.Context.WaterSurfaceDist >= -SHALLOW_WATER_DEPTH || player.Context.WaterSurfaceDist == NO_HEIGHT)) ||
(playInWater && player.Context.WaterSurfaceDist < -SHALLOW_WATER_DEPTH && player.Context.WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, &item)))
{
SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
}
}
else
{
if (item.RoomNumber == NO_VALUE)
{
SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
}
else if (TestEnvironment(ENV_FLAG_WATER, &item))
{
if (playAlways || (playInWater && TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber)))
SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
}
else if (playAlways || (playOnLand && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.RoomNumber) && !TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber)))
{
SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, SoundEnvironment::Always);
}
}
}
else
{ {
SoundEffect(commandDataPtr[1] & 0x3FFF, &item.Pose, TestEnvironment(ENV_FLAG_WATER, &item) ? SoundEnvironment::Water : SoundEnvironment::Land); SoundEffect(soundID, &item.Pose, SoundEnvironment::Always);
commandDataPtr += 2;
break;
} }
// Get required sound environment from flag.
auto requiredSoundEnv = SoundEnvironment::Always;
switch (soundEnvFlag)
{
default:
case 0:
requiredSoundEnv = SoundEnvironment::Always;
break;
case (1 << 14):
requiredSoundEnv = SoundEnvironment::Land;
break;
case (1 << 15):
requiredSoundEnv = SoundEnvironment::ShallowWater;
break;
case (1 << 12):
requiredSoundEnv = SoundEnvironment::Swamp;
break;
case (1 << 13):
requiredSoundEnv = SoundEnvironment::Underwater;
break;
}
int roomNumberAtPos = GetPointCollision(item).GetRoomNumber();
bool isWater = TestEnvironment(ENV_FLAG_WATER, roomNumberAtPos);
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, roomNumberAtPos);
// Get sound environment for sound effect.
auto soundEnv = std::optional<SoundEnvironment>();
switch (requiredSoundEnv)
{
case SoundEnvironment::Always:
soundEnv = SoundEnvironment::Always;
break;
case SoundEnvironment::Land:
if (!isWater && !isSwamp)
soundEnv = SoundEnvironment::Land;
break;
case SoundEnvironment::ShallowWater:
if (isWater)
{
// HACK: Must update assets before removing this exception for water creatures.
const auto& object = Objects[item.ObjectNumber];
soundEnv = object.waterCreature ? SoundEnvironment::Underwater : SoundEnvironment::ShallowWater;
}
break;
case SoundEnvironment::Swamp:
if (isSwamp)
soundEnv = SoundEnvironment::Swamp;
break;
case SoundEnvironment::Underwater:
if (isWater || isSwamp)
soundEnv = SoundEnvironment::Underwater;
break;
}
if (soundEnv.has_value())
SoundEffect(soundID, &item.Pose, *soundEnv);
} }
commandDataPtr += 2; commandDataPtr += 2;
}
break; break;
case AnimCommandType::Flipeffect: case AnimCommandType::Flipeffect:
@ -162,6 +212,13 @@ static void PerformAnimCommands(ItemInfo& item, bool isFrameBased)
commandDataPtr += 2; commandDataPtr += 2;
break; break;
case AnimCommandType::DisableInterpolation:
if (isFrameBased && item.Animation.FrameNumber == commandDataPtr[0])
item.DisableInterpolation = true;
commandDataPtr += 1;
break;
default: default:
break; break;
} }
@ -506,7 +563,7 @@ const AnimFrame* GetFrame(GAME_OBJECT_ID objectID, int animNumber, int frameNumb
const auto& object = Objects[objectID]; const auto& object = Objects[objectID];
int animIndex = object.animIndex + animNumber; int animIndex = object.animIndex + animNumber;
assertion(animIndex < g_Level.Anims.size(), "GetFrame() attempted to access missing animation."); TENAssert(animIndex < g_Level.Anims.size(), "GetFrame() attempted to access missing animation.");
const auto& anim = GetAnimData(object, animNumber); const auto& anim = GetAnimData(object, animNumber);
@ -663,7 +720,7 @@ void ClampRotation(Pose& outPose, short angle, short rotation)
Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset) Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset)
{ {
// Use matrices done in renderer to transform relative offset. // Use matrices done in renderer to transform relative offset.
return Vector3i(g_Renderer.GetAbsEntityBonePosition(item.Index, jointIndex, relOffset.ToVector3())); return Vector3i(g_Renderer.GetMoveableBonePosition(item.Index, jointIndex, relOffset.ToVector3()));
} }
Vector3i GetJointPosition(ItemInfo* item, int jointIndex, const Vector3i& relOffset) Vector3i GetJointPosition(ItemInfo* item, int jointIndex, const Vector3i& relOffset)
@ -689,16 +746,9 @@ Vector3 GetJointOffset(GAME_OBJECT_ID objectID, int jointIndex)
return Vector3(*(bonePtr + 1), *(bonePtr + 2), *(bonePtr + 3)); return Vector3(*(bonePtr + 1), *(bonePtr + 2), *(bonePtr + 3));
} }
Quaternion GetBoneOrientation(const ItemInfo& item, int boneIndex) Quaternion GetBoneOrientation(const ItemInfo& item, int boneID)
{ {
static const auto REF_DIRECTION = Vector3::UnitZ; return g_Renderer.GetMoveableBoneOrientation(item.Index, boneID);
auto origin = g_Renderer.GetAbsEntityBonePosition(item.Index, boneIndex);
auto target = g_Renderer.GetAbsEntityBonePosition(item.Index, boneIndex, REF_DIRECTION);
auto direction = target - origin;
direction.Normalize();
return Geometry::ConvertDirectionToQuat(direction);
} }
// NOTE: Will not work for bones at ends of hierarchies. // NOTE: Will not work for bones at ends of hierarchies.

View file

@ -24,7 +24,8 @@ enum class AnimCommandType
AttackReady, AttackReady,
Deactivate, Deactivate,
SoundEffect, SoundEffect,
Flipeffect Flipeffect,
DisableInterpolation
}; };
struct AnimFrame struct AnimFrame

View file

@ -3,6 +3,7 @@
#include "Game/animation.h" #include "Game/animation.h"
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/collision/Point.h"
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/effects/debris.h" #include "Game/effects/debris.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
@ -20,13 +21,14 @@
#include "Sound/sound.h" #include "Sound/sound.h"
#include "Specific/Input/Input.h" #include "Specific/Input/Input.h"
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/winmain.h"
using TEN::Renderer::g_Renderer; using namespace TEN::Collision::Point;
using namespace TEN::Effects::Environment; using namespace TEN::Effects::Environment;
using namespace TEN::Entities::Generic; using namespace TEN::Entities::Generic;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Math; using namespace TEN::Math;
using TEN::Renderer::g_Renderer;
constexpr auto PARTICLE_FADE_THRESHOLD = BLOCK(14); constexpr auto PARTICLE_FADE_THRESHOLD = BLOCK(14);
constexpr auto COLL_CHECK_THRESHOLD = BLOCK(4); constexpr auto COLL_CHECK_THRESHOLD = BLOCK(4);
@ -132,8 +134,8 @@ static int GetLookCameraVerticalOffset(const ItemInfo& item, const CollisionInfo
} }
// Get floor-to-ceiling height. // Get floor-to-ceiling height.
auto pointColl = GetCollision(item); auto pointColl = GetPointCollision(item);
int floorToCeilHeight = abs(pointColl.Position.Ceiling - pointColl.Position.Floor); int floorToCeilHeight = abs(pointColl.GetCeilingHeight() - pointColl.GetFloorHeight());
// Return appropriate vertical offset. // Return appropriate vertical offset.
return -((verticalOffset < floorToCeilHeight) ? verticalOffset : floorToCeilHeight); return -((verticalOffset < floorToCeilHeight) ? verticalOffset : floorToCeilHeight);
@ -164,7 +166,7 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
bool isInSwamp = TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber); bool isInSwamp = TestEnvironment(ENV_FLAG_SWAMP, item.RoomNumber);
auto basePos = Vector3i( auto basePos = Vector3i(
item.Pose.Position.x, item.Pose.Position.x,
isInSwamp ? g_Level.Rooms[item.RoomNumber].maxceiling : item.Pose.Position.y, isInSwamp ? g_Level.Rooms[item.RoomNumber].TopHeight : item.Pose.Position.y,
item.Pose.Position.z); item.Pose.Position.z);
// Define landmarks. // Define landmarks.
@ -173,8 +175,8 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, LOOK_AT_DIST); auto lookAtPos = Geometry::TranslatePoint(pivotPos, orient, LOOK_AT_DIST);
// Determine best position. // Determine best position.
auto origin = GameVector(pivotPos, GetCollision(&item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).RoomNumber); auto origin = GameVector(pivotPos, GetPointCollision(item, item.Pose.Orientation.y, pivotOffset.z, pivotOffset.y).GetRoomNumber());
auto target = GameVector(idealPos, GetCollision(origin.ToVector3i(), origin.RoomNumber, orient, idealDist).RoomNumber); auto target = GameVector(idealPos, GetPointCollision(origin.ToVector3i(), origin.RoomNumber, orient.ToDirection(), idealDist).GetRoomNumber());
// Handle room and object collisions. // Handle room and object collisions.
LOSAndReturnTarget(&origin, &target, 0); LOSAndReturnTarget(&origin, &target, 0);
@ -192,15 +194,8 @@ void LookCamera(ItemInfo& item, const CollisionInfo& coll)
void LookAt(CAMERA_INFO* cam, short roll) void LookAt(CAMERA_INFO* cam, short roll)
{ {
auto pos = cam->pos.ToVector3(); cam->Fov = TO_RAD(CurrentFOV / 1.333333f);
auto target = cam->target.ToVector3(); cam->Roll = TO_RAD(roll);
auto up = Vector3::Down;
float fov = TO_RAD(CurrentFOV / 1.333333f);
float r = TO_RAD(roll);
float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1));
g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
} }
void AlterFOV(short value, bool store) void AlterFOV(short value, bool store)
@ -246,13 +241,13 @@ void InitializeCamera()
Camera.targetDistance = BLOCK(1.5f); Camera.targetDistance = BLOCK(1.5f);
Camera.item = nullptr; Camera.item = nullptr;
Camera.numberFrames = 1;
Camera.type = CameraType::Chase; Camera.type = CameraType::Chase;
Camera.speed = 1; Camera.speed = 1;
Camera.flags = CF_NONE; Camera.flags = CF_NONE;
Camera.bounce = 0; Camera.bounce = 0;
Camera.number = -1; Camera.number = -1;
Camera.fixedCamera = false; Camera.fixedCamera = false;
Camera.DisableInterpolation = true;
AlterFOV(ANGLE(DEFAULT_FOV)); AlterFOV(ANGLE(DEFAULT_FOV));
@ -341,11 +336,11 @@ void MoveCamera(GameVector* ideal, int speed)
int y = Camera.pos.y; int y = Camera.pos.y;
if (TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber)) if (TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.RoomNumber))
y = g_Level.Rooms[Camera.pos.RoomNumber].y - CLICK(1); y = g_Level.Rooms[Camera.pos.RoomNumber].Position.y - CLICK(1);
auto probe = GetCollision(Camera.pos.x, y, Camera.pos.z, Camera.pos.RoomNumber); auto pointColl = GetPointCollision(Vector3i(Camera.pos.x, y, Camera.pos.z), Camera.pos.RoomNumber);
if (y < probe.Position.Ceiling || if (y < pointColl.GetCeilingHeight() ||
y > probe.Position.Floor) y > pointColl.GetFloorHeight())
{ {
LOSAndReturnTarget(&Camera.target, &Camera.pos, 0); LOSAndReturnTarget(&Camera.target, &Camera.pos, 0);
@ -364,41 +359,41 @@ void MoveCamera(GameVector* ideal, int speed)
} }
} }
probe = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber); pointColl = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber);
int buffer = CLICK(1) - 1; int buffer = CLICK(1) - 1;
if ((Camera.pos.y - buffer) < probe.Position.Ceiling && if ((Camera.pos.y - buffer) < pointColl.GetCeilingHeight() &&
(Camera.pos.y + buffer) > probe.Position.Floor && (Camera.pos.y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
Camera.pos.y = (probe.Position.Floor + probe.Position.Ceiling) / 2; Camera.pos.y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
} }
else if ((Camera.pos.y + buffer) > probe.Position.Floor && else if ((Camera.pos.y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
Camera.pos.y = probe.Position.Floor - buffer; Camera.pos.y = pointColl.GetFloorHeight() - buffer;
} }
else if ((Camera.pos.y - buffer) < probe.Position.Ceiling && else if ((Camera.pos.y - buffer) < pointColl.GetCeilingHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
Camera.pos.y = probe.Position.Ceiling + buffer; Camera.pos.y = pointColl.GetCeilingHeight() + buffer;
} }
else if (probe.Position.Ceiling >= probe.Position.Floor || else if (pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT) pointColl.GetCeilingHeight() == NO_HEIGHT)
{ {
Camera.pos = *ideal; Camera.pos = *ideal;
} }
ItemsCollideCamera(); ItemsCollideCamera();
Camera.pos.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber).RoomNumber; Camera.pos.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0); LookAt(&Camera, 0);
UpdateMikePos(*LaraItem); UpdateMikePos(*LaraItem);
Camera.oldType = Camera.type; Camera.oldType = Camera.type;
@ -465,7 +460,7 @@ void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshId, ItemIn
} }
Camera.pos += (ideal->ToVector3i() - Camera.pos.ToVector3i()) / speed; Camera.pos += (ideal->ToVector3i() - Camera.pos.ToVector3i()) / speed;
Camera.pos.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber).RoomNumber; Camera.pos.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0); LookAt(&Camera, 0);
auto angle = Camera.target.ToVector3i() - Camera.pos.ToVector3i(); auto angle = Camera.target.ToVector3i() - Camera.pos.ToVector3i();
@ -529,21 +524,23 @@ void ChaseCamera(ItemInfo* item)
int distance = Camera.targetDistance * phd_cos(Camera.actualElevation); int distance = Camera.targetDistance * phd_cos(Camera.actualElevation);
auto probe = GetCollision(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z, Camera.target.RoomNumber); auto pointColl = GetPointCollision(Vector3i(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z), Camera.target.RoomNumber);
if (TestEnvironment(ENV_FLAG_SWAMP, probe.RoomNumber)) if (TestEnvironment(ENV_FLAG_SWAMP, pointColl.GetRoomNumber()))
Camera.target.y = g_Level.Rooms[probe.RoomNumber].maxceiling - CLICK(1); Camera.target.y = g_Level.Rooms[pointColl.GetRoomNumber()].TopHeight - CLICK(1);
int y = Camera.target.y; int y = Camera.target.y;
probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber); pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
if (((y < probe.Position.Ceiling || probe.Position.Floor < y) || probe.Position.Floor <= probe.Position.Ceiling) || if (((y < pointColl.GetCeilingHeight() || pointColl.GetFloorHeight() < y) || pointColl.GetFloorHeight() <= pointColl.GetCeilingHeight()) ||
(probe.Position.Floor == NO_HEIGHT || probe.Position.Ceiling == NO_HEIGHT)) (pointColl.GetFloorHeight() == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT))
{ {
TargetSnaps++; TargetSnaps++;
Camera.target = LastTarget; Camera.target = LastTarget;
} }
else else
{
TargetSnaps = 0; TargetSnaps = 0;
}
for (int i = 0; i < maxSwivelSteps; i++) for (int i = 0; i < maxSwivelSteps; i++)
Ideals[i].y = Camera.target.y + (Camera.targetDistance * phd_sin(Camera.actualElevation)); Ideals[i].y = Camera.target.y + (Camera.targetDistance * phd_sin(Camera.actualElevation));
@ -646,43 +643,43 @@ void CombatCamera(ItemInfo* item)
Camera.targetElevation = player.ExtraHeadRot.x + player.ExtraTorsoRot.x + item->Pose.Orientation.x - ANGLE(15.0f); Camera.targetElevation = player.ExtraHeadRot.x + player.ExtraTorsoRot.x + item->Pose.Orientation.x - ANGLE(15.0f);
} }
auto probe = GetCollision(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z, Camera.target.RoomNumber); auto pointColl = GetPointCollision(Vector3i(Camera.target.x, Camera.target.y + CLICK(1), Camera.target.z), Camera.target.RoomNumber);
if (TestEnvironment(ENV_FLAG_SWAMP, probe.RoomNumber)) if (TestEnvironment(ENV_FLAG_SWAMP, pointColl.GetRoomNumber()))
Camera.target.y = g_Level.Rooms[probe.RoomNumber].y - CLICK(1); Camera.target.y = g_Level.Rooms[pointColl.GetRoomNumber()].Position.y - CLICK(1);
probe = GetCollision(Camera.target.x, Camera.target.y, Camera.target.z, Camera.target.RoomNumber); pointColl = GetPointCollision(Camera.target.ToVector3i(), Camera.target.RoomNumber);
Camera.target.RoomNumber = probe.RoomNumber; Camera.target.RoomNumber = pointColl.GetRoomNumber();
int buffer = CLICK(0.25f); int buffer = CLICK(0.25f);
if ((probe.Position.Ceiling + buffer) > (probe.Position.Floor - buffer) && if ((pointColl.GetCeilingHeight() + buffer) > (pointColl.GetFloorHeight() - buffer) &&
probe.Position.Floor != NO_HEIGHT && pointColl.GetFloorHeight() != NO_HEIGHT &&
probe.Position.Ceiling != NO_HEIGHT) pointColl.GetCeilingHeight() != NO_HEIGHT)
{ {
Camera.target.y = (probe.Position.Ceiling + probe.Position.Floor) / 2; Camera.target.y = (pointColl.GetCeilingHeight() + pointColl.GetFloorHeight()) / 2;
Camera.targetElevation = 0; Camera.targetElevation = 0;
} }
else if (Camera.target.y > (probe.Position.Floor - buffer) && else if (Camera.target.y > (pointColl.GetFloorHeight() - buffer) &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
Camera.target.y = probe.Position.Floor - buffer; Camera.target.y = pointColl.GetFloorHeight() - buffer;
Camera.targetElevation = 0; Camera.targetElevation = 0;
} }
else if (Camera.target.y < (probe.Position.Ceiling + buffer) && else if (Camera.target.y < (pointColl.GetCeilingHeight() + buffer) &&
probe.Position.Ceiling != NO_HEIGHT) pointColl.GetCeilingHeight() != NO_HEIGHT)
{ {
Camera.target.y = probe.Position.Ceiling + buffer; Camera.target.y = pointColl.GetCeilingHeight() + buffer;
Camera.targetElevation = 0; Camera.targetElevation = 0;
} }
int y = Camera.target.y; int y = Camera.target.y;
probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber); pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
Camera.target.RoomNumber = probe.RoomNumber; Camera.target.RoomNumber = pointColl.GetRoomNumber();
if (y < probe.Position.Ceiling || if (y < pointColl.GetCeilingHeight() ||
y > probe.Position.Floor || y > pointColl.GetFloorHeight() ||
probe.Position.Ceiling >= probe.Position.Floor || pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT) pointColl.GetCeilingHeight() == NO_HEIGHT)
{ {
TargetSnaps++; TargetSnaps++;
Camera.target = LastTarget; Camera.target = LastTarget;
@ -768,116 +765,114 @@ bool CameraCollisionBounds(GameVector* ideal, int push, bool yFirst)
int y = ideal->y; int y = ideal->y;
int z = ideal->z; int z = ideal->z;
CollisionResult probe = {}; auto pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
if (yFirst) if (yFirst)
{ {
probe = GetCollision(x, y, z, ideal->RoomNumber);
int buffer = CLICK(1) - 1; int buffer = CLICK(1) - 1;
if ((y - buffer) < probe.Position.Ceiling && if ((y - buffer) < pointColl.GetCeilingHeight() &&
(y + buffer) > probe.Position.Floor && (y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = (probe.Position.Floor + probe.Position.Ceiling) / 2; y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
} }
else if ((y + buffer) > probe.Position.Floor && else if ((y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = probe.Position.Floor - buffer; y = pointColl.GetFloorHeight() - buffer;
} }
else if ((y - buffer) < probe.Position.Ceiling && else if ((y - buffer) < pointColl.GetCeilingHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = probe.Position.Ceiling + buffer; y = pointColl.GetCeilingHeight() + buffer;
} }
} }
probe = GetCollision(x - push, y, z, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x - push, y, z), ideal->RoomNumber);
if (y > probe.Position.Floor || if (y > pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT ||
probe.Position.Ceiling >= probe.Position.Floor || pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
y < probe.Position.Ceiling) y < pointColl.GetCeilingHeight())
{ {
x = (x & (~1023)) + push; x = (x & (~1023)) + push;
} }
probe = GetCollision(x, y, z - push, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x, y, z - push), ideal->RoomNumber);
if (y > probe.Position.Floor || if (y > pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT ||
probe.Position.Ceiling >= probe.Position.Floor || pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
y < probe.Position.Ceiling) y < pointColl.GetCeilingHeight())
{ {
z = (z & (~1023)) + push; z = (z & (~1023)) + push;
} }
probe = GetCollision(x + push, y, z, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x + push, y, z), ideal->RoomNumber);
if (y > probe.Position.Floor || if (y > pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT ||
probe.Position.Ceiling >= probe.Position.Floor || pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
y < probe.Position.Ceiling) y < pointColl.GetCeilingHeight())
{ {
x = (x | 1023) - push; x = (x | 1023) - push;
} }
probe = GetCollision(x, y, z + push, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x, y, z + push), ideal->RoomNumber);
if (y > probe.Position.Floor || if (y > pointColl.GetFloorHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT ||
probe.Position.Ceiling >= probe.Position.Floor || pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight() ||
y < probe.Position.Ceiling) y < pointColl.GetCeilingHeight())
{ {
z = (z | 1023) - push; z = (z | 1023) - push;
} }
if (!yFirst) if (!yFirst)
{ {
probe = GetCollision(x, y, z, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
int buffer = CLICK(1) - 1; int buffer = CLICK(1) - 1;
if ((y - buffer) < probe.Position.Ceiling && if ((y - buffer) < pointColl.GetCeilingHeight() &&
(y + buffer) > probe.Position.Floor && (y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = (probe.Position.Floor + probe.Position.Ceiling) / 2; y = (pointColl.GetFloorHeight() + pointColl.GetCeilingHeight()) / 2;
} }
else if ((y + buffer) > probe.Position.Floor && else if ((y + buffer) > pointColl.GetFloorHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = probe.Position.Floor - buffer; y = pointColl.GetFloorHeight() - buffer;
} }
else if ((y - buffer) < probe.Position.Ceiling && else if ((y - buffer) < pointColl.GetCeilingHeight() &&
probe.Position.Ceiling < probe.Position.Floor && pointColl.GetCeilingHeight() < pointColl.GetFloorHeight() &&
probe.Position.Ceiling != NO_HEIGHT && pointColl.GetCeilingHeight() != NO_HEIGHT &&
probe.Position.Floor != NO_HEIGHT) pointColl.GetFloorHeight() != NO_HEIGHT)
{ {
y = probe.Position.Ceiling + buffer; y = pointColl.GetCeilingHeight() + buffer;
} }
} }
probe = GetCollision(x, y, z, ideal->RoomNumber); pointColl = GetPointCollision(Vector3i(x, y, z), ideal->RoomNumber);
if (y > probe.Position.Floor || if (y > pointColl.GetFloorHeight() ||
y < probe.Position.Ceiling || y < pointColl.GetCeilingHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT || pointColl.GetCeilingHeight() == NO_HEIGHT ||
probe.Position.Ceiling >= probe.Position.Floor) pointColl.GetCeilingHeight() >= pointColl.GetFloorHeight())
{ {
return true; return true;
} }
ideal->RoomNumber = probe.RoomNumber; ideal->RoomNumber = pointColl.GetRoomNumber();
ideal->x = x; ideal->x = x;
ideal->y = y; ideal->y = y;
ideal->z = z; ideal->z = z;
@ -950,9 +945,19 @@ void BinocularCamera(ItemInfo* item)
player.Inventory.IsBusy = false; player.Inventory.IsBusy = false;
Camera.type = BinocularOldCamera; Camera.type = BinocularOldCamera;
Camera.target = LastTarget;
AlterFOV(LastFOV); AlterFOV(LastFOV);
return; return;
} }
if (IsHeld(In::Action))
{
ClearAction(In::Action);
auto origin = Camera.pos.ToVector3i();
auto target = Camera.target.ToVector3i();
LaraTorch(&origin, &target, player.ExtraHeadRot.y, 192);
}
} }
AlterFOV(7 * (ANGLE(11.5f) - player.Control.Look.OpticRange), false); AlterFOV(7 * (ANGLE(11.5f) - player.Control.Look.OpticRange), false);
@ -961,20 +966,20 @@ void BinocularCamera(ItemInfo* item)
int y = item->Pose.Position.y - CLICK(2); int y = item->Pose.Position.y - CLICK(2);
int z = item->Pose.Position.z; int z = item->Pose.Position.z;
auto probe = GetCollision(x, y, z, item->RoomNumber); auto pointColl = GetPointCollision(Vector3i(x, y, z), item->RoomNumber);
if (probe.Position.Ceiling <= (y - CLICK(1))) if (pointColl.GetCeilingHeight() <= (y - CLICK(1)))
{ {
y -= CLICK(1); y -= CLICK(1);
} }
else else
{ {
y = probe.Position.Ceiling + CLICK(0.25f); y = pointColl.GetCeilingHeight() + CLICK(0.25f);
} }
Camera.pos.x = x; Camera.pos.x = x;
Camera.pos.y = y; Camera.pos.y = y;
Camera.pos.z = z; Camera.pos.z = z;
Camera.pos.RoomNumber = probe.RoomNumber; Camera.pos.RoomNumber = pointColl.GetRoomNumber();
float l = BLOCK(20.25f) * phd_cos(player.Control.Look.Orientation.x); float l = BLOCK(20.25f) * phd_cos(player.Control.Look.Orientation.x);
float tx = x + l * phd_sin(item->Pose.Orientation.y + player.Control.Look.Orientation.y); float tx = x + l * phd_sin(item->Pose.Orientation.y + player.Control.Look.Orientation.y);
@ -1014,19 +1019,12 @@ void BinocularCamera(ItemInfo* item)
} }
} }
Camera.target.RoomNumber = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.RoomNumber).RoomNumber; Camera.target.RoomNumber = GetPointCollision(Camera.pos.ToVector3i(), Camera.target.RoomNumber).GetRoomNumber();
LookAt(&Camera, 0); LookAt(&Camera, 0);
UpdateMikePos(*item); UpdateMikePos(*item);
Camera.oldType = Camera.type; Camera.oldType = Camera.type;
GetTargetOnLOS(&Camera.pos, &Camera.target, false, false); GetTargetOnLOS(&Camera.pos, &Camera.target, false, false);
if (IsHeld(In::Action))
{
auto origin = Camera.pos.ToVector3i();
auto target = Camera.target.ToVector3i();
LaraTorch(&origin, &target, player.ExtraHeadRot.y, 192);
}
} }
void ConfirmCameraTargetPos() void ConfirmCameraTargetPos()
@ -1050,12 +1048,12 @@ void ConfirmCameraTargetPos()
} }
int y = Camera.target.y; int y = Camera.target.y;
auto probe = GetCollision(Camera.target.x, y, Camera.target.z, Camera.target.RoomNumber); auto pointColl = GetPointCollision(Vector3i(Camera.target.x, y, Camera.target.z), Camera.target.RoomNumber);
if (y < probe.Position.Ceiling || if (y < pointColl.GetCeilingHeight() ||
probe.Position.Floor < y || pointColl.GetFloorHeight() < y ||
probe.Position.Floor <= probe.Position.Ceiling || pointColl.GetFloorHeight() <= pointColl.GetCeilingHeight() ||
probe.Position.Floor == NO_HEIGHT || pointColl.GetFloorHeight() == NO_HEIGHT ||
probe.Position.Ceiling == NO_HEIGHT) pointColl.GetCeilingHeight() == NO_HEIGHT)
{ {
Camera.target.x = pos.x; Camera.target.x = pos.x;
Camera.target.y = pos.y; Camera.target.y = pos.y;
@ -1166,7 +1164,6 @@ void CalculateCamera(const CollisionInfo& coll)
Lara.ExtraTorsoRot.x = Lara.ExtraHeadRot.x; Lara.ExtraTorsoRot.x = Lara.ExtraHeadRot.x;
Lara.Control.Look.Orientation = lookOrient; Lara.Control.Look.Orientation = lookOrient;
Camera.type = CameraType::Look; Camera.type = CameraType::Look;
Camera.item->LookedAt = true; Camera.item->LookedAt = true;
} }
@ -1266,7 +1263,7 @@ void CalculateCamera(const CollisionInfo& coll)
Camera.speed = 1; Camera.speed = 1;
} }
Camera.target.RoomNumber = GetCollision(x, y, z, Camera.target.RoomNumber).RoomNumber; Camera.target.RoomNumber = GetPointCollision(Vector3i(x, y, z), Camera.target.RoomNumber).GetRoomNumber();
if (abs(LastTarget.x - Camera.target.x) < 4 && if (abs(LastTarget.x - Camera.target.x) < 4 &&
abs(LastTarget.y - Camera.target.y) < 4 && abs(LastTarget.y - Camera.target.y) < 4 &&
@ -1289,9 +1286,13 @@ void CalculateCamera(const CollisionInfo& coll)
Camera.fixedCamera = isFixedCamera; Camera.fixedCamera = isFixedCamera;
Camera.last = Camera.number; Camera.last = Camera.number;
Camera.DisableInterpolation = (Camera.DisableInterpolation || Camera.lastType != Camera.type);
Camera.lastType = Camera.type;
if ((Camera.type != CameraType::Heavy || Camera.timer == -1) && if (CalculateDeathCamera())
LaraItem->HitPoints > 0) return;
if (Camera.type != CameraType::Heavy || Camera.timer == -1)
{ {
Camera.type = CameraType::Chase; Camera.type = CameraType::Chase;
Camera.speed = 10; Camera.speed = 10;
@ -1306,6 +1307,27 @@ void CalculateCamera(const CollisionInfo& coll)
} }
} }
bool CalculateDeathCamera()
{
// If player is alive, it's not a death camera.
if (LaraItem->HitPoints > 0)
return false;
// If Lara is in a special death animation (from extra_anims) triggered by enemies.
if (LaraItem->Animation.AnimObjectID == ID_LARA_EXTRA_ANIMS)
return true;
// Special death animations
if (LaraItem->Animation.AnimNumber == LA_SPIKE_DEATH ||
LaraItem->Animation.AnimNumber == LA_BOULDER_DEATH ||
LaraItem->Animation.AnimNumber == LA_TRAIN_OVERBOARD_DEATH)
{
return true;
}
return false;
}
bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius) bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius)
{ {
auto sphere = BoundingSphere(Camera.pos.ToVector3(), radius); auto sphere = BoundingSphere(Camera.pos.ToVector3(), radius);
@ -1359,9 +1381,9 @@ void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius)
Camera.pos.x = pos->Position.x + ((x * cosY) + (z * sinY)); Camera.pos.x = pos->Position.x + ((x * cosY) + (z * sinY));
Camera.pos.z = pos->Position.z + ((z * cosY) - (x * sinY)); Camera.pos.z = pos->Position.z + ((z * cosY) - (x * sinY));
auto pointColl = GetCollision(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.RoomNumber); auto pointColl = GetPointCollision(Camera.pos.ToVector3i(), Camera.pos.RoomNumber);
if (pointColl.Position.Floor == NO_HEIGHT || Camera.pos.y > pointColl.Position.Floor || Camera.pos.y < pointColl.Position.Ceiling) if (pointColl.GetFloorHeight() == NO_HEIGHT || Camera.pos.y > pointColl.GetFloorHeight() || Camera.pos.y < pointColl.GetCeilingHeight())
Camera.pos = GameVector(CamOldPos, pointColl.RoomNumber); Camera.pos = GameVector(CamOldPos, pointColl.GetRoomNumber());
} }
bool CheckItemCollideCamera(ItemInfo* item) bool CheckItemCollideCamera(ItemInfo* item)
@ -1391,7 +1413,7 @@ bool CheckItemCollideCamera(ItemInfo* item)
static std::vector<int> FillCollideableItemList() static std::vector<int> FillCollideableItemList()
{ {
auto itemList = std::vector<int>{}; auto itemList = std::vector<int>{};
auto& roomList = g_Level.Rooms[Camera.pos.RoomNumber].neighbors; auto& roomList = g_Level.Rooms[Camera.pos.RoomNumber].NeighborRoomNumbers;
for (short i = 0; i < g_Level.NumItems; i++) for (short i = 0; i < g_Level.NumItems; i++)
{ {
@ -1441,7 +1463,7 @@ bool CheckStaticCollideCamera(MESH_INFO* mesh)
std::vector<MESH_INFO*> FillCollideableStaticsList() std::vector<MESH_INFO*> FillCollideableStaticsList()
{ {
std::vector<MESH_INFO*> staticList; std::vector<MESH_INFO*> staticList;
auto& roomList = g_Level.Rooms[Camera.pos.RoomNumber].neighbors; auto& roomList = g_Level.Rooms[Camera.pos.RoomNumber].NeighborRoomNumbers;
for (int i : roomList) for (int i : roomList)
{ {
@ -1484,7 +1506,7 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS)) if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS))
ItemPushCamera(&bounds, &item->Pose, RADIUS); ItemPushCamera(&bounds, &item->Pose, RADIUS);
TEN::Renderer::g_Renderer.AddDebugBox( DrawDebugBox(
bounds.ToBoundingOrientedBox(item->Pose), bounds.ToBoundingOrientedBox(item->Pose),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats); Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
} }
@ -1507,7 +1529,7 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS)) if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS))
ItemPushCamera(&bounds, &mesh->pos, RADIUS); ItemPushCamera(&bounds, &mesh->pos, RADIUS);
TEN::Renderer::g_Renderer.AddDebugBox( DrawDebugBox(
bounds.ToBoundingOrientedBox(mesh->pos), bounds.ToBoundingOrientedBox(mesh->pos),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats); Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
} }
@ -1516,6 +1538,76 @@ void ItemsCollideCamera()
staticList.clear(); staticList.clear();
} }
void PrepareCamera()
{
if (TrackCameraInit)
{
UseSpotCam = false;
AlterFOV(LastFOV);
}
}
static void DrawPortals()
{
constexpr auto EXT_COLOR = Color(1.0f, 1.0f, 0.0f, 0.15f);
constexpr auto INT_COLOR = Color(1.0f, 0.0f, 0.0f, 0.15f);
if (!DebugMode)
return;
auto neighborRoomNumbers = GetNeighborRoomNumbers(Camera.pos.RoomNumber, 1);
for (auto& roomNumber : neighborRoomNumbers)
{
const auto& room = g_Level.Rooms[roomNumber];
auto pos = room.Position.ToVector3();
auto color = (roomNumber == Camera.pos.RoomNumber) ? INT_COLOR : EXT_COLOR;
for (const auto& door : room.doors)
{
DrawDebugTriangle(door.vertices[0] + pos, door.vertices[1] + pos, door.vertices[2] + pos, color, RendererDebugPage::PortalDebug);
DrawDebugTriangle(door.vertices[2] + pos, door.vertices[3] + pos, door.vertices[0] + pos, color, RendererDebugPage::PortalDebug);
DrawDebugLine(door.vertices[0] + pos, door.vertices[2] + pos, color, RendererDebugPage::PortalDebug);
DrawDebugLine(door.vertices[1] + pos, door.vertices[3] + pos, color, RendererDebugPage::PortalDebug);
auto center = pos + ((door.vertices[0] + door.vertices[1] + door.vertices[2] + door.vertices[3]) / 4);
auto target = Geometry::TranslatePoint(center, door.normal, CLICK(1));
DrawDebugLine(center, target, color, RendererDebugPage::PortalDebug);
}
}
}
void UpdateCamera()
{
// HACK: Disable interpolation when switching to/from flyby camera.
// When camera structs are converted to a class, this should go to getter/setter. -- Lwmte, 29.10.2024
static bool spotcamSwitched = false;
if (UseSpotCam != spotcamSwitched)
{
Camera.DisableInterpolation = true;
spotcamSwitched = UseSpotCam;
}
if (UseSpotCam)
{
// Draw flyby cameras.
CalculateSpotCameras();
}
else
{
// Do the standard camera.
TrackCameraInit = false;
CalculateCamera(LaraCollision);
}
// Update cameras matrices there, after having done all the possible camera logic.
g_Renderer.UpdateCameraMatrices(&Camera, BLOCK(g_GameFlow->GetLevel(CurrentLevel)->GetFarView()));
DrawPortals();
}
void UpdateMikePos(const ItemInfo& item) void UpdateMikePos(const ItemInfo& item)
{ {
if (Camera.mikeAtLara) if (Camera.mikeAtLara)
@ -1543,7 +1635,8 @@ void UpdateMikePos(const ItemInfo& item)
void RumbleScreen() void RumbleScreen()
{ {
if (!(GlobalCounter & 0x1FF)) if (!(GlobalCounter & 0x1FF))
SoundEffect(SFX_TR5_KLAXON, nullptr, SoundEnvironment::Land, 0.25f); // SFX Enum Changed from TR5 and pitch shift removed. User can set this in their sound XML. Stranger1992 31st August 2024
SoundEffect(SFX_TR4_ENVIORONMENT_RUMBLE, nullptr, SoundEnvironment::Land);
if (RumbleTimer >= 0) if (RumbleTimer >= 0)
RumbleTimer++; RumbleTimer++;

View file

@ -24,11 +24,11 @@ struct CAMERA_INFO
GameVector target; GameVector target;
CameraType type; CameraType type;
CameraType oldType; CameraType oldType;
CameraType lastType;
int shift; int shift;
int flags; int flags;
bool fixedCamera; bool fixedCamera;
bool underwater; bool underwater;
int numberFrames;
int bounce; int bounce;
int targetDistance; int targetDistance;
short targetAngle; short targetAngle;
@ -46,6 +46,11 @@ struct CAMERA_INFO
ItemInfo* lastItem; ItemInfo* lastItem;
int mikeAtLara; int mikeAtLara;
Vector3i mikePos; Vector3i mikePos;
float Roll = 0.0f;
float Fov = 0.0f;
bool DisableInterpolation = false;
}; };
struct ObjectCameraInfo struct ObjectCameraInfo
@ -100,19 +105,24 @@ void BinocularCamera(ItemInfo* item);
void ConfirmCameraTargetPos(); void ConfirmCameraTargetPos();
void CalculateCamera(const CollisionInfo& coll); void CalculateCamera(const CollisionInfo& coll);
void RumbleScreen(); void RumbleScreen();
bool CalculateDeathCamera();
bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius); bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius);
void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius); void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius);
void ItemsCollideCamera(); void ItemsCollideCamera();
void RefreshFixedCamera(short camNumber);
void ObjCamera(ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID, bool cond); void ObjCamera(ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID, bool cond);
void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID); void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID);
void RefreshFixedCamera(short camNumber); void ClearObjCamera();
void SetScreenFadeOut(float speed, bool force = false); void SetScreenFadeOut(float speed, bool force = false);
void SetScreenFadeIn(float speed, bool force = false); void SetScreenFadeIn(float speed, bool force = false);
void SetCinematicBars(float height, float speed); void SetCinematicBars(float height, float speed);
void ClearCinematicBars(); void ClearCinematicBars();
void PrepareCamera();
void UpdateCamera();
void DrawPortals();
void UpdateFadeScreenAndCinematicBars(); void UpdateFadeScreenAndCinematicBars();
void UpdateMikePos(const ItemInfo& item); void UpdateMikePos(const ItemInfo& item);
void ClearObjCamera();
float GetParticleDistanceFade(const Vector3i& pos); float GetParticleDistanceFade(const Vector3i& pos);

View file

@ -0,0 +1,593 @@
#include "framework.h"
#include "Game/collision/Point.h"
#include "Game/collision/collide_room.h"
#include "Game/collision/floordata.h"
#include "Game/items.h"
#include "Game/room.h"
#include "Game/Setup.h"
#include "Math/Math.h"
#include "Objects/game_object_ids.h"
#include "Specific/level.h"
using namespace TEN::Collision::Floordata;
using namespace TEN::Collision::Room;
using namespace TEN::Math;
namespace TEN::Collision::Point
{
PointCollisionData::PointCollisionData(const Vector3i& pos, int roomNumber)
{
_position = pos;
_roomNumber = roomNumber;
}
Vector3i PointCollisionData::GetPosition() const
{
return _position;
}
int PointCollisionData::GetRoomNumber() const
{
return _roomNumber;
}
FloorInfo& PointCollisionData::GetSector()
{
if (_sector != nullptr)
return *_sector;
// Set current sector.
short probeRoomNumber = _roomNumber;
_sector = GetFloor(_position.x, _position.y, _position.z, &probeRoomNumber);
return *_sector;
}
FloorInfo& PointCollisionData::GetBottomSector()
{
if (_bottomSector != nullptr)
return *_bottomSector;
// Set bottom sector.
auto* bottomSector = &GetSector();
auto roomNumberBelow = bottomSector->GetNextRoomNumber(_position, true);
while (roomNumberBelow.has_value())
{
int roomNumber = roomNumberBelow.value_or(bottomSector->RoomNumber);
auto& room = g_Level.Rooms[roomNumber];
bottomSector = Room::GetSector(&room, _position.x - room.Position.x, _position.z - room.Position.z);
roomNumberBelow = bottomSector->GetNextRoomNumber(_position, true);
}
_bottomSector = bottomSector;
return *_bottomSector;
}
FloorInfo& PointCollisionData::GetTopSector()
{
if (_topSector != nullptr)
return *_topSector;
// Set top sector.
auto* topSector = &GetSector();
auto roomNumberAbove = topSector->GetNextRoomNumber(_position, false);
while (roomNumberAbove.has_value())
{
int roomNumber = roomNumberAbove.value_or(topSector->RoomNumber);
auto& room = g_Level.Rooms[roomNumber];
topSector = Room::GetSector(&room, _position.x - room.Position.x, _position.z - room.Position.z);
roomNumberAbove = topSector->GetNextRoomNumber(_position, false);
}
_topSector = topSector;
return *_topSector;
}
int PointCollisionData::GetFloorHeight()
{
if (_floorHeight.has_value())
return *_floorHeight;
// Set floor height.
auto location = RoomVector(GetSector().RoomNumber, _position.y);
_floorHeight = Floordata::GetSurfaceHeight(location, _position.x, _position.z, true).value_or(NO_HEIGHT);
return *_floorHeight;
}
int PointCollisionData::GetCeilingHeight()
{
if (_ceilingHeight.has_value())
return *_ceilingHeight;
// Set ceiling height.
auto location = RoomVector(GetSector().RoomNumber, _position.y);
_ceilingHeight = Floordata::GetSurfaceHeight(location, _position.x, _position.z, false).value_or(NO_HEIGHT);
return *_ceilingHeight;
}
Vector3 PointCollisionData::GetFloorNormal()
{
if (_floorNormal.has_value())
return *_floorNormal;
// Set floor normal.
if (GetFloorBridgeItemNumber() != NO_VALUE)
{
_floorNormal = GetBridgeNormal(true);
}
else
{
_floorNormal = GetBottomSector().GetSurfaceNormal(_position.x, _position.z, true);
}
return *_floorNormal;
}
Vector3 PointCollisionData::GetCeilingNormal()
{
if (_ceilingNormal.has_value())
return *_ceilingNormal;
// Set ceiling normal.
if (GetCeilingBridgeItemNumber() != NO_VALUE)
{
_ceilingNormal = GetBridgeNormal(false);
}
else
{
_ceilingNormal = GetTopSector().GetSurfaceNormal(_position.x, _position.z, false);
}
return *_ceilingNormal;
}
int PointCollisionData::GetFloorBridgeItemNumber()
{
if (_floorBridgeItemNumber.has_value())
return *_floorBridgeItemNumber;
// Set floor bridge item number.
int floorHeight = GetFloorHeight();
auto pos = Vector3i(_position.x, floorHeight, _position.z);
_floorBridgeItemNumber = GetBottomSector().GetInsideBridgeItemNumber(pos, true, false);
return *_floorBridgeItemNumber;
}
int PointCollisionData::GetCeilingBridgeItemNumber()
{
if (_ceilingBridgeItemNumber.has_value())
return *_ceilingBridgeItemNumber;
// Set ceiling bridge item number.
int ceilingHeight = GetCeilingHeight();
auto pos = Vector3i(_position.x, ceilingHeight, _position.z);
_ceilingBridgeItemNumber = GetTopSector().GetInsideBridgeItemNumber(pos, false, true);
return *_ceilingBridgeItemNumber;
}
int PointCollisionData::GetWaterSurfaceHeight()
{
if (_waterSurfaceHeight.has_value())
return *_waterSurfaceHeight;
auto* room = &g_Level.Rooms[_roomNumber];
const auto* sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
// Set water surface height.
bool isBelow = !TestEnvironment(ENV_FLAG_WATER, room);
while (sector->GetNextRoomNumber(_position, isBelow).has_value())
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, isBelow).value_or(sector->RoomNumber)];
if (isBelow == TestEnvironment(ENV_FLAG_WATER, room))
{
_waterSurfaceHeight = sector->GetSurfaceHeight(_position.x, _position.z, isBelow);
return *_waterSurfaceHeight;
}
sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
}
_waterSurfaceHeight = NO_HEIGHT;
return *_waterSurfaceHeight;
}
int PointCollisionData::GetWaterBottomHeight()
{
if (_waterBottomHeight.has_value())
return *_waterBottomHeight;
FloorInfo* sector = nullptr;
auto* room = &g_Level.Rooms[_roomNumber];
short roomNumber = _roomNumber;
int adjoiningRoomNumber = NO_VALUE;
do
{
int x = (_position.x - room->Position.x) / BLOCK(1);
int z = (_position.z - room->Position.z) / BLOCK(1);
if (z <= 0)
{
z = 0;
if (x < 1)
{
x = 1;
}
else if (x > (room->XSize - 2))
{
x = room->XSize - 2;
}
}
else if (z >= (room->ZSize - 1))
{
z = room->ZSize - 1;
if (x < 1)
{
x = 1;
}
else if (x > (room->XSize - 2))
{
x = room->XSize - 2;
}
}
else if (x < 0)
{
x = 0;
}
else if (x >= room->XSize)
{
x = room->XSize - 1;
}
sector = &room->Sectors[z + (x * room->ZSize)];
adjoiningRoomNumber = sector->SidePortalRoomNumber;
if (adjoiningRoomNumber != NO_VALUE)
{
roomNumber = adjoiningRoomNumber;
room = &g_Level.Rooms[adjoiningRoomNumber];
}
}
while (adjoiningRoomNumber != NO_VALUE);
// Set water bottom height.
if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room))
{
while (sector->GetNextRoomNumber(_position, false).value_or(NO_VALUE) != NO_VALUE)
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, false).value_or(sector->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, room) && !TestEnvironment(ENV_FLAG_SWAMP, room))
{
int waterHeight = sector->GetSurfaceHeight(_position.x, _position.z, false);
int floorHeight = GetPointCollision(_position, sector->RoomNumber).GetBottomSector().GetSurfaceHeight(_position.x, _position.z, true);
_waterBottomHeight = floorHeight - waterHeight;
return *_waterBottomHeight;
}
sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
}
_waterBottomHeight = DEEP_WATER;
return *_waterBottomHeight;
}
else
{
while (sector->GetNextRoomNumber(_position, true).value_or(NO_VALUE) != NO_VALUE)
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, true).value_or(sector->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room))
{
int waterHeight = sector->GetSurfaceHeight(_position.x, _position.z, true);
sector = GetFloor(_position.x, _position.y, _position.z, &roomNumber);
_waterBottomHeight = GetPointCollision(_position, sector->RoomNumber).GetFloorHeight() - waterHeight;
return *_waterBottomHeight;
}
sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
}
_waterBottomHeight = NO_HEIGHT;
return *_waterBottomHeight;
}
}
int PointCollisionData::GetWaterTopHeight()
{
if (_waterTopHeight.has_value())
return *_waterTopHeight;
FloorInfo* sector = nullptr;
auto* room = &g_Level.Rooms[_roomNumber];
int roomNumber = _roomNumber;
int adjoiningRoomNumber = NO_VALUE;
do
{
int x = (_position.x - room->Position.x) / BLOCK(1);
int z = (_position.z - room->Position.z) / BLOCK(1);
if (z <= 0)
{
z = 0;
if (x < 1)
{
x = 1;
}
else if (x > (room->XSize - 2))
{
x = room->XSize - 2;
}
}
else if (z >= (room->ZSize - 1))
{
z = room->ZSize - 1;
if (x < 1)
{
x = 1;
}
else if (x > (room->XSize - 2))
{
x = room->XSize - 2;
}
}
else if (x < 0)
{
x = 0;
}
else if (x >= room->XSize)
{
x = room->XSize - 1;
}
sector = &room->Sectors[z + (x * room->ZSize)];
adjoiningRoomNumber = sector->SidePortalRoomNumber;
if (adjoiningRoomNumber != NO_VALUE)
{
roomNumber = adjoiningRoomNumber;
room = &g_Level.Rooms[adjoiningRoomNumber];
}
}
while (adjoiningRoomNumber != NO_VALUE);
if (sector->IsWall(_position.x, _position.z))
{
_waterTopHeight = NO_HEIGHT;
return *_waterTopHeight;
}
if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room))
{
while (sector->GetNextRoomNumber(_position, false).has_value())
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, false).value_or(sector->RoomNumber)];
if (!TestEnvironment(ENV_FLAG_WATER, room) && !TestEnvironment(ENV_FLAG_SWAMP, room))
break;
sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
}
_waterTopHeight = sector->GetSurfaceHeight(_position, false);
return *_waterTopHeight;
}
else if (sector->GetNextRoomNumber(_position, true).has_value())
{
while (sector->GetNextRoomNumber(_position, true).has_value())
{
room = &g_Level.Rooms[sector->GetNextRoomNumber(_position, true).value_or(sector->RoomNumber)];
if (TestEnvironment(ENV_FLAG_WATER, room) || TestEnvironment(ENV_FLAG_SWAMP, room))
break;
sector = Room::GetSector(room, _position.x - room->Position.x, _position.z - room->Position.z);
}
_waterTopHeight = sector->GetSurfaceHeight(_position, true);
return *_waterTopHeight;
}
_waterTopHeight = NO_HEIGHT;
return *_waterTopHeight;
}
bool PointCollisionData::IsWall()
{
return (GetFloorHeight() == NO_HEIGHT || GetCeilingHeight() == NO_HEIGHT ||
GetFloorHeight() <= GetCeilingHeight());
}
bool PointCollisionData::IsSteepFloor()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetFloorNormal());
short steepSlopeAngle = (GetFloorBridgeItemNumber() != NO_VALUE) ?
DEFAULT_STEEP_FLOOR_SLOPE_ANGLE :
GetBottomSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, true);
return (abs(slopeAngle) >= steepSlopeAngle);
}
bool PointCollisionData::IsSteepCeiling()
{
short slopeAngle = Geometry::GetSurfaceSlopeAngle(GetCeilingNormal(), -Vector3::UnitY);
short steepSlopeAngle = (GetCeilingBridgeItemNumber() != NO_VALUE) ?
DEFAULT_STEEP_CEILING_SLOPE_ANGLE :
GetTopSector().GetSurfaceIllegalSlopeAngle(_position.x, _position.z, false);
return (abs(slopeAngle) >= steepSlopeAngle);
}
bool PointCollisionData::IsDiagonalFloorStep()
{
return GetBottomSector().IsSurfaceDiagonalStep(true);
}
bool PointCollisionData::IsDiagonalCeilingStep()
{
return GetTopSector().IsSurfaceDiagonalStep(false);
}
bool PointCollisionData::IsDiagonalFloorSplit()
{
float splitAngle = GetBottomSector().FloorSurface.SplitAngle;
return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
bool PointCollisionData::IsDiagonalCeilingSplit()
{
float splitAngle = GetTopSector().CeilingSurface.SplitAngle;
return (splitAngle == SectorSurfaceData::SPLIT_ANGLE_0 || splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
bool PointCollisionData::IsFlippedDiagonalFloorSplit()
{
float splitAngle = GetBottomSector().FloorSurface.SplitAngle;
return (IsDiagonalFloorStep() && splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
bool PointCollisionData::IsFlippedDiagonalCeilingSplit()
{
float splitAngle = GetTopSector().CeilingSurface.SplitAngle;
return (IsDiagonalCeilingStep() && splitAngle == SectorSurfaceData::SPLIT_ANGLE_1);
}
bool PointCollisionData::TestEnvironmentFlag(RoomEnvFlags envFlag)
{
const auto& room = g_Level.Rooms[_roomNumber];
return ((room.flags & envFlag) == envFlag);
}
// HACK.
Vector3 PointCollisionData::GetBridgeNormal(bool isFloor)
{
constexpr auto ANGLE_STEP = ANGLE(45.0f / 4);
int bridgeItemNumber = isFloor ? GetFloorBridgeItemNumber() : GetCeilingBridgeItemNumber();
const auto& bridgeItem = g_Level.Items[bridgeItemNumber];
auto orient = bridgeItem.Pose.Orientation;
switch (bridgeItem.ObjectNumber)
{
default:
case ID_BRIDGE_FLAT:
break;
case ID_BRIDGE_TILT1:
orient.z -= ANGLE_STEP;
break;
case ID_BRIDGE_TILT2:
orient.z -= ANGLE_STEP * 2;
break;
case ID_BRIDGE_TILT3:
orient.z -= ANGLE_STEP * 3;
break;
case ID_BRIDGE_TILT4:
orient.z -= ANGLE_STEP * 4;
break;
}
int sign = isFloor ? -1 : 1;
return Vector3::Transform(Vector3::UnitY * sign, orient.ToRotationMatrix());
}
static int GetProbeRoomNumber(const Vector3i& pos, const RoomVector& location, const Vector3i& probePos)
{
// Conduct L-shaped room traversal.
short probeRoomNumber = GetRoomVector(location, Vector3i(pos.x, probePos.y, pos.z)).RoomNumber;
GetFloor(probePos.x, probePos.y, probePos.z, &probeRoomNumber);
return probeRoomNumber;
}
static RoomVector GetLocation(const Vector3i& pos, int roomNumber)
{
short tempRoomNumber = roomNumber;
const auto& sector = *GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber);
return RoomVector(sector.RoomNumber, pos.y);
}
static RoomVector GetLocation(const ItemInfo& item)
{
// TODO: Find cleaner solution. Manually constructing a player "location" can result in stumbles when climbing onto thin platforms.
// May have to do with player's room number being updated at half-height? -- Sezz 2022.06.14
if (item.IsLara())
return item.Location;
short tempRoomNumber = item.RoomNumber;
const auto& sector = *GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &tempRoomNumber);
return RoomVector(sector.RoomNumber, item.Pose.Position.y);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber)
{
// HACK: Ensure room number is correct if position extends to another room.
// Accounts for some calls to this function which directly pass offset position instead of using dedicated probe overloads.
GetFloor(pos.x, pos.y, pos.z, (short*)&roomNumber);
return PointCollisionData(pos, roomNumber);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist)
{
// Get "location".
auto location = GetLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, dir, dist);
short probeRoomNumber = GetProbeRoomNumber(pos, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right, const Vector3& axis)
{
// Get "location".
auto location = GetLocation(pos, roomNumber);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(pos, headingAngle, forward, down, right, axis);
short probeRoomNumber = GetProbeRoomNumber(pos, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
PointCollisionData GetPointCollision(const ItemInfo& item)
{
return GetPointCollision(item.Pose.Position, item.RoomNumber);
}
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist)
{
// Get "location".
auto location = GetLocation(item);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, dir, dist);
short probeRoomNumber = GetProbeRoomNumber(item.Pose.Position, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down, float right, const Vector3& axis)
{
// Get "location".
auto location = GetLocation(item);
// Calculate probe position.
auto probePos = Geometry::TranslatePoint(item.Pose.Position, headingAngle, forward, down, right, axis);
short probeRoomNumber = GetProbeRoomNumber(item.Pose.Position, location, probePos);
return PointCollisionData(probePos, probeRoomNumber);
}
}

View file

@ -0,0 +1,90 @@
#pragma once
#include "Game/collision/collide_room.h"
#include "Math/Math.h"
enum RoomEnvFlags;
class FloorInfo;
struct ItemInfo;
using namespace TEN::Math;
namespace TEN::Collision::Point
{
class PointCollisionData
{
private:
// Members
Vector3i _position = Vector3i::Zero;
int _roomNumber = 0;
FloorInfo* _sector = nullptr;
FloorInfo* _bottomSector = nullptr;
FloorInfo* _topSector = nullptr;
std::optional<int> _floorHeight = std::nullopt;
std::optional<int> _ceilingHeight = std::nullopt;
std::optional<Vector3> _floorNormal = std::nullopt;
std::optional<Vector3> _ceilingNormal = std::nullopt;
std::optional<int> _floorBridgeItemNumber = std::nullopt;
std::optional<int> _ceilingBridgeItemNumber = std::nullopt;
std::optional<int> _waterSurfaceHeight = std::nullopt;
std::optional<int> _waterBottomHeight = std::nullopt;
std::optional<int> _waterTopHeight = std::nullopt;
public:
// Constructors
PointCollisionData(const Vector3i& pos, int roomNumber);
// Getters
Vector3i GetPosition() const;
int GetRoomNumber() const;
FloorInfo& GetSector();
FloorInfo& GetBottomSector();
FloorInfo& GetTopSector();
int GetFloorHeight();
int GetCeilingHeight();
Vector3 GetFloorNormal();
Vector3 GetCeilingNormal();
int GetFloorBridgeItemNumber();
int GetCeilingBridgeItemNumber();
int GetWaterSurfaceHeight();
int GetWaterBottomHeight();
int GetWaterTopHeight();
// Inquirers
bool IsWall();
bool IsSteepFloor();
bool IsSteepCeiling();
bool IsDiagonalFloorStep();
bool IsDiagonalCeilingStep();
bool IsDiagonalFloorSplit();
bool IsDiagonalCeilingSplit();
bool IsFlippedDiagonalFloorSplit();
bool IsFlippedDiagonalCeilingSplit();
bool TestEnvironmentFlag(RoomEnvFlags envFlag);
private:
// Helpers
Vector3 GetBridgeNormal(bool isFloor);
};
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber);
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, const Vector3& dir, float dist);
PointCollisionData GetPointCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f,
const Vector3& axis = Vector3::UnitY);
PointCollisionData GetPointCollision(const ItemInfo& item);
PointCollisionData GetPointCollision(const ItemInfo& item, const Vector3& dir, float dist);
PointCollisionData GetPointCollision(const ItemInfo& item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f,
const Vector3& axis = Vector3::UnitY);
}

Some files were not shown because too many files have changed in this diff Show more