Merge branch 'develop' into sezz_target_highlighter

This commit is contained in:
Sezz 2023-07-31 20:21:56 +10:00
commit c484013e29
341 changed files with 6386 additions and 4889 deletions

View file

@ -1,24 +1,54 @@
Version 1.1.1
==============
* Fix burning torch not working properly if there is more than 256 objects in a level.
Version 1.1.0 Version 1.1.0
============== ==============
* Fix enemies shooting Lara through static meshes and moveables. * Fix enemies shooting Lara through static meshes and moveables.
* Fix skeletons and mummies not 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.
* Fix various crashes specific to 64-bit build.
* Fix random crashes when playing audio tracks with names longer than 15 symbols. * Fix random crashes when playing audio tracks with names longer than 15 symbols.
* Fix crashes when trying to play .wav audio tracks on some Windows 11 systems.
* Fix last selected gun type not preserved after level jump.
* Fix incorrect vertical position after reloading a savegame made while standing on a bridge.
* Fix sprint value going below zero. * Fix sprint value going below zero.
* Fix fog bulb density formula. * Fix fog bulb density formula.
* Fix electricity effect crashing 64-bit version of the engine.
* Fix clockwork beetle activation crashing the game. * Fix clockwork beetle activation crashing the game.
* Fix corrupted vehicle positions after savegame reload. * Fix corrupted vehicle positions after savegame reload.
* Fix default ambience overlapping current one when loading a savegame. * Fix default ambience overlapping current one when loading a savegame.
* Fix doppelganger being limited to be in a single room. * Fix doppelganger being limited to a single room.
* Add multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger. * Fix bat AI, damage value, and incorrect collision after death.
* Implement separate audio track channel for playing voiceovers with subtitles. * Fix regeneration for pickups with OCB 128.
* Fix raising blocks still shaking without OCB.
* Fix spiky ceiling, improve collision, and allow setting velocity via OCB.
* Fix TR1 winged mutant pathfinding and damage issues and add new OCBs.
* Fix TR1 Natla facing angle, bomb and shard projectiles, shooting anim in the second phase.
* Fix last inventory item position not being saved.
* Fix some puzzle hole objects crashing the game on item insertion.
* Fix incorrect harpoon bolt speed and angle when shooting vertically.
* Fix black shatter debris.
* Fix Lara's shadow projecting only her joints on some occasions.
* Fix sun and spot bulbs direction and sheen casts.
* Fix room collector freezing game on some occasions.
* Fix incorrect culling for scaled static meshes.
* Fix normal mapping.
* Add ability to save screenshot in the "Screenshots" subfolder by pressing the "Print screen" key.
* Implement separate audio track channel for playing voiceovers with subtitles in .srt format.
* Don't stop ambience when Lara dies. * Don't stop ambience when Lara dies.
* Pause all sounds when entering inventory or pause menu. * Pause all sounds when entering inventory or pause menu.
* Preserve hit points on level jump.
* Improve deflection against slopes. * Improve deflection against slopes.
* Move and rotate Lara together with dynamic bridge objects. * Move and rotate Lara and activated pickups together with dynamic bridge objects.
* Move and rotate activated pickups together with dynamic bridge objects. * Reduce camera bounce.
* Improve spiky wall collision accuracy.
* Expand control settings page.
* Allow key bindings for previously hardcoded actions (weapon hotkeys, vehicle controls).
* Add input actions for weapon scroll.
* Add splash effect to rockets and grenades when they enter water.
* Allow multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger.
* Add TR1 skateboard kid. * Add TR1 skateboard kid.
* Add TR1 Kold. * Add TR1 Kold.

View file

@ -12,7 +12,7 @@ new_type("luautil", "5 Lua utility modules", true)
not_luadoc = true not_luadoc = true
local version = "1.0.9" local version = "1.1.0"
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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -506,7 +507,7 @@
</li> </li>
<li><span class="parameter">speed</span> <li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span> <span class="types"><span class="type">float</span></span>
(default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0] (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0].
</li> </li>
</ul> </ul>
@ -522,7 +523,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -669,7 +670,7 @@ Specify which translations in the strings table correspond to which languages.
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -245,7 +246,7 @@ Similar to <a href="../1 modules/Inventory.html#GiveItem">GiveItem</a> but repla
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -408,7 +409,7 @@ end
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -126,7 +127,7 @@
<td class="summary">Shows the mode of the game camera.</td> <td class="summary">Shows the mode of the game camera.</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#PlayAudioTrack">PlayAudioTrack(name, loop)</a></td> <td class="name" ><a href="#PlayAudioTrack">PlayAudioTrack(name, type)</a></td>
<td class="summary">Play an audio track</td> <td class="summary">Play an audio track</td>
</tr> </tr>
<tr> <tr>
@ -138,10 +139,18 @@
<td class="summary">Stop any audio tracks currently playing</td> <td class="summary">Stop any audio tracks currently playing</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#StopAudioTrack">StopAudioTrack(looped)</a></td> <td class="name" ><a href="#StopAudioTrack">StopAudioTrack(type)</a></td>
<td class="summary">Stop audio track that is currently playing</td> <td class="summary">Stop audio track that is currently playing</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#GetAudioTrackLoudness">GetAudioTrackLoudness(type)</a></td>
<td class="summary">Get current loudness level for specified track type</td>
</tr>
<tr>
<td class="name" ><a href="#GetCurrentSubtitle">GetCurrentSubtitle()</a></td>
<td class="summary">Get current subtitle string for a voice track currently playing.</td>
</tr>
<tr>
<td class="name" ><a href="#PlaySound">PlaySound(sound[, position])</a></td> <td class="name" ><a href="#PlaySound">PlaySound(sound[, position])</a></td>
<td class="summary">Play sound effect</td> <td class="summary">Play sound effect</td>
</tr> </tr>
@ -150,6 +159,10 @@
<td class="summary">Check if the sound effect is playing</td> <td class="summary">Check if the sound effect is playing</td>
</tr> </tr>
<tr> <tr>
<td class="name" ><a href="#IsAudioTrackPlaying">IsAudioTrackPlaying(Track)</a></td>
<td class="summary">Check if the audio track is playing</td>
</tr>
<tr>
<td class="name" ><a href="#FlipMap">FlipMap(flipmap)</a></td> <td class="name" ><a href="#FlipMap">FlipMap(flipmap)</a></td>
<td class="summary">Do FlipMap with specific ID</td> <td class="summary">Do FlipMap with specific ID</td>
</tr> </tr>
@ -410,7 +423,7 @@ eyes of the creatures would be.
</dd> </dd>
<dt> <dt>
<a name = "PlayAudioTrack"></a> <a name = "PlayAudioTrack"></a>
<strong>PlayAudioTrack(name, loop)</strong> <strong>PlayAudioTrack(name, type)</strong>
</dt> </dt>
<dd> <dd>
Play an audio track Play an audio track
@ -423,9 +436,9 @@ eyes of the creatures would be.
<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>
of track (without file extension) to play of track (without file extension) to play
</li> </li>
<li><span class="parameter">loop</span> <li><span class="parameter">type</span>
<span class="types"><span class="type">bool</span></span> <span class="types"><a class="type" href="../4 enums/Misc.SoundTrackType.html#">SoundTrackType</a></span>
if true, the track will loop; if false, it won't (default: false) of the audio track to play
</li> </li>
</ul> </ul>
@ -473,7 +486,7 @@ eyes of the creatures would be.
</dd> </dd>
<dt> <dt>
<a name = "StopAudioTrack"></a> <a name = "StopAudioTrack"></a>
<strong>StopAudioTrack(looped)</strong> <strong>StopAudioTrack(type)</strong>
</dt> </dt>
<dd> <dd>
Stop audio track that is currently playing Stop audio track that is currently playing
@ -482,9 +495,9 @@ eyes of the creatures would be.
<h3>Parameters:</h3> <h3>Parameters:</h3>
<ul> <ul>
<li><span class="parameter">looped</span> <li><span class="parameter">type</span>
<span class="types"><span class="type">bool</span></span> <span class="types"><a class="type" href="../4 enums/Misc.SoundTrackType.html#">SoundTrackType</a></span>
if set, stop looped audio track, if not, stop one-shot audio track of the audio track
</li> </li>
</ul> </ul>
@ -492,6 +505,57 @@ eyes of the creatures would be.
</dd>
<dt>
<a name = "GetAudioTrackLoudness"></a>
<strong>GetAudioTrackLoudness(type)</strong>
</dt>
<dd>
Get current loudness level for specified track type
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">type</span>
<span class="types"><a class="type" href="../4 enums/Misc.SoundTrackType.html#">SoundTrackType</a></span>
of the audio track
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">float</span></span>
current loudness of a specified audio track
</ol>
</dd>
<dt>
<a name = "GetCurrentSubtitle"></a>
<strong>GetCurrentSubtitle()</strong>
</dt>
<dd>
Get current subtitle string for a voice track currently playing.
Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track.
Returns nil if no voice track is playing or no subtitle present.
<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>
current subtitle string
</ol>
</dd> </dd>
<dt> <dt>
<a name = "PlaySound"></a> <a name = "PlaySound"></a>
@ -541,6 +605,28 @@ eyes of the creatures would be.
</dd>
<dt>
<a name = "IsAudioTrackPlaying"></a>
<strong>IsAudioTrackPlaying(Track)</strong>
</dt>
<dd>
Check if the audio track is playing
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">Track</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
filename to check. Should be without extension and without full directory path.
</li>
</ul>
</dd> </dd>
<dt> <dt>
<a name = "FlipMap"></a> <a name = "FlipMap"></a>
@ -915,7 +1001,7 @@ PrintLog(<span class="string">'test error log'</span>, LogLevel.ERROR)
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -465,7 +466,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -205,7 +206,7 @@ with a call to <a href="../1 modules/Strings.html#ShowString">ShowString</a>, or
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -106,7 +107,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -233,7 +234,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -191,7 +192,7 @@ EXAMINE
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -536,7 +537,7 @@ Must be at least 4.</p>
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -106,7 +107,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -146,7 +147,7 @@ has an unrecoverable error, the game will close.
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -204,7 +205,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -407,7 +408,7 @@ aiObj:SetObjectID(TEN.Objects.ObjID.AI_PATROL1)</pre>
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -320,7 +321,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -671,7 +672,7 @@ ROCKETLAUNCHER
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -1859,7 +1860,7 @@ sas:SetPosition(destinationPosition, <span class="keyword">false</span>)</pre>
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -334,7 +335,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -270,7 +271,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -268,7 +269,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -554,7 +555,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -431,7 +432,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -407,7 +408,7 @@ varDisplayString:SetFlags({ TEN.Strings.DisplayStringOption.SHADOW, TEN.Strings.
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -109,7 +110,7 @@
</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 is opaque, 0 is invisible)</td> <td class="summary">(int) alpha component (255 = opaque, 0 = invisible)</td>
</tr> </tr>
</table> </table>
<h2><a href="#Functions">Functions</a></h2> <h2><a href="#Functions">Functions</a></h2>
@ -191,7 +192,7 @@
<strong>a</strong> <strong>a</strong>
</dt> </dt>
<dd> <dd>
(int) alpha component (255 is opaque, 0 is invisible) (int) alpha component (255 = opaque, 0 = invisible)
@ -322,7 +323,7 @@
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -257,7 +258,7 @@ All values will be clamped to [0.0f, 360.0f].</p>
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -259,7 +260,7 @@ numbers, this will be less accurate at smaller lengths.
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -285,7 +286,7 @@ However, this function would return it as (0, 1, 1).
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -152,7 +153,7 @@ ALPHABLEND
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -150,7 +151,7 @@ CUSTOM
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <here>Misc.ActionID</here></li> <li> <here>Misc.ActionID</here></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -119,19 +120,46 @@
BACK BACK
LEFT LEFT
RIGHT RIGHT
CROUCH STEP_LEFT
SPRINT STEP_RIGHT
WALK WALK
SPRINT
CROUCH
JUMP JUMP
ROLL
ACTION ACTION
DRAW DRAW
FLARE
LOOK LOOK
ROLL
INVENTORY ACCELERATE
REVERSE
SPEED
SLOW
BRAKE
FIRE
FLARE
SMALL_MEDIPACK
LARGE_MEDIPACK
PREVIOUS_WEAPON
NEXT_WEAPON
WEAPON_1
WEAPON_2
WEAPON_3
WEAPON_4
WEAPON_5
WEAPON_6
WEAPON_7
WEAPON_8
WEAPON_9
WEAPON_10
SELECT
DESELECT
PAUSE PAUSE
STEPLEFT INVENTORY
STEPRIGHT SAVE
LOAD
</code></pre> </code></pre>
@ -159,7 +187,7 @@ STEPRIGHT
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-24 14:47:38 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <here>Misc.CameraType</here></li> <li> <here>Misc.CameraType</here></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -148,7 +149,7 @@ OBJECT
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <here>Misc.LogLevel</here></li> <li> <here>Misc.LogLevel</here></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -144,7 +145,7 @@ ERROR
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

View file

@ -0,0 +1,153 @@
<!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.1.0 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/Inventory.html">Inventory</a></li>
<li> <a href="../1 modules/Logic.html">Logic</a></li>
<li> <a href="../1 modules/Misc.html">Misc</a></li>
<li> <a href="../1 modules/Objects.html">Objects</a></li>
<li> <a href="../1 modules/Strings.html">Strings</a></li>
</ul>
<h2>2 Classes</h2>
<ul class="nowrap">
<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.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/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/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <here>Misc.SoundTrackType</here></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>
</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>Enum <code>Misc.SoundTrackType</code></h1>
<p>Constants for the type of the audio tracks.</p>
<p>
</p>
<h2><a href="#Misc_SoundTrackType_constants">Misc.SoundTrackType constants </a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#CONSTANT_STRING_HERE">CONSTANT_STRING_HERE</a></td>
<td class="summary">Table of sound track type constants (for use with sound track functions).</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header has-description"><a name="Misc_SoundTrackType_constants"></a>Misc.SoundTrackType constants </h2>
<div class="section-description">
<p>The following constants are inside SoundTrackType.</p>
<pre><code>ONESHOT
LOOPED
VOICE
</code></pre>
</div>
<dl class="function">
<dt>
<a name = "CONSTANT_STRING_HERE"></a>
<strong>CONSTANT_STRING_HERE</strong>
</dt>
<dd>
Table of sound track type constants (for use with sound track functions).
</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>
<i style="float:right;">Last updated 2023-07-20 12:10:11 </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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <here>Objects.ObjID</here></li> <li> <here>Objects.ObjID</here></li>
<li> <a href="../4 enums/Objects.RoomFlagID.html">Objects.RoomFlagID</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/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -275,9 +276,7 @@ WINGED_MUMMY
CENTAUR_MUTANT CENTAUR_MUTANT
DOPPELGANGER DOPPELGANGER
NATLA NATLA
WINGED_NATLA
GIANT_MUTANT GIANT_MUTANT
PROJ_NATLA
PROJ_SHARD PROJ_SHARD
PROJ_BOMB PROJ_BOMB
YETI YETI
@ -345,6 +344,8 @@ BOSS_EXPLOSION_SHOCKWAVE
BOSS_EXPLOSION_RING BOSS_EXPLOSION_RING
CLAW_MUTANT CLAW_MUTANT
WASP_MUTANT WASP_MUTANT
SKATEBOARD
SKATEBOARD_KID
SPRINGBOARD SPRINGBOARD
ROLLING_SPINDLE ROLLING_SPINDLE
DISK_SHOOTER DISK_SHOOTER
@ -873,7 +874,7 @@ AI_X2
LARA_START_POS LARA_START_POS
TELEPORTER TELEPORTER
LIFT_TELEPORTER LIFT_TELEPORTER
LASERS LASER_BARRIER
STEAM_LASERS STEAM_LASERS
FLOOR_LASERS FLOOR_LASERS
KILL_ALL_TRIGGERS KILL_ALL_TRIGGERS
@ -907,7 +908,7 @@ WATERFALL6
WATERFALLSS1 WATERFALLSS1
WATERFALLSS2 WATERFALLSS2
FISHTANK FISHTANK
BACON_REFERENCE DOPPELGANGER_ORIGIN
CORPSE CORPSE
WRAITH_TRAP WRAITH_TRAP
MESHSWAP1 MESHSWAP1
@ -1321,7 +1322,7 @@ PC_SAVE_INV_ITEM
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li> <li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li>
<li> <here>Objects.RoomFlagID</here></li> <li> <here>Objects.RoomFlagID</here></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -149,7 +150,7 @@ NOLENSFLARE
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <here>Objects.RoomReverb</here></li> <li> <here>Objects.RoomReverb</here></li>
@ -147,7 +148,7 @@ PIPE
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -347,7 +348,7 @@ LevelFuncs.SpawnBaddy = <span class="keyword">function</span>(baddy, name, pos)
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="../4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="../4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="../4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="../4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="../4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -520,7 +521,7 @@ LevelFuncs.TriggerTimer = <span class="keyword">function</span>(obj)
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

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.0.9 Lua API</title> <title>TombEngine 1.1.0 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>
@ -74,6 +74,7 @@
<li> <a href="4 enums/Misc.ActionID.html">Misc.ActionID</a></li> <li> <a href="4 enums/Misc.ActionID.html">Misc.ActionID</a></li>
<li> <a href="4 enums/Misc.CameraType.html">Misc.CameraType</a></li> <li> <a href="4 enums/Misc.CameraType.html">Misc.CameraType</a></li>
<li> <a href="4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li> <li> <a href="4 enums/Misc.LogLevel.html">Misc.LogLevel</a></li>
<li> <a href="4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></li>
<li> <a href="4 enums/Objects.ObjID.html">Objects.ObjID</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.RoomFlagID.html">Objects.RoomFlagID</a></li>
<li> <a href="4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li> <li> <a href="4 enums/Objects.RoomReverb.html">Objects.RoomReverb</a></li>
@ -89,7 +90,7 @@
<div id="content"> <div id="content">
<h2>TombEngine 1.0.9 scripting interface</h2> <h2>TombEngine 1.1.0 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>
@ -254,6 +255,10 @@ local door = GetMoveableByName("door_type4_14")
<td class="name" ><a href="4 enums/Misc.LogLevel.html">Misc.LogLevel</a></td> <td class="name" ><a href="4 enums/Misc.LogLevel.html">Misc.LogLevel</a></td>
<td class="summary">Constants for LogLevel IDs.</td> <td class="summary">Constants for LogLevel IDs.</td>
</tr> </tr>
<tr>
<td class="name" ><a href="4 enums/Misc.SoundTrackType.html">Misc.SoundTrackType</a></td>
<td class="summary">Constants for the type of the audio tracks.</td>
</tr>
<tr> <tr>
<td class="name" ><a href="4 enums/Objects.ObjID.html">Objects.ObjID</a></td> <td class="name" ><a href="4 enums/Objects.ObjID.html">Objects.ObjID</a></td>
<td class="summary">Constants for object IDs.</td> <td class="summary">Constants for object IDs.</td>
@ -283,7 +288,7 @@ local door = GetMoveableByName("door_type4_14")
</div> <!-- id="main" --> </div> <!-- id="main" -->
<div id="about"> <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> <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>
<i style="float:right;">Last updated 2023-06-03 11:42:57 </i> <i style="float:right;">Last updated 2023-07-20 12:10:11 </i>
</div> <!-- id="about" --> </div> <!-- id="about" -->
</div> <!-- id="container" --> </div> <!-- id="container" -->
</body> </body>

View file

@ -356,7 +356,7 @@
<parameter> <parameter>
<name>speed</name> <name>speed</name>
<type>float</type> <type>float</type>
<description>(default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0]</description> <description>(default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0].</description>
</parameter> </parameter>
</parameters> </parameters>
</function> </function>
@ -1013,9 +1013,9 @@ eyes of the creatures would be.</description>
<description>of track (without file extension) to play</description> <description>of track (without file extension) to play</description>
</parameter> </parameter>
<parameter> <parameter>
<name>loop</name> <name>type</name>
<type>bool</type> <type>Misc.SoundTrackType</type>
<description>if true, the track will loop; if false, it won't (default: false)</description> <description>of the audio track to play</description>
</parameter> </parameter>
</parameters> </parameters>
</function> </function>
@ -1045,13 +1045,46 @@ eyes of the creatures would be.</description>
<summary>Stop audio track that is currently playing</summary> <summary>Stop audio track that is currently playing</summary>
<parameters> <parameters>
<parameter> <parameter>
<name>looped</name> <name>type</name>
<type>bool</type> <type>Misc.SoundTrackType</type>
<description>if set, stop looped audio track, if not, stop one-shot audio track</description> <description>of the audio track</description>
</parameter> </parameter>
</parameters> </parameters>
</function> </function>
<function>
<module>Misc</module>
<name>GetAudioTrackLoudness</name>
<summary>Get current loudness level for specified track type</summary>
<parameters>
<parameter>
<name>type</name>
<type>Misc.SoundTrackType</type>
<description>of the audio track</description>
</parameter>
</parameters>
<returns>
<return>
<type>float</type>
<description>current loudness of a specified audio track</description>
</return>
</returns>
</function>
<function>
<module>Misc</module>
<name>GetCurrentSubtitle</name>
<summary>Get current subtitle string for a voice track currently playing.</summary>
<description>Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track.
Returns nil if no voice track is playing or no subtitle present.</description>
<returns>
<return>
<type>string</type>
<description>current subtitle string</description>
</return>
</returns>
</function>
<function> <function>
<module>Misc</module> <module>Misc</module>
<name>PlaySound</name> <name>PlaySound</name>
@ -1083,6 +1116,19 @@ eyes of the creatures would be.</description>
</parameters> </parameters>
</function> </function>
<function>
<module>Misc</module>
<name>IsAudioTrackPlaying</name>
<summary>Check if the audio track is playing</summary>
<parameters>
<parameter>
<name>Track</name>
<type>string</type>
<description>filename to check. Should be without extension and without full directory path.</description>
</parameter>
</parameters>
</function>
<function> <function>
<module>Misc</module> <module>Misc</module>
<name>FlipMap</name> <name>FlipMap</name>

View file

@ -125,7 +125,10 @@ Timer = {
else else
t.remainingTime = t.remainingTime + t.totalTime t.remainingTime = t.remainingTime + t.totalTime
end end
t.func(table.unpack(t.funcArgs))
if (t.func ~= nil) then
t.func(table.unpack(t.funcArgs))
end
end end
end end

View file

@ -5,6 +5,48 @@ corresponding to languages in the table at the end of this file.
local strings = local strings =
{ {
actions_accelerate = { "Accelerate" },
actions_reverse = { "Reverse" },
actions_speed = { "Speed" },
actions_slow = { "Slow" },
actions_brake = { "Brake/Dismount" },
actions_fire = { "Fire" },
actions_action = { "Action" },
actions_sprint = { "Sprint" },
actions_draw = { "Draw" },
actions_crouch = { "Crouch" },
actions_inventory = { "Inventory" },
actions_jump = { "Jump" },
actions_look = { "Look" },
actions_backward = { "Backward" },
actions_forward = { "Forward" },
actions_left = { "Left" },
actions_right = { "Right" },
actions_roll = { "Roll" },
actions_step_left = { "Step Left" },
actions_step_right = { "Step Right" },
actions_pause = { "Pause" },
actions_walk = { "Walk" },
actions_save = { "Save" },
actions_load = { "Load" },
actions_select = { "Select" },
actions_deselect = { "Deselect" },
actions_large_medipack = { "Large Medipack" },
actions_flare = { "Flare" },
actions_next_weapon = { "Next Weapon" },
actions_previous_weapon = { "Previous Weapon" },
actions_small_medipack = { "Small Medipack" },
actions_weapon_1 = { "Weapon 1" },
actions_weapon_2 = { "Weapon 2" },
actions_weapon_3 = { "Weapon 3" },
actions_weapon_4 = { "Weapon 4" },
actions_weapon_5 = { "Weapon 5" },
actions_weapon_6 = { "Weapon 6" },
actions_weapon_7 = { "Weapon 7" },
actions_weapon_8 = { "Weapon 8" },
actions_weapon_9 = { "Weapon 9" },
actions_weapon_10 = { "Weapon 10" },
window_title = { "TombEngine" },
all = { "All" }, all = { "All" },
apply = { "Apply" }, apply = { "Apply" },
automatic_targeting = { "Automatic Targeting" }, automatic_targeting = { "Automatic Targeting" },
@ -18,24 +60,7 @@ local strings =
combine = { "Combine" }, combine = { "Combine" },
combine_with = { "Combine With" }, combine_with = { "Combine With" },
controls = { "Controls" }, controls = { "Controls" },
controls_action = { "Action" }, reset_to_defaults = { "Reset to Defaults" },
controls_sprint = { "Sprint" },
controls_draw_weapon = { "Draw Weapon" },
controls_crouch = { "Crouch" },
controls_inventory = { "Inventory" },
controls_jump = { "Jump" },
controls_look = { "Look" },
controls_move_backward = { "Move Backward" },
controls_move_forward = { "Move Forward" },
controls_move_left = { "Move Left" },
controls_move_right = { "Move Right" },
controls_roll = { "Roll" },
controls_step_left = { "Step Left" },
controls_step_right = { "Step Right" },
controls_pause = { "Pause" },
controls_use_flare = { "Use Flare" },
controls_walk = { "Walk" },
controls_defaults = { "Reset to Defaults" },
crossbow = { "Crossbow" }, crossbow = { "Crossbow" },
crossbow_normal_ammo = { "Crossbow Normal Ammo" }, crossbow_normal_ammo = { "Crossbow Normal Ammo" },
crossbow_poison_ammo = { "Crossbow Poison Ammo" }, crossbow_poison_ammo = { "Crossbow Poison Ammo" },
@ -54,6 +79,7 @@ local strings =
exit_game = { "Exit Game" }, exit_game = { "Exit Game" },
exit_to_title = { "Exit to Title" }, exit_to_title = { "Exit to Title" },
flares = { "Flares" }, flares = { "Flares" },
general_actions = { "General Actions"},
grenade_launcher = { "Grenade Launcher" }, grenade_launcher = { "Grenade Launcher" },
grenade_launcher_normal_ammo = { "Grenade Launcher Normal Ammo" }, grenade_launcher_normal_ammo = { "Grenade Launcher Normal Ammo" },
grenade_launcher_super_ammo = { "Grenade Launcher Super Ammo" }, grenade_launcher_super_ammo = { "Grenade Launcher Super Ammo" },
@ -70,6 +96,7 @@ local strings =
lara_home = { "Lara's Home" }, lara_home = { "Lara's Home" },
large_medipack = { "Large Medipack" }, large_medipack = { "Large Medipack" },
lasersight = { "Lasersight" }, lasersight = { "Lasersight" },
menu_actions = { "Menu Actions" },
music_volume = { "Music Volume" }, music_volume = { "Music Volume" },
new_game = { "New Game" }, new_game = { "New Game" },
none = { "None" }, none = { "None" },
@ -125,6 +152,8 @@ local strings =
waiting_for_input = { "Waiting For Input" }, waiting_for_input = { "Waiting For Input" },
windowed = { "Windowed" }, windowed = { "Windowed" },
load_game = { "Load Game" }, load_game = { "Load Game" },
quick_actions = { "Quick Actions" },
vehicle_actions = { "Vehicle Actions" },
test_level = { "Test Level" }, test_level = { "Test Level" },
torch2 = { "Torch 2" }, torch2 = { "Torch 2" },
waterskin_small_empty = { "Small Waterskin (Empty)" }, waterskin_small_empty = { "Small Waterskin (Empty)" },
@ -141,13 +170,7 @@ local strings =
mechanical_scarab = { "Mechanical Scarab With Winding Key" }, mechanical_scarab = { "Mechanical Scarab With Winding Key" },
mechanical_scarab_1 = { "Mechanical Scarab (No Winding Key)" }, mechanical_scarab_1 = { "Mechanical Scarab (No Winding Key)" },
mechanical_scarab_2 = { "Mechanical Scarab Winding Key" }, mechanical_scarab_2 = { "Mechanical Scarab Winding Key" },
title = { "Title" }, title = { "Title" }
accelerate = { "Accelerate" },
reverse = { "Reverse" },
speed = { "Speed" },
slow = { "Slow" },
brake = { "Brake" },
fire = { "Fire" }
} }
TEN.Flow.SetStrings(strings) TEN.Flow.SetStrings(strings)

View file

@ -10,7 +10,7 @@ namespace TEN::Hud
{ {
static constexpr auto LIFE_MAX = 3.0f; static constexpr auto LIFE_MAX = 3.0f;
GAME_OBJECT_ID ObjectID = ID_NO_OBJECT; GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_NO_OBJECT;
unsigned int Count = 0; unsigned int Count = 0;
Vector2 Position2D = Vector2::Zero; Vector2 Position2D = Vector2::Zero;

View file

@ -38,6 +38,7 @@
#include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h"
#include "Scripting/Include/ScriptInterfaceLevel.h" #include "Scripting/Include/ScriptInterfaceLevel.h"
#include "Sound/sound.h" #include "Sound/sound.h"
#include "Specific/winmain.h"
using namespace TEN::Control::Volumes; using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Hair; using namespace TEN::Effects::Hair;
@ -491,6 +492,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (lara->Status.Stamina < LARA_STAMINA_MAX && item->Animation.ActiveState != LS_SPRINT) if (lara->Status.Stamina < LARA_STAMINA_MAX && item->Animation.ActiveState != LS_SPRINT)
lara->Status.Stamina++; lara->Status.Stamina++;
HandlePlayerQuickActions(*item);
RumbleLaraHealthCondition(item); RumbleLaraHealthCondition(item);
bool isWater = TestEnvironment(ENV_FLAG_WATER, item); bool isWater = TestEnvironment(ENV_FLAG_WATER, item);
@ -588,7 +590,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (item->Animation.ActiveState == LS_SWAN_DIVE || if (item->Animation.ActiveState == LS_SWAN_DIVE ||
item->Animation.ActiveState == LS_FREEFALL_DIVE) item->Animation.ActiveState == LS_FREEFALL_DIVE)
{ {
item->Pose.Position.y = waterHeight + (SECTOR(1) - 24); item->Pose.Position.y = waterHeight + (BLOCK(1) - 24);
} }
SetAnimation(item, LA_WADE); SetAnimation(item, LA_WADE);
@ -707,9 +709,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
} }
if (TestEnvironment(ENV_FLAG_DAMAGE, item) && item->HitPoints > 0) if (TestEnvironment(ENV_FLAG_DAMAGE, item) && item->HitPoints > 0)
{
item->HitPoints--; item->HitPoints--;
}
if (item->HitPoints <= 0) if (item->HitPoints <= 0)
{ {
@ -861,6 +861,12 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
} }
Statistics.Game.Distance += (int)round(Vector3::Distance(prevPos.ToVector3(), item->Pose.Position.ToVector3())); Statistics.Game.Distance += (int)round(Vector3::Distance(prevPos.ToVector3(), item->Pose.Position.ToVector3()));
if (DebugMode)
{
DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box);
DrawNearbySectorFlags(*item);
}
} }
void LaraAboveWater(ItemInfo* item, CollisionInfo* coll) void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
@ -931,9 +937,7 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
// Test for flags and triggers. // Test for flags and triggers.
ProcessSectorFlags(item); ProcessSectorFlags(item);
TestTriggers(item, false); TestTriggers(item, false);
TestVolumes(Lara.ItemNumber, &coll->Setup); TestVolumes(item->Index, &coll->Setup);
DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box);
} }
void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll) void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
@ -1005,7 +1009,7 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
ProcessSectorFlags(item); ProcessSectorFlags(item);
TestTriggers(item, false); TestTriggers(item, false);
TestVolumes(Lara.ItemNumber); TestVolumes(item->Index);
} }
void LaraUnderwater(ItemInfo* item, CollisionInfo* coll) void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
@ -1094,7 +1098,7 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
ProcessSectorFlags(item); ProcessSectorFlags(item);
TestTriggers(item, false); TestTriggers(item, false);
TestVolumes(Lara.ItemNumber); TestVolumes(item->Index);
} }
void LaraCheat(ItemInfo* item, CollisionInfo* coll) void LaraCheat(ItemInfo* item, CollisionInfo* coll)

View file

@ -103,7 +103,7 @@ void lara_as_vault(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableObjectPush = false; coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
EaseOutLaraHeight(item, lara->Context.ProjectedFloorHeight - item->Pose.Position.y); EasePlayerVerticalPosition(item, lara->Context.ProjectedFloorHeight - item->Pose.Position.y);
item->Pose.Orientation.Lerp(lara->Context.TargetOrientation, 0.4f); item->Pose.Orientation.Lerp(lara->Context.TargetOrientation, 0.4f);
item->Animation.TargetState = LS_IDLE; item->Animation.TargetState = LS_IDLE;
@ -252,13 +252,13 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_FAST_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_FAST_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
} }
if (TrInput & IN_JUMP || lara->Control.RunJumpQueued) if (IsHeld(In::Jump) || lara->Control.RunJumpQueued)
{ {
if (!(TrInput & IN_SPRINT) && lara->Control.Count.Run >= LARA_RUN_JUMP_TIME && if (!(TrInput & IN_SPRINT) && lara->Control.Count.Run >= LARA_RUN_JUMP_TIME &&
TestLaraRunJumpForward(item, coll)) TestLaraRunJumpForward(item, coll))
@ -418,8 +418,8 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
if (!IsHeld(In::Jump) || isSwamp) // JUMP locks orientation outside swamps. if (!IsHeld(In::Jump) || isSwamp) // JUMP locks orientation outside swamps.
{ {
// Sidestep locks orientation. // Sidestep locks orientation.
if ((IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left))) || if ((IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) ||
(IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right)))) (IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right))))
{ {
ModulateLaraTurnRateY(item, 0, 0, 0); ModulateLaraTurnRateY(item, 0, 0, 0);
} }
@ -508,7 +508,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
} }
} }
if (IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left))) if (IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left)))
{ {
if (TestLaraStepLeft(item, coll)) if (TestLaraStepLeft(item, coll))
item->Animation.TargetState = LS_STEP_LEFT; item->Animation.TargetState = LS_STEP_LEFT;
@ -517,7 +517,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
else if (IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right))) else if (IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right)))
{ {
if (TestLaraStepRight(item, coll)) if (TestLaraStepRight(item, coll))
item->Animation.TargetState = LS_STEP_RIGHT; item->Animation.TargetState = LS_STEP_RIGHT;
@ -571,7 +571,7 @@ void PseudoLaraAsWadeIdle(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_PREPARE; item->Animation.TargetState = LS_JUMP_PREPARE;
lara->Control.JumpDirection = JumpDirection::Up; lara->Control.JumpDirection = JumpDirection::Up;
@ -798,7 +798,7 @@ void lara_as_run_back(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
@ -822,7 +822,6 @@ void lara_col_run_back(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f); lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f);
item->Animation.Velocity.y = 0; item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false; item->Animation.IsAirborne = false;
coll->Setup.BlockFloorSlopeDown = true;
coll->Setup.LowerFloorBound = NO_LOWER_BOUND; coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT; coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0; coll->Setup.LowerCeilingBound = 0;
@ -885,7 +884,7 @@ void lara_as_turn_right_slow(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
SetLaraJumpDirection(item, coll); SetLaraJumpDirection(item, coll);
if (lara->Control.JumpDirection != JumpDirection::None) if (lara->Control.JumpDirection != JumpDirection::None)
@ -994,7 +993,7 @@ void PsuedoLaraAsWadeTurnRightSlow(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX);
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_PREPARE; item->Animation.TargetState = LS_JUMP_PREPARE;
lara->Control.JumpDirection = JumpDirection::Up; lara->Control.JumpDirection = JumpDirection::Up;
@ -1131,7 +1130,7 @@ void lara_as_turn_left_slow(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
SetLaraJumpDirection(item, coll); SetLaraJumpDirection(item, coll);
if (lara->Control.JumpDirection != JumpDirection::None) if (lara->Control.JumpDirection != JumpDirection::None)
@ -1240,7 +1239,7 @@ void PsuedoLaraAsWadeTurnLeftSlow(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX);
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_PREPARE; item->Animation.TargetState = LS_JUMP_PREPARE;
lara->Control.JumpDirection = JumpDirection::Up; lara->Control.JumpDirection = JumpDirection::Up;
@ -1465,7 +1464,7 @@ void lara_as_walk_back(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
@ -1486,7 +1485,7 @@ void PseudoLaraAsSwampWalkBack(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 3); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 3);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX / 3); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX / 3);
@ -1563,7 +1562,7 @@ void lara_as_turn_right_fast(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
SetLaraJumpDirection(item, coll); SetLaraJumpDirection(item, coll);
if (lara->Control.JumpDirection != JumpDirection::None) if (lara->Control.JumpDirection != JumpDirection::None)
@ -1690,7 +1689,7 @@ void lara_as_turn_left_fast(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
SetLaraJumpDirection(item, coll); SetLaraJumpDirection(item, coll);
if (lara->Control.JumpDirection != JumpDirection::None) if (lara->Control.JumpDirection != JumpDirection::None)
@ -1826,7 +1825,7 @@ void lara_as_step_right(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, 0, 0, 0); ModulateLaraTurnRateY(item, 0, 0, 0);
else else
{ {
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
} }
@ -1920,7 +1919,7 @@ void lara_as_step_left(ItemInfo* item, CollisionInfo* coll)
ModulateLaraTurnRateY(item, 0, 0, 0); ModulateLaraTurnRateY(item, 0, 0, 0);
else else
{ {
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
} }
@ -2143,7 +2142,7 @@ void lara_as_wade_forward(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX);
@ -2175,7 +2174,7 @@ void PseudoLaraAsSwampWadeForward(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX * 0.6f); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX * 0.6f);
@ -2264,13 +2263,13 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
} }
if (TrInput & IN_JUMP || lara->Control.RunJumpQueued) if (IsHeld(In::Jump) || lara->Control.RunJumpQueued)
{ {
if (TrInput & IN_WALK || !g_GameFlow->HasSprintJump()) if (TrInput & IN_WALK || !g_GameFlow->HasSprintJump())
{ {
@ -2400,7 +2399,7 @@ void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll)
if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME) if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME)
lara->Control.Count.Run = LARA_RUN_JUMP_TIME; lara->Control.Count.Run = LARA_RUN_JUMP_TIME;
if (TrInput & (IN_LEFT | IN_RIGHT)) if (IsHeld(In::Left) || IsHeld(In::Right))
{ {
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f);

View file

@ -35,10 +35,7 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION) if (TrInput & IN_ACTION)
TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150); TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150);
if (TrInput & IN_OPTION) if (IsHeld(In::Jump))
lara->Control.TurnRate = -ANGLE(12.0f);
if (TrInput & IN_JUMP)
{ {
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL * 2; item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL * 2;
if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX * 2) if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX * 2)

View file

@ -378,7 +378,7 @@ void lara_as_climb_idle(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_LADDER_RIGHT; item->Animation.TargetState = LS_LADDER_RIGHT;
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(90.0f); lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(90.0f);
} }
else if (TrInput & IN_JUMP) else if (IsHeld(In::Jump))
{ {
if (item->Animation.AnimNumber == LA_LADDER_IDLE) if (item->Animation.AnimNumber == LA_LADDER_IDLE)
{ {
@ -619,8 +619,8 @@ int LaraClimbRightCornerTest(ItemInfo* item, CollisionInfo* coll)
if (angle && angle != SOUTH) if (angle && angle != SOUTH)
{ {
x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1);
z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1);
} }
else else
{ {
@ -649,24 +649,24 @@ int LaraClimbRightCornerTest(ItemInfo* item, CollisionInfo* coll)
switch (angle) switch (angle)
{ {
case NORTH: case NORTH:
x = ((item->Pose.Position.x + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); x = ((item->Pose.Position.x + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1);
z = ((item->Pose.Position.z + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); z = ((item->Pose.Position.z + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1);
break; break;
case SOUTH: case SOUTH:
x = ((item->Pose.Position.x - SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); x = ((item->Pose.Position.x - BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1);
z = ((item->Pose.Position.z - SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); z = ((item->Pose.Position.z - BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1);
break; break;
case EAST: case EAST:
x = ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) ^ (item->Pose.Position.x + SECTOR(1)); x = ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) ^ (item->Pose.Position.x + BLOCK(1));
z = (item->Pose.Position.z ^ ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1))) - SECTOR(1); z = (item->Pose.Position.z ^ ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1))) - BLOCK(1);
break; break;
case WEST: case WEST:
default: default:
x = (item->Pose.Position.x ^ (item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) - SECTOR(1); x = (item->Pose.Position.x ^ (item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) - BLOCK(1);
z = ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) ^ (item->Pose.Position.z + SECTOR(1)); z = ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) ^ (item->Pose.Position.z + BLOCK(1));
break; break;
} }
@ -713,8 +713,8 @@ int LaraClimbLeftCornerTest(ItemInfo* item, CollisionInfo* coll)
} }
else else
{ {
x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK) + SECTOR(1); x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK) + BLOCK(1);
z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK) + SECTOR(1); z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK) + BLOCK(1);
} }
int shift = 0; int shift = 0;
@ -738,24 +738,24 @@ int LaraClimbLeftCornerTest(ItemInfo* item, CollisionInfo* coll)
switch (angle) switch (angle)
{ {
case NORTH: case NORTH:
x = (item->Pose.Position.x ^ ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK)) - SECTOR(1); x = (item->Pose.Position.x ^ ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK)) - BLOCK(1);
z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z + SECTOR(1)); z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z + BLOCK(1));
break; break;
case SOUTH: case SOUTH:
x = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.x + SECTOR(1)); x = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.x + BLOCK(1));
z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z - SECTOR(1)); z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z - BLOCK(1));
break; break;
case EAST: case EAST:
x = ((item->Pose.Position.x + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK) + SECTOR(1); x = ((item->Pose.Position.x + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK) + BLOCK(1);
z = ((item->Pose.Position.z + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK) + SECTOR(1); z = ((item->Pose.Position.z + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK) + BLOCK(1);
break; break;
case WEST: case WEST:
default: default:
x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK); x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK);
z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK); z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK);
break; break;
} }

View file

@ -633,8 +633,8 @@ void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll)
const auto& sink = g_Level.Sinks[lara->Context.WaterCurrentActive - 1]; const auto& sink = g_Level.Sinks[lara->Context.WaterCurrentActive - 1];
short headingAngle = Geometry::GetOrientToPoint(item->Pose.Position.ToVector3(), sink.Position).y; short headingAngle = Geometry::GetOrientToPoint(item->Pose.Position.ToVector3(), sink.Position).y;
lara->Context.WaterCurrentPull.x += ((sink.Strength * SECTOR(1) * phd_sin(headingAngle)) - lara->Context.WaterCurrentPull.x) / 16; lara->Context.WaterCurrentPull.x += ((sink.Strength * BLOCK(1) * phd_sin(headingAngle)) - lara->Context.WaterCurrentPull.x) / 16;
lara->Context.WaterCurrentPull.z += ((sink.Strength * SECTOR(1) * phd_cos(headingAngle)) - lara->Context.WaterCurrentPull.z) / 16; lara->Context.WaterCurrentPull.z += ((sink.Strength * BLOCK(1) * phd_cos(headingAngle)) - lara->Context.WaterCurrentPull.z) / 16;
item->Pose.Position.y += (sink.Position.y - item->Pose.Position.y) / 16; item->Pose.Position.y += (sink.Position.y - item->Pose.Position.y) / 16;
} }

View file

@ -40,7 +40,7 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -65,7 +65,7 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK)) if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK))
@ -157,7 +157,7 @@ void lara_as_crouch_roll(ItemInfo* item, CollisionInfo* coll)
lara->Control.CanLook = false; lara->Control.CanLook = false;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -230,7 +230,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -243,7 +243,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK) if (TrInput & IN_LOOK)
LookUpDown(item); LookUpDown(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) && if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) &&
@ -287,7 +287,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -300,7 +300,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK) if (TrInput & IN_LOOK)
LookUpDown(item); LookUpDown(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) && if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) &&
@ -344,11 +344,11 @@ void lara_as_crouch_turn_180(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & (IN_FORWARD | IN_BACK) && TestLaraCrouchToCrawl(item)) if (TrInput & (IN_FORWARD | IN_BACK) && TestLaraCrouchToCrawl(item))
@ -381,7 +381,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
{ {
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -409,7 +409,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK)) if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK))
@ -419,7 +419,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
} }
if ((TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) || if ((TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) ||
(TrInput & (IN_DRAW | IN_FLARE) && ((IsHeld(In::Draw) || IsHeld(In::Flare)) &&
!IsStandingWeapon(item, lara->Control.Weapon.GunType) && HasStateDispatch(item, LS_CROUCH_IDLE))) !IsStandingWeapon(item, lara->Control.Weapon.GunType) && HasStateDispatch(item, LS_CROUCH_IDLE)))
{ {
item->Animation.TargetState = LS_CROUCH_IDLE; item->Animation.TargetState = LS_CROUCH_IDLE;
@ -431,7 +431,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
{ {
auto crawlVaultResult = TestLaraCrawlVault(item, coll); auto crawlVaultResult = TestLaraCrawlVault(item, coll);
if (TrInput & (IN_ACTION | IN_JUMP) && crawlVaultResult.Success && if ((IsHeld(In::Action) || IsHeld(In::Jump)) && crawlVaultResult.Success &&
g_GameFlow->HasCrawlExtended()) g_GameFlow->HasCrawlExtended())
{ {
item->Animation.TargetState = crawlVaultResult.TargetState; item->Animation.TargetState = crawlVaultResult.TargetState;
@ -447,7 +447,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
} }
else if (TrInput & IN_BACK) else if (TrInput & IN_BACK)
{ {
if (TrInput & (IN_ACTION | IN_JUMP) && TestLaraCrawlToHang(item, coll)) if ((IsHeld(In::Action) || IsHeld(In::Jump)) && TestLaraCrawlToHang(item, coll))
{ {
item->Animation.TargetState = LS_CRAWL_TO_HANG; item->Animation.TargetState = LS_CRAWL_TO_HANG;
DoLaraCrawlToHangSnap(item, coll); DoLaraCrawlToHangSnap(item, coll);
@ -532,7 +532,7 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll)
lara->Control.HandStatus = HandStatus::Busy; lara->Control.HandStatus = HandStatus::Busy;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -548,7 +548,7 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll)
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX); ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
} }
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -628,7 +628,7 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll)
lara->Control.HandStatus = HandStatus::Busy; lara->Control.HandStatus = HandStatus::Busy;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -644,7 +644,7 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll)
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX); ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
} }
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_BACK) if (TrInput & IN_BACK)
@ -715,7 +715,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll)
lara->Control.HandStatus = HandStatus::Busy; lara->Control.HandStatus = HandStatus::Busy;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -725,7 +725,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -776,7 +776,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll)
lara->Control.HandStatus = HandStatus::Busy; lara->Control.HandStatus = HandStatus::Busy;
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
@ -786,7 +786,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
@ -835,11 +835,11 @@ void lara_as_crawl_turn_180(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
AlignLaraToSurface(item); AlignLaraToSurface(item);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && if ((IsHeld(In::Crouch) || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade) lara->Control.WaterStatus != WaterStatus::Wade)
{ {
item->Animation.TargetState = LS_CRAWL_IDLE; item->Animation.TargetState = LS_CRAWL_IDLE;
@ -864,7 +864,7 @@ void lara_col_crawl_to_hang(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableObjectPush = true; coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = 0; Camera.targetAngle = 0;
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
ResetPlayerLean(item, 1 / 6.0f); ResetPlayerLean(item, 1 / 6.0f);

View file

@ -519,7 +519,7 @@ void HandleWeapon(ItemInfo& laraItem)
else if (player.Control.HandStatus == HandStatus::Free) else if (player.Control.HandStatus == HandStatus::Free)
{ {
// Draw weapon. // Draw weapon.
if (IsHeld(In::DrawWeapon)) if (IsHeld(In::Draw))
{ {
// No weapon - no any actions. // No weapon - no any actions.
if (player.Control.Weapon.LastGunType != LaraWeaponType::None) if (player.Control.Weapon.LastGunType != LaraWeaponType::None)
@ -547,7 +547,7 @@ void HandleWeapon(ItemInfo& laraItem)
} }
} }
if ((IsHeld(In::DrawWeapon) && player.Control.Weapon.LastGunType != LaraWeaponType::None) || if ((IsHeld(In::Draw) && player.Control.Weapon.LastGunType != LaraWeaponType::None) ||
player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType) player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType)
{ {
if (player.Control.IsLow && if (player.Control.IsLow &&
@ -596,7 +596,7 @@ void HandleWeapon(ItemInfo& laraItem)
} }
else if (player.Control.HandStatus == HandStatus::WeaponReady) else if (player.Control.HandStatus == HandStatus::WeaponReady)
{ {
if (IsHeld(In::DrawWeapon) || if (IsHeld(In::Draw) ||
player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType) player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType)
{ {
player.Control.HandStatus = HandStatus::WeaponUndraw; player.Control.HandStatus = HandStatus::WeaponUndraw;

View file

@ -130,7 +130,7 @@ void lara_col_hang(ItemInfo* item, CollisionInfo* coll)
} }
// TODO: Allow direction locking just like with standing jumps. Needs new ledge jump prepare state? -- Sezz 24.10.2022 // TODO: Allow direction locking just like with standing jumps. Needs new ledge jump prepare state? -- Sezz 24.10.2022
if (TrInput & IN_JUMP && TestLaraLedgeJump(item, coll)) if (IsHeld(In::Jump) && TestLaraLedgeJump(item, coll))
{ {
if (TrInput & IN_BACK) if (TrInput & IN_BACK)
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;

View file

@ -13,6 +13,7 @@
#include "Game/Lara/lara_collide.h" #include "Game/Lara/lara_collide.h"
#include "Game/Lara/lara_fire.h" #include "Game/Lara/lara_fire.h"
#include "Game/Lara/lara_tests.h" #include "Game/Lara/lara_tests.h"
#include "Game/savegame.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer11.h" #include "Renderer/Renderer11.h"
@ -68,7 +69,7 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
lara->Control.RunJumpQueued = false; lara->Control.RunJumpQueued = false;
// Reset lean. // Reset lean.
if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(TrInput & (IN_LEFT | IN_RIGHT)))) && if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(IsHeld(In::Left) || IsHeld(In::Right)))) &&
(!lara->Control.IsLow && item->Animation.ActiveState != LS_DEATH)) // HACK: Don't interfere with surface alignment in crouch, crawl, and death states. (!lara->Control.IsLow && item->Animation.ActiveState != LS_DEATH)) // HACK: Don't interfere with surface alignment in crouch, crawl, and death states.
{ {
ResetPlayerLean(item, 1 / 6.0f); ResetPlayerLean(item, 1 / 6.0f);
@ -76,20 +77,186 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
// Reset crawl flex. // Reset crawl flex.
if (!(TrInput & IN_LOOK) && coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM && // HACK if (!(TrInput & IN_LOOK) && coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM && // HACK
(!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(TrInput & (IN_LEFT | IN_RIGHT))))) (!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(IsHeld(In::Left) || IsHeld(In::Right)))))
{ {
ResetPlayerFlex(item, 0.1f); ResetPlayerFlex(item, 0.1f);
} }
// Apply and reset turn rate. // Apply and reset turn rate.
item->Pose.Orientation.y += lara->Control.TurnRate; item->Pose.Orientation.y += lara->Control.TurnRate;
if (!(TrInput & (IN_LEFT | IN_RIGHT))) if (!(IsHeld(In::Left) || IsHeld(In::Right)))
lara->Control.TurnRate = 0; lara->Control.TurnRate = 0;
lara->Control.IsLow = false; lara->Control.IsLow = false;
lara->Control.IsMonkeySwinging = false; lara->Control.IsMonkeySwinging = false;
} }
static void UsePlayerMedipack(ItemInfo& item)
{
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;
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>
{
LaraWeaponType::Pistol,
LaraWeaponType::Shotgun,
LaraWeaponType::Uzi,
LaraWeaponType::Revolver,
LaraWeaponType::GrenadeLauncher,
LaraWeaponType::Crossbow,
LaraWeaponType::HarpoonGun,
LaraWeaponType::HK,
LaraWeaponType::RocketLauncher
};
auto& player = GetLaraInfo(item);
// Get vector index for current weapon type.
auto currentIndex = std::optional<unsigned int>(std::nullopt);
for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++)
{
if (SCROLL_WEAPON_TYPES[i] == currentWeaponType)
{
currentIndex = i;
break;
}
}
// Invalid current weapon type; return nullopt.
if (!currentIndex.has_value())
return std::nullopt;
// Getter for next index.
auto getNextIndex = [getPrev](unsigned int index)
{
return (index + (getPrev ? ((unsigned int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (unsigned int)SCROLL_WEAPON_TYPES.size();
};
// Get next valid weapon type in sequence.
unsigned int nextIndex = getNextIndex(*currentIndex);
while (nextIndex != *currentIndex)
{
auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex];
if (player.Weapons[(int)nextWeaponType].Present)
return nextWeaponType;
nextIndex = getNextIndex(nextIndex);
}
// No valid weapon type; return nullopt.
return std::nullopt;
}
void HandlePlayerQuickActions(ItemInfo& item)
{
auto& player = GetLaraInfo(item);
// Handle medipacks.
if (IsClicked(In::SmallMedipack) || IsClicked(In::LargeMedipack))
UsePlayerMedipack(item);
// Handle weapon scroll requests.
if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon))
{
bool getPrev = IsClicked(In::PreviousWeapon);
auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, getPrev);
if (weaponType.has_value())
player.Control.Weapon.RequestGunType = *weaponType;
}
// Handle weapon requests.
if (IsClicked(In::Weapon1) && player.Weapons[(int)LaraWeaponType::Pistol].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Pistol;
if (IsClicked(In::Weapon2) && player.Weapons[(int)LaraWeaponType::Shotgun].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun;
if (IsClicked(In::Weapon3) && player.Weapons[(int)LaraWeaponType::Uzi].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Uzi;
if (IsClicked(In::Weapon4) && player.Weapons[(int)LaraWeaponType::Revolver].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Revolver;
if (IsClicked(In::Weapon5) && player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher;
if (IsClicked(In::Weapon6) && player.Weapons[(int)LaraWeaponType::Crossbow].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow;
if (IsClicked(In::Weapon7) && player.Weapons[(int)LaraWeaponType::HarpoonGun].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun;
if (IsClicked(In::Weapon8) && player.Weapons[(int)LaraWeaponType::HK].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::HK;
if (IsClicked(In::Weapon9) && player.Weapons[(int)LaraWeaponType::RocketLauncher].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher;
// TODO: 10th possible weapon, probably grapple gun.
/*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present)
player.Control.Weapon.RequestGunType = LaraWeaponType::;*/
// TODO: Could theoretically remove SwitchTarget and instead do unique behaviour handling using only Look. -- Sezz 2023.07.08
// HACK: Handle target switch when locked on to an entity.
if (player.Control.HandStatus == HandStatus::WeaponReady &&
player.TargetEntity != nullptr)
{
if (IsClicked(In::Look))
{
ActionMap[(int)In::SwitchTarget].Update(true);
}
else
{
ClearAction(In::SwitchTarget);
}
}
else
{
ClearAction(In::SwitchTarget);
}
}
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll) bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
@ -229,7 +396,7 @@ void HandlePlayerAirBubbles(ItemInfo* item)
SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water); SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water);
const auto& level = *g_GameFlow->GetLevel(CurrentLevel); const auto& level = *g_GameFlow->GetLevel(CurrentLevel);
auto pos = (level.GetLaraType() == LaraType::Divesuit) ? auto pos = (level.GetLaraType() == LaraType::Divesuit) ?
GetJointPosition(item, LM_TORSO, Vector3i(0, -192, -160)).ToVector3() : GetJointPosition(item, LM_TORSO, Vector3i(0, -192, -160)).ToVector3() :
GetJointPosition(item, LM_HEAD, Vector3i(0, -4, -64)).ToVector3(); GetJointPosition(item, LM_HEAD, Vector3i(0, -4, -64)).ToVector3();
@ -243,12 +410,9 @@ void HandlePlayerAirBubbles(ItemInfo* item)
// Potential solutions: // Potential solutions:
// 1. Consider floor tilt when translating objects. // 1. Consider floor tilt when translating objects.
// 2. Object parenting. -- Sezz 2022.10.28 // 2. Object parenting. -- Sezz 2022.10.28
void EaseOutLaraHeight(ItemInfo* item, int height) void EasePlayerVerticalPosition(ItemInfo* item, int height)
{ {
constexpr auto LINEAR_THRESHOLD = STEPUP_HEIGHT / 2; constexpr auto LINEAR_RATE_MIN = 50.0f;
constexpr auto EASING_THRESHOLD_MIN = BLOCK(1.0f / 64);
constexpr auto LINEAR_RATE = 50;
constexpr auto EASING_ALPHA = 0.35f;
// Check for wall. // Check for wall.
if (height == NO_HEIGHT) if (height == NO_HEIGHT)
@ -261,18 +425,12 @@ void EaseOutLaraHeight(ItemInfo* item, int height)
return; return;
} }
int easingThreshold = std::max(abs(item->Animation.Velocity.z), EASING_THRESHOLD_MIN);
// Handle regular case. // Handle regular case.
if (abs(height) > LINEAR_THRESHOLD) float linearRate = std::max(LINEAR_RATE_MIN, abs(item->Animation.Velocity.z));
if (abs(height) > linearRate)
{ {
int sign = std::copysign(1, height); int sign = std::copysign(1, height);
item->Pose.Position.y += LINEAR_RATE * sign; item->Pose.Position.y += linearRate * sign;
}
else if (abs(height) > easingThreshold)
{
int vPos = item->Pose.Position.y;
item->Pose.Position.y = (int)round(Lerp(vPos, vPos + height, EASING_ALPHA));
} }
else else
{ {
@ -306,12 +464,12 @@ void DoLaraStep(ItemInfo* item, CollisionInfo* coll)
} }
} }
EaseOutLaraHeight(item, coll->Middle.Floor); EasePlayerVerticalPosition(item, coll->Middle.Floor);
} }
void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll) void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll)
{ {
EaseOutLaraHeight(item, coll->Middle.Ceiling); EasePlayerVerticalPosition(item, coll->Middle.Ceiling);
} }
void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll) void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll)
@ -513,7 +671,7 @@ void ModulateLaraSwimTurnRates(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
/*if (TrInput & (IN_FORWARD | IN_BACK)) /*if (TrInput & (IN_FORWARD | IN_BACK))
ModulateLaraTurnRateX(item, 0, 0, 0);*/ ModulateLaraTurnRateX(item, 0, 0, 0);*/
if (TrInput & IN_FORWARD) if (TrInput & IN_FORWARD)
item->Pose.Orientation.x -= ANGLE(3.0f); item->Pose.Orientation.x -= ANGLE(3.0f);
@ -609,16 +767,16 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
else if (lara->Control.TurnRate < 0) else if (lara->Control.TurnRate < 0)
lara->Control.Subsuit.Velocity[1] += 2 * abs(lara->Control.TurnRate); lara->Control.Subsuit.Velocity[1] += 2 * abs(lara->Control.TurnRate);
if (lara->Control.Subsuit.Velocity[0] > SECTOR(1.5f)) if (lara->Control.Subsuit.Velocity[0] > BLOCK(1.5f))
lara->Control.Subsuit.Velocity[0] = SECTOR(1.5f); lara->Control.Subsuit.Velocity[0] = BLOCK(1.5f);
if (lara->Control.Subsuit.Velocity[1] > SECTOR(1.5f)) if (lara->Control.Subsuit.Velocity[1] > BLOCK(1.5f))
lara->Control.Subsuit.Velocity[1] = SECTOR(1.5f); lara->Control.Subsuit.Velocity[1] = BLOCK(1.5f);
if (lara->Control.Subsuit.Velocity[0] != 0 || lara->Control.Subsuit.Velocity[1] != 0) if (lara->Control.Subsuit.Velocity[0] != 0 || lara->Control.Subsuit.Velocity[1] != 0)
{ {
auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / SECTOR(8); auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / BLOCK(8);
auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / SECTOR(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::Water, 1.0f + (mul1 + mul2), vol);
} }
@ -686,7 +844,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
//lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness); //lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
} }
//else //else
//lara->ExtraVelocity.x += minVelocity; //lara->ExtraVelocity.x += minVelocity;
} }
void AlignLaraToSurface(ItemInfo* item, float alpha) void AlignLaraToSurface(ItemInfo* item, float alpha)
@ -737,7 +895,7 @@ void SetLaraRunJumpQueue(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
int distance = SECTOR(1); int distance = BLOCK(1);
auto probe = GetCollision(item, item->Pose.Orientation.y, distance, -coll->Setup.Height); auto probe = GetCollision(item, item->Pose.Orientation.y, distance, -coll->Setup.Height);
if ((TestLaraRunJumpForward(item, coll) || // Area close ahead is permissive... if ((TestLaraRunJumpForward(item, coll) || // Area close ahead is permissive...

View file

@ -12,12 +12,13 @@ struct VaultTestResult;
// ----------------------------- // -----------------------------
void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll); void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll);
void HandlePlayerQuickActions(ItemInfo& item);
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll); bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll);
void HandlePlayerWetnessDrips(ItemInfo& item); void HandlePlayerWetnessDrips(ItemInfo& item);
void HandlePlayerDiveBubbles(ItemInfo& item); void HandlePlayerDiveBubbles(ItemInfo& item);
void HandlePlayerAirBubbles(ItemInfo* item); void HandlePlayerAirBubbles(ItemInfo* item);
void EaseOutLaraHeight(ItemInfo* item, int height); void EasePlayerVerticalPosition(ItemInfo* item, int height);
void DoLaraStep(ItemInfo* item, CollisionInfo* coll); void DoLaraStep(ItemInfo* item, CollisionInfo* coll);
void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll); void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll);
void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll); void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll);

View file

@ -12,31 +12,36 @@
using namespace TEN::Hud; using namespace TEN::Hud;
void InitializeLara(bool restore) LaraInfo lBackup = {};
int lHitPoints = 0;
void BackupLara()
{ {
if (Lara.ItemNumber == NO_ITEM) if (LaraItem == nullptr || LaraItem->Index == NO_ITEM)
return; return;
LaraInfo lBackup = {}; memcpy(&lBackup, &Lara, sizeof(LaraInfo));
if (restore) lHitPoints = LaraItem->HitPoints;
memcpy(&lBackup, &Lara, sizeof(LaraInfo)); }
short itemNumber = Lara.ItemNumber; void InitializeLara(bool restore)
{
if (LaraItem == nullptr || LaraItem->Index == NO_ITEM)
return;
ZeroMemory(&Lara, sizeof(LaraInfo));
LaraItem->Data = &Lara; LaraItem->Data = &Lara;
LaraItem->Collidable = false; LaraItem->Collidable = false;
LaraItem->Location.roomNumber = LaraItem->RoomNumber; LaraItem->Location.roomNumber = LaraItem->RoomNumber;
LaraItem->Location.yNumber = LaraItem->Pose.Position.y; LaraItem->Location.yNumber = LaraItem->Pose.Position.y;
ZeroMemory(&Lara, sizeof(LaraInfo));
Lara.Status.Air = LARA_AIR_MAX; Lara.Status.Air = LARA_AIR_MAX;
Lara.Status.Exposure = LARA_EXPOSURE_MAX; Lara.Status.Exposure = LARA_EXPOSURE_MAX;
Lara.Status.Poison = 0; Lara.Status.Poison = 0;
Lara.Status.Stamina = LARA_STAMINA_MAX; Lara.Status.Stamina = LARA_STAMINA_MAX;
Lara.Control.CanLook = true; Lara.Control.CanLook = true;
Lara.ItemNumber = itemNumber;
Lara.HitDirection = -1; Lara.HitDirection = -1;
Lara.Control.Weapon.WeaponItem = NO_ITEM; Lara.Control.Weapon.WeaponItem = NO_ITEM;
Lara.Context.WaterSurfaceDist = 100; Lara.Context.WaterSurfaceDist = 100;
@ -46,13 +51,18 @@ void InitializeLara(bool restore)
Lara.Location = -1; Lara.Location = -1;
Lara.HighestLocation = -1; Lara.HighestLocation = -1;
Lara.Control.Rope.Ptr = -1; Lara.Control.Rope.Ptr = -1;
LaraItem->HitPoints = LARA_HEALTH_MAX;
Lara.Control.HandStatus = HandStatus::Free; Lara.Control.HandStatus = HandStatus::Free;
if (restore) if (restore)
InitializeLaraLevelJump(itemNumber, &lBackup); {
InitializeLaraLevelJump(LaraItem->Index, &lBackup);
LaraItem->HitPoints = lHitPoints;
}
else else
{
InitializeLaraDefaultInventory(); InitializeLaraDefaultInventory();
LaraItem->HitPoints = LARA_HEALTH_MAX;
}
InitializeLaraMeshes(LaraItem); InitializeLaraMeshes(LaraItem);
InitializeLaraAnims(LaraItem); InitializeLaraAnims(LaraItem);
@ -143,10 +153,9 @@ void InitializeLaraAnims(ItemInfo* item)
} }
} }
void InitializeLaraLoad(short itemNum) void InitializeLaraLoad(short itemNumber)
{ {
Lara.ItemNumber = itemNum; LaraItem = &g_Level.Items[itemNumber];
LaraItem = &g_Level.Items[itemNum];
} }
void InitializeLaraLevelJump(short itemNum, LaraInfo* lBackup) void InitializeLaraLevelJump(short itemNum, LaraInfo* lBackup)
@ -157,6 +166,7 @@ void InitializeLaraLevelJump(short itemNum, LaraInfo* lBackup)
// Restore inventory. // Restore inventory.
// It restores even puzzle/key items, to reset them, a ResetHub analog must be made. // It restores even puzzle/key items, to reset them, a ResetHub analog must be made.
lara->Inventory = lBackup->Inventory; lara->Inventory = lBackup->Inventory;
lara->Control.Weapon.LastGunType = lBackup->Control.Weapon.LastGunType;
memcpy(&lara->Weapons, &lBackup->Weapons, sizeof(CarriedWeaponInfo) * int(LaraWeaponType::NumWeapons)); memcpy(&lara->Weapons, &lBackup->Weapons, sizeof(CarriedWeaponInfo) * int(LaraWeaponType::NumWeapons));
// If no flare present, quit // If no flare present, quit

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include "Game/Lara/lara_struct.h" #include "Game/Lara/lara_struct.h"
void BackupLara();
void InitializeLara(bool restore); void InitializeLara(bool restore);
void InitializeLaraMeshes(ItemInfo* item); void InitializeLaraMeshes(ItemInfo* item);
void InitializeLaraAnims(ItemInfo* item); void InitializeLaraAnims(ItemInfo* item);

View file

@ -265,12 +265,12 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
} }
// JUMP key repressed without directional key; cancel directional jump lock. // JUMP key repressed without directional key; cancel directional jump lock.
if (DbInput & IN_JUMP && !IsDirectionActionHeld()) if (IsClicked(In::Jump) && !IsDirectionalActionHeld())
lara->Control.JumpDirection = JumpDirection::None; lara->Control.JumpDirection = JumpDirection::None;
if (((TrInput & IN_FORWARD && if (((TrInput & IN_FORWARD &&
!(TrInput & IN_BACK && lara->Control.JumpDirection == JumpDirection::Back)) || // Back jump takes priority in this exception. !(TrInput & IN_BACK && lara->Control.JumpDirection == JumpDirection::Back)) || // Back jump takes priority in this exception.
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) && !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) &&
TestLaraJumpForward(item, coll)) TestLaraJumpForward(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;
@ -278,7 +278,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
else if ((TrInput & IN_BACK || else if ((TrInput & IN_BACK ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) && !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) &&
TestLaraJumpBack(item, coll)) TestLaraJumpBack(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_BACK; item->Animation.TargetState = LS_JUMP_BACK;
@ -287,7 +287,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
} }
if ((TrInput & IN_LEFT || if ((TrInput & IN_LEFT ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) && !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) &&
TestLaraJumpLeft(item, coll)) TestLaraJumpLeft(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_LEFT; item->Animation.TargetState = LS_JUMP_LEFT;
@ -295,7 +295,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
return; return;
} }
else if ((TrInput & IN_RIGHT || else if ((TrInput & IN_RIGHT ||
!IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) && !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) &&
TestLaraJumpRight(item, coll)) TestLaraJumpRight(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_RIGHT; item->Animation.TargetState = LS_JUMP_RIGHT;

View file

@ -57,7 +57,7 @@ void lara_as_monkey_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
{ {
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;
lara->Control.HandStatus = HandStatus::Free; lara->Control.HandStatus = HandStatus::Free;
@ -497,7 +497,7 @@ void lara_as_monkey_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
{ {
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;
lara->Control.HandStatus = HandStatus::Free; lara->Control.HandStatus = HandStatus::Free;
@ -576,7 +576,7 @@ void lara_as_monkey_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
{ {
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;
lara->Control.HandStatus = HandStatus::Free; lara->Control.HandStatus = HandStatus::Free;

View file

@ -37,7 +37,7 @@ void lara_as_pickup(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = -ANGLE(130.0f); Camera.targetAngle = -ANGLE(130.0f);
Camera.targetElevation = -ANGLE(15.0f); Camera.targetElevation = -ANGLE(15.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
if (TestLastFrame(item)) if (TestLastFrame(item))
item->Animation.TargetState = GetNextAnimState(item); item->Animation.TargetState = GetNextAnimState(item);
@ -54,7 +54,7 @@ void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = ANGLE(130.0f); Camera.targetAngle = ANGLE(130.0f);
Camera.targetElevation = -ANGLE(15.0f); Camera.targetElevation = -ANGLE(15.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
if (item->Animation.FrameNumber == (GetAnimData(*item).frameEnd - 1)) if (item->Animation.FrameNumber == (GetAnimData(*item).frameEnd - 1))
lara->Control.HandStatus = HandStatus::Free; lara->Control.HandStatus = HandStatus::Free;
@ -75,7 +75,7 @@ void lara_as_switch_on(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = ANGLE(80.0f); Camera.targetAngle = ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f); Camera.targetElevation = -ANGLE(25.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
Camera.speed = 6; Camera.speed = 6;
} }
@ -90,7 +90,7 @@ void lara_as_switch_off(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = ANGLE(80.0f); Camera.targetAngle = ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f); Camera.targetElevation = -ANGLE(25.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
Camera.speed = 6; Camera.speed = 6;
} }
@ -129,7 +129,7 @@ void lara_as_use_key(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = -ANGLE(80.0f); Camera.targetAngle = -ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f); Camera.targetElevation = -ANGLE(25.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
} }
// State: LS_USE_PUZZLE (43) // State: LS_USE_PUZZLE (43)
@ -143,7 +143,7 @@ void lara_as_use_puzzle(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false; coll->Setup.EnableSpasm = false;
Camera.targetAngle = -ANGLE(80.0f); Camera.targetAngle = -ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f); Camera.targetElevation = -ANGLE(25.0f);
Camera.targetDistance = SECTOR(1); Camera.targetDistance = BLOCK(1);
if (TestLastFrame(item) && item->ItemFlags[0]) if (TestLastFrame(item) && item->ItemFlags[0])
{ {
@ -266,7 +266,7 @@ void lara_as_horizontal_bar_swing(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION) if (TrInput & IN_ACTION)
{ {
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
item->Animation.TargetState = LS_HORIZONTAL_BAR_LEAP; item->Animation.TargetState = LS_HORIZONTAL_BAR_LEAP;
item->Animation.TargetState = LS_HORIZONTAL_BAR_SWING; item->Animation.TargetState = LS_HORIZONTAL_BAR_SWING;
@ -502,7 +502,7 @@ void lara_col_rope_swing(ItemInfo* item, CollisionInfo* coll)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
Camera.targetDistance = SECTOR(2); Camera.targetDistance = BLOCK(2);
UpdateRopeSwing(item); UpdateRopeSwing(item);
RopeSwingCollision(item, coll, true); RopeSwingCollision(item, coll, true);
@ -550,7 +550,7 @@ void lara_col_rope_swing(ItemInfo* item, CollisionInfo* coll)
item->Animation.FrameNumber = GetAnimData(item).frameBase; item->Animation.FrameNumber = GetAnimData(item).frameBase;
} }
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
JumpOffRope(item); JumpOffRope(item);
} }
else if (item->Animation.FrameNumber == GetAnimData(LA_ROPE_IDLE_TO_SWING).frameBase + 15) else if (item->Animation.FrameNumber == GetAnimData(LA_ROPE_IDLE_TO_SWING).frameBase + 15)
@ -618,7 +618,7 @@ void lara_as_pole_idle(ItemInfo* item, CollisionInfo* coll)
} }
// TODO: Add forward jump. // TODO: Add forward jump.
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_JUMP_BACK; item->Animation.TargetState = LS_JUMP_BACK;
return; return;
@ -707,7 +707,7 @@ void lara_as_pole_up(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true); ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_POLE_IDLE; item->Animation.TargetState = LS_POLE_IDLE;
return; return;
@ -756,7 +756,7 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true); ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
{ {
item->Animation.TargetState = LS_POLE_IDLE; item->Animation.TargetState = LS_POLE_IDLE;
return; return;

View file

@ -9,6 +9,7 @@
#include "Game/control/los.h" #include "Game/control/los.h"
#include "Game/effects/Bubble.h" #include "Game/effects/Bubble.h"
#include "Game/effects/debris.h" #include "Game/effects/debris.h"
#include "Game/effects/Drip.h"
#include "Game/effects/effects.h" #include "Game/effects/effects.h"
#include "Game/effects/item_fx.h" #include "Game/effects/item_fx.h"
#include "Game/effects/Ripple.h" #include "Game/effects/Ripple.h"
@ -31,6 +32,7 @@
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Effects::Bubble; using namespace TEN::Effects::Bubble;
using namespace TEN::Effects::Drip;
using namespace TEN::Effects::Environment; using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Items; using namespace TEN::Effects::Items;
using namespace TEN::Effects::Ripple; using namespace TEN::Effects::Ripple;
@ -44,6 +46,9 @@ constexpr auto GRENADE_FLASH_TIMEOUT = 4;
constexpr auto HARPOON_VELOCITY = BLOCK(0.25f); constexpr auto HARPOON_VELOCITY = BLOCK(0.25f);
constexpr auto HARPOON_TIME = 10 * FPS; constexpr auto HARPOON_TIME = 10 * FPS;
constexpr auto BOLT_VELOCITY = BLOCK(0.25f);
constexpr auto BOLT_TIME = 10 * FPS;
constexpr auto BOLT_STUCK_LIFE = 5 * FPS;
constexpr auto ROCKET_VELOCITY = CLICK(2); constexpr auto ROCKET_VELOCITY = CLICK(2);
constexpr auto ROCKET_TIME = 4.5f * FPS; constexpr auto ROCKET_TIME = 4.5f * FPS;
constexpr auto GRENADE_VELOCITY = BLOCK(1 / 8.0f); constexpr auto GRENADE_VELOCITY = BLOCK(1 / 8.0f);
@ -204,7 +209,7 @@ void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType)
break; break;
case LaraWeaponType::Crossbow: case LaraWeaponType::Crossbow:
FireCrossbow(laraItem, nullptr); FireCrossbow(laraItem);
break; break;
case LaraWeaponType::HK: case LaraWeaponType::HK:
@ -556,109 +561,112 @@ void UndrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType)
} }
} }
ItemInfo* FireHarpoon(ItemInfo& laraItem) bool FireHarpoon(ItemInfo& laraItem, const std::optional<Pose>& pose)
{ {
auto& player = *GetLaraInfo(&laraItem); auto& player = *GetLaraInfo(&laraItem);
auto& ammo = GetAmmo(player, LaraWeaponType::HarpoonGun); auto& ammo = GetAmmo(player, LaraWeaponType::HarpoonGun);
if (!ammo) if (!ammo)
return nullptr; return false;
player.Control.Weapon.HasFired = true; player.Control.Weapon.HasFired = true;
// Create a new item for harpoon. int itemNumber = CreateItem();
short itemNumber = CreateItem();
if (itemNumber == NO_ITEM) if (itemNumber == NO_ITEM)
return nullptr; return false;
auto& harpoonItem = g_Level.Items[itemNumber];
harpoonItem.ObjectNumber = ID_HARPOON;
harpoonItem.Model.Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
if (!ammo.HasInfinite()) if (!ammo.HasInfinite())
ammo--; ammo--;
auto& item = g_Level.Items[itemNumber]; if (pose.has_value())
item.Model.Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
item.ObjectNumber = ID_HARPOON;
item.RoomNumber = laraItem.RoomNumber;
auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77));
int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, item.RoomNumber).Position.Floor;
if (floorHeight >= jointPos.y)
{ {
item.Pose.Position = jointPos; harpoonItem.Pose.Position = pose->Position;
harpoonItem.RoomNumber = laraItem.RoomNumber;
InitializeItem(itemNumber);
harpoonItem.Pose.Orientation = EulerAngles(
player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x,
player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y,
0);
} }
else else
{ {
item.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z); auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77));
item.RoomNumber = laraItem.RoomNumber; harpoonItem.RoomNumber = laraItem.RoomNumber;
int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, harpoonItem.RoomNumber).Position.Floor;
if (floorHeight >= jointPos.y)
{
harpoonItem.Pose.Position = jointPos;
}
else
{
harpoonItem.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z);
harpoonItem.RoomNumber = laraItem.RoomNumber;
}
InitializeItem(itemNumber);
harpoonItem.Pose.Orientation.x = player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x;
harpoonItem.Pose.Orientation.z = 0;
harpoonItem.Pose.Orientation.y = player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y;
if (!player.LeftArm.Locked)
harpoonItem.Pose.Orientation += player.ExtraTorsoRot;
} }
InitializeItem(itemNumber); harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY;
harpoonItem.HitPoints = HARPOON_TIME;
item.Pose.Orientation = EulerAngles( AddActiveItem(itemNumber);
player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x,
player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y,
0);
if (!player.LeftArm.Locked) harpoonItem.ItemFlags[0] = (int)ProjectileType::Harpoon;
item.Pose.Orientation += player.ExtraTorsoRot;
item.Pose.Orientation.z = 0;
item.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(item.Pose.Orientation.x);
item.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(item.Pose.Orientation.x);
item.HitPoints = HARPOON_TIME;
Rumble(0.2f, 0.1f); Rumble(0.2f, 0.1f);
AddActiveItem(itemNumber);
Statistics.Level.AmmoUsed++; Statistics.Level.AmmoUsed++;
Statistics.Game.AmmoUsed++; Statistics.Game.AmmoUsed++;
return &item; return true;
} }
void HarpoonBoltControl(short itemNumber) void HarpoonBoltControl(short itemNumber)
{ {
auto& harpoonItem = g_Level.Items[itemNumber]; auto& harpoonItem = g_Level.Items[itemNumber];
if (harpoonItem.HitPoints < HARPOON_TIME) if (harpoonItem.HitPoints < HARPOON_TIME)
{ {
if (harpoonItem.HitPoints > 0) harpoonItem.HitPoints--;
if (harpoonItem.HitPoints == 0)
{ {
harpoonItem.HitPoints--; ExplodeItemNode(&harpoonItem, 0, 0, BODY_DO_EXPLOSION);
}
else
{
ExplodeItemNode(&harpoonItem, 0, 0, BODY_EXPLODE);
KillItem(itemNumber); KillItem(itemNumber);
} }
return; return;
} }
harpoonItem.Pose.Orientation.z += ANGLE(35.0f); if (TestEnvironment(ENV_FLAG_WATER, &harpoonItem))
if (!TestEnvironment(ENV_FLAG_WATER, harpoonItem.RoomNumber))
{ {
harpoonItem.Pose.Orientation.x -= ANGLE(1.0f); if (harpoonItem.Animation.Velocity.z > 64.0f)
harpoonItem.Animation.Velocity.z -= harpoonItem.Animation.Velocity.z / 16;
if (harpoonItem.Pose.Orientation.x < ANGLE(-90.0f)) if (GlobalCounter & 1)
harpoonItem.Pose.Orientation.x = ANGLE(-90.0f); SpawnBubble(harpoonItem.Pose.Position.ToVector3(), harpoonItem.RoomNumber);
harpoonItem.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(harpoonItem.Pose.Orientation.x);
harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(harpoonItem.Pose.Orientation.x);
}
else
{
if (Wibble & 4)
SpawnBubble(harpoonItem.Pose.Position.ToVector3(), harpoonItem.RoomNumber, (int)BubbleFlags::HighAmplitude);
harpoonItem.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(harpoonItem.Pose.Orientation.x) / 2;
harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(harpoonItem.Pose.Orientation.x) / 2;
} }
auto prevPos = harpoonItem.Pose.Position;
TranslateItem(&harpoonItem, harpoonItem.Pose.Orientation, harpoonItem.Animation.Velocity.z); TranslateItem(&harpoonItem, harpoonItem.Pose.Orientation, harpoonItem.Animation.Velocity.z);
HandleProjectile(harpoonItem, *LaraItem, harpoonItem.Pose.Position, ProjectileType::Harpoon, Weapons[(int)LaraWeaponType::HarpoonGun].Damage);
int damage = Weapons[(int)LaraWeaponType::HarpoonGun].Damage;
HandleProjectile(harpoonItem, *LaraItem, prevPos, (ProjectileType)harpoonItem.ItemFlags[0], damage);
} }
void FireGrenade(ItemInfo& laraItem) void FireGrenade(ItemInfo& laraItem)
@ -983,7 +991,7 @@ void RocketControl(short itemNumber)
HandleProjectile(rocketItem, *LaraItem, prevPos, ProjectileType::Explosive, Weapons[(int)LaraWeaponType::RocketLauncher].ExplosiveDamage); HandleProjectile(rocketItem, *LaraItem, prevPos, ProjectileType::Explosive, Weapons[(int)LaraWeaponType::RocketLauncher].ExplosiveDamage);
} }
void FireCrossbow(ItemInfo& laraItem, Pose* pos) void FireCrossbow(ItemInfo& laraItem, const std::optional<Pose>& pose)
{ {
auto& player = *GetLaraInfo(&laraItem); auto& player = *GetLaraInfo(&laraItem);
auto& ammo = GetAmmo(player, LaraWeaponType::Crossbow); auto& ammo = GetAmmo(player, LaraWeaponType::Crossbow);
@ -1004,14 +1012,14 @@ void FireCrossbow(ItemInfo& laraItem, Pose* pos)
if (!ammo.HasInfinite()) if (!ammo.HasInfinite())
ammo--; ammo--;
if (pos) if (pose.has_value())
{ {
boltItem.Pose.Position = pos->Position; boltItem.Pose.Position = pose->Position;
boltItem.RoomNumber = laraItem.RoomNumber; boltItem.RoomNumber = laraItem.RoomNumber;
InitializeItem(itemNumber); InitializeItem(itemNumber);
boltItem.Pose.Orientation = pos->Orientation; boltItem.Pose.Orientation = pose->Orientation;
} }
else else
{ {
@ -1040,8 +1048,8 @@ void FireCrossbow(ItemInfo& laraItem, Pose* pos)
} }
} }
boltItem.Animation.Velocity.z = 512.0f; boltItem.Animation.Velocity.z = BOLT_VELOCITY;
boltItem.HitPoints = HARPOON_TIME; boltItem.HitPoints = BOLT_TIME;
AddActiveItem(itemNumber); AddActiveItem(itemNumber);
@ -1074,7 +1082,7 @@ void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVect
{ {
auto orient = Geometry::GetOrientToPoint(origin->ToVector3(), target->ToVector3()); auto orient = Geometry::GetOrientToPoint(origin->ToVector3(), target->ToVector3());
auto boltPose = Pose(origin->x, origin->y, origin->z, orient); auto boltPose = Pose(origin->x, origin->y, origin->z, orient);
FireCrossbow(laraItem, &boltPose); FireCrossbow(laraItem, boltPose);
} }
void CrossbowBoltControl(short itemNumber) void CrossbowBoltControl(short itemNumber)
@ -1412,18 +1420,31 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type)
bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll) bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll)
{ {
// Has projectile changed room? // Check if projectile changed room.
if (item.RoomNumber == coll.RoomNumber) if (item.RoomNumber == coll.RoomNumber)
return false; return false;
// If currently in water and previously on land, add a 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, coll.RoomNumber))
{ {
const auto& player = GetLaraInfo(item);
int floorDiff = abs(coll.Position.Floor - item.Pose.Position.y); int floorDiff = abs(coll.Position.Floor - item.Pose.Position.y);
int ceilingDiff = abs(coll.Position.Ceiling - item.Pose.Position.y); int ceilingDiff = abs(coll.Position.Ceiling - item.Pose.Position.y);
int yPoint = (floorDiff > ceilingDiff) ? coll.Position.Ceiling : coll.Position.Floor; int yPoint = (floorDiff > ceilingDiff) ? coll.Position.Ceiling : coll.Position.Floor;
SpawnRipple(Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z), item.RoomNumber, Random::GenerateInt(8, 16)); if (player.Control.Weapon.GunType != LaraWeaponType::GrenadeLauncher && player.Control.Weapon.GunType != LaraWeaponType::RocketLauncher)
{
SpawnSplashDrips(
Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z),
item.RoomNumber, 3, false);
SpawnRipple(Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z), item.RoomNumber, Random::GenerateInt(8, 16));
}
else
{
Splash(&item);
}
} }
ItemNewRoom(item.Index, coll.RoomNumber); ItemNewRoom(item.Index, coll.RoomNumber);
@ -1458,8 +1479,8 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
bool hasHit = false; bool hasHit = false;
bool hasHitNotByEmitter = false; bool hasHitNotByEmitter = false;
bool isExplosive = type >= ProjectileType::Explosive; bool isExplosive = (type >= ProjectileType::Explosive);
bool isShatterable = type != ProjectileType::Harpoon; bool isShatterable = (type != ProjectileType::Harpoon);
// For non-grenade projectiles, check for room collision. // For non-grenade projectiles, check for room collision.
if (type < ProjectileType::Grenade) if (type < ProjectileType::Grenade)
@ -1467,7 +1488,6 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
if (pointColl.Position.Floor < projectile.Pose.Position.y || if (pointColl.Position.Floor < projectile.Pose.Position.y ||
pointColl.Position.Ceiling > projectile.Pose.Position.y) pointColl.Position.Ceiling > projectile.Pose.Position.y)
{ {
projectile.Pose.Position = prevPos;
hasHit = hasHit =
hasHitNotByEmitter = true; hasHitNotByEmitter = true;
} }
@ -1620,18 +1640,16 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
DoDamage(itemPtr, damage); DoDamage(itemPtr, damage);
} }
} }
} }
else if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && else if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 &&
itemPtr->ObjectNumber <= ID_SMASH_OBJECT8) itemPtr->ObjectNumber <= ID_SMASH_OBJECT8)
{ {
doShatter = hasHit = true; doShatter = hasHit = true;
// Smash objects are legacy objects from TRC. Let's make them explode in the legacy way. // Smash objects are legacy objects from TRC. Make them explode in legacy way.
ExplodeItemNode(itemPtr, 0, 0, 128); ExplodeItemNode(itemPtr, 0, 0, 128);
short currentItemNumber = (itemPtr - CollidedItems[0]); SmashObject(itemPtr->Index);
SmashObject(currentItemNumber); KillItem(itemPtr->Index);
KillItem(currentItemNumber);
} }
} }
@ -1651,7 +1669,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p
} }
else if (doShatter) else if (doShatter)
{ {
ExplodeItemNode(&projectile, 0, 0, BODY_EXPLODE); ExplodeItemNode(&projectile, 0, 0, BODY_DO_EXPLOSION);
} }
switch (type) switch (type)

View file

@ -1,9 +1,9 @@
#pragma once #pragma once
#include "Math/Math.h"
using namespace TEN::Math;
enum class LaraWeaponType; enum class LaraWeaponType;
class GameVector;
class Pose;
class Vector3i;
struct ItemInfo; struct ItemInfo;
enum class GrenadeType enum class GrenadeType
@ -34,13 +34,13 @@ void UndrawShotgun(ItemInfo& laraItem, LaraWeaponType weaponType);
void DrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType); void DrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType);
void UndrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType); void UndrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType);
ItemInfo* FireHarpoon(ItemInfo& laraItem); bool FireHarpoon(ItemInfo& laraItem, const std::optional<Pose>& pose = std::nullopt);
void HarpoonBoltControl(short itemNumber); 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 RocketControl(short itemNumber); void RocketControl(short itemNumber);
void FireCrossbow(ItemInfo& laraItem, Pose* pos); 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);
void CrossbowBoltControl(short itemNumber); void CrossbowBoltControl(short itemNumber);

View file

@ -361,7 +361,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll)
if (GetClimbFlags(probeUp.BottomBlock) & slopeData.ClimbOrient && if (GetClimbFlags(probeUp.BottomBlock) & 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 <= (SECTOR(1.5f) - 80)) // Check if a wall is actually there. 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.
{ {
AlignToEdge(item, FORWARD_ALIGNMENT); AlignToEdge(item, FORWARD_ALIGNMENT);
SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START); SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START);
@ -451,7 +451,7 @@ void lara_as_slopeclimb(ItemInfo* item, CollisionInfo* coll)
return; return;
Camera.targetElevation = -ANGLE(16.75f); Camera.targetElevation = -ANGLE(16.75f);
Camera.targetDistance = SECTOR(1.75f); Camera.targetDistance = BLOCK(1.75f);
Camera.speed = 15; Camera.speed = 15;
} }
@ -470,7 +470,7 @@ void lara_as_slopefall(ItemInfo* item, CollisionInfo* coll)
return; return;
Camera.targetElevation = -ANGLE(16.75f); Camera.targetElevation = -ANGLE(16.75f);
Camera.targetDistance = SECTOR(1.75f); Camera.targetDistance = BLOCK(1.75f);
Camera.speed = 15; Camera.speed = 15;
} }
@ -547,7 +547,7 @@ void lara_as_slopehang(ItemInfo* item, CollisionInfo* coll)
if (Camera.type != CameraType::Chase) if (Camera.type != CameraType::Chase)
return; return;
Camera.targetElevation = -SECTOR(1); Camera.targetElevation = -BLOCK(1);
Camera.targetDistance = CLICK(6.5f); Camera.targetDistance = CLICK(6.5f);
Camera.speed = 15; Camera.speed = 15;
} }
@ -604,7 +604,7 @@ void lara_as_slopeshimmy(ItemInfo* item, CollisionInfo* coll)
if (Camera.type != CameraType::Chase) if (Camera.type != CameraType::Chase)
return; return;
Camera.targetElevation = -SECTOR(1); Camera.targetElevation = -BLOCK(1);
Camera.targetDistance = CLICK(6.5f); Camera.targetDistance = CLICK(6.5f);
Camera.speed = 15; Camera.speed = 15;
@ -634,7 +634,7 @@ void lara_as_slopeclimbup(ItemInfo* item, CollisionInfo* coll)
if (Camera.type != CameraType::Chase) if (Camera.type != CameraType::Chase)
return; // If camera mode isn't chase (0) then don't change camera angles. return; // If camera mode isn't chase (0) then don't change camera angles.
Camera.targetElevation = SECTOR(2); Camera.targetElevation = BLOCK(2);
Camera.targetDistance = CLICK(7); Camera.targetDistance = CLICK(7);
Camera.speed = 15; Camera.speed = 15;
@ -697,12 +697,12 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll)
Camera.flags = CF_FOLLOW_CENTER; Camera.flags = CF_FOLLOW_CENTER;
int distance = TestLaraWall(item, 0, SECTOR(1.5f), 0) ? SECTOR(1) : CLICK(6.5f); int distance = TestLaraWall(item, 0, BLOCK(1.5f)) ? BLOCK(1) : CLICK(6.5f);
if (item->Animation.FrameNumber < GetAnimData(item).frameEnd) if (item->Animation.FrameNumber < GetAnimData(item).frameEnd)
{ {
Camera.targetDistance = distance; Camera.targetDistance = distance;
Camera.targetElevation = int(SECTOR(3) * frac); Camera.targetElevation = int(BLOCK(3) * frac);
Camera.targetAngle = int(-ANGLE(180.0f) * frac); Camera.targetAngle = int(-ANGLE(180.0f) * frac);
Camera.targetspeed = 15; Camera.targetspeed = 15;
} }
@ -710,7 +710,7 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll)
{ {
Camera.targetDistance = distance; Camera.targetDistance = distance;
Camera.targetElevation = SECTOR(3); Camera.targetElevation = BLOCK(3);
Camera.targetAngle = 0; Camera.targetAngle = 0;
Camera.targetspeed = 15; Camera.targetspeed = 15;
} }
@ -757,13 +757,13 @@ void lara_as_sclimbstop(ItemInfo* item, CollisionInfo* coll)
{ {
Camera.targetAngle = (short)(-ANGLE(90.0f) * frac); Camera.targetAngle = (short)(-ANGLE(90.0f) * frac);
Camera.targetDistance = SECTOR(1.75f) - int(CLICK(2) * frac); Camera.targetDistance = BLOCK(1.75f) - int(CLICK(2) * frac);
Camera.targetspeed = 15; Camera.targetspeed = 15;
} }
else else
{ {
Camera.targetAngle = ANGLE(90.0f); Camera.targetAngle = ANGLE(90.0f);
Camera.targetDistance = SECTOR(1.25f); Camera.targetDistance = BLOCK(1.25f);
Camera.targetspeed = 15; Camera.targetspeed = 15;
} }
} }

View file

@ -66,7 +66,7 @@ void lara_as_slide_forward(ItemInfo* item, CollisionInfo* coll)
else else
ApproachLaraTargetOrientation(item, direction);*/ ApproachLaraTargetOrientation(item, direction);*/
if (TrInput & IN_JUMP && TestLaraSlideJump(item, coll)) if (IsHeld(In::Jump) && TestLaraSlideJump(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_FORWARD; item->Animation.TargetState = LS_JUMP_FORWARD;
StopSoundEffect(SFX_TR4_LARA_SLIPPING); StopSoundEffect(SFX_TR4_LARA_SLIPPING);
@ -175,7 +175,7 @@ void lara_as_slide_back(ItemInfo* item, CollisionInfo* coll)
else else
ApproachLaraTargetOrientation(item, direction);*/ ApproachLaraTargetOrientation(item, direction);*/
if (TrInput & IN_JUMP && TestLaraSlideJump(item, coll)) if (IsHeld(In::Jump) && TestLaraSlideJump(item, coll))
{ {
item->Animation.TargetState = LS_JUMP_BACK; item->Animation.TargetState = LS_JUMP_BACK;
StopSoundEffect(SFX_TR4_LARA_SLIPPING); StopSoundEffect(SFX_TR4_LARA_SLIPPING);

View file

@ -1280,7 +1280,7 @@ struct PlayerContextData
int ProjectedFloorHeight = 0; int ProjectedFloorHeight = 0;
float CalcJumpVelocity = 0; float CalcJumpVelocity = 0;
Pose NextCornerPos = Pose::Zero; Pose NextCornerPos = Pose::Zero;
EulerAngles TargetOrientation = EulerAngles::Zero; EulerAngles TargetOrientation = EulerAngles::Zero; // TargetOrient
int WaterSurfaceDist = 0; int WaterSurfaceDist = 0;
short WaterCurrentActive = 0; // Sink number? Often used as bool. short WaterCurrentActive = 0; // Sink number? Often used as bool.
@ -1300,8 +1300,6 @@ struct LaraInfo
{ {
static constexpr auto TARGET_COUNT_MAX = 8; static constexpr auto TARGET_COUNT_MAX = 8;
int ItemNumber = 0; // TODO: Remove. No longer necessary since ItemInfo already has it. -- Sezz 2023.04.09
LaraControlData Control = {}; LaraControlData Control = {};
PlayerContextData Context = {}; PlayerContextData Context = {};
PlayerStatusData Status = {}; PlayerStatusData Status = {};
@ -1319,13 +1317,12 @@ struct LaraInfo
ArmInfo RightArm = {}; ArmInfo RightArm = {};
ItemInfo* TargetEntity = nullptr; // TargetEntityPtr. Should use item number instead? ItemInfo* TargetEntity = nullptr; // TargetEntityPtr. Should use item number instead?
std::array<ItemInfo*, TARGET_COUNT_MAX> TargetList = {}; std::array<ItemInfo*, TARGET_COUNT_MAX> TargetList = {};
std::array<ItemInfo*, TARGET_COUNT_MAX> LastTargets = {}; std::array<ItemInfo*, TARGET_COUNT_MAX> LastTargets = {};
// TODO: Rewrite and restore spasm effect. Also move to PlayerEffectData? // TODO: Rewrite and restore spasm effect. Also move to PlayerEffectData?
int HitFrame = 0; // Frame index. int HitFrame = 0; // Frame index.
int HitDirection = 0; // Cardinal direction. int HitDirection = 0; // Cardinal direction.
FX_INFO* SpasmEffect = nullptr; // Not saved.
int ExtraAnim = 0; // Item number? Only ever set to NO_ITEM or 1. int ExtraAnim = 0; // Item number? Only ever set to NO_ITEM or 1.

View file

@ -60,7 +60,7 @@ void lara_as_surface_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_MED_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_MED_TURN_RATE_MAX);
if (DbInput & IN_JUMP) if (IsClicked(In::Jump))
{ {
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
return; return;
@ -125,7 +125,7 @@ void lara_as_surface_swim_forward(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_FORWARD)) if (!(TrInput & IN_FORWARD))
item->Animation.TargetState = LS_ONWATER_IDLE; item->Animation.TargetState = LS_ONWATER_IDLE;
if (DbInput & IN_JUMP) if (IsClicked(In::Jump))
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
@ -167,7 +167,7 @@ void lara_as_surface_swim_left(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) if (!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT)))
item->Animation.TargetState = LS_ONWATER_IDLE; item->Animation.TargetState = LS_ONWATER_IDLE;
if (DbInput & IN_JUMP) if (IsClicked(In::Jump))
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
@ -206,7 +206,7 @@ void lara_as_surface_swim_right(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT))) if (!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT)))
item->Animation.TargetState = LS_ONWATER_IDLE; item->Animation.TargetState = LS_ONWATER_IDLE;
if (DbInput & IN_JUMP) if (IsClicked(In::Jump))
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
@ -239,7 +239,7 @@ void lara_as_surface_swim_back(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_LEFT | IN_RIGHT)) if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX); ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX);
if (DbInput & IN_JUMP) if (IsClicked(In::Jump))
SetLaraSwimDiveAnimation(item); SetLaraSwimDiveAnimation(item);
if (!(TrInput & IN_BACK)) if (!(TrInput & IN_BACK))

View file

@ -51,7 +51,7 @@ void lara_as_underwater_idle(ItemInfo* item, CollisionInfo* coll)
else else
ModulateLaraSwimTurnRates(item, coll); ModulateLaraSwimTurnRates(item, coll);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD; item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL; item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;
@ -96,7 +96,7 @@ void lara_as_underwater_swim_forward(ItemInfo* item, CollisionInfo* coll)
if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX) if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX; item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX;
if (!(TrInput & IN_JUMP)) if (!(IsHeld(In::Jump)))
item->Animation.TargetState = LS_UNDERWATER_INERTIA; item->Animation.TargetState = LS_UNDERWATER_INERTIA;
} }
@ -130,7 +130,7 @@ void lara_as_underwater_inertia(ItemInfo* item, CollisionInfo* coll)
else else
ModulateLaraSubsuitSwimTurnRates(item); ModulateLaraSubsuitSwimTurnRates(item);
if (TrInput & IN_JUMP) if (IsHeld(In::Jump))
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD; item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL; item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;

View file

@ -53,8 +53,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
if (frontLeft.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height) || frontRight.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height)) if (frontLeft.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height) || frontRight.Position.Ceiling > (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, RENDERER_DEBUG_PAGE::LARA_STATS); //g_Renderer.AddDebugSphere(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, RENDERER_DEBUG_PAGE::LARA_STATS); //g_Renderer.AddDebugSphere(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
@ -71,7 +71,7 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo
return false; return false;
// Determine allowed slope difference for a given collision radius // Determine allowed slope difference for a given collision radius
auto slopeDelta = ((float)STEPUP_HEIGHT / (float)SECTOR(1)) * (coll->Setup.Radius * 2); auto slopeDelta = ((float)STEPUP_HEIGHT / (float)BLOCK(1)) * (coll->Setup.Radius * 2);
// Discard if there is a slope beyond tolerance delta // Discard if there is a slope beyond tolerance delta
if (abs(left - right) >= slopeDelta) if (abs(left - right) >= slopeDelta)
@ -773,24 +773,16 @@ bool TestLaraHangSideways(ItemInfo* item, CollisionInfo* coll, short angle)
return !res; return !res;
} }
bool TestLaraWall(ItemInfo* item, int distance, int height, int side) bool TestLaraWall(ItemInfo* item, float dist, float height)
{ {
float s = phd_sin(item->Pose.Orientation.y); auto origin = GameVector(
float c = phd_cos(item->Pose.Orientation.y); Geometry::TranslatePoint(item->Pose.Position, item->Pose.Orientation.y, 0.0f, height),
item->RoomNumber);
auto start = GameVector( auto target = GameVector(
item->Pose.Position.x + (side * c), Geometry::TranslatePoint(item->Pose.Position, item->Pose.Orientation.y, dist, height),
item->Pose.Position.y + height,
item->Pose.Position.z + (-side * s),
item->RoomNumber); item->RoomNumber);
auto end = GameVector( return !LOS(&origin, &target);
item->Pose.Position.x + (distance * s) + (side * c),
item->Pose.Position.y + height,
item->Pose.Position.z + (distance * c) + (-side * s),
item->RoomNumber);
return !LOS(&start, &end);
} }
bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance) bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance)
@ -1046,11 +1038,11 @@ bool TestLaraLadderClimbOut(ItemInfo* item, CollisionInfo* coll) // NEW function
break; break;
case SOUTH: case SOUTH:
item->Pose.Position.z = (item->Pose.Position.z & -SECTOR(1)) + LARA_RADIUS + 1; item->Pose.Position.z = (item->Pose.Position.z & -BLOCK(1)) + LARA_RADIUS + 1;
break; break;
case WEST: case WEST:
item->Pose.Position.x = (item->Pose.Position.x & -SECTOR(1)) + LARA_RADIUS + 1; item->Pose.Position.x = (item->Pose.Position.x & -BLOCK(1)) + LARA_RADIUS + 1;
break; break;
} }
@ -1202,11 +1194,11 @@ bool TestLaraPose(ItemInfo* item, CollisionInfo* coll)
if (TestEnvironment(ENV_FLAG_SWAMP, item)) if (TestEnvironment(ENV_FLAG_SWAMP, item))
return false; return false;
if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions. if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions.
lara->Control.HandStatus == HandStatus::Free && // Hands are free. lara->Control.HandStatus == HandStatus::Free && // Hands are free.
(lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Flare is not being handled. (lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Flare is not being handled.
lara->Flare.Life) && lara->Flare.Life) &&
lara->Context.Vehicle == NO_ITEM) // Not in a vehicle. lara->Context.Vehicle == NO_ITEM) // Not in a vehicle.
{ {
return true; return true;
} }
@ -1638,7 +1630,7 @@ bool TestLaraCrouchRoll(ItemInfo* item, CollisionInfo* coll)
// Assess continuity of path. // Assess continuity of path.
int distance = 0; int distance = 0;
auto probeA = GetCollision(item); auto probeA = GetCollision(item);
while (distance < SECTOR(1)) while (distance < BLOCK(1))
{ {
distance += CLICK(1); distance += CLICK(1);
auto probeB = GetCollision(item, item->Pose.Orientation.y, distance, -LARA_HEIGHT_CRAWL); auto probeB = GetCollision(item, item->Pose.Orientation.y, distance, -LARA_HEIGHT_CRAWL);
@ -1673,7 +1665,7 @@ bool TestLaraCrouchToCrawl(ItemInfo* item)
{ {
auto* lara = GetLaraInfo(item); auto* lara = GetLaraInfo(item);
if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions. if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions.
lara->Control.HandStatus == HandStatus::Free && // Hands are free. lara->Control.HandStatus == HandStatus::Free && // Hands are free.
(lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Not handling flare. TODO: Should be allowed, but the flare animation bugs out right now. @Sezz 2022.03.18 (lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Not handling flare. TODO: Should be allowed, but the flare animation bugs out right now. @Sezz 2022.03.18
lara->Flare.Life)) lara->Flare.Life))
@ -2292,7 +2284,7 @@ CrawlVaultTestResult TestLaraCrawlExitJump(ItemInfo* item, CollisionInfo* coll)
CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll) CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll)
{ {
if (!(TrInput & (IN_ACTION | IN_JUMP))) if (!(IsHeld(In::Action) || IsHeld(In::Jump)))
return CrawlVaultTestResult{ false }; return CrawlVaultTestResult{ false };
// Crawl vault exit down 1 step. // Crawl vault exit down 1 step.
@ -2538,7 +2530,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
bool atLeastOnePoleCollided = false; bool atLeastOnePoleCollided = false;
if (GetCollidedObjects(item, SECTOR(1), true, CollidedItems, nullptr, false) && if (GetCollidedObjects(item, BLOCK(1), true, CollidedItems, nullptr, false) &&
CollidedItems[0] != nullptr) CollidedItems[0] != nullptr)
{ {
auto laraBox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose); auto laraBox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose);
@ -2555,7 +2547,7 @@ 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), RENDERER_DEBUG_PAGE::LARA_STATS); //g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
int i = 0; int i = 0;
while (CollidedItems[i] != nullptr) while (CollidedItems[i] != nullptr)
@ -2569,7 +2561,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl
auto poleBox = GameBoundingBox(object).ToBoundingOrientedBox(object->Pose); auto poleBox = GameBoundingBox(object).ToBoundingOrientedBox(object->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), RENDERER_DEBUG_PAGE::LARA_STATS); //g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere)) if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere))
{ {

View file

@ -29,7 +29,7 @@ CornerTestResult TestItemAtNextCornerPosition(ItemInfo* item, CollisionInfo* col
bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll); bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll);
bool TestLaraHangSideways(ItemInfo* item, CollisionInfo* coll, short angle); bool TestLaraHangSideways(ItemInfo* item, CollisionInfo* coll, short angle);
bool TestLaraWall(ItemInfo* item, int distance, int height, int side = 0); bool TestLaraWall(ItemInfo* item, float dist, float height);
bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance); bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance);
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);

View file

@ -31,8 +31,9 @@ using namespace TEN::Effects::Hair;
using namespace TEN::Entities; using namespace TEN::Entities;
using namespace TEN::Entities::Switches; using namespace TEN::Entities::Switches;
ObjectInfo Objects[ID_NUMBER_OBJECTS]; ObjectHandler Objects;
STATIC_INFO StaticObjects[MAX_STATICS]; StaticInfo StaticObjects[MAX_STATICS];
void InitializeGameFlags() void InitializeGameFlags()
{ {
@ -49,7 +50,6 @@ void InitializeSpecialEffects()
memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS)); memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS));
memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SMOKE_SPARKS)); memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SMOKE_SPARKS));
memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT)); memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT));
memset(&Gunflashes, 0, (MAX_GUNFLASH * sizeof(GUNFLASH_STRUCT)));
memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT)); memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT));
memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT)); memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT));
memset(&ShockWaves, 0, MAX_SHOCKWAVE * sizeof(SHOCKWAVE_STRUCT)); memset(&ShockWaves, 0, MAX_SHOCKWAVE * sizeof(SHOCKWAVE_STRUCT));

View file

@ -142,7 +142,58 @@ struct ObjectInfo
} }
}; };
struct STATIC_INFO class ObjectHandler
{
private:
ObjectInfo Objects[ID_NUMBER_OBJECTS];
ObjectInfo& GetFirstAvailableObject()
{
for (int i = 0; i < ID_NUMBER_OBJECTS; i++)
{
if (Objects[i].loaded)
return Objects[i];
}
return Objects[0];
}
public:
void Initialize()
{
std::memset(Objects, 0, sizeof(ObjectInfo) * GAME_OBJECT_ID::ID_NUMBER_OBJECTS);
}
bool CheckID(int index, bool isSilent = false)
{
if (index == GAME_OBJECT_ID::ID_NO_OBJECT || index >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS)
{
if (!isSilent)
{
TENLog("Attempted to access unavailable slot ID (" + std::to_string(index) + "). " +
"Check if last accessed item exists in level.", LogLevel::Warning, LogConfig::Debug);
}
return false;
}
return true;
}
ObjectInfo& operator[](int index)
{
if (CheckID(index))
{
return Objects[index];
}
else
{
return GetFirstAvailableObject();
}
}
};
struct StaticInfo
{ {
int meshNumber; int meshNumber;
int flags; int flags;
@ -158,8 +209,8 @@ constexpr auto SF_SHATTERABLE = 0x02;
constexpr auto GRAVITY = 6.0f; constexpr auto GRAVITY = 6.0f;
constexpr auto SWAMP_GRAVITY = GRAVITY / 3.0f; constexpr auto SWAMP_GRAVITY = GRAVITY / 3.0f;
extern ObjectInfo Objects[ID_NUMBER_OBJECTS]; extern ObjectHandler Objects;
extern STATIC_INFO StaticObjects[MAX_STATICS]; extern StaticInfo StaticObjects[MAX_STATICS];
void InitializeGameFlags(); void InitializeGameFlags();
void InitializeSpecialEffects(); void InitializeSpecialEffects();

View file

@ -234,6 +234,9 @@ void AnimateItem(ItemInfo* item)
unsigned int frameCount = GetNonZeroFrameCount(*animPtr); unsigned int frameCount = GetNonZeroFrameCount(*animPtr);
int currentFrame = item->Animation.FrameNumber - animPtr->frameBase; int currentFrame = item->Animation.FrameNumber - animPtr->frameBase;
auto animAccel = (animPtr->VelocityEnd - animPtr->VelocityStart) / frameCount;
auto animVel = animPtr->VelocityStart + (animAccel * currentFrame);
if (item->Animation.IsAirborne) if (item->Animation.IsAirborne)
{ {
if (item->IsLara()) if (item->IsLara())
@ -258,7 +261,7 @@ void AnimateItem(ItemInfo* item)
else else
{ {
item->Animation.Velocity.y += (item->Animation.Velocity.y >= 128.0f) ? 1.0f : GRAVITY; item->Animation.Velocity.y += (item->Animation.Velocity.y >= 128.0f) ? 1.0f : GRAVITY;
item->Animation.Velocity.z += (animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount; item->Animation.Velocity.z += animAccel.z;
item->Pose.Position.y += item->Animation.Velocity.y; item->Pose.Position.y += item->Animation.Velocity.y;
} }
@ -273,25 +276,23 @@ void AnimateItem(ItemInfo* item)
{ {
if (item->IsLara()) if (item->IsLara())
{ {
const auto& player = *GetLaraInfo(item); const auto& player = GetLaraInfo(*item);
if (player.Control.WaterStatus == WaterStatus::Wade && TestEnvironment(ENV_FLAG_SWAMP, item)) bool isInSwamp = (player.Control.WaterStatus == WaterStatus::Wade && TestEnvironment(ENV_FLAG_SWAMP, item));
item->Animation.Velocity.z = (animPtr->VelocityStart.z / 2) + ((((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame) / 4); item->Animation.Velocity.z = isInSwamp ? (animVel.z / 2) : animVel.z;
else
item->Animation.Velocity.z = animPtr->VelocityStart.z + (((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame);
} }
else else
{ {
item->Animation.Velocity.x = animPtr->VelocityStart.x + (((animPtr->VelocityEnd.x - animPtr->VelocityStart.x) / frameCount) * currentFrame); item->Animation.Velocity.x = animVel.x;
item->Animation.Velocity.z = animPtr->VelocityStart.z + (((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame); item->Animation.Velocity.z = animVel.z;
} }
} }
if (item->IsLara()) if (item->IsLara())
{ {
const auto& player = *GetLaraInfo(item); const auto& player = GetLaraInfo(*item);
item->Animation.Velocity.x = animPtr->VelocityStart.x + (((animPtr->VelocityEnd.x - animPtr->VelocityStart.x) / frameCount) * currentFrame); item->Animation.Velocity.x = animVel.x;
if (player.Control.Rope.Ptr != -1) if (player.Control.Rope.Ptr != -1)
DelAlignLaraToRope(item); DelAlignLaraToRope(item);

View file

@ -26,9 +26,9 @@ using namespace TEN::Effects::Environment;
using namespace TEN::Entities::Generic; using namespace TEN::Entities::Generic;
using namespace TEN::Input; using namespace TEN::Input;
constexpr auto PARTICLE_FADE_THRESHOLD = SECTOR(14); constexpr auto PARTICLE_FADE_THRESHOLD = BLOCK(14);
constexpr auto COLL_CHECK_THRESHOLD = SECTOR(4); constexpr auto COLL_CHECK_THRESHOLD = BLOCK(4);
constexpr auto COLL_CANCEL_THRESHOLD = SECTOR(2); constexpr auto COLL_CANCEL_THRESHOLD = BLOCK(2);
constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f); constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f);
constexpr auto CAMERA_RADIUS = CLICK(1); constexpr auto CAMERA_RADIUS = CLICK(1);
@ -93,7 +93,7 @@ void LookAt(CAMERA_INFO* cam, short roll)
float fov = TO_RAD(CurrentFOV / 1.333333f); float fov = TO_RAD(CurrentFOV / 1.333333f);
float r = TO_RAD(roll); float r = TO_RAD(roll);
float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(SECTOR(1)); float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1));
g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView); g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView);
} }
@ -119,7 +119,7 @@ inline void RumbleFromBounce()
void InitializeCamera() void InitializeCamera()
{ {
Camera.shift = LaraItem->Pose.Position.y - SECTOR(1); Camera.shift = LaraItem->Pose.Position.y - BLOCK(1);
LastTarget.x = LaraItem->Pose.Position.x; LastTarget.x = LaraItem->Pose.Position.x;
LastTarget.y = Camera.shift; LastTarget.y = Camera.shift;
@ -136,7 +136,7 @@ void InitializeCamera()
Camera.pos.z = LastTarget.z - 100; Camera.pos.z = LastTarget.z - 100;
Camera.pos.RoomNumber = LaraItem->RoomNumber; Camera.pos.RoomNumber = LaraItem->RoomNumber;
Camera.targetDistance = SECTOR(1.5f); Camera.targetDistance = BLOCK(1.5f);
Camera.item = NULL; Camera.item = NULL;
Camera.numberFrames = 1; Camera.numberFrames = 1;
Camera.type = CameraType::Chase; Camera.type = CameraType::Chase;
@ -218,7 +218,7 @@ void MoveCamera(GameVector* ideal, int speed)
if (Camera.bounce <= 0) if (Camera.bounce <= 0)
{ {
int bounce = -Camera.bounce; int bounce = -Camera.bounce;
int bounce2 = -Camera.bounce >> 2; int bounce2 = bounce / 2;
Camera.target.x += GetRandomControl() % bounce - bounce2; Camera.target.x += GetRandomControl() % bounce - bounce2;
Camera.target.y += GetRandomControl() % bounce - bounce2; Camera.target.y += GetRandomControl() % bounce - bounce2;
Camera.target.z += GetRandomControl() % bounce - bounce2; Camera.target.z += GetRandomControl() % bounce - bounce2;
@ -243,9 +243,9 @@ void MoveCamera(GameVector* ideal, int speed)
{ {
LOSAndReturnTarget(&Camera.target, &Camera.pos, 0); LOSAndReturnTarget(&Camera.target, &Camera.pos, 0);
if (abs(Camera.pos.x - ideal->x) < SECTOR(0.5f) && if (abs(Camera.pos.x - ideal->x) < BLOCK(0.5f) &&
abs(Camera.pos.y - ideal->y) < SECTOR(0.5f) && abs(Camera.pos.y - ideal->y) < BLOCK(0.5f) &&
abs(Camera.pos.z - ideal->z) < SECTOR(0.5f)) abs(Camera.pos.z - ideal->z) < BLOCK(0.5f))
{ {
to.x = Camera.pos.x; to.x = Camera.pos.x;
to.y = Camera.pos.y; to.y = Camera.pos.y;
@ -538,7 +538,7 @@ void ChaseCamera(ItemInfo* item)
void DoThumbstickCamera() void DoThumbstickCamera()
{ {
if (!g_Configuration.EnableThumbstickCameraControl) if (!g_Configuration.EnableThumbstickCamera)
return; return;
if (Camera.laraNode == -1 && (Camera.target.x == OldCam.target.x && if (Camera.laraNode == -1 && (Camera.target.x == OldCam.target.x &&
@ -560,7 +560,7 @@ void UpdateCameraElevation()
if (Camera.laraNode != -1) if (Camera.laraNode != -1)
{ {
auto pos = GetJointPosition(LaraItem, Camera.laraNode, Vector3i::Zero); auto pos = GetJointPosition(LaraItem, Camera.laraNode, Vector3i::Zero);
auto pos1 = GetJointPosition(LaraItem, Camera.laraNode, Vector3i(0, -CLICK(1), SECTOR(2))); auto pos1 = GetJointPosition(LaraItem, Camera.laraNode, Vector3i(0, -CLICK(1), BLOCK(2)));
pos = pos1 - pos; pos = pos1 - pos;
Camera.actualAngle = Camera.targetAngle + phd_atan(pos.z, pos.x); Camera.actualAngle = Camera.targetAngle + phd_atan(pos.z, pos.x);
} }
@ -637,7 +637,7 @@ void CombatCamera(ItemInfo* item)
UpdateCameraElevation(); UpdateCameraElevation();
Camera.targetDistance = SECTOR(1.5f); Camera.targetDistance = BLOCK(1.5f);
int distance = Camera.targetDistance * phd_cos(Camera.actualElevation); int distance = Camera.targetDistance * phd_cos(Camera.actualElevation);
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
@ -955,7 +955,7 @@ void LookCamera(ItemInfo* item)
} }
} }
auto pos2 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, -SECTOR(1))); auto pos2 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, -BLOCK(1)));
auto pos3 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, CLICK(8))); auto pos3 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, CLICK(8)));
int dx = (pos2.x - pos.x) >> 3; int dx = (pos2.x - pos.x) >> 3;
@ -1171,7 +1171,7 @@ void BinocularCamera(ItemInfo* item)
if (!LaserSight) if (!LaserSight)
{ {
if (IsClicked(In::Deselect) || if (IsClicked(In::Deselect) ||
IsClicked(In::DrawWeapon) || IsClicked(In::Draw) ||
IsClicked(In::Look) || IsClicked(In::Look) ||
IsHeld(In::Flare)) IsHeld(In::Flare))
{ {
@ -1216,10 +1216,10 @@ void BinocularCamera(ItemInfo* item)
Camera.pos.z = z; Camera.pos.z = z;
Camera.pos.RoomNumber = probe.RoomNumber; Camera.pos.RoomNumber = probe.RoomNumber;
int l = SECTOR(20.25f) * phd_cos(headXRot); int l = BLOCK(20.25f) * phd_cos(headXRot);
int tx = x + l * phd_sin(item->Pose.Orientation.y + headYRot); int tx = x + l * phd_sin(item->Pose.Orientation.y + headYRot);
int ty = y - SECTOR(20.25f) * phd_sin(headXRot); int ty = y - BLOCK(20.25f) * phd_sin(headXRot);
int tz = z + l * phd_cos(item->Pose.Orientation.y + headYRot); int tz = z + l * phd_cos(item->Pose.Orientation.y + headYRot);
if (Camera.oldType == CameraType::Fixed) if (Camera.oldType == CameraType::Fixed)
@ -1289,7 +1289,10 @@ void BinocularCamera(ItemInfo* item)
void ConfirmCameraTargetPos() void ConfirmCameraTargetPos()
{ {
auto pos = GetJointPosition(LaraItem, LM_TORSO); auto pos = Vector3i(
LaraItem->Pose.Position.x,
LaraItem->Pose.Position.y - (LaraCollision.Setup.Height / 2),
LaraItem->Pose.Position.z);
if (Camera.laraNode != -1) if (Camera.laraNode != -1)
{ {
@ -1529,7 +1532,7 @@ void CalculateCamera()
Camera.item = NULL; Camera.item = NULL;
Camera.targetElevation = 0; Camera.targetElevation = 0;
Camera.targetAngle = 0; Camera.targetAngle = 0;
Camera.targetDistance = SECTOR(1.5f); Camera.targetDistance = BLOCK(1.5f);
Camera.flags = 0; Camera.flags = 0;
Camera.laraNode = -1; Camera.laraNode = -1;
} }
@ -1847,8 +1850,9 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS)) if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS))
ItemPushCamera(&bounds, &item->Pose, rad); ItemPushCamera(&bounds, &item->Pose, rad);
TEN::Renderer::g_Renderer.AddDebugBox(bounds.ToBoundingOrientedBox(item->Pose), TEN::Renderer::g_Renderer.AddDebugBox(
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); bounds.ToBoundingOrientedBox(item->Pose),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
} }
itemList.clear(); // Done itemList.clear(); // Done
@ -1874,8 +1878,9 @@ void ItemsCollideCamera()
if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS)) if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS))
ItemPushCamera(&bounds, &mesh->pos, rad); ItemPushCamera(&bounds, &mesh->pos, rad);
TEN::Renderer::g_Renderer.AddDebugBox(bounds.ToBoundingOrientedBox(mesh->pos), TEN::Renderer::g_Renderer.AddDebugBox(
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); bounds.ToBoundingOrientedBox(mesh->pos),
Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
} }
staticList.clear(); // Done staticList.clear(); // Done
@ -1896,7 +1901,7 @@ void UpdateMikePos(ItemInfo* item)
} }
else else
{ {
int phdPerspective = g_Configuration.Width / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2); int phdPerspective = g_Configuration.ScreenWidth / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2);
Camera.actualAngle = phd_atan(Camera.target.z - Camera.pos.z, Camera.target.x - Camera.pos.x); Camera.actualAngle = phd_atan(Camera.target.z - Camera.pos.z, Camera.target.x - Camera.pos.x);
Camera.mikePos.x = Camera.pos.x + phdPerspective * phd_sin(Camera.actualAngle); Camera.mikePos.x = Camera.pos.x + phdPerspective * phd_sin(Camera.actualAngle);

View file

@ -312,19 +312,18 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
auto origin = Vector3( auto origin = Vector3(
item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)), item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)),
item->Pose.Position.y - (height + CLICK(1)), item->Pose.Position.y - (height + CLICK(1)),
item->Pose.Position.z + (cosHeading * (coll->Setup.Radius)) item->Pose.Position.z + (cosHeading * (coll->Setup.Radius)));
);
auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f); auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f);
auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation(); auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation();
// g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RENDERER_DEBUG_PAGE::DIMENSION_STATS); // g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RendererDebugPage::CollisionStats);
for (auto i : g_Level.Rooms[item->RoomNumber].neighbors) for (auto i : g_Level.Rooms[item->RoomNumber].neighbors)
{ {
if (!g_Level.Rooms[i].Active()) if (!g_Level.Rooms[i].Active())
continue; continue;
short itemNumber = g_Level.Rooms[i].itemNumber; int itemNumber = g_Level.Rooms[i].itemNumber;
while (itemNumber != NO_ITEM) while (itemNumber != NO_ITEM)
{ {
auto* item2 = &g_Level.Items[itemNumber]; auto* item2 = &g_Level.Items[itemNumber];
@ -979,7 +978,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
itemBounds.Extents = itemBounds.Extents - Vector3(BLOCK(1)); itemBounds.Extents = itemBounds.Extents - Vector3(BLOCK(1));
// Draw static bounds. // Draw static bounds.
g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RENDERER_DEBUG_PAGE::DIMENSION_STATS); g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RendererDebugPage::CollisionStats);
// Calculate horizontal item collision bounds according to radius. // Calculate horizontal item collision bounds according to radius.
GameBoundingBox collBox; GameBoundingBox collBox;
@ -1010,7 +1009,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
bool prevHorIntersects = staticBounds.Intersects(prevCollBounds); bool prevHorIntersects = staticBounds.Intersects(prevCollBounds);
// Draw item coll bounds. // Draw item coll bounds.
g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::DIMENSION_STATS); g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
// Decompose static bounds into top/bottom plane vertices. // Decompose static bounds into top/bottom plane vertices.
Vector3 corners[8]; Vector3 corners[8];
@ -1990,17 +1989,19 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll
} }
} }
void TrapCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) void TrapCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{ {
auto* item = &g_Level.Items[itemNumber]; auto& item = g_Level.Items[itemNumber];
if (item->Status == ITEM_ACTIVE) if (item.Status == ITEM_ACTIVE)
{ {
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
return; return;
TestCollision(item, laraItem); TestCollision(&item, playerItem);
}
else if (item.Status != ITEM_INVISIBLE)
{
ObjectCollision(itemNumber, playerItem, coll);
} }
else if (item->Status != ITEM_INVISIBLE)
ObjectCollision(itemNumber, laraItem, coll);
} }

View file

@ -8,7 +8,7 @@ struct ItemInfo;
struct MESH_INFO; struct MESH_INFO;
constexpr auto MAX_COLLIDED_OBJECTS = 1024; constexpr auto MAX_COLLIDED_OBJECTS = 1024;
constexpr auto ITEM_RADIUS_YMAX = SECTOR(3); constexpr auto ITEM_RADIUS_YMAX = BLOCK(3);
constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30.0f; constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30.0f;

View file

@ -74,13 +74,13 @@ void SnapItemToGrid(ItemInfo* item, CollisionInfo* coll)
int FindGridShift(int x, int z) int FindGridShift(int x, int z)
{ {
if ((x / SECTOR(1)) == (z / SECTOR(1))) if ((x / BLOCK(1)) == (z / BLOCK(1)))
return 0; return 0;
if ((z / SECTOR(1)) <= (x / SECTOR(1))) if ((z / BLOCK(1)) <= (x / BLOCK(1)))
return (-1 - (x & WALL_MASK)); return (-1 - (x & WALL_MASK));
else else
return ((SECTOR(1) + 1) - (x & WALL_MASK)); return ((BLOCK(1) + 1) - (x & WALL_MASK));
} }
// Test if the axis-aligned bounding box collides with geometry at all. // Test if the axis-aligned bounding box collides with geometry at all.
@ -114,18 +114,24 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
return collided; return collided;
} }
// Overload used to quickly get point/room collision parameters at a given item's position. // Overload used to quickly get point collision parameters at a given item's position.
CollisionResult GetCollision(ItemInfo* item) CollisionResult GetCollision(const ItemInfo& item)
{ {
auto newRoomNumber = item->RoomNumber; auto newRoomNumber = item.RoomNumber;
auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &newRoomNumber); auto floor = GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &newRoomNumber);
auto probe = GetCollision(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); auto probe = GetCollision(floor, item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z);
probe.RoomNumber = newRoomNumber; probe.RoomNumber = newRoomNumber;
return probe; return probe;
} }
// Overload used to probe point/room collision parameters from a given item's position. // Deprecated.
CollisionResult GetCollision(ItemInfo* item)
{
return GetCollision(*item);
}
// Overload used to probe point collision parameters from a given item's position.
CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down, float right) CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down, float right)
{ {
short tempRoomNumber = item->RoomNumber; short tempRoomNumber = item->RoomNumber;
@ -140,8 +146,8 @@ CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward,
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber); return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
} }
// Overload used to probe point/room collision parameters from a given position. // Overload used to probe point collision parameters from a given position.
CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, float forward, float down, float right) CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right)
{ {
short tempRoomNumber = roomNumber; short tempRoomNumber = roomNumber;
auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y }; auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
@ -151,11 +157,17 @@ CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, f
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber); return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
} }
// Overload used as a universal wrapper across collisional code to replace // Overload used as universal wrapper across collisional code replacing
// triads of roomNumber-GetFloor()-GetFloorHeight() operations. // triads of roomNumber-GetFloor()-GetFloorHeight() calls.
// The advantage is that it does NOT modify the incoming roomNumber argument, // Advantage is that it does NOT modify incoming roomNumber argument,
// instead storing one modified by GetFloor() within the returned CollisionResult struct. // instead storing one modified by GetFloor() within a returned CollisionResult struct.
// This way, no external variables are modified as output arguments. // This way, no external variables are modified as output arguments.
CollisionResult GetCollision(const Vector3i& pos, int roomNumber)
{
return GetCollision(pos.x, pos.y, pos.z, roomNumber);
}
// Deprecated.
CollisionResult GetCollision(int x, int y, int z, short roomNumber) CollisionResult GetCollision(int x, int y, int z, short roomNumber)
{ {
auto room = roomNumber; auto room = roomNumber;
@ -166,9 +178,10 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber)
return result; return result;
} }
CollisionResult GetCollision(const GameVector& point) // NOTE: To be used only when absolutely necessary.
CollisionResult GetCollision(const GameVector& pos)
{ {
return GetCollision(point.x, point.y, point.z, point.RoomNumber); return GetCollision(pos.x, pos.y, pos.z, pos.RoomNumber);
} }
// A reworked legacy GetFloorHeight() function which writes data // A reworked legacy GetFloorHeight() function which writes data
@ -218,10 +231,52 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom)
GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom); GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom);
} }
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom) static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSetup& collSetup, const CollisionResult& pointColl,
const Vector3i& probePos, int realRoomNumber)
{ {
constexpr auto ASPECT_ANGLE_DELTA_MAX = ANGLE(90.0f); constexpr auto ASPECT_ANGLE_DELTA_MAX = ANGLE(90.0f);
auto floorNormal = GetSurfaceNormal(pointColl.FloorTilt, true);
short aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
short aspectAngleDelta = Geometry::GetShortestAngle(collSetup.ForwardAngle, aspectAngle);
if (collSetup.BlockFloorSlopeUp &&
sectorAttribs.FloorSlope &&
sectorAttribs.Floor <= STEPUP_HEIGHT &&
sectorAttribs.Floor >= -STEPUP_HEIGHT &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
sectorAttribs.Floor = MAX_HEIGHT;
}
else if (collSetup.BlockFloorSlopeDown &&
sectorAttribs.FloorSlope &&
sectorAttribs.Floor <= STEPUP_HEIGHT &&
sectorAttribs.Floor >= -STEPUP_HEIGHT &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
sectorAttribs.Floor = MAX_HEIGHT;
}
else if (collSetup.BlockCeilingSlope &&
sectorAttribs.CeilingSlope)
{
sectorAttribs.Floor = MAX_HEIGHT;
}
else if (collSetup.BlockDeathFloorDown &&
sectorAttribs.Floor >= CLICK(0.5f) &&
pointColl.BottomBlock->Flags.Death)
{
sectorAttribs.Floor = MAX_HEIGHT;
}
else if (collSetup.BlockMonkeySwingEdge)
{
auto monkeyPointColl = GetCollision(probePos.x, probePos.y + collSetup.Height, probePos.z, realRoomNumber);
if (!monkeyPointColl.BottomBlock->Flags.Monkeyswing)
sectorAttribs.Floor = MAX_HEIGHT;
}
}
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom)
{
// Player collision has several more precise checks for bridge collisions. // Player collision has several more precise checks for bridge collisions.
// Therefore, we should differentiate these code paths. // Therefore, we should differentiate these code paths.
bool doPlayerCollision = item->IsLara(); bool doPlayerCollision = item->IsLara();
@ -357,7 +412,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
probePos.x = entityPos.x + xFront; probePos.x = entityPos.x + xFront;
probePos.z = entityPos.z + zFront; probePos.z = entityPos.z + zFront;
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats);
collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber); collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber);
@ -405,46 +460,14 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
if (height != NO_HEIGHT) if (height != NO_HEIGHT)
height -= (doPlayerCollision ? entityPos.y : probePos.y); height -= (doPlayerCollision ? entityPos.y : probePos.y);
auto floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); SetSectorAttribs(coll->Front, coll->Setup, collResult, probePos, realRoomNumber);
short aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
short aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle);
if (coll->Setup.BlockFloorSlopeUp &&
coll->Front.FloorSlope &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
coll->Front.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockFloorSlopeDown &&
coll->Front.FloorSlope &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
coll->Front.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockCeilingSlope &&
coll->Front.CeilingSlope)
{
coll->Front.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockDeathFloorDown &&
coll->Front.Floor >= CLICK(0.5f) &&
collResult.BottomBlock->Flags.Death)
{
coll->Front.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockMonkeySwingEdge)
{
auto monkeyProbe = GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, realRoomNumber);
if (!monkeyProbe.BottomBlock->Flags.Monkeyswing)
coll->Front.Floor = MAX_HEIGHT;
}
// TEST 4: MIDDLE-LEFT PROBE // TEST 4: MIDDLE-LEFT PROBE
probePos.x = entityPos.x + xLeft; probePos.x = entityPos.x + xLeft;
probePos.z = entityPos.z + zLeft; probePos.z = entityPos.z + zLeft;
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RENDERER_DEBUG_PAGE::LARA_STATS); g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats);
collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber); collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber);
@ -472,38 +495,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
coll->MiddleLeft.Floor = height; coll->MiddleLeft.Floor = height;
coll->MiddleLeft.Ceiling = ceiling; coll->MiddleLeft.Ceiling = ceiling;
floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); SetSectorAttribs(coll->MiddleLeft, coll->Setup, collResult, probePos, realRoomNumber);
aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle);
if (coll->Setup.BlockFloorSlopeUp &&
coll->MiddleLeft.FloorSlope &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
coll->MiddleLeft.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockFloorSlopeDown &&
coll->MiddleLeft.FloorSlope &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
coll->MiddleLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockCeilingSlope &&
coll->MiddleLeft.CeilingSlope)
{
coll->MiddleLeft.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockDeathFloorDown &&
coll->MiddleLeft.Floor >= CLICK(0.5f) &&
collResult.BottomBlock->Flags.Death)
{
coll->MiddleLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockMonkeySwingEdge &&
!GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing)
{
coll->MiddleLeft.Floor = MAX_HEIGHT;
}
// TEST 5: FRONT-LEFT PROBE // TEST 5: FRONT-LEFT PROBE
@ -533,45 +525,14 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
coll->FrontLeft.Floor = height; coll->FrontLeft.Floor = height;
coll->FrontLeft.Ceiling = ceiling; coll->FrontLeft.Ceiling = ceiling;
floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); SetSectorAttribs(coll->FrontLeft, coll->Setup, collResult, probePos, realRoomNumber);
aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle);
if (coll->Setup.BlockFloorSlopeUp &&
coll->FrontLeft.FloorSlope &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
coll->FrontLeft.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockFloorSlopeDown &&
coll->FrontLeft.FloorSlope &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
coll->FrontLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockCeilingSlope &&
coll->FrontLeft.CeilingSlope)
{
coll->FrontLeft.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockDeathFloorDown &&
coll->FrontLeft.Floor >= CLICK(0.5f) &&
collResult.BottomBlock->Flags.Death)
{
coll->FrontLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockMonkeySwingEdge &&
!GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing)
{
coll->FrontLeft.Floor = MAX_HEIGHT;
}
// TEST 6: MIDDLE-RIGHT PROBE // TEST 6: MIDDLE-RIGHT PROBE
probePos.x = entityPos.x + xRight; probePos.x = entityPos.x + xRight;
probePos.z = entityPos.z + zRight; probePos.z = entityPos.z + zRight;
g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber); collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber);
@ -599,38 +560,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
coll->MiddleRight.Floor = height; coll->MiddleRight.Floor = height;
coll->MiddleRight.Ceiling = ceiling; coll->MiddleRight.Ceiling = ceiling;
floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); SetSectorAttribs(coll->MiddleRight, coll->Setup, collResult, probePos, realRoomNumber);
aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle);
if (coll->Setup.BlockFloorSlopeUp &&
coll->MiddleRight.FloorSlope &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
coll->MiddleRight.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockFloorSlopeDown &&
coll->MiddleRight.FloorSlope &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
coll->MiddleRight.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockCeilingSlope &&
coll->MiddleRight.CeilingSlope)
{
coll->MiddleRight.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockDeathFloorDown &&
coll->MiddleRight.Floor >= CLICK(0.5f) &&
collResult.BottomBlock->Flags.Death)
{
coll->MiddleRight.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockMonkeySwingEdge &&
!GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing)
{
coll->MiddleRight.Floor = MAX_HEIGHT;
}
// TEST 7: FRONT-RIGHT PROBE // TEST 7: FRONT-RIGHT PROBE
@ -660,38 +590,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
coll->FrontRight.Floor = height; coll->FrontRight.Floor = height;
coll->FrontRight.Ceiling = ceiling; coll->FrontRight.Ceiling = ceiling;
floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); SetSectorAttribs(coll->FrontRight, coll->Setup, collResult, probePos, realRoomNumber);
aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal);
aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle);
if (coll->Setup.BlockFloorSlopeUp &&
coll->FrontRight.FloorSlope &&
abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX)
{
coll->FrontRight.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockFloorSlopeDown &&
coll->FrontRight.FloorSlope &&
abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX)
{
coll->FrontRight.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockCeilingSlope &&
coll->FrontRight.CeilingSlope)
{
coll->FrontRight.Floor = MAX_HEIGHT;
}
else if (coll->Setup.BlockDeathFloorDown &&
coll->FrontRight.Floor >= CLICK(0.5f) &&
collResult.BottomBlock->Flags.Death)
{
coll->FrontRight.Floor = STOP_SIZE;
}
else if (coll->Setup.BlockMonkeySwingEdge &&
!GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing)
{
coll->FrontRight.Floor = MAX_HEIGHT;
}
// TEST 8: SOLID STATIC MESHES // TEST 8: SOLID STATIC MESHES
@ -979,7 +878,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
} }
// Debug probe point // Debug probe point
// g_Renderer.AddDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); // g_Renderer.AddDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RendererDebugPage::CollisionStats);
// Determine front floor probe offset. // Determine front floor probe offset.
// It is needed to identify if there is bridge or ceiling split in front. // It is needed to identify if there is bridge or ceiling split in front.
@ -1021,7 +920,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
auto fpZ = eZ + floorProbeOffset * cosForwardAngle; auto fpZ = eZ + floorProbeOffset * cosForwardAngle;
// Debug probe point. // Debug probe point.
// g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); // g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats);
// Get true room number and block, based on derived height // Get true room number and block, based on derived height
room = GetRoom(item->Location, fpX, height, fpZ).roomNumber; room = GetRoom(item->Location, fpX, height, fpZ).roomNumber;
@ -1086,17 +985,17 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance)
auto splitAngle = (useCeilingLedge ? block->CeilingCollision.SplitAngle : block->FloorCollision.SplitAngle); auto splitAngle = (useCeilingLedge ? block->CeilingCollision.SplitAngle : block->FloorCollision.SplitAngle);
// Get horizontal block corner coordinates. // Get horizontal block corner coordinates.
auto fX = floor(eX / SECTOR(1)) * SECTOR(1) - 1; auto fX = floor(eX / BLOCK(1)) * BLOCK(1) - 1;
auto fZ = floor(eZ / SECTOR(1)) * SECTOR(1) - 1; auto fZ = floor(eZ / BLOCK(1)) * BLOCK(1) - 1;
auto cX = fX + SECTOR(1) + 1; auto cX = fX + BLOCK(1) + 1;
auto cZ = fZ + SECTOR(1) + 1; auto cZ = fZ + BLOCK(1) + 1;
// Debug used block // Debug used block
// g_Renderer.AddDebugSphere(Vector3(round(eX / WALL_SIZE) * WALL_SIZE + 512, y, round(eZ / WALL_SIZE) * WALL_SIZE + 512), 16, Vector4(1, 1, 1, 1), RENDERER_DEBUG_PAGE::LARA_STATS); // g_Renderer.AddDebugSphere(Vector3(round(eX / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f), y, round(eZ / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f)), 16, Vector4::One, RendererDebugPage::CollisionStats);
// Get split angle coordinates. // Get split angle coordinates.
auto sX = fX + 1 + SECTOR(0.5f); auto sX = fX + 1 + BLOCK(0.5f);
auto sZ = fZ + 1 + SECTOR(0.5f); auto sZ = fZ + 1 + BLOCK(0.5f);
auto sShiftX = coll->Setup.Radius * sin(splitAngle); auto sShiftX = coll->Setup.Radius * sin(splitAngle);
auto sShiftZ = coll->Setup.Radius * cos(splitAngle); auto sShiftZ = coll->Setup.Radius * cos(splitAngle);
@ -1267,7 +1166,7 @@ void AlterFloorHeight(ItemInfo* item, int height)
short roomNumber = item->RoomNumber; short roomNumber = item->RoomNumber;
FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
FloorInfo* ceiling = GetFloor(item->Pose.Position.x, height + item->Pose.Position.y - SECTOR(1), item->Pose.Position.z, &roomNumber); FloorInfo* ceiling = GetFloor(item->Pose.Position.x, height + item->Pose.Position.y - BLOCK(1), item->Pose.Position.z, &roomNumber);
floor->FloorCollision.Planes[0].z += height; floor->FloorCollision.Planes[0].z += height;
floor->FloorCollision.Planes[1].z += height; floor->FloorCollision.Planes[1].z += height;
@ -1328,8 +1227,8 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
short roomIndex = NO_ROOM; short roomIndex = NO_ROOM;
do do
{ {
int zFloor = (z - room->z) / SECTOR(1); int zFloor = (z - room->z) / BLOCK(1);
int xFloor = (x - room->x) / SECTOR(1); int xFloor = (x - room->x) / BLOCK(1);
if (zFloor <= 0) if (zFloor <= 0)
{ {
@ -1416,8 +1315,8 @@ int GetWaterHeight(int x, int y, int z, short roomNumber)
short adjoiningRoom = NO_ROOM; short adjoiningRoom = NO_ROOM;
do do
{ {
int xBlock = (x - room->x) / SECTOR(1); int xBlock = (x - room->x) / BLOCK(1);
int zBlock = (z - room->z) / SECTOR(1); int zBlock = (z - room->z) / BLOCK(1);
if (zBlock <= 0) if (zBlock <= 0)
{ {

View file

@ -11,7 +11,7 @@ enum RoomEnvFlags;
constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBound. constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBound.
constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound. constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound.
constexpr auto COLLISION_CHECK_DISTANCE = SECTOR(8); constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8);
enum CollisionType enum CollisionType
{ {
@ -126,11 +126,13 @@ struct CollisionInfo
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item); [[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
CollisionResult GetCollision(const ItemInfo& item);
CollisionResult GetCollision(ItemInfo* item); CollisionResult GetCollision(ItemInfo* item);
CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f); CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f); CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f);
CollisionResult GetCollision(const Vector3i& pos, int roomNumber);
CollisionResult GetCollision(int x, int y, int z, short roomNumber); CollisionResult GetCollision(int x, int y, int z, short roomNumber);
CollisionResult GetCollision(const GameVector& point); CollisionResult GetCollision(const GameVector& pos);
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z); CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z);
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false); void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false);

View file

@ -1,10 +1,12 @@
#include "framework.h" #include "framework.h"
#include "Game/collision/floordata.h" #include "Game/collision/floordata.h"
#include "Game/collision/collide_room.h"
#include "Game/items.h" #include "Game/items.h"
#include "Game/room.h" #include "Game/room.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Math/Math.h" #include "Math/Math.h"
#include "Renderer/Renderer11.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Floordata; using namespace TEN::Collision::Floordata;
@ -750,6 +752,10 @@ namespace TEN::Collision::Floordata
void AddBridge(int itemNumber, int x, int z) void AddBridge(int itemNumber, int x, int z)
{ {
const auto& item = g_Level.Items[itemNumber]; const auto& item = g_Level.Items[itemNumber];
if (!Objects.CheckID(item.ObjectNumber))
return;
x += item.Pose.Position.x; x += item.Pose.Position.x;
z += item.Pose.Position.z; z += item.Pose.Position.z;
@ -788,6 +794,10 @@ namespace TEN::Collision::Floordata
void RemoveBridge(int itemNumber, int x, int z) void RemoveBridge(int itemNumber, int x, int z)
{ {
const auto& item = g_Level.Items[itemNumber]; const auto& item = g_Level.Items[itemNumber];
if (!Objects.CheckID(item.ObjectNumber))
return;
x += item.Pose.Position.x; x += item.Pose.Position.x;
z += item.Pose.Position.z; z += item.Pose.Position.z;
@ -862,7 +872,12 @@ namespace TEN::Collision::Floordata
void UpdateBridgeItem(int itemNumber, bool forceRemoval) void UpdateBridgeItem(int itemNumber, bool forceRemoval)
{ {
auto item = &g_Level.Items[itemNumber]; auto item = &g_Level.Items[itemNumber];
if (!Objects[item->ObjectNumber].loaded) return;
if (!Objects.CheckID(item->ObjectNumber))
return;
if (!Objects[item->ObjectNumber].loaded)
return;
// Force removal if object was killed // Force removal if object was killed
if (item->Flags & IFLAG_KILLED) if (item->Flags & IFLAG_KILLED)
@ -924,4 +939,103 @@ namespace TEN::Collision::Floordata
return false; return false;
} }
static void DrawSectorFlagLabel(const Vector3& pos, const std::string& string, const Vector4& color, float verticalOffset)
{
constexpr auto LABEL_SCALE = 0.8f;
constexpr auto HALF_BLOCK = BLOCK(0.5f);
// Get 2D label position.
auto labelPos = pos + Vector3(HALF_BLOCK, 0.0f, HALF_BLOCK);
auto labelPos2D = g_Renderer.Get2DPosition(labelPos);
// Draw label.
if (labelPos2D.has_value())
{
*labelPos2D += Vector2(0.0f, verticalOffset);
g_Renderer.AddDebugString(string, *labelPos2D, color, LABEL_SCALE, 0, RendererDebugPage::CollisionStats);
}
}
void DrawNearbySectorFlags(const ItemInfo& item)
{
constexpr auto DRAW_RANGE = BLOCK(3);
constexpr auto STRING_SPACING = -20.0f;
constexpr auto STOPPER_COLOR = Vector4(1.0f, 0.4f, 0.4f, 1.0f);
constexpr auto DEATH_COLOR = Vector4(0.4f, 1.0f, 0.4f, 1.0f);
constexpr auto MONKEY_SWING_COLOR = Vector4(1.0f, 0.4f, 0.4f, 1.0f);
constexpr auto BEETLE_MINECART_RIGHT_COLOR = Vector4(0.4f, 0.4f, 1.0f, 1.0f);
constexpr auto ACTIVATOR_MINECART_LEFT_COLOR = Vector4(1.0f, 0.4f, 1.0f, 1.0f);
constexpr auto MINECART_STOP_COLOR = Vector4(0.4f, 1.0f, 1.0f, 1.0f);
// Only check sectors in player vicinity.
const auto& room = g_Level.Rooms[item.RoomNumber];
int minX = std::max(item.Pose.Position.x - DRAW_RANGE, room.x) / BLOCK(1);
int maxX = std::min(item.Pose.Position.x + DRAW_RANGE, room.x + (room.xSize * BLOCK(1))) / BLOCK(1);
int minZ = std::max(item.Pose.Position.z - DRAW_RANGE, room.z) / BLOCK(1);
int maxZ = std::min(item.Pose.Position.z + DRAW_RANGE, room.z + (room.zSize * BLOCK(1))) / BLOCK(1);
auto pointColl = GetCollision(item);
auto pos = item.Pose.Position.ToVector3();
// Draw sector flag labels.
for (int x = minX; x < maxX; x++)
{
for (int z = minZ; z < maxZ; z++)
{
pos.x = BLOCK(x);
pos.z = BLOCK(z);
pointColl = GetCollision(pos, item.RoomNumber);
pos.y = pointColl.Position.Floor;
float verticalOffset = STRING_SPACING;
// Stopper
if (pointColl.Block->Stopper)
{
DrawSectorFlagLabel(pos, "Stopper", STOPPER_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Death
if (pointColl.Block->Flags.Death)
{
DrawSectorFlagLabel(pos, "Death", DEATH_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Monkey Swing
if (pointColl.Block->Flags.Monkeyswing)
{
DrawSectorFlagLabel(pos, "Monkey Swing", MONKEY_SWING_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Beetle / Minecart Right
if (pointColl.Block->Flags.MarkBeetle)
{
auto labelString = std::string("Beetle") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Right" : "");
DrawSectorFlagLabel(pos, labelString, BEETLE_MINECART_RIGHT_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Activator / Minecart Left
if (pointColl.Block->Flags.MarkTriggerer)
{
auto labelString = std::string("Activator") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Left" : "");
DrawSectorFlagLabel(pos, labelString, ACTIVATOR_MINECART_LEFT_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
// Minecart Stop
if (pointColl.Block->Flags.MinecartStop())
{
DrawSectorFlagLabel(pos, "Minecart Stop", MINECART_STOP_COLOR, verticalOffset);
verticalOffset += STRING_SPACING;
}
}
}
}
} }

View file

@ -189,4 +189,6 @@ namespace TEN::Collision::Floordata
void UpdateBridgeItem(int itemNumber, bool forceRemoval = false); void UpdateBridgeItem(int itemNumber, bool forceRemoval = false);
bool TestMaterial(MaterialType refMaterial, const std::vector<MaterialType>& materialList); bool TestMaterial(MaterialType refMaterial, const std::vector<MaterialType>& materialList);
void DrawNearbySectorFlags(const ItemInfo& item);
} }

View file

@ -19,9 +19,7 @@ int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local)
return 0; return 0;
BoundingSphere spheres[MAX_SPHERES]; BoundingSphere spheres[MAX_SPHERES];
short itemNumber = (item - g_Level.Items.data()); int num = g_Renderer.GetSpheres(item->Index, spheres, worldSpace, local);
int num = g_Renderer.GetSpheres(itemNumber, spheres, worldSpace, local);
for (int i = 0; i < MAX_SPHERES; i++) for (int i = 0; i < MAX_SPHERES; i++)
{ {

View file

@ -24,10 +24,10 @@
using namespace TEN::Effects::Smoke; using namespace TEN::Effects::Smoke;
constexpr auto ESCAPE_DIST = SECTOR(5); constexpr auto ESCAPE_DIST = BLOCK(5);
constexpr auto STALK_DIST = SECTOR(3); constexpr auto STALK_DIST = BLOCK(3);
constexpr auto REACHED_GOAL_RADIUS = 640; constexpr auto REACHED_GOAL_RADIUS = 640;
constexpr auto ATTACK_RANGE = SQUARE(SECTOR(3)); constexpr auto ATTACK_RANGE = SQUARE(BLOCK(3));
constexpr auto ESCAPE_CHANCE = 0x800; constexpr auto ESCAPE_CHANCE = 0x800;
constexpr auto RECOVER_CHANCE = 0x100; constexpr auto RECOVER_CHANCE = 0x100;
constexpr auto BIFF_AVOID_TURN = ANGLE(11.25f); constexpr auto BIFF_AVOID_TURN = ANGLE(11.25f);
@ -59,14 +59,14 @@ void DrawBox(int boxIndex, Vector3 color)
float z = ((float)currBox.top + (float)(currBox.bottom - currBox.top) / 2.0f) * 1024.0f; float z = ((float)currBox.top + (float)(currBox.bottom - currBox.top) / 2.0f) * 1024.0f;
auto center = Vector3(z, y, x); auto center = Vector3(z, y, x);
auto corner = Vector3(currBox.bottom * SECTOR(1), currBox.height + CLICK(1), currBox.right * SECTOR(1)); auto corner = Vector3(currBox.bottom * BLOCK(1), currBox.height + CLICK(1), currBox.right * BLOCK(1));
auto extents = (corner - center) * 0.9f; auto extents = (corner - center) * 0.9f;
auto dBox = BoundingOrientedBox(center, extents, Vector4::UnitY); auto dBox = BoundingOrientedBox(center, extents, Vector4::UnitY);
for (int i = 0; i <= 10; i++) for (int i = 0; i <= 10; i++)
{ {
dBox.Extents = extents + Vector3(i); dBox.Extents = extents + Vector3(i);
TEN::Renderer::g_Renderer.AddDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RENDERER_DEBUG_PAGE::LOGIC_STATS); TEN::Renderer::g_Renderer.AddDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RendererDebugPage::PathfindingStats);
} }
} }
@ -75,11 +75,16 @@ void DrawNearbyPathfinding(int boxIndex)
if (boxIndex == NO_BOX) if (boxIndex == NO_BOX)
return; return;
DrawBox(boxIndex, Vector3(0, 1, 1));
auto& currBox = g_Level.Boxes[boxIndex]; auto& currBox = g_Level.Boxes[boxIndex];
auto index = currBox.overlapIndex; auto index = currBox.overlapIndex;
// Grey flag box.
auto currentBoxColor = Vector3(0.0f, 1.0f, 1.0f);
if (currBox.flags & BLOCKABLE)
currentBoxColor = (currBox.flags & BLOCKED) ? Vector3(1.0f, 0.0f, 0.0f) : Vector3(0.0f, 1.0f, 0.0f);
DrawBox(boxIndex, currentBoxColor);
while (true) while (true)
{ {
if (index >= g_Level.Overlaps.size()) if (index >= g_Level.Overlaps.size())
@ -287,10 +292,10 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
boxHeight - height > LOT->Step || boxHeight - height > LOT->Step ||
boxHeight - height < LOT->Drop)) boxHeight - height < LOT->Drop))
{ {
xPos = item->Pose.Position.x / SECTOR(1); xPos = item->Pose.Position.x / BLOCK(1);
zPos = item->Pose.Position.z / SECTOR(1); zPos = item->Pose.Position.z / BLOCK(1);
shiftX = prevPos.x / SECTOR(1); shiftX = prevPos.x / BLOCK(1);
shiftZ = prevPos.z / SECTOR(1); shiftZ = prevPos.z / BLOCK(1);
if (xPos < shiftX) if (xPos < shiftX)
item->Pose.Position.x = prevPos.x & (~WALL_MASK); item->Pose.Position.x = prevPos.x & (~WALL_MASK);
@ -346,23 +351,23 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
shiftX = radius - xPos; shiftX = radius - xPos;
} }
} }
else if (xPos > SECTOR(1) - radius) else if (xPos > BLOCK(1) - radius)
{ {
if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT))
shiftX = SECTOR(1) - radius - xPos; shiftX = BLOCK(1) - radius - xPos;
else if (!shiftZ && BadFloor(x + radius, y, z - radius, height, nextHeight, roomNumber, LOT)) else if (!shiftZ && BadFloor(x + radius, y, z - radius, height, nextHeight, roomNumber, LOT))
{ {
if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f)) if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f))
shiftZ = radius - zPos; shiftZ = radius - zPos;
else else
shiftX = SECTOR(1) - radius - xPos; shiftX = BLOCK(1) - radius - xPos;
} }
} }
} }
else if (zPos > SECTOR(1) - radius) else if (zPos > BLOCK(1) - radius)
{ {
if (BadFloor(x, y, z + radius, height, nextHeight, roomNumber, LOT)) if (BadFloor(x, y, z + radius, height, nextHeight, roomNumber, LOT))
shiftZ = SECTOR(1) - radius - zPos; shiftZ = BLOCK(1) - radius - zPos;
if (xPos < radius) if (xPos < radius)
{ {
@ -373,19 +378,19 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f)) if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f))
shiftX = radius - xPos; shiftX = radius - xPos;
else else
shiftZ = SECTOR(1) - radius - zPos; shiftZ = BLOCK(1) - radius - zPos;
} }
} }
else if (xPos > SECTOR(1) - radius) else if (xPos > BLOCK(1) - radius)
{ {
if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT))
shiftX = SECTOR(1) - radius - xPos; shiftX = BLOCK(1) - radius - xPos;
else if (!shiftZ && BadFloor(x + radius, y, z + radius, height, nextHeight, roomNumber, LOT)) else if (!shiftZ && BadFloor(x + radius, y, z + radius, height, nextHeight, roomNumber, LOT))
{ {
if (item->Pose.Orientation.y > -ANGLE(135.0f) && item->Pose.Orientation.y < ANGLE(45.0f)) if (item->Pose.Orientation.y > -ANGLE(135.0f) && item->Pose.Orientation.y < ANGLE(45.0f))
shiftX = SECTOR(1) - radius - xPos; shiftX = BLOCK(1) - radius - xPos;
else else
shiftZ = SECTOR(1) - radius - zPos; shiftZ = BLOCK(1) - radius - zPos;
} }
} }
} }
@ -394,10 +399,10 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt)
if (BadFloor(x - radius, y, z, height, nextHeight, roomNumber, LOT)) if (BadFloor(x - radius, y, z, height, nextHeight, roomNumber, LOT))
shiftX = radius - xPos; shiftX = radius - xPos;
} }
else if (xPos > SECTOR(1) - radius) else if (xPos > BLOCK(1) - radius)
{ {
if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT))
shiftX = SECTOR(1) - radius - xPos; shiftX = BLOCK(1) - radius - xPos;
} }
item->Pose.Position.x += shiftX; item->Pose.Position.x += shiftX;
@ -566,7 +571,7 @@ void CreatureKill(ItemInfo* creatureItem, int creatureAnimNumber, int playerAnim
playerItem.Animation.Velocity = Vector3::Zero; playerItem.Animation.Velocity = Vector3::Zero;
if (creatureItem->RoomNumber != playerItem.RoomNumber) if (creatureItem->RoomNumber != playerItem.RoomNumber)
ItemNewRoom(player.ItemNumber, creatureItem->RoomNumber); ItemNewRoom(playerItem.Index, creatureItem->RoomNumber);
AnimateItem(&playerItem); AnimateItem(&playerItem);
@ -788,39 +793,53 @@ void CreatureHealth(ItemInfo* item)
} }
} }
void CreatureDie(short itemNumber, bool explode) void CreatureDie(int itemNumber, bool doExplosion)
{ {
auto* item = &g_Level.Items[itemNumber]; int flags = 0;
auto* object = &Objects[item->ObjectNumber]; if (doExplosion)
item->HitPoints = NOT_TARGETABLE;
item->Collidable = false;
if (explode)
{ {
switch (object->hitEffect) const auto& item = g_Level.Items[itemNumber];
const auto& object = Objects[item.ObjectNumber];
switch (object.hitEffect)
{ {
case HitEffect::Blood: case HitEffect::Blood:
ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_GIBS); flags |= BODY_DO_EXPLOSION | BODY_GIBS;
break; break;
case HitEffect::Smoke: case HitEffect::Smoke:
ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_NO_BOUNCE); flags |= BODY_DO_EXPLOSION | BODY_NO_BOUNCE;
break; break;
default: default:
ExplodingDeath(itemNumber, BODY_EXPLODE); flags |= BODY_DO_EXPLOSION;
break; break;
} }
}
CreatureDie(itemNumber, doExplosion, flags);
}
void CreatureDie(int itemNumber, bool doExplosion, int flags)
{
auto& item = g_Level.Items[itemNumber];
item.HitPoints = NOT_TARGETABLE;
item.Collidable = false;
if (doExplosion)
{
ExplodingDeath(itemNumber, flags);
KillItem(itemNumber); KillItem(itemNumber);
} }
else else
{
RemoveActiveItem(itemNumber); RemoveActiveItem(itemNumber);
}
DisableEntityAI(itemNumber); DisableEntityAI(itemNumber);
item->Flags |= IFLAG_KILLED | IFLAG_INVISIBLE; item.Flags |= IFLAG_KILLED | IFLAG_INVISIBLE;
DropPickups(item); DropPickups(&item);
} }
bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT) bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT)
@ -938,8 +957,8 @@ void TargetBox(LOTInfo* LOT, int boxNumber)
auto* box = &g_Level.Boxes[boxNumber]; auto* box = &g_Level.Boxes[boxNumber];
// Maximize target precision. DO NOT change bracket precedence! // Maximize target precision. DO NOT change bracket precedence!
LOT->Target.x = (int)((box->top * SECTOR(1)) + (float)GetRandomControl() * (((float)(box->bottom - box->top) - 1.0f) / 32.0f) + CLICK(2.0f)); LOT->Target.x = (int)((box->top * BLOCK(1)) + (float)GetRandomControl() * (((float)(box->bottom - box->top) - 1.0f) / 32.0f) + CLICK(2.0f));
LOT->Target.z = (int)((box->left * SECTOR(1)) + (float)GetRandomControl() * (((float)(box->right - box->left) - 1.0f) / 32.0f) + CLICK(2.0f)); LOT->Target.z = (int)((box->left * BLOCK(1)) + (float)GetRandomControl() * (((float)(box->right - box->left) - 1.0f) / 32.0f) + CLICK(2.0f));
LOT->RequiredBox = boxNumber; LOT->RequiredBox = boxNumber;
if (LOT->Fly == NO_FLYING) if (LOT->Fly == NO_FLYING)
@ -1116,10 +1135,10 @@ bool StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber)
return false; return false;
auto* box = &g_Level.Boxes[boxNumber]; auto* box = &g_Level.Boxes[boxNumber];
int xRange = STALK_DIST + ((box->bottom - box->top) * SECTOR(1)); int xRange = STALK_DIST + ((box->bottom - box->top) * BLOCK(1));
int zRange = STALK_DIST + ((box->right - box->left) * SECTOR(1)); int zRange = STALK_DIST + ((box->right - box->left) * BLOCK(1));
int x = (box->top + box->bottom) * SECTOR(1) / 2 - enemy->Pose.Position.x; int x = (box->top + box->bottom) * BLOCK(1) / 2 - enemy->Pose.Position.x;
int z = (box->left + box->right) * SECTOR(1) / 2 - enemy->Pose.Position.z; int z = (box->left + box->right) * BLOCK(1) / 2 - enemy->Pose.Position.z;
if (x > xRange || x < -xRange || z > zRange || z < -zRange) if (x > xRange || x < -xRange || z > zRange || z < -zRange)
return false; return false;
@ -1183,8 +1202,8 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift)
auto* item = &g_Level.Items[itemNumber]; auto* item = &g_Level.Items[itemNumber];
auto* creature = GetCreatureInfo(item); auto* creature = GetCreatureInfo(item);
int xBlock = item->Pose.Position.x / SECTOR(1); int xBlock = item->Pose.Position.x / BLOCK(1);
int zBlock = item->Pose.Position.z / SECTOR(1); int zBlock = item->Pose.Position.z / BLOCK(1);
int y = item->Pose.Position.y; int y = item->Pose.Position.y;
short roomNumber = item->RoomNumber; short roomNumber = item->RoomNumber;
@ -1224,8 +1243,8 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift)
} }
// Jump // Jump
int newXblock = item->Pose.Position.x / SECTOR(1); int newXblock = item->Pose.Position.x / BLOCK(1);
int newZblock = item->Pose.Position.z / SECTOR(1); int newZblock = item->Pose.Position.z / BLOCK(1);
if (zBlock == newZblock) if (zBlock == newZblock)
{ {
@ -1234,12 +1253,12 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift)
if (xBlock < newXblock) if (xBlock < newXblock)
{ {
item->Pose.Position.x = (newXblock * SECTOR(1)) - shift; item->Pose.Position.x = (newXblock * BLOCK(1)) - shift;
item->Pose.Orientation.y = ANGLE(90.0f); item->Pose.Orientation.y = ANGLE(90.0f);
} }
else else
{ {
item->Pose.Position.x = (xBlock * SECTOR(1)) + shift; item->Pose.Position.x = (xBlock * BLOCK(1)) + shift;
item->Pose.Orientation.y = -ANGLE(90.0f); item->Pose.Orientation.y = -ANGLE(90.0f);
} }
} }
@ -1247,12 +1266,12 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift)
{ {
if (zBlock < newZblock) if (zBlock < newZblock)
{ {
item->Pose.Position.z = (newZblock * SECTOR(1)) - shift; item->Pose.Position.z = (newZblock * BLOCK(1)) - shift;
item->Pose.Orientation.y = 0; item->Pose.Orientation.y = 0;
} }
else else
{ {
item->Pose.Position.z = (zBlock * SECTOR(1)) + shift; item->Pose.Position.z = (zBlock * BLOCK(1)) + shift;
item->Pose.Orientation.y = -ANGLE(180.0f); item->Pose.Orientation.y = -ANGLE(180.0f);
} }
} }
@ -1550,8 +1569,8 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
vector.y = item->Pose.Position.y - enemy->Pose.Position.y; vector.y = item->Pose.Position.y - enemy->Pose.Position.y;
short angle = phd_atan(vector.z, vector.x); short angle = phd_atan(vector.z, vector.x);
if (vector.x > SECTOR(31.25f) || vector.x < -SECTOR(31.25f) || if (vector.x > BLOCK(31.25f) || vector.x < -BLOCK(31.25f) ||
vector.z > SECTOR(31.25f) || vector.z < -SECTOR(31.25f)) vector.z > BLOCK(31.25f) || vector.z < -BLOCK(31.25f))
{ {
AI->distance = INT_MAX; AI->distance = INT_MAX;
AI->verticalDistance = INT_MAX; AI->verticalDistance = INT_MAX;
@ -1809,7 +1828,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
case MoodType::Stalk: case MoodType::Stalk:
if (creature->Alerted && AI->zoneNumber != AI->enemyZone) if (creature->Alerted && AI->zoneNumber != AI->enemyZone)
{ {
if (AI->distance > SECTOR(3)) if (AI->distance > BLOCK(3))
creature->Mood = MoodType::Stalk; creature->Mood = MoodType::Stalk;
else else
creature->Mood = MoodType::Bored; creature->Mood = MoodType::Bored;
@ -1830,7 +1849,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent)
(GetRandomControl() < ESCAPE_CHANCE || (GetRandomControl() < ESCAPE_CHANCE ||
AI->zoneNumber != AI->enemyZone)) AI->zoneNumber != AI->enemyZone))
creature->Mood = MoodType::Stalk; creature->Mood = MoodType::Stalk;
else if (AI->zoneNumber != AI->enemyZone && AI->distance > SECTOR(6)) else if (AI->zoneNumber != AI->enemyZone && AI->distance > BLOCK(6))
creature->Mood = MoodType::Bored; creature->Mood = MoodType::Bored;
break; break;
@ -1872,10 +1891,10 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
auto* box = &g_Level.Boxes[boxNumber]; auto* box = &g_Level.Boxes[boxNumber];
int boxLeft = ((int)box->left * SECTOR(1)); int boxLeft = ((int)box->left * BLOCK(1));
int boxRight = ((int)box->right * SECTOR(1)) - 1; int boxRight = ((int)box->right * BLOCK(1)) - 1;
int boxTop = ((int)box->top * SECTOR(1)); int boxTop = ((int)box->top * BLOCK(1));
int boxBottom = ((int)box->bottom * SECTOR(1)) - 1; int boxBottom = ((int)box->bottom * BLOCK(1)) - 1;
int left = boxLeft; int left = boxLeft;
int right = boxRight; int right = boxRight;
int top = boxTop; int top = boxTop;
@ -1888,26 +1907,26 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT)
if (LOT->Fly != NO_FLYING) if (LOT->Fly != NO_FLYING)
{ {
if (target->y > box->height - SECTOR(1)) if (target->y > box->height - BLOCK(1))
target->y = box->height - SECTOR(1); target->y = box->height - BLOCK(1);
} }
else if(target->y > box->height) else if(target->y > box->height)
target->y = box->height; target->y = box->height;
boxLeft = ((int)box->left * SECTOR(1)); boxLeft = ((int)box->left * BLOCK(1));
boxRight = ((int)box->right * SECTOR(1)) - 1; boxRight = ((int)box->right * BLOCK(1)) - 1;
boxTop = ((int)box->top * SECTOR(1)); boxTop = ((int)box->top * BLOCK(1));
boxBottom = ((int)box->bottom * SECTOR(1)) - 1; boxBottom = ((int)box->bottom * BLOCK(1)) - 1;
if (item->Pose.Position.z >= boxLeft && if (item->Pose.Position.z >= boxLeft &&
item->Pose.Position.z <= boxRight && item->Pose.Position.z <= boxRight &&
item->Pose.Position.x >= boxTop && item->Pose.Position.x >= boxTop &&
item->Pose.Position.x <= boxBottom) item->Pose.Position.x <= boxBottom)
{ {
left = ((int)box->left * SECTOR(1)); left = ((int)box->left * BLOCK(1));
right = ((int)box->right * SECTOR(1)) - 1; right = ((int)box->right * BLOCK(1)) - 1;
top = ((int)box->top * SECTOR(1)); top = ((int)box->top * BLOCK(1));
bottom = ((int)box->bottom * SECTOR(1)) - 1; bottom = ((int)box->bottom * BLOCK(1)) - 1;
} }
else else
{ {
@ -2102,8 +2121,8 @@ void AdjustStopperFlag(ItemInfo* item, int direction)
auto* floor = GetSector(room, x - room->x, z - room->z); auto* floor = GetSector(room, x - room->x, z - room->z);
floor->Stopper = !floor->Stopper; floor->Stopper = !floor->Stopper;
x = item->Pose.Position.x + SECTOR(1) * phd_sin(direction); x = item->Pose.Position.x + BLOCK(1) * phd_sin(direction);
z = item->Pose.Position.z + SECTOR(1) * phd_cos(direction); z = item->Pose.Position.z + BLOCK(1) * phd_cos(direction);
room = &g_Level.Rooms[GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).RoomNumber]; room = &g_Level.Rooms[GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).RoomNumber];
floor = GetSector(room, x - room->x, z - room->z); floor = GetSector(room, x - room->x, z - room->z);
@ -2124,7 +2143,7 @@ void InitializeItemBoxData()
{ {
for (const auto& mesh : room.mesh) for (const auto& mesh : room.mesh)
{ {
long index = ((mesh.pos.Position.z - room.z) / SECTOR(1)) + room.zSize * ((mesh.pos.Position.x - room.x) / SECTOR(1)); long index = ((mesh.pos.Position.z - room.z) / BLOCK(1)) + room.zSize * ((mesh.pos.Position.x - room.x) / BLOCK(1));
if (index > room.floor.size()) if (index > room.floor.size())
continue; continue;

View file

@ -98,7 +98,8 @@ void CreatureFloat(short itemNumber);
void CreatureJoint(ItemInfo* item, short joint, short required, short maxAngle = ANGLE(70.0f)); void CreatureJoint(ItemInfo* item, short joint, short required, short maxAngle = ANGLE(70.0f));
void CreatureTilt(ItemInfo* item, short angle); void CreatureTilt(ItemInfo* item, short angle);
short CreatureTurn(ItemInfo* item, short maxTurn); short CreatureTurn(ItemInfo* item, short maxTurn);
void CreatureDie(short itemNumber, bool explode); void CreatureDie(int itemNumber, bool doExplosion);
void CreatureDie(int itemNumber, bool doExplosion, int flags);
bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT); bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT);
int CreatureCreature(short itemNumber); int CreatureCreature(short itemNumber);
bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber); bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber);

View file

@ -218,7 +218,6 @@ GameStatus ControlPhase(int numFrames)
UpdateSparkParticles(); UpdateSparkParticles();
UpdateSmokeParticles(); UpdateSmokeParticles();
UpdateSimpleParticles(); UpdateSimpleParticles();
UpdateDrips();
UpdateExplosionParticles(); UpdateExplosionParticles();
UpdateShockwaves(); UpdateShockwaves();
UpdateBeetleSwarm(); UpdateBeetleSwarm();
@ -305,16 +304,12 @@ GameStatus DoLevel(int levelIndex, bool loadGame)
InitializeScripting(levelIndex, loadGame); InitializeScripting(levelIndex, loadGame);
InitializeNodeScripts(); InitializeNodeScripts();
// Initialize menu and inventory state.
g_Gui.Initialize();
// Initialize game variables and optionally load game. // Initialize game variables and optionally load game.
InitializeOrLoadGame(loadGame); InitializeOrLoadGame(loadGame);
// Prepare title menu, if necessary.
if (isTitle)
{
g_Gui.SetMenuToDisplay(Menu::Title);
g_Gui.SetSelectedOption(0);
}
// DoGameLoop() returns only when level has ended. // DoGameLoop() returns only when level has ended.
return DoGameLoop(levelIndex); return DoGameLoop(levelIndex);
} }
@ -457,8 +452,8 @@ void InitializeScripting(int levelIndex, bool loadGame)
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags) g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{ {
g_Renderer.AddString( g_Renderer.AddString(
float(x) / float(g_Configuration.Width) * SCREEN_SPACE_RES.x, float(x) / float(g_Configuration.ScreenWidth) * SCREEN_SPACE_RES.x,
float(y) / float(g_Configuration.Height) * SCREEN_SPACE_RES.y, float(y) / float(g_Configuration.ScreenHeight) * SCREEN_SPACE_RES.y,
key.c_str(), col, flags); key.c_str(), col, flags);
}); });
} }
@ -638,7 +633,7 @@ GameStatus HandleMenuCalls(bool isTitle)
if (g_Gui.CallPause()) if (g_Gui.CallPause())
result = GameStatus::ExitToTitle; result = GameStatus::ExitToTitle;
} }
else if ((IsClicked(In::Option) || g_Gui.GetEnterInventory() != NO_ITEM) && else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_ITEM) &&
LaraItem->HitPoints > 0 && !BinocularOn) LaraItem->HitPoints > 0 && !BinocularOn)
{ {
if (g_Gui.CallInventory(LaraItem, true)) if (g_Gui.CallInventory(LaraItem, true))

View file

@ -315,11 +315,11 @@ void FloorShake(ItemInfo* item)
int y = abs(item->Pose.Position.y - Camera.pos.y); int y = abs(item->Pose.Position.y - Camera.pos.y);
int z = abs(item->Pose.Position.z - Camera.pos.z); int z = abs(item->Pose.Position.z - Camera.pos.z);
if (x < SECTOR(16) && if (x < BLOCK(16) &&
y < SECTOR(16) && y < BLOCK(16) &&
z < SECTOR(16)) z < BLOCK(16))
{ {
Camera.bounce = 66 * ((pow(x, 2) + pow(y, 2) + pow(z, 2)) / CLICK(1) - pow(SECTOR(1), 2)) / pow(SECTOR(1), 2); Camera.bounce = 66 * ((pow(x, 2) + pow(y, 2) + pow(z, 2)) / CLICK(1) - pow(BLOCK(1), 2)) / pow(BLOCK(1), 2);
} }
} }

View file

@ -606,7 +606,7 @@ int xLOS(GameVector* origin, GameVector* target)
break; break;
} }
x -= SECTOR(1); x -= BLOCK(1);
y -= dy; y -= dy;
z -= dz; z -= dz;
} }
@ -656,7 +656,7 @@ int xLOS(GameVector* origin, GameVector* target)
break; break;
} }
x += SECTOR(1); x += BLOCK(1);
y += dy; y += dy;
z += dz; z += dz;
} }
@ -726,7 +726,7 @@ int zLOS(GameVector* origin, GameVector* target)
break; break;
} }
z -= SECTOR(1); z -= BLOCK(1);
x -= dx; x -= dx;
y -= dy; y -= dy;
} }
@ -776,7 +776,7 @@ int zLOS(GameVector* origin, GameVector* target)
break; break;
} }
z += SECTOR(1); z += BLOCK(1);
x += dx; x += dx;
y += dy; y += dy;
} }

View file

@ -117,16 +117,16 @@ void InitializeSlot(short itemNumber, bool makeTarget)
// Can fly. // Can fly.
case LotType::Flyer: case LotType::Flyer:
creature->LOT.Step = SECTOR(20); creature->LOT.Step = BLOCK(20);
creature->LOT.Drop = -SECTOR(20); creature->LOT.Drop = -BLOCK(20);
creature->LOT.Fly = DEFAULT_FLY_UPDOWN_SPEED; creature->LOT.Fly = DEFAULT_FLY_UPDOWN_SPEED;
creature->LOT.Zone = ZoneType::Flyer; creature->LOT.Zone = ZoneType::Flyer;
break; break;
// Can swim. // Can swim.
case LotType::Water: case LotType::Water:
creature->LOT.Step = SECTOR(20); creature->LOT.Step = BLOCK(20);
creature->LOT.Drop = -SECTOR(20); creature->LOT.Drop = -BLOCK(20);
creature->LOT.Zone = ZoneType::Water; creature->LOT.Zone = ZoneType::Water;
if (item->ObjectNumber == ID_CROCODILE) if (item->ObjectNumber == ID_CROCODILE)
@ -197,7 +197,7 @@ void InitializeSlot(short itemNumber, bool makeTarget)
} }
ClearLOT(&creature->LOT); ClearLOT(&creature->LOT);
if (itemNumber != Lara.ItemNumber) if (itemNumber != LaraItem->Index)
CreateZone(item); CreateZone(item);
SlotsUsed++; SlotsUsed++;

View file

@ -30,7 +30,7 @@ namespace TEN::Control::Volumes
if (roomNumber == Camera.pos.RoomNumber) if (roomNumber == Camera.pos.RoomNumber)
{ {
g_Renderer.AddDebugBox(volume.Box, g_Renderer.AddDebugBox(volume.Box,
Vector4(color, 0.0f, color, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats);
} }
return volume.Box.Intersects(box); return volume.Box.Intersects(box);
@ -38,7 +38,7 @@ namespace TEN::Control::Volumes
if (roomNumber == Camera.pos.RoomNumber) if (roomNumber == Camera.pos.RoomNumber)
{ {
g_Renderer.AddDebugSphere(volume.Sphere.Center, volume.Sphere.Radius, g_Renderer.AddDebugSphere(volume.Sphere.Center, volume.Sphere.Radius,
Vector4(color, 0.0f, color, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats);
} }
return volume.Sphere.Intersects(box); return volume.Sphere.Intersects(box);
@ -171,7 +171,7 @@ namespace TEN::Control::Volumes
auto box = (coll != nullptr) ? auto box = (coll != nullptr) ?
ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose); ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
g_Renderer.AddDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); g_Renderer.AddDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);
if (item.IsLara() || item.Index == Lara.Context.Vehicle) if (item.IsLara() || item.Index == Lara.Context.Vehicle)
{ {

View file

@ -24,7 +24,7 @@ bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits)
if (1 << node & item->MeshBits.ToPackedBits()) if (1 << node & item->MeshBits.ToPackedBits())
{ {
int number = bits; int number = bits;
if (number == BODY_EXPLODE) if (number == BODY_DO_EXPLOSION)
number = -64; number = -64;
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity); GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);

View file

@ -1146,7 +1146,7 @@ void TriggerWaterfallMist(const ItemInfo& item)
if (item.TriggerFlags != 0) if (item.TriggerFlags != 0)
{ {
size = item.TriggerFlags % 100; size = item.TriggerFlags % 100;
width = std::clamp(int(round(item.TriggerFlags / 100) * 100) / 2, 0, SECTOR(8)); width = std::clamp(int(round(item.TriggerFlags / 100) * 100) / 2, 0, BLOCK(8));
} }
float cos = phd_cos(angle); float cos = phd_cos(angle);

View file

@ -157,8 +157,8 @@ struct Particle
BLEND_MODES blendMode; BLEND_MODES blendMode;
unsigned char extras; unsigned char extras;
signed char dynamic; signed char dynamic;
unsigned char fxObj; int fxObj;
unsigned char roomNumber; int roomNumber;
unsigned char nodeNumber; // ParticleNodeOffsetIDs enum. unsigned char nodeNumber; // ParticleNodeOffsetIDs enum.
}; };
@ -211,9 +211,10 @@ extern FX_INFO EffectList[NUM_EFFECTS];
template <typename TEffect> template <typename TEffect>
TEffect& GetNewEffect(std::vector<TEffect>& effects, unsigned int countMax) TEffect& GetNewEffect(std::vector<TEffect>& effects, unsigned int countMax)
{ {
assertion(effects.size() <= countMax, "Too many particle effects.");
// Add and return new effect. // Add and return new effect.
assert(effects.size() <= countMax); if (effects.size() < countMax)
if (effects.size() != countMax)
return effects.emplace_back(); return effects.emplace_back();
TEffect* effectPtr = nullptr; TEffect* effectPtr = nullptr;

View file

@ -29,7 +29,7 @@ namespace TEN::Effects::Hair
// Get world matrix from head bone. // Get world matrix from head bone.
auto worldMatrix = Matrix::Identity; auto worldMatrix = Matrix::Identity;
g_Renderer.GetBoneMatrix(player.ItemNumber, LM_HEAD, &worldMatrix); g_Renderer.GetBoneMatrix(item.Index, LM_HEAD, &worldMatrix);
// Apply base offset to world matrix. // Apply base offset to world matrix.
auto relOffset = GetRelBaseOffset(hairUnitIndex, isYoung); auto relOffset = GetRelBaseOffset(hairUnitIndex, isYoung);

View file

@ -30,6 +30,9 @@ using namespace TEN::Collision::Floordata;
using namespace TEN::Math; using namespace TEN::Math;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
// NOTE: This fixes body part exploding instantly if entity is on ground.
constexpr auto BODY_PART_SPAWN_VERTICAL_OFFSET = CLICK(1);
char LaserSightActive = 0; char LaserSightActive = 0;
char LaserSightCol = 0; char LaserSightCol = 0;
int NextGunshell = 0; int NextGunshell = 0;
@ -43,12 +46,11 @@ int NextSmokeSpark = 0;
int NextBlood = 0; int NextBlood = 0;
int NextGunShell = 0; int NextGunShell = 0;
GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL]; BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD]; SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
FIRE_LIST Fires[MAX_FIRE_LIST]; FIRE_LIST Fires[MAX_FIRE_LIST];
int GetFreeFireSpark() int GetFreeFireSpark()
@ -1168,7 +1170,7 @@ void ExplodeVehicle(ItemInfo* laraItem, ItemInfo* vehicle)
auto* lara = GetLaraInfo(laraItem); auto* lara = GetLaraInfo(laraItem);
ExplodingDeath(lara->Context.Vehicle, BODY_EXPLODE | BODY_STONE_SOUND); ExplodingDeath(lara->Context.Vehicle, BODY_DO_EXPLOSION | BODY_STONE_SOUND);
KillItem(lara->Context.Vehicle); KillItem(lara->Context.Vehicle);
vehicle->Status = ITEM_DEACTIVATED; vehicle->Status = ITEM_DEACTIVATED;
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose); SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose);
@ -1192,6 +1194,10 @@ void ExplodingDeath(short itemNumber, short flags)
auto world = item->Pose.Orientation.ToRotationMatrix(); auto world = item->Pose.Orientation.ToRotationMatrix();
// If only BODY_PART_EXPLODE flag exists but not BODY_EXPLODE, add it.
if ((flags & BODY_PART_EXPLODE) && !(flags & BODY_DO_EXPLOSION))
flags |= BODY_DO_EXPLOSION;
for (int i = 0; i < obj->nmeshes; i++) for (int i = 0; i < obj->nmeshes; i++)
{ {
Matrix boneMatrix; Matrix boneMatrix;
@ -1203,7 +1209,7 @@ void ExplodingDeath(short itemNumber, short flags)
item->MeshBits.Clear(i); item->MeshBits.Clear(i);
if (i == 0 || ((GetRandomControl() & 3) != 0 && (flags & BODY_EXPLODE))) if (i == 0 || ((GetRandomControl() & 3) != 0 && (flags & BODY_DO_EXPLOSION)))
{ {
short fxNumber = CreateNewEffect(item->RoomNumber); short fxNumber = CreateNewEffect(item->RoomNumber);
if (fxNumber != NO_ITEM) if (fxNumber != NO_ITEM)
@ -1211,26 +1217,26 @@ void ExplodingDeath(short itemNumber, short flags)
FX_INFO* fx = &EffectList[fxNumber]; FX_INFO* fx = &EffectList[fxNumber];
fx->pos.Position.x = boneMatrix.Translation().x; fx->pos.Position.x = boneMatrix.Translation().x;
fx->pos.Position.y = boneMatrix.Translation().y; fx->pos.Position.y = boneMatrix.Translation().y - BODY_PART_SPAWN_VERTICAL_OFFSET;
fx->pos.Position.z = boneMatrix.Translation().z; fx->pos.Position.z = boneMatrix.Translation().z;
fx->roomNumber = item->RoomNumber; fx->roomNumber = item->RoomNumber;
fx->pos.Orientation.x = 0; fx->pos.Orientation.x = 0;
fx->pos.Orientation.y = GetRandomControl() * 2; fx->pos.Orientation.y = Random::GenerateAngle();
if (!(flags & 0x10)) if (!(flags & BODY_NO_RAND_VELOCITY))
{ {
if (flags & 0x20) if (flags & BODY_MORE_RAND_VELOCITY)
fx->speed = GetRandomControl() >> 12; fx->speed = GetRandomControl() >> 12;
else else
fx->speed = GetRandomControl() >> 8; fx->speed = GetRandomControl() >> 8;
} }
if (flags & 0x40) if (flags & BODY_NO_VERTICAL_VELOCITY)
fx->fallspeed = 0; fx->fallspeed = 0;
else else
{ {
if ((flags & 0x80) == 0) if (flags & BODY_LESS_IMPULSE)
fx->fallspeed = -(GetRandomControl() >> 8); fx->fallspeed = -(GetRandomControl() >> 8);
else else
fx->fallspeed = -(GetRandomControl() >> 12); fx->fallspeed = -(GetRandomControl() >> 12);

View file

@ -10,20 +10,19 @@ struct ItemInfo;
enum BodyPartFlags enum BodyPartFlags
{ {
BODY_NO_BOUNCE = (1 << 0), BODY_NO_BOUNCE = (1 << 0), // No bounce.
BODY_GIBS = (1 << 1), BODY_GIBS = (1 << 1), // Add blood and SFX_TR4_LARA_THUD upon floor collision.
BODY_EXPLODE = (1 << 8), BODY_PART_EXPLODE = (1 << 2), // Explode upon impact. Requires BODY_EXPLODE flag.
BODY_NO_BOUNCE_ALT = (1 << 9), BODY_NO_FLAME = (1 << 3), // No flame.
BODY_STONE_SOUND = (1 << 11) BODY_NO_RAND_VELOCITY = (1 << 4), // No random velocity.
}; BODY_MORE_RAND_VELOCITY = (1 << 5), // Add more randomness to velocity.
BODY_NO_VERTICAL_VELOCITY = (1 << 6), // No vertical velocity.
struct Matrix3D BODY_LESS_IMPULSE = (1 << 7), // Add less vertical velocity than normal. TODO: Weird name.
{ BODY_DO_EXPLOSION = (1 << 8), // Explode.
short m00, m01, m02; BODY_NO_BOUNCE_ALT = (1 << 9), // Same as BODY_NO_BOUNCE, but with delay before despawning.
short m10, m11, m12; BODY_STONE_SOUND = (1 << 11), // Do impact sound if stone. NOTE: BODY_GIBS also add sound, but this one is prioritary.
short m20, m21, m22; BODY_NO_SMOKE = (1 << 12), // Remove smoke upon despawn or shatter.
short pad; BODY_NO_SHATTER_EFFECT = (1 << 13), // Remove shatter effect upon despawn.
int tx, ty, tz;
}; };
struct SMOKE_SPARKS struct SMOKE_SPARKS
@ -59,12 +58,6 @@ struct SMOKE_SPARKS
byte mirror; byte mirror;
}; };
struct GUNFLASH_STRUCT
{
Matrix3D matrix;
short on;
};
struct SHOCKWAVE_STRUCT struct SHOCKWAVE_STRUCT
{ {
int x; int x;
@ -219,7 +212,6 @@ constexpr auto MAX_GUNFLASH = 4;
constexpr auto MAX_GUNSHELL = 24; constexpr auto MAX_GUNSHELL = 24;
constexpr auto MAX_SHOCKWAVE = 16; constexpr auto MAX_SHOCKWAVE = 16;
extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH];
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL]; extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL];
@ -254,7 +246,7 @@ int GetFreeGunshell();
void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType); void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType);
void UpdateGunShells(); void UpdateGunShells();
void AddWaterSparks(int x, int y, int z, int num); void AddWaterSparks(int x, int y, int z, int num);
void ExplodingDeath(short itemNumber, short flags); // EXPLODE_ flags void ExplodingDeath(short itemNumber, short flags); // BODY_ flags
int GetFreeShockwave(); int GetFreeShockwave();
void TriggerShockwave(Pose* pos, short innerRad, short outerRad, int speed, unsigned char r, unsigned char g, unsigned char b, unsigned char life, EulerAngles rotation, short damage, bool sound, bool fadein, int style); void TriggerShockwave(Pose* pos, short innerRad, short outerRad, int speed, unsigned char r, unsigned char g, unsigned char b, unsigned char life, EulerAngles rotation, short damage, bool sound, bool fadein, int style);
void TriggerShockwaveHitEffect(int x, int y, int z, unsigned char r, unsigned char g, unsigned char b, short rot, int vel); void TriggerShockwaveHitEffect(int x, int y, int z, unsigned char r, unsigned char g, unsigned char b, short rot, int vel);

File diff suppressed because it is too large Load diff

View file

@ -5,11 +5,11 @@
#include "Specific/configuration.h" #include "Specific/configuration.h"
#include "Specific/Input/InputAction.h" #include "Specific/Input/InputAction.h"
struct ItemInfo;
using namespace TEN::Input; using namespace TEN::Input;
using namespace TEN::Math; using namespace TEN::Math;
struct ItemInfo;
namespace TEN::Gui namespace TEN::Gui
{ {
enum class InventoryMode enum class InventoryMode
@ -76,20 +76,23 @@ namespace TEN::Gui
LoadGame, LoadGame,
Options, Options,
Display, Display,
Controls, GeneralActions,
VehicleActions,
QuickActions,
MenuActions,
OtherSettings OtherSettings
}; };
struct MenuOption struct MenuOption
{ {
MenuType Type; MenuType Type = MenuType::None;
char const* Text; std::string Text = {};
}; };
struct ObjectList struct ObjectList
{ {
short InventoryItem; int InventoryItem = 0;
EulerAngles Orientation = EulerAngles::Zero; EulerAngles Orientation = EulerAngles::Zero;
unsigned short Bright; unsigned short Bright;
}; };
@ -115,7 +118,7 @@ namespace TEN::Gui
private: private:
// Input inquirers // Input inquirers
bool GuiIsPulsed(ActionID actionID) const; bool GuiIsPulsed(ActionID actionID) const;
bool GuiIsSelected() const; bool GuiIsSelected(bool onClicked = true) const;
bool GuiIsDeselected() const; bool GuiIsDeselected() const;
bool CanSelect() const; bool CanSelect() const;
bool CanDeselect() const; bool CanDeselect() const;
@ -135,9 +138,7 @@ namespace TEN::Gui
bool UseItem; bool UseItem;
char SeperateTypeFlag; char SeperateTypeFlag;
char CombineTypeFlag; char CombineTypeFlag;
InventoryRing PCRing1; InventoryRing Rings[2];
InventoryRing PCRing2;
InventoryRing* Rings[2];
int CurrentSelectedOption; int CurrentSelectedOption;
bool MenuActive; bool MenuActive;
char AmmoSelectorFlag; char AmmoSelectorFlag;
@ -161,12 +162,13 @@ namespace TEN::Gui
public: public:
int CompassNeedleAngle; int CompassNeedleAngle;
void Initialize();
bool CallPause(); bool CallPause();
bool CallInventory(ItemInfo* item, bool resetMode); bool CallInventory(ItemInfo* item, bool resetMode);
InventoryResult TitleOptions(ItemInfo* item); InventoryResult TitleOptions(ItemInfo* item);
InventoryResult DoPauseMenu(ItemInfo* item); InventoryResult DoPauseMenu(ItemInfo* item);
void DrawInventory(); void DrawInventory();
void DrawCurrentObjectList(ItemInfo* item, int ringIndex); void DrawCurrentObjectList(ItemInfo* item, RingTypes ringType);
int IsObjectInInventory(int objectNumber); int IsObjectInInventory(int objectNumber);
int ConvertObjectToInventoryItem(int objectNumber); int ConvertObjectToInventoryItem(int objectNumber);
int ConvertInventoryItemToObject(int objectNumber); int ConvertInventoryItemToObject(int objectNumber);
@ -176,7 +178,7 @@ namespace TEN::Gui
void DrawCompass(ItemInfo* item); void DrawCompass(ItemInfo* item);
// Getters // Getters
InventoryRing* GetRings(int ringIndex); const InventoryRing& GetRing(RingTypes ringType);
short GetSelectedOption(); short GetSelectedOption();
Menu GetMenuToDisplay(); Menu GetMenuToDisplay();
InventoryMode GetInventoryMode(); InventoryMode GetInventoryMode();
@ -192,6 +194,7 @@ namespace TEN::Gui
void SetInventoryMode(InventoryMode mode); void SetInventoryMode(InventoryMode mode);
void SetEnterInventory(int number); void SetEnterInventory(int number);
void SetInventoryItemChosen(int number); void SetInventoryItemChosen(int number);
void SetLastInventoryItem(int itemNumber);
private: private:
void HandleDisplaySettingsInput(bool fromPauseMenu); void HandleDisplaySettingsInput(bool fromPauseMenu);
@ -226,5 +229,9 @@ namespace TEN::Gui
}; };
extern GuiController g_Gui; extern GuiController g_Gui;
extern const char* ControlStrings[]; extern std::vector<std::string> OptionStrings;
extern std::vector<std::string> GeneralActionStrings;
extern std::vector<std::string> VehicleActionStrings;
extern std::vector<std::string> QuickActionStrings;
extern std::vector<std::string> MenuActionStrings;
} }

View file

@ -73,20 +73,20 @@ struct LOTInfo
struct CreatureBiteInfo struct CreatureBiteInfo
{ {
Vector3i Position = Vector3i::Zero; // TODO: Change back to Vector3. Vector3 Position = Vector3::Zero;
int BoneID = -1; int BoneID = -1;
CreatureBiteInfo() {} CreatureBiteInfo() {}
CreatureBiteInfo(const Vector3i& pos, int boneID) CreatureBiteInfo(const Vector3& pos, int boneID)
{ {
Position = pos; Position = pos;
BoneID = boneID; BoneID = boneID;
} }
CreatureBiteInfo(int x, int y, int z, int boneID) CreatureBiteInfo(float x, float y, float z, int boneID)
{ {
Position = Vector3i(x, y, z); Position = Vector3(x, y, z);
BoneID = boneID; BoneID = boneID;
} }
}; };
@ -103,7 +103,7 @@ struct CreatureMuzzleFlashInfo
CreatureMuzzleFlashInfo() {} CreatureMuzzleFlashInfo() {}
CreatureMuzzleFlashInfo(const Vector3i& pos, int boneID, int delay, bool changeToMuzzle2 = false) CreatureMuzzleFlashInfo(const Vector3& pos, int boneID, int delay, bool changeToMuzzle2 = false)
{ {
Bite = CreatureBiteInfo(pos, boneID); Bite = CreatureBiteInfo(pos, boneID);
Delay = delay; Delay = delay;

View file

@ -149,10 +149,23 @@ bool ItemInfo::IsCreature() const
void ItemInfo::ResetModelToDefault() void ItemInfo::ResetModelToDefault()
{ {
Model.BaseMesh = Objects[ObjectNumber].meshIndex; if (Objects[ObjectNumber].nmeshes > 0)
{
Model.MeshIndex.resize(Objects[ObjectNumber].nmeshes);
Model.BaseMesh = Objects[ObjectNumber].meshIndex;
for (int i = 0; i < Model.MeshIndex.size(); i++) for (int i = 0; i < Model.MeshIndex.size(); i++)
Model.MeshIndex[i] = Model.BaseMesh + i; Model.MeshIndex[i] = Model.BaseMesh + i;
Model.Mutators.resize(Objects[ObjectNumber].nmeshes);
for (auto& mutator : Model.Mutators)
mutator = {};
}
else
{
Model.Mutators.clear();
Model.MeshIndex.clear();
}
} }
bool TestState(int refState, const vector<int>& stateList) bool TestState(int refState, const vector<int>& stateList)
@ -239,7 +252,9 @@ void KillItem(short const itemNumber)
if (item == Lara.TargetEntity) if (item == Lara.TargetEntity)
Lara.TargetEntity = nullptr; Lara.TargetEntity = nullptr;
if (Objects[item->ObjectNumber].floor != nullptr) // AI target generation uses a hack with making a dummy item without ObjectNumber.
// Therefore, a check should be done here to prevent access violation.
if (item->ObjectNumber != GAME_OBJECT_ID::ID_NO_OBJECT && Objects[item->ObjectNumber].floor != nullptr)
UpdateBridgeItem(itemNumber, true); UpdateBridgeItem(itemNumber, true);
GameScriptHandleKilled(itemNumber, true); GameScriptHandleKilled(itemNumber, true);
@ -553,20 +568,7 @@ void InitializeItem(short itemNumber)
item->Floor = floor->GetSurfaceHeight(item->Pose.Position.x, item->Pose.Position.z, true); item->Floor = floor->GetSurfaceHeight(item->Pose.Position.x, item->Pose.Position.z, true);
item->BoxNumber = floor->Box; item->BoxNumber = floor->Box;
if (Objects[item->ObjectNumber].nmeshes > 0) item->ResetModelToDefault();
{
item->Model.MeshIndex.resize(Objects[item->ObjectNumber].nmeshes);
item->ResetModelToDefault();
item->Model.Mutators.resize(Objects[item->ObjectNumber].nmeshes);
for (auto& mutator : item->Model.Mutators)
mutator = {};
}
else
{
item->Model.Mutators.clear();
item->Model.MeshIndex.clear();
}
if (Objects[item->ObjectNumber].Initialize != nullptr) if (Objects[item->ObjectNumber].Initialize != nullptr)
Objects[item->ObjectNumber].Initialize(itemNumber); Objects[item->ObjectNumber].Initialize(itemNumber);
@ -710,7 +712,7 @@ ItemInfo* FindItem(GAME_OBJECT_ID objectID)
int FindItem(ItemInfo* item) int FindItem(ItemInfo* item)
{ {
if (item == LaraItem) if (item == LaraItem)
return Lara.ItemNumber; return item->Index;
for (int i = 0; i < g_Level.NumItems; i++) for (int i = 0; i < g_Level.NumItems; i++)
if (item == &g_Level.Items[i]) if (item == &g_Level.Items[i])
@ -729,6 +731,9 @@ void UpdateAllItems()
auto* item = &g_Level.Items[itemNumber]; auto* item = &g_Level.Items[itemNumber];
short nextItem = item->NextActive; short nextItem = item->NextActive;
if (!Objects.CheckID(item->ObjectNumber))
continue;
if (item->AfterDeath <= ITEM_DEATH_TIMEOUT) if (item->AfterDeath <= ITEM_DEATH_TIMEOUT)
{ {
if (Objects[item->ObjectNumber].control) if (Objects[item->ObjectNumber].control)

View file

@ -75,7 +75,9 @@ void ControlMissile(short fxNumber)
else if (fx.objectNumber == ID_PROJ_BOMB) else if (fx.objectNumber == ID_PROJ_BOMB)
{ {
SoundEffect(SFX_TR1_ATLANTEAN_EXPLODE, &fx.pos, soundFXType); SoundEffect(SFX_TR1_ATLANTEAN_EXPLODE, &fx.pos, soundFXType);
TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, false, isUnderwater, fx.roomNumber); TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -2, 0, fx.roomNumber);
TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -1, 0, fx.roomNumber);
TriggerShockwave(&fx.pos, 48, 304, (GetRandomControl() & 0x1F) + 112, 128, 32, 32, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, (int)ShockwaveStyle::Normal);
} }
if (hasHitPlayer) if (hasHitPlayer)
@ -83,24 +85,20 @@ void ControlMissile(short fxNumber)
if (fx.objectNumber == ID_KNIFETHROWER_KNIFE) if (fx.objectNumber == ID_KNIFETHROWER_KNIFE)
{ {
DoDamage(LaraItem, KNIFE_DAMAGE); DoDamage(LaraItem, KNIFE_DAMAGE);
KillEffect(fxNumber);
} }
else if (fx.objectNumber == ID_SCUBA_HARPOON) else if (fx.objectNumber == ID_SCUBA_HARPOON)
{ {
DoDamage(LaraItem, DIVER_HARPOON_DAMAGE); DoDamage(LaraItem, DIVER_HARPOON_DAMAGE);
KillEffect(fxNumber);
} }
else if (fx.objectNumber == ID_PROJ_BOMB) else if (fx.objectNumber == ID_PROJ_BOMB)
{ {
DoDamage(LaraItem, MUTANT_BOMB_DAMAGE); DoDamage(LaraItem, MUTANT_BOMB_DAMAGE);
KillEffect(fxNumber);
} }
else if (fx.objectNumber == ID_PROJ_SHARD) else if (fx.objectNumber == ID_PROJ_SHARD)
{ {
TriggerBlood(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, 10); TriggerBlood(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, 10);
SoundEffect(SFX_TR4_BLOOD_LOOP, &fx.pos, soundFXType); SoundEffect(SFX_TR4_BLOOD_LOOP, &fx.pos, soundFXType);
DoDamage(LaraItem, MUTANT_SHARD_DAMAGE); DoDamage(LaraItem, MUTANT_SHARD_DAMAGE);
KillEffect(fxNumber);
} }
LaraItem->HitStatus = true; LaraItem->HitStatus = true;
@ -109,6 +107,8 @@ void ControlMissile(short fxNumber)
fx.frameNumber = 0; fx.frameNumber = 0;
fx.counter = 0; fx.counter = 0;
} }
KillEffect(fxNumber);
} }
if (pointColl.RoomNumber != fx.roomNumber) if (pointColl.RoomNumber != fx.roomNumber)
@ -161,14 +161,14 @@ void ControlNatlaGun(short fxNumber)
fxNew.roomNumber = pointColl.RoomNumber; fxNew.roomNumber = pointColl.RoomNumber;
fxNew.speed = fx.speed; fxNew.speed = fx.speed;
fxNew.frameNumber = 0; fxNew.frameNumber = 0;
fxNew.objectNumber = ID_PROJ_NATLA; fxNew.objectNumber = ID_PROJ_BOMB;
} }
} }
} }
short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber) short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
{ {
short fxNumber = CreateNewEffect(roomNumber); int fxNumber = CreateNewEffect(roomNumber);
if (fxNumber != NO_ITEM) if (fxNumber != NO_ITEM)
{ {
auto& fx = EffectList[fxNumber]; auto& fx = EffectList[fxNumber];
@ -188,7 +188,7 @@ short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber
short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber) short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
{ {
short fxNumber = CreateNewEffect(roomNumber); int fxNumber = CreateNewEffect(roomNumber);
if (fxNumber != NO_ITEM) if (fxNumber != NO_ITEM)
{ {
auto& fx = EffectList[fxNumber]; auto& fx = EffectList[fxNumber];
@ -205,23 +205,3 @@ short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
return fxNumber; return fxNumber;
} }
short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
{
short fxNumber = CreateNewEffect(roomNumber);
if (fxNumber != NO_ITEM)
{
auto& fx = EffectList[fxNumber];
fx.pos.Position = Vector3i(x, y, z);
fx.pos.Orientation = EulerAngles(0, yRot, 0);
fx.roomNumber = roomNumber;
fx.speed = velocity;
fx.frameNumber = 0;
fx.objectNumber = ID_PROJ_NATLA;
fx.color = Vector4::One;
ShootAtLara(fx);
}
return fxNumber;
}

View file

@ -7,4 +7,3 @@ void ControlNatlaGun(short fxNumber);
short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber); short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber);
short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber); short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber);
short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber);

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