Merge branch 'master' into room_scripting

This commit is contained in:
Lwmte 2022-12-17 03:21:15 +02:00
commit 5d94e71520
59 changed files with 1177 additions and 696 deletions

View file

@ -1,3 +1,9 @@
Version 1.0.5
=============
* Fix combined items not existing in inventory upon game reload.
Version 1.0.4
=============
@ -19,8 +25,11 @@ Version 1.0.4
- Restored spark effects.
- Can destroy statics in shatter slots.
- Fix crash when attacking.
* Fix TR5 Autogun Rotation.
* Fix Choppy camera movement.
* SAS enhancements:
- Fix grenade shooting.
- Fix AI_MODIFY and AI_GUARD behaviour.
* Fix choppy camera movement in several cases.
* Fix Lara's vertical position when shimmying around steep slope corners.
* Fix legacy pickup triggers not working in certain cases.
* Fix crawl pickup not actually doing any pickups.
* Fix demigod and harpy shooting in incorrect directions.
@ -34,6 +43,7 @@ Version 1.0.4
* Fix original bug with incorrect climb up behaviour on ladders under sloped ceilings.
* Fix original bug with reassigned control keys still triggering default events.
* Fix TR1 centaur bubble targeting.
* Fix TR5 autogun rotation.
* Fix occasional wrong rollingball collision in narrow pits.
* Fix classic rollingball and big rollingball not behaving properly.
* Fix caustics not turning off in display settings.
@ -62,6 +72,7 @@ Lua API changes:
* Fix mounted vehicles ignoring Disable, Shatter and Explode script commands.
* Fix SetPosition command not updating room number correctly.
* Fix Rotation class using integers under the hood which prevented using fractional rotation values.
* Fix distance tests failing on a very high distances.
Version 1.0.3
=============

View file

@ -56,6 +56,7 @@
<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>
@ -515,7 +516,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -656,7 +657,7 @@ Specify which translations in the strings table correspond to which languages.
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -238,7 +239,7 @@ Similar to <a href="../1 modules/Inventory.html#GiveItem">GiveItem</a> but repla
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -365,7 +366,7 @@ and provides the delta time (a float representing game time since last call) via
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -801,7 +802,7 @@ To be used with <a href="../2 classes/Strings.DisplayString.html#DisplayString:G
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -122,6 +123,10 @@
<td class="name" ><a href="#GetAIObjectByName">GetAIObjectByName(name)</a></td>
<td class="summary">Get an AIObject by its name.</td>
</tr>
<tr>
<td class="name" ><a href="#GetVolumeByName">GetVolumeByName(name)</a></td>
<td class="summary">Get a Volume by its name.</td>
</tr>
</table>
<br/>
@ -354,6 +359,34 @@
</dd>
<dt>
<a name = "GetVolumeByName"></a>
<strong>GetVolumeByName(name)</strong>
</dt>
<dd>
Get a Volume by its name.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
the unique name of the volume as set in, or generated by, Tomb Editor
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Volume</span></span>
a non-owning Volume referencing the room.
</ol>
</dd>
</dl>
@ -362,7 +395,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -166,7 +167,7 @@ with a call to <a href="../1 modules/Strings.html#ShowString">ShowString</a>, or
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -99,7 +100,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -226,7 +227,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -183,7 +184,7 @@ EXAMINE
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -529,7 +530,7 @@ Must be at least 4.</p>
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -99,7 +100,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -139,7 +140,7 @@ has an unrecoverable error, the game will close.
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -197,7 +198,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -377,7 +378,7 @@ aiObj:SetObjectID(TEN.Objects.ObjID.AI_PATROL1)</pre>
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -261,7 +262,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -154,6 +155,10 @@
<td class="name" ><a href="#LaraObject:GetTarget">LaraObject:GetTarget()</a></td>
<td class="summary">Get current target enemy, if it exists</td>
</tr>
<tr>
<td class="name" ><a href="#LaraObject:TorchIsLit">LaraObject:TorchIsLit()</a></td>
<td class="summary">Get current light state of the torch, if it exists</td>
</tr>
</table>
<br/>
@ -540,7 +545,7 @@ ROCKETLAUNCHER
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Moveable</span></span>
<span class="types"><a class="type" href="../2 classes/Objects.Moveable.html#">Moveable</a></span>
current vehicle (nil if no vehicle present)
</ol>
@ -565,7 +570,7 @@ ROCKETLAUNCHER
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Moveable</span></span>
<span class="types"><a class="type" href="../2 classes/Objects.Moveable.html#">Moveable</a></span>
current target enemy (nil if no target present)
</ol>
@ -576,6 +581,31 @@ ROCKETLAUNCHER
<pre class="example"><span class="keyword">local</span> target = Lara:GetTarget()</pre>
</ul>
</dd>
<dt>
<a name = "LaraObject:TorchIsLit"></a>
<strong>LaraObject:TorchIsLit()</strong>
</dt>
<dd>
Get current light state of the torch, if it exists
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
is torch currently lit or not? (false if no torch exists)
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> torchIsLit = Lara:TorchIsLit()</pre>
</ul>
</dd>
</dl>
@ -584,7 +614,7 @@ ROCKETLAUNCHER
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -275,7 +276,7 @@ associated getters and setters.</td>
<td class="summary">Determine whether the moveable is active or not</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetJointPosition">Moveable:GetJointPosition()</a></td>
<td class="name" ><a href="#Moveable:GetJointPosition">Moveable:GetJointPosition(index)</a></td>
<td class="summary">Get the object's joint position</td>
</tr>
<tr>
@ -1377,13 +1378,20 @@ sas:SetAIBits({<span class="number">1</span>, <span class="number">0</span>, <sp
</dd>
<dt>
<a name = "Moveable:GetJointPosition"></a>
<strong>Moveable:GetJointPosition()</strong>
<strong>Moveable:GetJointPosition(index)</strong>
</dt>
<dd>
Get the object's joint position
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a joint to get position
</li>
</ul>
<h3>Returns:</h3>
<ol>
@ -1505,8 +1513,8 @@ sas:SetAIBits({<span class="number">1</span>, <span class="number">0</span>, <sp
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">valid</span></span>
bool true if the object is still not destroyed
<span class="types"><span class="type">bool</span></span>
valid true if the object is still not destroyed
</ol>
@ -1732,7 +1740,7 @@ sas:SetPosition(destinationPosition, <span class="keyword">false</span>)</pre>
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<li> <here>Objects.Sink</here></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>
@ -263,7 +264,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<li> <a href="../2 classes/Objects.Sink.html">Objects.Sink</a></li>
<li> <here>Objects.SoundSource</here></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>
@ -261,7 +262,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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> <here>Objects.Static</here></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>
@ -547,7 +548,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -0,0 +1,426 @@
<!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.0.4 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.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> <here>Objects.Volume</here></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/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/Objects.ObjID.html">Objects.ObjID</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li> <a href="../5 lua utility modules/EventSequence.html">EventSequence</a></li>
<li> <a href="../5 lua utility modules/Timer.html">Timer</a></li>
</ul>
</div>
<div id="content">
<h1>Class <code>Objects.Volume</code></h1>
<p>Volumes</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#Volume:Enable">Volume:Enable()</a></td>
<td class="summary">Enable the volume.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:Disable">Volume:Disable()</a></td>
<td class="summary">Disable the volume.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:GetActive">Volume:GetActive()</a></td>
<td class="summary">Determine whether the volume is active or not</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:GetPosition">Volume:GetPosition()</a></td>
<td class="summary">Get the volume's position.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:SetPosition">Volume:SetPosition(position)</a></td>
<td class="summary">Set the volume's position.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:GetRotation">Volume:GetRotation()</a></td>
<td class="summary">Get the volume's rotation.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:SetRotation">Volume:SetRotation(rotation)</a></td>
<td class="summary">Set the volume's rotation.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:GetScale">Volume:GetScale()</a></td>
<td class="summary">Get the volume's scale (separately on all 3 axes).</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:SetScale">Volume:SetScale(scale)</a></td>
<td class="summary">Set the volume's scale (separately on all 3 axes).</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:GetName">Volume:GetName()</a></td>
<td class="summary">Get the volume's unique string identifier.</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:SetName">Volume:SetName(name)</a></td>
<td class="summary">Set the volume's name (its unique string identifier).</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:ClearActivators">Volume:ClearActivators()</a></td>
<td class="summary">Clear activator list for volumes (makes volume trigger everything again)</td>
</tr>
<tr>
<td class="name" ><a href="#Volume:IsMoveableInside">Volume:IsMoveableInside(Moveable)</a></td>
<td class="summary">Check if specified moveable is inside the volume</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "Volume:Enable"></a>
<strong>Volume:Enable()</strong>
</dt>
<dd>
Enable the volume.
</dd>
<dt>
<a name = "Volume:Disable"></a>
<strong>Volume:Disable()</strong>
</dt>
<dd>
Disable the volume.
</dd>
<dt>
<a name = "Volume:GetActive"></a>
<strong>Volume:GetActive()</strong>
</dt>
<dd>
Determine whether the volume is active or not
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
true if the volume is active
</ol>
</dd>
<dt>
<a name = "Volume:GetPosition"></a>
<strong>Volume:GetPosition()</strong>
</dt>
<dd>
Get the volume's position.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
a copy of the volume's position
</ol>
</dd>
<dt>
<a name = "Volume:SetPosition"></a>
<strong>Volume:SetPosition(position)</strong>
</dt>
<dd>
Set the volume's position.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">position</span>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
the new position of the volume
</li>
</ul>
</dd>
<dt>
<a name = "Volume:GetRotation"></a>
<strong>Volume:GetRotation()</strong>
</dt>
<dd>
Get the volume's rotation.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Rotation.html#">Rotation</a></span>
a copy of the volume's rotation
</ol>
</dd>
<dt>
<a name = "Volume:SetRotation"></a>
<strong>Volume:SetRotation(rotation)</strong>
</dt>
<dd>
Set the volume's rotation.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">rotation</span>
<span class="types"><a class="type" href="../3 primitive classes/Rotation.html#">Rotation</a></span>
the volume's new rotation
</li>
</ul>
</dd>
<dt>
<a name = "Volume:GetScale"></a>
<strong>Volume:GetScale()</strong>
</dt>
<dd>
Get the volume's scale (separately on all 3 axes).
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
current volume scale
</ol>
</dd>
<dt>
<a name = "Volume:SetScale"></a>
<strong>Volume:SetScale(scale)</strong>
</dt>
<dd>
Set the volume's scale (separately on all 3 axes).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">scale</span>
<span class="types"><a class="type" href="../3 primitive classes/Vec3.html#">Vec3</a></span>
the volume's new scale
</li>
</ul>
</dd>
<dt>
<a name = "Volume:GetName"></a>
<strong>Volume:GetName()</strong>
</dt>
<dd>
Get the volume's unique string identifier.
<h3>Returns:</h3>
<ol>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
the volume's name
</ol>
</dd>
<dt>
<a name = "Volume:SetName"></a>
<strong>Volume:SetName(name)</strong>
</dt>
<dd>
Set the volume's name (its unique string identifier).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.4/manual.html#6.4">string</a></span>
The volume's new name
</li>
</ul>
</dd>
<dt>
<a name = "Volume:ClearActivators"></a>
<strong>Volume:ClearActivators()</strong>
</dt>
<dd>
Clear activator list for volumes (makes volume trigger everything again)
</dd>
<dt>
<a name = "Volume:IsMoveableInside"></a>
<strong>Volume:IsMoveableInside(Moveable)</strong>
</dt>
<dd>
Check if specified moveable is inside the volume
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">Moveable</span>
<span class="types"><a class="type" href="../2 classes/Objects.Moveable.html#">Moveable</a></span>
which should be checked for containment
</li>
</ul>
</dd>
</dl>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -56,6 +56,7 @@
<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> <here>Strings.DisplayString</here></li>
</ul>
<h2>3 Primitive Classes</h2>
@ -336,7 +337,7 @@ TEN.Strings.DisplayStringOption.SHADOW -- will give the text a small shadow
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -315,7 +316,7 @@
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -85,22 +86,22 @@
<p>Represents a rotation.</p>
<p>Rotations are specifed as a combination of individual
angles, in degrees, about each axis.
All values will be clamped to [-32768, 32767].</p>
All values will be clamped to [0.0f, 360.0f].</p>
<h2><a href="#Members">Members</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#x">x</a></td>
<td class="summary">(int) rotation about x axis</td>
<td class="summary">(float) rotation about x axis</td>
</tr>
<tr>
<td class="name" ><a href="#y">y</a></td>
<td class="summary">(int) rotation about y axis</td>
<td class="summary">(float) rotation about y axis</td>
</tr>
<tr>
<td class="name" ><a href="#z">z</a></td>
<td class="summary">(int) rotation about z axis</td>
<td class="summary">(float) rotation about z axis</td>
</tr>
</table>
<h2><a href="#Functions">Functions</a></h2>
@ -131,7 +132,7 @@ All values will be clamped to [-32768, 32767].</p>
<strong>x</strong>
</dt>
<dd>
(int) rotation about x axis
(float) rotation about x axis
@ -146,7 +147,7 @@ All values will be clamped to [-32768, 32767].</p>
<strong>y</strong>
</dt>
<dd>
(int) rotation about y axis
(float) rotation about y axis
@ -161,7 +162,7 @@ All values will be clamped to [-32768, 32767].</p>
<strong>z</strong>
</dt>
<dd>
(int) rotation about z axis
(float) rotation about z axis
@ -189,15 +190,15 @@ All values will be clamped to [-32768, 32767].</p>
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">X</span>
<span class="types"><span class="type">int</span></span>
<span class="types"><span class="type">float</span></span>
rotation about x axis
</li>
<li><span class="parameter">Y</span>
<span class="types"><span class="type">int</span></span>
<span class="types"><span class="type">float</span></span>
rotation about y axis
</li>
<li><span class="parameter">Z</span>
<span class="types"><span class="type">int</span></span>
<span class="types"><span class="type">float</span></span>
rotation about z axis
</li>
</ul>
@ -250,7 +251,7 @@ All values will be clamped to [-32768, 32767].</p>
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -278,7 +279,7 @@ However, this function would return it as (0, 1, 1).
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -145,7 +146,7 @@ ALPHABLEND
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -141,7 +142,7 @@ CUSTOM
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -152,7 +153,7 @@ STEPRIGHT
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -1307,7 +1308,7 @@ PC_SAVE_INV_ITEM
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -337,7 +338,7 @@ LevelFuncs.SpawnBaddy = <span class="keyword">function</span>(baddy, name, pos)
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -513,7 +514,7 @@ LevelFuncs.TriggerTimer = <span class="keyword">function</span>(obj)
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
<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>
@ -193,6 +194,10 @@ local door = GetMoveableByName("door_type4_14")
<td class="name" ><a href="2 classes/Objects.Static.html">Objects.Static</a></td>
<td class="summary">Statics</td>
</tr>
<tr>
<td class="name" ><a href="2 classes/Objects.Volume.html">Objects.Volume</a></td>
<td class="summary">Volumes</td>
</tr>
<tr>
<td class="name" ><a href="2 classes/Strings.DisplayString.html">Strings.DisplayString</a></td>
<td class="summary">A string appearing on the screen.</td>
@ -248,7 +253,7 @@ local door = GetMoveableByName("door_type4_14")
</div> <!-- id="main" -->
<div id="about">
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i>
<i style="float:right;">Last updated 2022-12-11 18:38:45 </i>
<i style="float:right;">Last updated 2022-12-16 18:35:53 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -635,7 +635,7 @@ CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAng
// Store next position
item->Pose = cornerResult.RealPositionResult;
lara->NextCornerPos.Position.x = item->Pose.Position.x;
lara->NextCornerPos.Position.y = GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius * 2, -(abs(bounds.Y1) + LARA_HEADROOM)).Position.Floor + abs(bounds.Y1);
lara->NextCornerPos.Position.y = GetCollision(item, item->Pose.Orientation.y, coll->Setup.Radius * 1.25f, -(abs(bounds.Y1) + LARA_HEADROOM)).Position.Floor + abs(bounds.Y1);
lara->NextCornerPos.Position.z = item->Pose.Position.z;
lara->NextCornerPos.Orientation.y = item->Pose.Orientation.y;
lara->Control.MoveAngle = item->Pose.Orientation.y;

View file

@ -1292,8 +1292,7 @@ void GetAITarget(CreatureInfo* creature)
abs(enemy->Pose.Position.y - item->Pose.Position.y) < REACHED_GOAL_RADIUS &&
abs(enemy->Pose.Position.z - item->Pose.Position.z) < REACHED_GOAL_RADIUS)
{
TestTriggers(enemy, true);
TestTriggers(enemy, true);
creature->ReachedGoal = true;
creature->Enemy = LaraItem;
item->AIBits &= ~(AMBUSH /* | MODIFY*/);

View file

@ -32,7 +32,7 @@
#include "Game/room.h"
#include "Game/savegame.h"
#include "Game/spotcam.h"
#include "Math/Random.h"
#include "Math/Math.h"
#include "Objects/Effects/tr4_locusts.h"
#include "Objects/Generic/Object/objects.h"
#include "Objects/Generic/Object/rope.h"
@ -65,7 +65,7 @@ using namespace TEN::Entities::Switches;
using namespace TEN::Entities::TR4;
using namespace TEN::Floordata;
using namespace TEN::Input;
using namespace TEN::Math::Random;
using namespace TEN::Math;
using namespace TEN::Renderer;
int GameTimer = 0;
@ -357,12 +357,12 @@ void KillMoveEffects()
int GetRandomControl()
{
return GenerateInt();
return Random::GenerateInt();
}
int GetRandomDraw()
{
return GenerateInt();
return Random::GenerateInt();
}
void CleanUp()

View file

@ -6,51 +6,38 @@
struct CollisionSetup;
constexpr auto NO_EVENT_SET = -1;
constexpr auto VOLUME_BUSY_TIMEOUT = 10;
constexpr auto VOLUME_LEAVE_TIMEOUT = 5;
constexpr auto VOLUME_STATE_QUEUE_SIZE = 16;
enum class VolumeStateStatus
{
Outside,
Entering,
Inside,
Leaving
};
enum class VolumeType
{
Box,
Sphere,
Prism // TODO: Unsupported as of now.
};
struct VolumeState
{
VolumeStateStatus Status = VolumeStateStatus::Outside;
VolumeActivator Activator = nullptr;
int Timestamp = 0;
};
struct TriggerVolume
{
bool Enabled = true;
int EventSetIndex = 0;
VolumeType Type = VolumeType::Box;
std::string Name = {};
BoundingOrientedBox Box = BoundingOrientedBox();
BoundingSphere Sphere = BoundingSphere();
std::vector<VolumeState> StateQueue = {};
};
namespace TEN::Control::Volumes
{
constexpr auto NO_EVENT_SET = -1;
constexpr auto VOLUME_BUSY_TIMEOUT = 10;
constexpr auto VOLUME_LEAVE_TIMEOUT = 5;
constexpr auto VOLUME_STATE_QUEUE_SIZE = 16;
enum class VolumeStateStatus
{
Outside,
Entering,
Inside,
Leaving
};
enum class VolumeType
{
Box,
Sphere,
Prism // TODO: Unsupported as of now.
};
struct VolumeState
{
VolumeStateStatus Status = VolumeStateStatus::Outside;
VolumeActivator Activator = nullptr;
int Timestamp = 0;
};
void TestVolumes(short roomNumber, const BoundingOrientedBox& box, VolumeActivatorFlags activatorFlag, VolumeActivator activator);
void TestVolumes(short itemNumber, const CollisionSetup* coll = nullptr);
void TestVolumes(short roomNumber, MESH_INFO* mesh);
@ -58,3 +45,18 @@ namespace TEN::Control::Volumes
void InitialiseNodeScripts();
}
// TODO: Move into namespace and deal with errors.
struct TriggerVolume
{
bool Enabled = true;
int EventSetIndex = 0;
std::string Name = {};
VolumeType Type = VolumeType::Box;
BoundingOrientedBox Box = BoundingOrientedBox();
BoundingSphere Sphere = BoundingSphere();
std::vector<VolumeState> StateQueue = {};
};

View file

@ -81,7 +81,7 @@ namespace TEN::Effects::Items
void LaraBreath(ItemInfo* item)
{
if (item->IsLara())
if (!item->IsLara())
return;
auto* lara = GetLaraInfo(item);

View file

@ -21,6 +21,7 @@
#include "Specific/setup.h"
using namespace TEN::Effects::Environment;
using namespace TEN::Effects::Smoke;
using namespace TEN::Floordata;
using namespace TEN::Math;
using std::vector;
@ -620,96 +621,7 @@ byte TriggerGunSmoke_SubFunction(LaraWeaponType weaponType)
void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte initial, LaraWeaponType weaponType, byte count)
{
/*
SMOKE_SPARKS* spark;
spark = &SmokeSparks[GetFreeSmokeSpark()];
spark->on = true;
spark->sShade = 0;
spark->dShade = (count << 2);
spark->colFadeSpeed = 4;
spark->fadeToBlack = 32 - (initial << 4);
spark->life = (GetRandomControl() & 3) + 40;
spark->sLife = spark->life;
if (weaponType == LaraWeaponType::Pistol || weaponType == LaraWeaponType::Revolver || weaponType == LaraWeaponType::Uzi)
{
if (spark->dShade > 64)
spark->dShade = 64;
}
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
spark->x = x + (GetRandomControl() & 31) - 16;
spark->y = y + (GetRandomControl() & 31) - 16;
spark->z = z + (GetRandomControl() & 31) - 16;
if (initial)
{
spark->xVel = ((GetRandomControl() & 1023) - 512) + xv;
spark->yVel = ((GetRandomControl() & 1023) - 512) + yv;
spark->zVel = ((GetRandomControl() & 1023) - 512) + zv;
}
else
{
float f = (frand() * 6) - 3;
spark->xVel = (frand() * 6) - 3;
spark->yVel = (frand() * 6) - 3;
spark->zVel = (frand() * 6) - 3;
}
spark->friction = 4;
if (GetRandomControl() & 1)
{
if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
spark->flags = SP_ROTATE | SP_WIND;
else
spark->flags = SP_ROTATE;
spark->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
spark->rotAdd = -(GetRandomControl() & 0x0F) - 16;
else
spark->rotAdd = (GetRandomControl() & 0x0F) + 16;
}
else if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WIND)
{
spark->flags = SP_WIND;
}
else
{
spark->flags = SP_NONE;
}
float gravity = frand() * 1.25f;
spark->gravity = gravity;
spark->maxYvel = frand() * 16;
byte size = ((GetRandomControl() & 0x0F) + 24); // -TriggerGunSmoke_SubFunction(weaponType);
if (initial)
{
spark->sSize = size >> 1;
spark->size = size >> 1;
spark->dSize = (size << 1) + 8;
}
else
{
spark->sSize = size >> 2;
spark->size = size >> 2;
spark->dSize = size;
}
/*if (gfLevelFlags & 0x20 && LaraItem->roomNumber == gfMirrorRoom) // 0x20 = GF_MIRROR_ENABLED
{
spark->mirror = 1;
}
else
{
spark->mirror = 0;
}*/
TEN::Effects::Smoke::TriggerGunSmokeParticles(x, y, z, xv, yv, zv, initial, weaponType, count);
TriggerGunSmokeParticles(x, y, z, xv, yv, zv, initial, weaponType, count);
}
void TriggerShatterSmoke(int x, int y, int z)

View file

@ -1759,7 +1759,7 @@ bool SaveGame::Load(int slot)
ZeroMemory(Lara.Inventory.PickupsCombo, NUM_PICKUPS * 2 * sizeof(int));
for (int i = 0; i < s->lara()->inventory()->pickups_combo()->size(); i++)
{
Lara.Inventory.Pickups[i] = s->lara()->inventory()->pickups_combo()->Get(i);
Lara.Inventory.PickupsCombo[i] = s->lara()->inventory()->pickups_combo()->Get(i);
}
ZeroMemory(Lara.Inventory.Examines, NUM_EXAMINES * sizeof(int));

View file

@ -30,7 +30,7 @@ namespace TEN::Entities::Traps::TR1
object.initialise = InitialiseDamoclesSword;
object.control = ControlDamoclesSword;
object.collision = CollideDamoclesSword;
//object->shadowSize = UNIT_SHADOW;
object.shadowType = ShadowMode::All;
}
void InitialiseDamoclesSword(short itemNumber)

View file

@ -2,6 +2,7 @@
#include "Objects/TR4/Entity/tr4_knight_templar.h"
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/control/box.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
@ -56,6 +57,24 @@ namespace TEN::Entities::TR4
KTEMPLAR_ANIM_WALK_FORWARD_RIGHT_2 = 12
};
void SetupKnightTemplar(ObjectInfo& object)
{
object.initialise = InitialiseKnightTemplar;
object.control = KnightTemplarControl;
object.collision = CreatureCollision;
object.shadowType = ShadowMode::All;
object.HitPoints = 15;
object.hitEffect = HIT_SMOKE;
object.pivotLength = 50;
object.radius = 128;
object.intelligent = true;
object.undead = true;
object.ZoneType = ZoneType::Basic;
g_Level.Bones[object.boneIndex + 6 * 4] |= ROT_X | ROT_Y;
g_Level.Bones[object.boneIndex + 7 * 4] |= ROT_Y;
}
void InitialiseKnightTemplar(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];

View file

@ -1,7 +1,10 @@
#pragma once
struct ObjectInfo;
namespace TEN::Entities::TR4
{
void SetupKnightTemplar(ObjectInfo& object);
void InitialiseKnightTemplar(short itemNumber);
void KnightTemplarControl(short itemNumber);
}

View file

@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
@ -15,36 +16,41 @@
#include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_one_gun.h"
#include "Game/people.h"
#include "Game/misc.h"
#include "Math/Math.h"
#include "Objects/Generic/Object/objects.h"
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Math/Random.h"
#include "Specific/setup.h"
using namespace TEN::Input;
using namespace TEN::Math::Random;
using namespace TEN::Control::Volumes;
using namespace TEN::Input;
using namespace TEN::Math;
namespace TEN::Entities::TR4
{
const auto SasGunBite = BiteInfo(Vector3(0.0f, 300.0f, 64.0f), 7);
constexpr auto SAS_SHOT_DAMAGE = 15;
constexpr auto SAS_WALK_RANGE = SQUARE(BLOCK(2));
constexpr auto SAS_SHOOT_RANGE = SQUARE(BLOCK(3));
const auto SasGunBite = BiteInfo(Vector3(0.0f, 550.0f, 84.0f), 7);
const auto SasDragBodyPosition = Vector3i(0, 0, -460);
const auto SasDragBounds = ObjectCollisionBounds
{
GameBoundingBox(
-BLOCK(1.0f / 4), BLOCK(1.0f / 4),
-BLOCK(0.25f), BLOCK(0.25f),
-100, 100,
-BLOCK(1.0f / 2), -460
),
-BLOCK(0.5f), -460),
std::pair(
EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), 0),
EulerAngles(ANGLE(10.0f), ANGLE(30.0f), 0)
)
EulerAngles(ANGLE(10.0f), ANGLE(30.0f), 0))
};
enum SasState
{
SAS_STATE_NONE = 0,
// No state 0.
SAS_STATE_IDLE = 1,
SAS_STATE_WALK = 2,
SAS_STATE_RUN = 3,
@ -98,16 +104,65 @@ namespace TEN::Entities::TR4
SAS_ANIM_BLIND_TO_STAND = 29
};
void SetupSas(ObjectInfo& object)
{
object.initialise = InitialiseSas;
object.control = SasControl;
object.collision = CreatureCollision;
object.shadowType = ShadowMode::All;
object.biteOffset = 10;
object.HitPoints = 40;
object.hitEffect = HIT_BLOOD;
object.pivotLength = 50;
object.radius = 102;
object.intelligent = true;
object.ZoneType = ZoneType::HumanClassic;
g_Level.Bones[object.boneIndex] |= ROT_Y;
g_Level.Bones[object.boneIndex] |= ROT_X;
g_Level.Bones[object.boneIndex + 28 * 4] |= ROT_Y;
g_Level.Bones[object.boneIndex + 28 * 4] |= ROT_X;
}
void SetupInjuredSas(ObjectInfo& object)
{
object.initialise = InitialiseInjuredSas;
object.control = InjuredSasControl;
object.collision = ObjectCollision;
object.hitEffect = HIT_BLOOD;
object.ZoneType = ZoneType::Basic;
}
void SetupSasDraggableSas(ObjectInfo& object)
{
object.control = AnimatingControl;
object.collision = SasDragBlokeCollision;
}
void InitialiseSas(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
auto& item = g_Level.Items[itemNumber];
ClearItem(itemNumber);
SetAnimation(&item, SAS_ANIM_STAND);
}
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + SAS_ANIM_STAND;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.TargetState = SAS_STATE_IDLE;
item->Animation.ActiveState = SAS_STATE_IDLE;
void InitialiseInjuredSas(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];
if (item.TriggerFlags)
{
item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex;
item.Animation.TargetState = item.Animation.ActiveState = 1;
}
else
{
item.Animation.AnimNumber = Objects[item.ObjectNumber].animIndex + 3;
item.Animation.TargetState = item.Animation.ActiveState = 4;
}
item.Animation.FrameNumber = g_Level.Anims[item.Animation.AnimNumber].frameBase;
}
void SasControl(short itemNumber)
@ -115,9 +170,9 @@ namespace TEN::Entities::TR4
if (!CreatureActive(itemNumber))
return;
auto* item = &g_Level.Items[itemNumber];
auto* creature = (CreatureInfo*)item->Data;
auto* enemy = creature->Enemy;
auto& item = g_Level.Items[itemNumber];
auto& creature = *(CreatureInfo*)item.Data;
auto& enemy = creature.Enemy;
short tilt = 0;
short angle = 0;
@ -126,233 +181,221 @@ namespace TEN::Entities::TR4
short joint2 = 0;
// Handle SAS firing.
if (creature->FiredWeapon)
if (creature.FiredWeapon)
{
auto pos = GetJointPosition(item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
auto pos = GetJointPosition(&item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 24, 16, 4);
creature->FiredWeapon--;
creature.FiredWeapon--;
}
if (item->HitPoints > 0)
if (item.HitPoints > 0)
{
if (item->AIBits)
GetAITarget(creature);
if (item.AIBits)
GetAITarget(&creature);
else
creature->Enemy = LaraItem;
creature.Enemy = LaraItem;
AI_INFO AI;
CreatureAIInfo(item, &AI);
CreatureAIInfo(&item, &AI);
int distance = 0;
float distance2D = 0;
int angle = 0;
if (creature->Enemy->IsLara())
if (creature.Enemy->IsLara())
{
angle = AI.angle;
distance = AI.distance;
distance2D = AI.distance;
}
else
{
int dx = LaraItem->Pose.Position.x - item->Pose.Position.x;
int dz = LaraItem->Pose.Position.z - item->Pose.Position.z;
int ang = phd_atan(dz, dx) - item->Pose.Orientation.y;
distance = pow(dx, 2) + pow(dz, 2);
distance2D = Vector2::Distance(
Vector2(item.Pose.Position.x, item.Pose.Position.z),
Vector2(LaraItem->Pose.Position.x, LaraItem->Pose.Position.z));
}
GetCreatureMood(item, &AI, !creature->Enemy->IsLara());
GetCreatureMood(&item, &AI, !creature.Enemy->IsLara());
// Vehicle handling
if (Lara.Vehicle != NO_ITEM && AI.bite)
creature->Mood = MoodType::Escape;
creature.Mood = MoodType::Escape;
CreatureMood(item, &AI, !creature->Enemy->IsLara());
angle = CreatureTurn(item, creature->MaxTurn);
CreatureMood(&item, &AI, !creature.Enemy->IsLara());
angle = CreatureTurn(&item, creature.MaxTurn);
if (item->HitStatus)
if (item.HitStatus)
AlertAllGuards(itemNumber);
int angle1 = 0;
int angle2 = 0;
switch (item->Animation.ActiveState)
switch (item.Animation.ActiveState)
{
case SAS_STATE_IDLE:
creature->MaxTurn = 0;
creature->Flags = 0;
creature.MaxTurn = 0;
creature.Flags = 0;
joint2 = angle;
if (item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + SAS_ANIM_WALK_TO_STAND)
if (item.Animation.AnimNumber == Objects[item.ObjectNumber].animIndex + SAS_ANIM_WALK_TO_STAND)
{
if (abs(AI.angle) >= ANGLE(10.0f))
{
if (AI.angle >= 0)
item->Pose.Orientation.y += ANGLE(10.0f);
else
item->Pose.Orientation.y -= ANGLE(10.0f);
}
if (abs(AI.angle) < ANGLE(10.0f))
item.Pose.Orientation.y += AI.angle;
else if (AI.angle < 0)
item.Pose.Orientation.y -= ANGLE(10.0f);
else
item->Pose.Orientation.y += AI.angle;
item.Pose.Orientation.y += ANGLE(10.0f);
}
else if (item->AIBits & MODIFY || Lara.Vehicle != NO_ITEM)
else if (item.AIBits & MODIFY || Lara.Vehicle != NO_ITEM)
{
if (abs(AI.angle) >= ANGLE(2.0f))
{
if (AI.angle >= 0)
item->Pose.Orientation.y += ANGLE(2.0f);
else
item->Pose.Orientation.y -= ANGLE(2.0f);
}
if (abs(AI.angle) < ANGLE(2.0f))
item.Pose.Orientation.y += AI.angle;
else if (AI.angle < 0)
item.Pose.Orientation.y -= ANGLE(2.0f);
else
item->Pose.Orientation.y += AI.angle;
item.Pose.Orientation.y += ANGLE(2.0f);
}
if (item->AIBits & GUARD)
if (item.AIBits & GUARD)
{
joint2 = AIGuard(creature);
joint2 = AIGuard(&creature);
if (!GetRandomControl())
if (!(GetRandomControl() & 0xFF))
{
if (item->Animation.ActiveState == SAS_STATE_IDLE)
{
item->Animation.TargetState = SAS_STATE_WAIT;
break;
}
item->Animation.TargetState = SAS_STATE_IDLE;
if (item.Animation.ActiveState == SAS_STATE_IDLE)
item.Animation.TargetState = SAS_STATE_WAIT;
else
item.Animation.TargetState = SAS_STATE_IDLE;
}
}
else if (!(item->AIBits & PATROL1) ||
item->AIBits & MODIFY ||
Lara.Vehicle != NO_ITEM)
else if (item.AIBits & PATROL1 &&
item.AIBits != MODIFY &&
Lara.Vehicle == NO_ITEM)
{
if (Targetable(item, &AI))
item.Animation.TargetState = SAS_STATE_WALK;
joint2 = 0;
}
else if (Targetable(&item, &AI))
{
if (AI.distance >= SAS_SHOOT_RANGE &&
AI.zoneNumber == AI.enemyZone)
{
if (AI.distance < pow(SECTOR(3), 2) ||
AI.zoneNumber != AI.enemyZone)
{
if (TestProbability(0.5f))
item->Animation.TargetState = SAS_STATE_SIGHT_AIM;
else if (TestProbability(0.5f))
item->Animation.TargetState = SAS_STATE_HOLD_AIM;
else
item->Animation.TargetState = SAS_STATE_KNEEL_AIM;
}
else if (!(item->AIBits & MODIFY))
item->Animation.TargetState = SAS_STATE_WALK;
if (item.AIBits != MODIFY)
item.Animation.TargetState = SAS_STATE_WALK;
}
else if (Random::TestProbability(1 / 2.0f))
{
item.Animation.TargetState = SAS_STATE_SIGHT_AIM;
}
else if (Random::TestProbability(1 / 2.0f))
{
item.Animation.TargetState = SAS_STATE_HOLD_AIM;
}
else
{
if (item->AIBits & MODIFY)
item->Animation.TargetState = SAS_STATE_IDLE;
else
{
if (creature->Mood == MoodType::Escape)
item->Animation.TargetState = SAS_STATE_RUN;
else
{
if ((creature->Alerted ||
creature->Mood != MoodType::Bored) &&
(!(item->AIBits & FOLLOW) ||
!creature->ReachedGoal &&
distance <= pow(SECTOR(2), 2)))
{
if (creature->Mood == MoodType::Bored ||
AI.distance <= pow(SECTOR(2), 2))
{
item->Animation.TargetState = SAS_STATE_WALK;
break;
}
item->Animation.TargetState = SAS_STATE_RUN;
}
else
item->Animation.TargetState = SAS_STATE_IDLE;
}
}
item.Animation.TargetState = SAS_STATE_KNEEL_AIM;
}
}
else if (item.AIBits == MODIFY)
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
else if (creature.Mood == MoodType::Escape)
{
item.Animation.TargetState = SAS_STATE_RUN;
}
else if ((creature.Alerted || creature.Mood != MoodType::Bored) &&
(!(item.AIBits & FOLLOW) || (!creature.ReachedGoal && distance2D <= SAS_WALK_RANGE)))
{
if (creature.Mood != MoodType::Bored &&
AI.distance > SAS_WALK_RANGE)
{
item.Animation.TargetState = SAS_STATE_RUN;
}
else
{
item.Animation.TargetState = SAS_STATE_WALK;
}
}
else
{
item->Animation.TargetState = SAS_STATE_WALK;
joint2 = 0;
item.Animation.TargetState = SAS_STATE_IDLE;
}
break;
case SAS_STATE_WAIT:
creature->MaxTurn = 0;
creature->Flags = 0;
creature.MaxTurn = 0;
creature.Flags = 0;
joint2 = angle;
if (item->AIBits & GUARD)
if (item.AIBits & GUARD)
{
joint2 = AIGuard(creature);
joint2 = AIGuard(&creature);
if (!GetRandomControl())
item->Animation.TargetState = SAS_STATE_IDLE;
if (!(GetRandomControl() & 0xFF))
item.Animation.TargetState = SAS_STATE_IDLE;
}
else if (Targetable(item, &AI) ||
creature->Mood != MoodType::Bored ||
else if (Targetable(&item, &AI) ||
creature.Mood == MoodType::Bored ||
!AI.ahead ||
item->AIBits & MODIFY ||
item.AIBits & MODIFY ||
Lara.Vehicle != NO_ITEM)
{
item->Animation.TargetState = SAS_STATE_IDLE;
item.Animation.TargetState = SAS_STATE_IDLE;
}
break;
case SAS_STATE_WALK:
creature->MaxTurn = ANGLE(5.0f);
creature->Flags = 0;
creature.MaxTurn = ANGLE(5.0f);
creature.Flags = 0;
joint2 = angle;
if (item->AIBits & PATROL1)
item->Animation.TargetState = SAS_STATE_WALK;
else if (Lara.Vehicle == NO_ITEM ||
!(item->AIBits & MODIFY) &&
item->AIBits)
if (item.AIBits & PATROL1)
{
if (creature->Mood == MoodType::Escape)
item->Animation.TargetState = SAS_STATE_RUN;
item.Animation.TargetState = SAS_STATE_WALK;
}
else if (Lara.Vehicle != NO_ITEM &&
(item.AIBits == MODIFY ||
!item.AIBits))
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
else if (creature.Mood == MoodType::Escape)
{
item.Animation.TargetState = SAS_STATE_RUN;
}
else if (item.AIBits & GUARD ||
item.AIBits & FOLLOW &&
(creature.ReachedGoal ||
distance2D > SAS_WALK_RANGE))
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
else if (Targetable(&item, &AI))
{
if (AI.distance >= SAS_SHOOT_RANGE &&
AI.zoneNumber == AI.enemyZone)
{
item.Animation.TargetState = SAS_STATE_WALK_AIM;
}
else
{
if (item->AIBits & GUARD ||
item->AIBits & FOLLOW &&
(creature->ReachedGoal ||
distance > pow(SECTOR(2), 2)))
{
item->Animation.TargetState = SAS_STATE_IDLE;
break;
}
if (Targetable(item, &AI))
{
if (AI.distance < pow(SECTOR(3), 2) ||
AI.enemyZone != AI.zoneNumber)
{
item->Animation.TargetState = SAS_STATE_IDLE;
break;
}
item->Animation.TargetState = SAS_STATE_WALK_AIM;
}
else if (creature->Mood != MoodType::Bored)
{
if (AI.distance > pow(SECTOR(2), 2))
item->Animation.TargetState = SAS_STATE_RUN;
}
else if (AI.ahead)
{
item->Animation.TargetState = SAS_STATE_IDLE;
break;
}
item.Animation.TargetState = SAS_STATE_IDLE;
}
}
else
item->Animation.TargetState = SAS_STATE_IDLE;
else if (creature.Mood != MoodType::Bored)
{
if (AI.distance > SAS_WALK_RANGE)
item.Animation.TargetState = SAS_STATE_RUN;
}
else if (AI.ahead)
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
break;
case SAS_STATE_RUN:
creature->MaxTurn = ANGLE(10.0f);
creature.MaxTurn = ANGLE(10.0f);
tilt = angle / 2;
if (AI.ahead)
@ -360,35 +403,30 @@ namespace TEN::Entities::TR4
if (Lara.Vehicle != NO_ITEM)
{
if (item->AIBits & MODIFY || !item->AIBits)
if (item.AIBits == MODIFY || !item.AIBits)
{
item->Animation.TargetState = SAS_STATE_WAIT;
item.Animation.TargetState = SAS_STATE_WALK;
break;
}
}
if (item->AIBits & GUARD ||
item->AIBits & FOLLOW &&
(creature->ReachedGoal ||
distance > pow(SECTOR(2), 2)))
if (item.AIBits & GUARD ||
(item.AIBits & FOLLOW && (creature.ReachedGoal || distance2D > SAS_WALK_RANGE)))
{
item->Animation.TargetState = SAS_STATE_WALK;
break;
item.Animation.TargetState = SAS_STATE_WALK;
}
if (creature->Mood != MoodType::Escape)
else if (creature.Mood != MoodType::Escape)
{
if (Targetable(item, &AI))
item->Animation.TargetState = SAS_STATE_WALK;
else
if (Targetable(&item, &AI))
{
if (creature->Mood != MoodType::Bored ||
creature->Mood == MoodType::Stalk &&
item->AIBits & FOLLOW &&
AI.distance < pow(SECTOR(2), 2))
{
item->Animation.TargetState = SAS_STATE_WALK;
}
item.Animation.TargetState = SAS_STATE_WALK;
}
else if (creature.Mood == MoodType::Bored ||
(creature.Mood == MoodType::Stalk &&
!(item.AIBits & FOLLOW) &&
AI.distance < SAS_WALK_RANGE))
{
item.Animation.TargetState = SAS_STATE_WALK;
}
}
@ -397,42 +435,52 @@ namespace TEN::Entities::TR4
case SAS_STATE_SIGHT_AIM:
case SAS_STATE_HOLD_AIM:
case SAS_STATE_KNEEL_AIM:
creature->Flags = 0;
creature.Flags = 0;
if (AI.ahead)
{
joint0 = AI.angle;
joint1 = AI.xAngle;
if (Targetable(item, &AI))
if (Targetable(&item, &AI))
{
if (item->Animation.ActiveState == SAS_STATE_SIGHT_AIM)
item->Animation.TargetState = SAS_STATE_SIGHT_SHOOT;
else if (item->Animation.ActiveState == SAS_STATE_KNEEL_AIM)
item->Animation.TargetState = SAS_STATE_KNEEL_SHOOT;
else if (TestProbability(0.5f))
item->Animation.TargetState = SAS_STATE_HOLD_SHOOT;
if (item.Animation.ActiveState == SAS_STATE_SIGHT_AIM)
{
item.Animation.TargetState = SAS_STATE_SIGHT_SHOOT;
}
else if (item.Animation.ActiveState == SAS_STATE_KNEEL_AIM)
{
item.Animation.TargetState = SAS_STATE_KNEEL_SHOOT;
}
else if (Random::TestProbability(1 / 2.0f))
{
item.Animation.TargetState = SAS_STATE_HOLD_SHOOT;
}
else
item->Animation.TargetState = SAS_STATE_HOLD_PREPARE_GRENADE;
{
item.Animation.TargetState = SAS_STATE_HOLD_PREPARE_GRENADE;
}
}
else
item->Animation.TargetState = SAS_STATE_IDLE;
{
item.Animation.TargetState = SAS_STATE_IDLE;
}
}
break;
case SAS_STATE_WALK_AIM:
creature->Flags = 0;
creature.Flags = 0;
if (AI.ahead)
{
joint0 = AI.angle;
joint1 = AI.xAngle;
if (Targetable(item, &AI))
item->Animation.TargetState = SAS_STATE_WALK_SHOOT;
if (Targetable(&item, &AI))
item.Animation.TargetState = SAS_STATE_WALK_SHOOT;
else
item->Animation.TargetState = SAS_STATE_WALK;
item.Animation.TargetState = SAS_STATE_WALK;
}
break;
@ -454,7 +502,7 @@ namespace TEN::Entities::TR4
joint0 = AI.angle;
joint1 = AI.xAngle;
if (AI.distance > pow(SECTOR(3), 2))
if (AI.distance > SAS_SHOOT_RANGE)
{
angle2 = sqrt(AI.distance) + AI.xAngle - ANGLE(5.6f);
joint1 = angle2;
@ -466,9 +514,9 @@ namespace TEN::Entities::TR4
angle2 = 0;
}
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 20)
if (item.Animation.FrameNumber == (g_Level.Anims[item.Animation.AnimNumber].frameBase + 20))
{
if (!creature->Enemy->Animation.Velocity.z)
if (!creature.Enemy->Animation.Velocity.z)
{
angle1 += (GetRandomControl() & 0x1FF) - 256;
angle2 += (GetRandomControl() & 0x1FF) - 256;
@ -478,8 +526,8 @@ namespace TEN::Entities::TR4
SasFireGrenade(item, angle2, angle1);
if (Targetable(item, &AI))
item->Animation.TargetState = SAS_STATE_HOLD_PREPARE_GRENADE;
if (Targetable(&item, &AI))
item.Animation.TargetState = SAS_STATE_HOLD_PREPARE_GRENADE;
}
break;
@ -488,18 +536,18 @@ namespace TEN::Entities::TR4
case SAS_STATE_KNEEL_SHOOT:
case SAS_STATE_SIGHT_SHOOT:
case SAS_STATE_WALK_SHOOT:
if (item->Animation.ActiveState == SAS_STATE_HOLD_SHOOT ||
item->Animation.ActiveState == SAS_STATE_KNEEL_SHOOT)
if (item.Animation.ActiveState == SAS_STATE_HOLD_SHOOT ||
item.Animation.ActiveState == SAS_STATE_KNEEL_SHOOT)
{
if (item->Animation.TargetState != SAS_STATE_IDLE &&
item->Animation.TargetState != SAS_STATE_KNEEL_STOP &&
(creature->Mood == MoodType::Escape ||
!Targetable(item, &AI)))
if (item.Animation.TargetState != SAS_STATE_IDLE &&
item.Animation.TargetState != SAS_STATE_KNEEL_STOP &&
(creature.Mood == MoodType::Escape ||
!Targetable(&item, &AI)))
{
if (item->Animation.ActiveState == SAS_STATE_HOLD_SHOOT)
item->Animation.TargetState = SAS_STATE_IDLE;
if (item.Animation.ActiveState == SAS_STATE_HOLD_SHOOT)
item.Animation.TargetState = SAS_STATE_IDLE;
else
item->Animation.TargetState = SAS_STATE_KNEEL_STOP;
item.Animation.TargetState = SAS_STATE_KNEEL_STOP;
}
}
@ -509,20 +557,22 @@ namespace TEN::Entities::TR4
joint1 = AI.xAngle;
}
if (creature->Flags)
creature->Flags -= 1;
if (creature.Flags)
{
creature.Flags -= 1;
}
else
{
ShotLara(item, &AI, SasGunBite, joint0, 15);
creature->Flags = 5;
creature->FiredWeapon = 3;
ShotLara(&item, &AI, SasGunBite, joint0, SAS_SHOT_DAMAGE);
creature.FiredWeapon = 3;
creature.Flags = 5;
}
break;
case SAS_STATE_BLIND:
if (!FlashGrenadeAftershockTimer && !(GetRandomControl() & 0x7F))
item->Animation.TargetState = SAS_STATE_WAIT;
if (!FlashGrenadeAftershockTimer && !(GetRandomControl() & 0x7F)) // TODO: This is a probabliity of roughly 0.998f.
item.Animation.TargetState = SAS_STATE_WAIT;
break;
@ -531,169 +581,150 @@ namespace TEN::Entities::TR4
}
if (FlashGrenadeAftershockTimer > 100 &&
item->Animation.ActiveState != SAS_STATE_BLIND)
item.Animation.ActiveState != SAS_STATE_BLIND)
{
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + SAS_ANIM_BLIND;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase + (GetRandomControl() & 7);
item->Animation.ActiveState = SAS_STATE_BLIND;
creature->MaxTurn = 0;
SetAnimation(&item, SAS_ANIM_BLIND, Random::GenerateInt(0, 8));
creature.MaxTurn = 0;
}
}
else
{
if (item->Animation.ActiveState != SAS_STATE_DEATH)
{
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + SAS_ANIM_DEATH;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.ActiveState = SAS_STATE_DEATH;
}
if (item.Animation.ActiveState != SAS_STATE_DEATH)
SetAnimation(&item, SAS_ANIM_DEATH);
}
CreatureTilt(item, tilt);
CreatureJoint(item, 0, joint0);
CreatureJoint(item, 1, joint1);
CreatureJoint(item, 2, joint2);
CreatureTilt(&item, tilt);
CreatureJoint(&item, 0, joint0);
CreatureJoint(&item, 1, joint1);
CreatureJoint(&item, 2, joint2);
CreatureAnimation(itemNumber, angle, 0);
}
void SasFireGrenade(ItemInfo* item, short angle1, short angle2)
{
short itemNumber = CreateItem();
if (itemNumber != NO_ITEM)
{
auto* grenadeItem = &g_Level.Items[itemNumber];
grenadeItem->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
grenadeItem->ObjectNumber = ID_GRENADE;
grenadeItem->RoomNumber = item->RoomNumber;
auto pos = GetJointPosition(item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
grenadeItem->Pose.Position = pos;
auto probe = GetCollision(pos.x, pos.y, pos.z, grenadeItem->RoomNumber);
grenadeItem->RoomNumber = probe.RoomNumber;
if (probe.Position.Floor < grenadeItem->Pose.Position.y)
{
grenadeItem->Pose.Position = Vector3i(item->Pose.Position.x, probe.Position.Floor, item->Pose.Position.z);
grenadeItem->RoomNumber = item->RoomNumber;
}
for (int i = 0; i < 5; i++)
TriggerGunSmoke(pos.x, pos.y, pos.z, 0, 0, 0, 1, LaraWeaponType::GrenadeLauncher, 32);
InitialiseItem(itemNumber);
grenadeItem->Pose.Orientation.x = angle1 + item->Pose.Orientation.x;
grenadeItem->Pose.Orientation.y = angle2 + item->Pose.Orientation.y;
grenadeItem->Pose.Orientation.z = 0;
if (TestProbability(0.75f))
grenadeItem->ItemFlags[0] = (int)GrenadeType::Normal;
else
grenadeItem->ItemFlags[0] = (int)GrenadeType::Super;
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
grenadeItem->Animation.RequiredState = 0;
grenadeItem->Animation.Velocity.z = 128;
grenadeItem->Animation.Velocity.y = -128 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->HitPoints = 120;
grenadeItem->ItemFlags[2] = 1;
AddActiveItem(itemNumber);
}
}
void InitialiseInjuredSas(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
if (item->TriggerFlags)
{
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex;
item->Animation.TargetState = item->Animation.ActiveState = 1;
}
else
{
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 3;
item->Animation.TargetState = item->Animation.ActiveState = 4;
}
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
}
void InjuredSasControl(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
auto& item = g_Level.Items[itemNumber];
if (item->Animation.ActiveState == 1)
if (item.Animation.ActiveState == 1)
{
if (TestProbability(1.0f / 128))
if (Random::TestProbability(1 / 128.0f))
{
item->Animation.TargetState = 2;
AnimateItem(item);
item.Animation.TargetState = 2;
AnimateItem(&item);
}
else if (!(byte)GetRandomControl())
item->Animation.TargetState = 3;
{
item.Animation.TargetState = 3;
}
}
else if (item->Animation.ActiveState == 4 &&
TestProbability(1.0f / 128))
else if (item.Animation.ActiveState == 4 &&
Random::TestProbability(1 / 128.0f))
{
item->Animation.TargetState = 5;
AnimateItem(item);
item.Animation.TargetState = 5;
AnimateItem(&item);
}
else
AnimateItem(item);
{
AnimateItem(&item);
}
}
void SasDragBlokeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
{
auto* item = &g_Level.Items[itemNumber];
auto* lara = GetLaraInfo(laraItem);
auto& item = g_Level.Items[itemNumber];
auto& player = *GetLaraInfo(laraItem);
if ((IsHeld(In::Action) &&
laraItem->Animation.ActiveState == LS_IDLE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
lara->Control.HandStatus == HandStatus::Free &&
player.Control.HandStatus == HandStatus::Free &&
!laraItem->Animation.IsAirborne &&
!(item->Flags & IFLAG_ACTIVATION_MASK)) ||
lara->Control.IsMoving && lara->InteractedItem == itemNumber)
!(item.Flags & IFLAG_ACTIVATION_MASK)) ||
player.Control.IsMoving && player.InteractedItem == itemNumber)
{
if (TestLaraPosition(SasDragBounds, item, laraItem))
if (TestLaraPosition(SasDragBounds, &item, laraItem))
{
if (MoveLaraPosition(SasDragBodyPosition, item, laraItem))
if (MoveLaraPosition(SasDragBodyPosition, &item, laraItem))
{
SetAnimation(laraItem, LA_DRAG_BODY);
ResetLaraFlex(laraItem);
laraItem->Pose.Orientation.y = item->Pose.Orientation.y;
lara->Control.HandStatus = HandStatus::Busy;
lara->Control.IsMoving = false;
laraItem->Pose.Orientation.y = item.Pose.Orientation.y;
player.Control.HandStatus = HandStatus::Busy;
player.Control.IsMoving = false;
AddActiveItem(itemNumber);
item->Flags |= IFLAG_ACTIVATION_MASK;
item->Status = ITEM_ACTIVE;
item.Flags |= IFLAG_ACTIVATION_MASK;
item.Status = ITEM_ACTIVE;
}
else
lara->InteractedItem = itemNumber;
{
player.InteractedItem = itemNumber;
}
}
}
else
{
if (item->Status != ITEM_ACTIVE)
if (item.Status != ITEM_ACTIVE)
{
ObjectCollision(itemNumber, laraItem, coll);
return;
}
if (!TestLastFrame(item))
if (!TestLastFrame(&item))
return;
auto pos = GetJointPosition(item, 0);
TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true);
auto pos = GetJointPosition(&item, 0);
TestTriggers(pos.x, pos.y, pos.z, item.RoomNumber, true);
RemoveActiveItem(itemNumber);
item->Status = ITEM_DEACTIVATED;
item.Status = ITEM_DEACTIVATED;
}
}
void SasFireGrenade(ItemInfo& item, short angle1, short angle2)
{
short itemNumber = CreateItem();
if (itemNumber == NO_ITEM)
return;
auto grenadeItem = &g_Level.Items[itemNumber];
grenadeItem->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f);
grenadeItem->ObjectNumber = ID_GRENADE;
grenadeItem->RoomNumber = item.RoomNumber;
auto pos = GetJointPosition(&item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
grenadeItem->Pose.Position = pos;
auto floorHeight = GetCollision(pos.x, pos.y, pos.z, grenadeItem->RoomNumber).Position.Floor;
if (floorHeight < pos.y)
{
grenadeItem->Pose.Position = Vector3i(item.Pose.Position.x, pos.y, item.Pose.Position.z);
grenadeItem->RoomNumber = item.RoomNumber;
}
for (int i = 0; i < 5; i++)
TriggerGunSmoke(pos.x, pos.y, pos.z, 0, 0, 0, 1, LaraWeaponType::GrenadeLauncher, 32);
InitialiseItem(itemNumber);
grenadeItem->Pose.Orientation = EulerAngles(
angle1 + item.Pose.Orientation.x,
angle2 + item.Pose.Orientation.y,
0);
grenadeItem->Animation.Velocity.y = -128 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->Animation.Velocity.z = 128;
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
grenadeItem->Animation.RequiredState = 0;
if (Random::TestProbability(3 / 4.0f))
grenadeItem->ItemFlags[0] = (int)ProjectileType::Grenade;
else
grenadeItem->ItemFlags[0] = (int)ProjectileType::FragGrenade;
grenadeItem->HitPoints = 120;
grenadeItem->ItemFlags[2] = 1;
AddActiveItem(itemNumber);
}
}

View file

@ -1,12 +1,21 @@
#pragma once
#include "Game/collision/collide_room.h"
struct CollisionInfo;
struct ItemInfo;
struct ObjectInfo;
namespace TEN::Entities::TR4
{
void SetupSas(ObjectInfo& object);
void SetupInjuredSas(ObjectInfo& object);
void SetupSasDraggableSas(ObjectInfo& object);
void InitialiseSas(short itemNumber);
void SasControl(short itemNumber);
void InitialiseInjuredSas(short itemNumber);
void SasControl(short itemNumber);
void InjuredSasControl(short itemNumber);
void SasDragBlokeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void SasFireGrenade(ItemInfo* item, short angle1, short angle2);
void SasFireGrenade(ItemInfo& item, short angle1, short angle2);
}

View file

@ -3,6 +3,7 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/collision/collide_item.h"
#include "Game/collision/collide_room.h"
#include "Game/control/control.h"
#include "Game/effects/effects.h"
@ -108,6 +109,21 @@ namespace TEN::Entities::TR4
SETH_ANIM_HOVER_IDLE = 28
};
void SetupSeth(ObjectInfo& object)
{
object.initialise = InitialiseSeth;
object.control = SethControl;
object.collision = CreatureCollision;
object.shadowType = ShadowMode::All;
object.HitPoints = 500;
object.hitEffect = HIT_NONE;
object.pivotLength = 50;
object.radius = 341;
object.intelligent = true;
object.undead = true;
object.ZoneType = ZoneType::Basic;
}
void InitialiseSeth(short itemNumber)
{
auto& item = g_Level.Items[itemNumber];

View file

@ -2,11 +2,14 @@
class Pose;
struct ItemInfo;
struct ObjectInfo;
namespace TEN::Entities::TR4
{
void SetupSeth(ObjectInfo& object);
void InitialiseSeth(short itemNumber);
void SethControl(short itemNumber);
void SethProjectileAttack(const Pose& pose, int roomNumber, int flags);
void SethAttack(int itemNumber);
void SethKillAttack(ItemInfo* item, ItemInfo* laraItem);

View file

@ -10,76 +10,76 @@
#include "Specific/level.h"
// Creatures
#include "tr4_enemy_jeep.h"
#include "tr4_ahmet.h" // OK
#include "tr4_baddy.h" // OK
#include "tr4_bat.h" // OK
#include "tr4_big_scorpion.h" // OK
#include "tr4_crocodile.h" // OK
#include "tr4_demigod.h" // OK
#include "tr4_guide.h" // OK
#include "tr4_harpy.h" // OK
#include "tr4_horseman.h" // OFF
#include "tr4_jean_yves.h" // OK
#include "tr4_knight_templar.h" // OK
#include "Objects/TR4/Entity/tr4_enemy_jeep.h"
#include "Objects/TR4/Entity/tr4_ahmet.h" // OK
#include "Objects/TR4/Entity/tr4_baddy.h" // OK
#include "Objects/TR4/Entity/tr4_bat.h" // OK
#include "Objects/TR4/Entity/tr4_big_scorpion.h" // OK
#include "Objects/TR4/Entity/tr4_crocodile.h" // OK
#include "Objects/TR4/Entity/tr4_demigod.h" // OK
#include "Objects/TR4/Entity/tr4_guide.h" // OK
#include "Objects/TR4/Entity/tr4_harpy.h" // OK
#include "Objects/TR4/Entity/tr4_horseman.h" // OFF
#include "Objects/TR4/Entity/tr4_jean_yves.h" // OK
#include "Objects/TR4/Entity/tr4_knight_templar.h" // OK
#include "Objects/TR4/Entity/tr4_lara_double.h"
#include "Objects/TR4/Entity/tr4_beetle_swarm.h"
#include "tr4_mummy.h" // OK
#include "tr4_sas.h" // OK
#include "tr4_sentry_gun.h" // OK
#include "tr4_skeleton.h" // OK
#include "tr4_small_scorpion.h" // OK
#include "tr4_sphinx.h" // OK
#include "tr4_troops.h" // OK
#include "tr4_wild_boar.h" // OK
#include "tr4_wraith.h" // OFF
#include "tr4_baboon.h" // OK
#include "tr4_mutant.h" // OK
#include "tr4_locusts.h" // OK
#include "tr4_big_beetle.h" // OFF
#include "tr4_joby_spikes.h"
#include "tr4_mapper.h"
#include "tr4_moving_blade.h"
#include "tr4_element_puzzle.h"
#include "tr4_von_croy.h"
#include "tr4_hammerhead.h"
#include "tr4_dog.h"
#include "tr4_hammer.h"
#include "Objects/TR4/Entity/tr4_mummy.h" // OK
#include "Objects/TR4/Entity/tr4_sas.h" // OK
#include "Objects/TR4/Entity/tr4_sentry_gun.h" // OK
#include "Objects/TR4/Entity/tr4_skeleton.h" // OK
#include "Objects/TR4/Entity/tr4_small_scorpion.h" // OK
#include "Objects/TR4/Entity/tr4_sphinx.h" // OK
#include "Objects/TR4/Entity/tr4_troops.h" // OK
#include "Objects/TR4/Entity/tr4_wild_boar.h" // OK
#include "Objects/TR4/Entity/tr4_wraith.h" // OFF
#include "Objects/TR4/Entity/tr4_baboon.h" // OK
#include "Objects/TR4/Entity/tr4_mutant.h" // OK
#include "Objects/TR4/Entity/tr4_big_beetle.h" // OFF
#include "Objects/TR4/Entity/tr4_von_croy.h"
#include "Objects/TR4/Entity/tr4_hammerhead.h"
#include "Objects/TR4/Entity/tr4_dog.h"
#include "Objects/TR4/Entity/tr4_setha.h"
// Objects
#include "tr4_sarcophagus.h"
#include "tr4_senet.h"
#include "Objects/TR4/Object/tr4_element_puzzle.h"
#include "Objects/TR4/Object/tr4_mapper.h"
#include "Objects/TR4/Object/tr4_sarcophagus.h"
#include "Objects/TR4/Object/tr4_senet.h"
#include "Objects/TR4/Object/tr4_clockwork_beetle.h"
#include "tr4_obelisk.h"
// Puzzles
#include "tr4_scales.h"
#include "Objects/TR4/Object/tr4_obelisk.h"
#include "Objects/TR4/Object/tr4_scales.h"
// Switches
// Traps
#include "tr4_birdblade.h"
#include "tr4_blade.h"
#include "tr4_catwalkblade.h"
#include "tr4_chain.h"
#include "tr4_fourblades.h"
#include "tr4_mine.h"
#include "tr4_plinthblade.h"
#include "tr4_plough.h"
#include "tr4_sethblade.h"
#include "tr4_slicerdicer.h"
#include "tr4_spikeball.h"
#include "tr4_spikywall.h"
#include "tr4_spikyceiling.h"
#include "tr4_stargate.h"
#include "tr4_cog.h"
#include "tr4_lara_double.h"
#include "tr4_setha.h"
#include "tr4_teethspike.h"
#include "Objects/TR4/Trap/tr4_birdblade.h"
#include "Objects/TR4/Trap/tr4_blade.h"
#include "Objects/TR4/Trap/tr4_catwalkblade.h"
#include "Objects/TR4/Trap/tr4_chain.h"
#include "Objects/TR4/Trap/tr4_fourblades.h"
#include "Objects/TR4/Trap/tr4_hammer.h"
#include "Objects/TR4/Trap/tr4_joby_spikes.h"
#include "Objects/TR4/Trap/tr4_mine.h"
#include "Objects/TR4/Trap/tr4_moving_blade.h"
#include "Objects/TR4/Trap/tr4_plinthblade.h"
#include "Objects/TR4/Trap/tr4_plough.h"
#include "Objects/TR4/Trap/tr4_sethblade.h"
#include "Objects/TR4/Trap/tr4_slicerdicer.h"
#include "Objects/TR4/Trap/tr4_spikeball.h"
#include "Objects/TR4/Trap/tr4_spikywall.h"
#include "Objects/TR4/Trap/tr4_spikyceiling.h"
#include "Objects/TR4/Trap/tr4_stargate.h"
#include "Objects/TR4/Trap/tr4_cog.h"
#include "Objects/TR4/Trap/tr4_teethspike.h"
// Vehicles
#include "Objects/TR4/Vehicles/jeep.h"
#include "Objects/TR4/Vehicles/motorbike.h"
// Effects
#include "Objects/Effects/tr4_locusts.h" // OK
using namespace TEN::Entities::Traps;
namespace TEN::Entities
@ -242,23 +242,7 @@ namespace TEN::Entities
obj = &Objects[ID_SAS_CAIRO];
if (obj->loaded)
{
obj->biteOffset = 10;
obj->initialise = InitialiseSas;
obj->control = SasControl;
obj->collision = CreatureCollision;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
obj->radius = 102;
obj->intelligent = true;
obj->ZoneType = ZoneType::HumanClassic;
g_Level.Bones[obj->boneIndex] |= ROT_Y;
g_Level.Bones[obj->boneIndex] |= ROT_X;
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_X;
}
SetupSas(*obj);
obj = &Objects[ID_MUMMY];
if (obj->loaded)
@ -298,19 +282,6 @@ namespace TEN::Entities
obj = &Objects[ID_KNIGHT_TEMPLAR];
if (obj->loaded)
{
obj->initialise = InitialiseKnightTemplar;
obj->control = KnightTemplarControl;
obj->collision = CreatureCollision;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
obj->radius = 128;
obj->intelligent = true;
obj->undead = true;
obj->ZoneType = ZoneType::Basic;
g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X | ROT_Y;
g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y;
}
obj = &Objects[ID_BIG_BEETLE];
@ -650,13 +621,7 @@ namespace TEN::Entities
obj = &Objects[ID_SAS_DYING];
if (obj->loaded)
{
obj->initialise = InitialiseInjuredSas;
obj->control = InjuredSasControl;
obj->collision = ObjectCollision;
obj->hitEffect = HIT_BLOOD;
obj->ZoneType = ZoneType::Basic;
}
SetupInjuredSas(*obj);
obj = &Objects[ID_ENEMY_JEEP];
if (obj->loaded)
@ -699,10 +664,7 @@ namespace TEN::Entities
{
obj = &Objects[ID_SAS_DRAG_BLOKE];
if (obj->loaded)
{
obj->control = AnimatingControl;
obj->collision = SasDragBlokeCollision;
}
SetupSasDraggableSas(*obj);
obj = &Objects[ID_SARCOPHAGUS];
if (obj->loaded)

View file

@ -1,6 +1,6 @@
#pragma once
#include <string>
#include <functional>
#include <string>
#include "Specific/level.h"
@ -15,16 +15,16 @@ using VarMapVal = std::variant<
std::reference_wrapper<AI_OBJECT>,
std::reference_wrapper<ROOM_INFO>>;
using CallbackDrawString = std::function<void(std::string const&, D3DCOLOR, int, int, int)>;
using CallbackDrawString = std::function<void(const std::string&, D3DCOLOR, int, int, int)>;
class ScriptInterfaceObjectsHandler
{
public:
virtual ~ScriptInterfaceObjectsHandler() = default;
[[nodiscard]] virtual short GetIndexByName(std::string const& name) const = 0;
virtual bool AddName(std::string const& key, VarMapVal val) = 0;
virtual bool NotifyKilled(ItemInfo *) = 0;
[[nodiscard]] virtual short GetIndexByName(const std::string& name) const = 0;
virtual bool AddName(const std::string& key, VarMapVal val) = 0;
virtual bool NotifyKilled(ItemInfo*) = 0;
virtual void FreeEntities() = 0;
virtual void AssignLara() = 0;
@ -34,4 +34,3 @@ public:
};
extern ScriptInterfaceObjectsHandler* g_GameScriptEntities;

View file

@ -1,6 +1,6 @@
#pragma once
#include <string>
#include <functional>
#include <string>
#include "Game/control/volumeactivator.h"
#include "Game/room.h"
@ -18,9 +18,7 @@ using VarMapVal = std::variant<
std::reference_wrapper<ROOM_INFO>>;
using CallbackDrawString = std::function<void(std::string const&, D3DCOLOR, int, int, int)>;
using VarSaveType = std::variant<bool, double, std::string>;
using IndexTable = std::vector<std::pair<uint32_t, uint32_t>>;
struct FuncName

View file

@ -239,8 +239,9 @@ namespace Misc
//@treturn int the direct distance from one position to the other
static int CalculateDistance(Vec3 const& pos1, Vec3 const& pos2)
{
auto result = sqrt(SQUARE(pos1.x - pos2.x) + SQUARE(pos1.y - pos2.y) + SQUARE(pos1.z - pos2.z));
return static_cast<int>(round(result));
auto p1 = Vector3{ (float)pos1.x, (float)pos1.y, (float)pos1.z };
auto p2 = Vector3{ (float)pos2.x, (float)pos2.y, (float)pos2.z };
return static_cast<int>(round(Vector3::Distance(p1, p2)));
}
///Calculate the horizontal distance between two positions.
@ -250,8 +251,9 @@ namespace Misc
//@treturn int the direct distance on the XZ plane from one position to the other
static int CalculateHorizontalDistance(Vec3 const& pos1, Vec3 const& pos2)
{
auto result = sqrt(SQUARE(pos1.x - pos2.x) + SQUARE(pos1.z - pos2.z));
return static_cast<int>(round(result));
auto p1 = Vector2{ (float)pos1.x, (float)pos1.z };
auto p2 = Vector2{ (float)pos2.x, (float)pos2.z };
return static_cast<int>(round(Vector2::Distance(p1, p2)));
}
///Translate a pair of percentages to screen-space pixel coordinates.

View file

@ -239,7 +239,7 @@ int LaraObject::GetAmmoCount() const
/// Get current vehicle, if it exists
// @function LaraObject:GetVehicle
// @treturn Moveable current vehicle (nil if no vehicle present)
// @treturn Objects.Moveable current vehicle (nil if no vehicle present)
// @usage
// local vehicle = Lara:GetVehicle()
std::unique_ptr<Moveable> LaraObject::GetVehicle() const
@ -254,7 +254,7 @@ std::unique_ptr<Moveable> LaraObject::GetVehicle() const
/// Get current target enemy, if it exists
// @function LaraObject:GetTarget
// @treturn Moveable current target enemy (nil if no target present)
// @treturn Objects.Moveable current target enemy (nil if no target present)
// @usage
// local target = Lara:GetTarget()
std::unique_ptr<Moveable> LaraObject::GetTarget() const

View file

@ -418,6 +418,7 @@ ScriptReserved_GetSlotHP, & Moveable::GetSlotHP,
/// Get the object's joint position
// @function Moveable:GetJointPosition
// @tparam int index of a joint to get position
// @treturn Vec3 a copy of the moveable's position
ScriptReserved_GetJointPosition, & Moveable::GetJointPos,
@ -450,7 +451,7 @@ ScriptReserved_GetSlotHP, & Moveable::GetSlotHP,
/// Test if the object is in a valid state (i.e. has not been destroyed through Lua or killed by Lara).
// @function Moveable:GetValid
// @treturn valid bool true if the object is still not destroyed
// @treturn bool valid true if the object is still not destroyed
ScriptReserved_GetValid, &Moveable::GetValid,
/// Destroy the moveable. This will mean it can no longer be used, except to re-initialise it with another object.
@ -459,7 +460,9 @@ ScriptReserved_GetSlotHP, & Moveable::GetSlotHP,
/// Attach camera to an object.
// @function Moveable:AttachObjCamera
// @tparam int mesh 1 for camera, mesh 2 for target
// @tparam int mesh of a moveable to use as a camera position
// @tparam Moveable target moveable to attach camera to
// @tparam int mesh of a target moveable to use as a camera target
ScriptReserved_AttachObjCamera, &Moveable::AttachObjCamera,
/// Borrow animation from an object

View file

@ -21,7 +21,7 @@ Moveables, statics, cameras, and so on.
@pragma nostrip
*/
ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table & parent) :
ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
m_handler{ lua },
m_table_objects(sol::table{m_handler.GetState()->lua_state(), sol::create})
{
@ -112,38 +112,32 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table & parent) :
Moveable::Register(m_table_objects);
Moveable::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Static::Register(m_table_objects);
Static::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
CameraObject::Register(m_table_objects);
CameraObject::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Sink::Register(m_table_objects);
Sink::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
AIObject::Register(m_table_objects);
AIObject::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); } );
SoundSource::Register(m_table_objects);
SoundSource::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Room::Register(m_table_objects);
Room::SetNameCallbacks(
@ -154,8 +148,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table & parent) :
Volume::Register(m_table_objects);
Volume::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_ObjID, kObjIDs);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomFlagID, kRoomFlagIDs);
@ -165,11 +158,9 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table & parent) :
void ObjectsHandler::TestCollidingObjects()
{
// remove any items which can't collide
// Remove any items which can't collide.
for (const auto id : m_collidingItemsToRemove)
{
m_collidingItems.erase(id);
}
m_collidingItemsToRemove.clear();
for (const auto idOne : m_collidingItems)
@ -177,7 +168,7 @@ void ObjectsHandler::TestCollidingObjects()
auto item = &g_Level.Items[idOne];
if (!item->Callbacks.OnObjectCollided.empty())
{
//test against other moveables
// Test against other moveables.
GetCollidedObjects(item, 0, true, CollidedItems, nullptr, 0);
size_t i = 0;
while (CollidedItems[i])
@ -190,11 +181,9 @@ void ObjectsHandler::TestCollidingObjects()
if (!item->Callbacks.OnRoomCollided.empty())
{
//test against room geometry
// Test against room geometry.
if (TestItemRoomCollisionAABB(item))
{
g_GameScript->ExecuteFunction(item->Callbacks.OnRoomCollided, idOne);
}
}
}
}
@ -204,18 +193,17 @@ void ObjectsHandler::AssignLara()
m_table_objects.set(ScriptReserved_Lara, LaraObject(Lara.ItemNumber, true));
}
bool ObjectsHandler::NotifyKilled(ItemInfo* key)
{
auto it = m_moveables.find(key);
if (std::end(m_moveables) != it)
{
for (auto& m : m_moveables[key])
{
m->Invalidate();
}
return true;
}
return false;
}
@ -243,12 +231,10 @@ bool ObjectsHandler::RemoveMoveableFromMap(ItemInfo* key, Moveable* mov)
auto& set = m_moveables[key];
bool erased = static_cast<bool>(set.erase(mov));
if (erased && set.empty())
{
erased = erased && static_cast<bool>(m_moveables.erase(key));
}
return erased;
}
return false;
}

View file

@ -1,6 +1,7 @@
#pragma once
#include <unordered_map>
#include <unordered_set>
#include "LuaHandler.h"
#include "Objects/ScriptInterfaceObjectsHandler.h"
#include "Objects/Moveable/MoveableObject.h"
@ -9,7 +10,6 @@
class ObjectsHandler : public ScriptInterfaceObjectsHandler
{
public:
ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent);
@ -56,7 +56,7 @@ private:
void AssignLara() override;
template <typename R, char const* S>
std::unique_ptr<R> GetByName(std::string const& name)
std::unique_ptr<R> GetByName(const std::string& name)
{
if (!ScriptAssertF(m_nameMap.find(name) != m_nameMap.end(), "{} name not found: {}", S, name))
return nullptr;
@ -126,16 +126,16 @@ private:
return std::get<short>(m_nameMap.at(name));
}
bool AddName(std::string const& key, VarMapVal val) override
bool AddName(const std::string& key, VarMapVal val) override
{
if (key.empty())
return false;
auto p = std::pair<std::string const&, VarMapVal>{ key, val };
auto p = std::pair< const std::string&, VarMapVal>{ key, val };
return m_nameMap.insert(p).second;
}
bool RemoveName(std::string const& key)
bool RemoveName(const std::string& key)
{
return m_nameMap.erase(key);
}
@ -145,5 +145,3 @@ private:
m_nameMap.clear();
}
};

View file

@ -88,7 +88,8 @@ void Volume::Register(sol::table& parent)
/// Check if specified moveable is inside the volume
// @function Volume:IsMoveableInside
// @tparam Moveable moveable which should be checked for containment
// @tparam Objects.Moveable Moveable which should be checked for containment
// @treturn bool state of the moveable, true if contained, false if not
ScriptReserved_IsMoveableInside, &Volume::IsMoveableInside);
}
@ -178,7 +179,7 @@ bool Volume::IsMoveableInside(const Moveable& moveable)
short id = std::get<short>(entry.Activator);
auto& mov = std::make_unique<Moveable>(id);
if (mov.get() == &moveable)
if (mov.get()->GetName() == moveable.GetName())
return true;
}
}

View file

@ -35,9 +35,9 @@ void Rotation::Register(sol::table& parent)
}
/***
@float X rotation about x axis
@float Y rotation about y axis
@float Z rotation about z axis
@tparam float X rotation about x axis
@tparam float Y rotation about y axis
@tparam float Z rotation about z axis
@treturn Rotation A Rotation object.
@function Rotation
*/

View file

@ -965,6 +965,14 @@ void LoadAIObjects()
}
}
void LoadEvent(VolumeEvent& event)
{
event.Mode = (VolumeEventMode)ReadInt32();
event.Function = ReadString();
event.Data = ReadString();
event.CallCounter = ReadInt32();
}
void LoadEventSets()
{
int eventSetCount = ReadInt32();
@ -977,20 +985,9 @@ void LoadEventSets()
eventSet.Name = ReadString();
eventSet.Activators = (VolumeActivatorFlags)ReadInt32();
eventSet.OnEnter.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnEnter.Function = ReadString();
eventSet.OnEnter.Data = ReadString();
eventSet.OnEnter.CallCounter = ReadInt32();
eventSet.OnInside.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnInside.Function = ReadString();
eventSet.OnInside.Data = ReadString();
eventSet.OnInside.CallCounter = ReadInt32();
eventSet.OnLeave.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnLeave.Function = ReadString();
eventSet.OnLeave.Data = ReadString();
eventSet.OnLeave.CallCounter = ReadInt32();
LoadEvent(eventSet.OnEnter);
LoadEvent(eventSet.OnInside);
LoadEvent(eventSet.OnLeave);
g_Level.EventSets.push_back(eventSet);
}