Merge branch 'ten_beta'

This commit is contained in:
Lwmte 2022-08-07 00:28:35 +03:00
commit 2e4e598a80
168 changed files with 6511 additions and 4334 deletions

View file

@ -1,4 +1,4 @@
file = "TombEngine/Scripting/Internal"
file = {"../TombEngine/Scripting/Internal", "../Scripts"}
new_type("mem", "Members", false)
new_type("files", "Script Files", true)
new_type("entityclass", "Entity classes", true)
@ -8,6 +8,7 @@ new_type("tentable", "1 Modules", true)
new_type("tenclass", "2 Classes", true)
new_type("tenprimitive", "3 Primitive Classes", true)
new_type("enum", "4 Enums", true)
new_type("luautil", "5 Lua utility modules", true)
project = "TombEngine"
title = "TombEngine Lua API"
description = "TombEngine scripting interface"

View file

@ -0,0 +1,517 @@
<!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 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>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>1 Modules</h2>
<ul class="nowrap">
<li><strong>Effects</strong></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.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><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/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
<div id="content">
<h1>Table <code>Effects</code></h1>
<p>Functions to generate effects.</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#EmitLightningArc">EmitLightningArc(src, dest, color, lifetime, amplitude, beamWidth, detail, smooth, endDrift)</a></td>
<td class="summary">Emit a lightning arc.</td>
</tr>
<tr>
<td class="name" ><a href="#EmitParticle">EmitParticle(pos, velocity, spriteIndex, gravity, rot, startColor, endColor, blendMode, startSize, endSize, lifetime, damage, poison)</a></td>
<td class="summary">Emit a particle.</td>
</tr>
<tr>
<td class="name" ><a href="#EmitShockwave">EmitShockwave(pos, innerRadius, outerRadius, color, lifetime, speed, angle, hurtsLara)</a></td>
<td class="summary">Emit a shockwave, similar to that seen when a harpy projectile hits something.</td>
</tr>
<tr>
<td class="name" ><a href="#EmitLight">EmitLight(pos, color, radius)</a></td>
<td class="summary">Emit dynamic light that lasts for a single frame.</td>
</tr>
<tr>
<td class="name" ><a href="#EmitBlood">EmitBlood(pos, count)</a></td>
<td class="summary">Emit blood.</td>
</tr>
<tr>
<td class="name" ><a href="#EmitFire">EmitFire(pos, size)</a></td>
<td class="summary">Emit fire for one frame.</td>
</tr>
<tr>
<td class="name" ><a href="#MakeExplosion">MakeExplosion(pos, size, shockwave)</a></td>
<td class="summary">Make an explosion.</td>
</tr>
<tr>
<td class="name" ><a href="#MakeEarthquake">MakeEarthquake(strength)</a></td>
<td class="summary">Make an earthquake</td>
</tr>
<tr>
<td class="name" ><a href="#FlashScreen">FlashScreen(color, speed)</a></td>
<td class="summary">Flash screen.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "EmitLightningArc"></a>
<strong>EmitLightningArc(src, dest, color, lifetime, amplitude, beamWidth, detail, smooth, endDrift)</strong>
</dt>
<dd>
Emit a lightning arc.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">src</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">dest</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">color</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255))
</li>
<li><span class="parameter">lifetime</span>
<span class="types"><span class="type">float</span></span>
Lifetime in seconds. Clamped to [0, 4.233] for now because of strange internal maths. (default 1.0)
</li>
<li><span class="parameter">amplitude</span>
<span class="types"><span class="type">int</span></span>
"strength" of the lightning - the higher the value, the "taller" the arcs. Clamped to [1, 255]. (default 20)
</li>
<li><span class="parameter">beamWidth</span>
<span class="types"><span class="type">int</span></span>
Clamped to [1, 127]. (default 2)
</li>
<li><span class="parameter">detail</span>
<span class="types"><span class="type">int</span></span>
Higher numbers equal more segments, but it's not a 1:1 correlation. Clamped to [1, 127]. (default 10)
</li>
<li><span class="parameter">smooth</span>
<span class="types"><span class="type">bool</span></span>
If true, the arc will have large, smooth curves; if false, it will have small, jagged spikes. (default false)
</li>
<li><span class="parameter">endDrift</span>
<span class="types"><span class="type">bool</span></span>
If true, the end of the arc will be able to gradually drift away from its destination in a random direction (default false)
</li>
</ul>
</dd>
<dt>
<a name = "EmitParticle"></a>
<strong>EmitParticle(pos, velocity, spriteIndex, gravity, rot, startColor, endColor, blendMode, startSize, endSize, lifetime, damage, poison)</strong>
</dt>
<dd>
<p>Emit a particle. </p>
<pre><code> See the sprite editor in WadTool for DEFAULT_SPRITES to see a list of sprite indices.
</code></pre>
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">velocity</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">spriteIndex</span>
<span class="types"><span class="type">int</span></span>
an index of a sprite in DEFAULT_SPRITES object.
</li>
<li><span class="parameter">gravity</span>
<span class="types"><span class="type">int</span></span>
(default 0) Specifies whether particle will fall (positive values) or ascend (negative values) over time. Clamped to [-32768, 32767], but values between -1000 and 1000 are recommended; values too high or too low (e.g. under -2000 or above 2000) will cause the velocity of the particle to "wrap around" and switch directions.
</li>
<li><span class="parameter">rot</span>
<span class="types"><span class="type">float</span></span>
(default 0) specifies a speed with which it will rotate (0 = no rotation, negative = anticlockwise rotation, positive = clockwise rotation).
</li>
<li><span class="parameter">startColor</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255)) color at start of life
</li>
<li><span class="parameter">endColor</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255)) color to fade to - at the time of writing this fade will finish long before the end of the particle's life due to internal maths
</li>
<li><span class="parameter">blendMode</span>
<span class="types"><span class="type">BlendID</span></span>
(default TEN.Misc.BlendID.ALPHABLEND) How will we blend this with its surroundings?
</li>
<li><span class="parameter">startSize</span>
<span class="types"><span class="type">int</span></span>
(default 10) Size on spawn. A value of 15 is approximately the size of Lara's head.
</li>
<li><span class="parameter">endSize</span>
<span class="types"><span class="type">int</span></span>
(default 0) Size on death - the particle will linearly shrink or grow to this size during its lifespan
</li>
<li><span class="parameter">lifetime</span>
<span class="types"><span class="type">float</span></span>
(default 2) Lifespan in seconds
</li>
<li><span class="parameter">damage</span>
<span class="types"><span class="type">bool</span></span>
(default false) specifies whether particle can damage Lara (does a very small amount of damage, like the small lava emitters in TR1)
</li>
<li><span class="parameter">poison</span>
<span class="types"><span class="type">bool</span></span>
(default false) specifies whether particle can poison Lara
</li>
</ul>
<h3>Usage:</h3>
<ul>
<pre class="example">EmitParticle(
yourPositionVarHere,
Vec3(<span class="global">math</span>.random(), <span class="global">math</span>.random(), <span class="global">math</span>.random()),
<span class="number">22</span>, <span class="comment">-- spriteIndex
</span> <span class="number">0</span>, <span class="comment">-- gravity
</span> -<span class="number">2</span>, <span class="comment">-- rot
</span> Color(<span class="number">255</span>, <span class="number">0</span>, <span class="number">0</span>), <span class="comment">-- startColor
</span> Color(<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>), <span class="comment">-- endColor
</span> TEN.Misc.BlendID.ADDITIVE, <span class="comment">-- blendMode
</span> <span class="number">15</span>, <span class="comment">-- startSize
</span> <span class="number">50</span>, <span class="comment">-- endSize
</span> <span class="number">20</span>, <span class="comment">-- lifetime
</span> <span class="keyword">false</span>, <span class="comment">-- damage
</span> <span class="keyword">true</span> <span class="comment">-- poison
</span> )</pre>
</ul>
</dd>
<dt>
<a name = "EmitShockwave"></a>
<strong>EmitShockwave(pos, innerRadius, outerRadius, color, lifetime, speed, angle, hurtsLara)</strong>
</dt>
<dd>
Emit a shockwave, similar to that seen when a harpy projectile hits something.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
Origin position
</li>
<li><span class="parameter">innerRadius</span>
<span class="types"><span class="type">int</span></span>
(default 0) Initial inner radius of the shockwave circle - 128 will be approx a click, 512 approx a block
</li>
<li><span class="parameter">outerRadius</span>
<span class="types"><span class="type">int</span></span>
(default 128) Initial outer radius of the shockwave circle
</li>
<li><span class="parameter">color</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255))
</li>
<li><span class="parameter">lifetime</span>
<span class="types"><span class="type">float</span></span>
(default 1.0) Lifetime in seconds (max 8.5 because of inner maths weirdness)
</li>
<li><span class="parameter">speed</span>
<span class="types"><span class="type">int</span></span>
(default 50) Initial speed of the shockwave's expansion (the shockwave will always slow as it goes)
</li>
<li><span class="parameter">angle</span>
<span class="types"><span class="type">int</span></span>
(default 0) Angle about the X axis - a value of 90 will cause the shockwave to be entirely vertical
</li>
<li><span class="parameter">hurtsLara</span>
<span class="types"><span class="type">bool</span></span>
(default false) If true, the shockwave will hurt Lara, with the damage being relative to the shockwave's current speed
</li>
</ul>
</dd>
<dt>
<a name = "EmitLight"></a>
<strong>EmitLight(pos, color, radius)</strong>
</dt>
<dd>
Emit dynamic light that lasts for a single frame.
If you want a light that sticks around, you must call this each frame.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">color</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255))
</li>
<li><span class="parameter">radius</span>
<span class="types"><span class="type">int</span></span>
(default 20) corresponds loosely to both intensity and range
</li>
</ul>
</dd>
<dt>
<a name = "EmitBlood"></a>
<strong>EmitBlood(pos, count)</strong>
</dt>
<dd>
Emit blood.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">count</span>
<span class="types"><span class="type">int</span></span>
(default 1) "amount" of blood. Higher numbers won't add more blood but will make it more "flickery", with higher numbers turning it into a kind of red orb.
</li>
</ul>
</dd>
<dt>
<a name = "EmitFire"></a>
<strong>EmitFire(pos, size)</strong>
</dt>
<dd>
Emit fire for one frame. Will not hurt Lara. Call this each frame if you want a continuous fire.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">size</span>
<span class="types"><span class="type">float</span></span>
(default 1.0)
</li>
</ul>
</dd>
<dt>
<a name = "MakeExplosion"></a>
<strong>MakeExplosion(pos, size, shockwave)</strong>
</dt>
<dd>
Make an explosion. Does not hurt Lara
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">pos</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
<li><span class="parameter">size</span>
<span class="types"><span class="type">float</span></span>
(default 512.0) this will not be the size of the sprites, but rather the distance between the origin and any additional sprites
</li>
<li><span class="parameter">shockwave</span>
<span class="types"><span class="type">bool</span></span>
(default false) if true, create a very faint white shockwave which will not hurt Lara
</li>
</ul>
</dd>
<dt>
<a name = "MakeEarthquake"></a>
<strong>MakeEarthquake(strength)</strong>
</dt>
<dd>
Make an earthquake
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">strength</span>
<span class="types"><span class="type">int</span></span>
(default 100) How strong should the earthquake be? Increasing this value also increases the lifespan of the earthquake.
</li>
</ul>
</dd>
<dt>
<a name = "FlashScreen"></a>
<strong>FlashScreen(color, speed)</strong>
</dt>
<dd>
Flash screen.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">color</span>
<span class="types"><span class="type">Color</span></span>
(default Color(255, 255, 255))
</li>
<li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span>
(default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0]
</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-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -40,6 +40,7 @@
<h2>1 Modules</h2>
<ul class="nowrap">
<li><a href="../1 modules/Effects.html">Effects</a></li>
<li><strong>Flow</strong></li>
<li><a href="../1 modules/Inventory.html">Inventory</a></li>
<li><a href="../1 modules/Logic.html">Logic</a></li>
@ -73,8 +74,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -373,7 +380,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -38,6 +38,7 @@
<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><strong>Inventory</strong></li>
<li><a href="../1 modules/Logic.html">Logic</a></li>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -196,7 +203,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -39,6 +39,7 @@
<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><strong>Logic</strong></li>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -271,7 +278,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -38,6 +38,7 @@
<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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -88,14 +95,34 @@
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#SetAmbientTrack">SetAmbientTrack(name)</a></td>
<td class="summary">Set and play an ambient track</td>
<td class="name" ><a href="#HasLineOfSight">HasLineOfSight(room1, pos1, pos2)</a></td>
<td class="summary">Determine if there's a line of sight between two points.</td>
</tr>
<tr>
<td class="name" ><a href="#FadeOut">FadeOut(speed)</a></td>
<td class="summary">Do a full-screen fade-to-black.</td>
</tr>
<tr>
<td class="name" ><a href="#FadeIn">FadeIn(speed)</a></td>
<td class="summary">Do a full-screen fade-in from black.</td>
</tr>
<tr>
<td class="name" ><a href="#SetCineBars">SetCineBars(height, speed)</a></td>
<td class="summary">Move black cinematic bars in from the top and bottom of the game window.</td>
</tr>
<tr>
<td class="name" ><a href="#SetFOV">SetFOV(angle)</a></td>
<td class="summary">Set field of view.</td>
</tr>
<tr>
<td class="name" ><a href="#PlayAudioTrack">PlayAudioTrack(name, loop)</a></td>
<td class="summary">Play an audio track</td>
</tr>
<tr>
<td class="name" ><a href="#SetAmbientTrack">SetAmbientTrack(name)</a></td>
<td class="summary">Set and play an ambient track</td>
</tr>
<tr>
<td class="name" ><a href="#CalculateDistance">CalculateDistance(posA, posB)</a></td>
<td class="summary">Calculate the distance between two positions.</td>
</tr>
@ -108,13 +135,33 @@
<td class="summary">Translate a pair of percentages to screen-space pixel coordinates.</td>
</tr>
<tr>
<td class="name" ><a href="#HasLineOfSight">HasLineOfSight(room1, pos1, pos2)</a></td>
<td class="summary">Determine if there's a line of sight between two points.</td>
</tr>
<tr>
<td class="name" ><a href="#ScreenToPercent">ScreenToPercent(x, y)</a></td>
<td class="summary">Translate a pair of coordinates to percentages of window dimensions.</td>
</tr>
<tr>
<td class="name" ><a href="#Vibrate">Vibrate(strength, time)</a></td>
<td class="summary">Vibrate gamepad, if possible.</td>
</tr>
<tr>
<td class="name" ><a href="#PlaySound">PlaySound(sound, position)</a></td>
<td class="summary">Play sound effect</td>
</tr>
<tr>
<td class="name" ><a href="#KeyIsHeld">KeyIsHeld(action)</a></td>
<td class="summary">Check if particular action key is held</td>
</tr>
<tr>
<td class="name" ><a href="#KeyIsHit">KeyIsHit(action)</a></td>
<td class="summary">Check if particular action key was hit (once)</td>
</tr>
<tr>
<td class="name" ><a href="#KeyPush">KeyPush(action)</a></td>
<td class="summary">Emulate pushing of a certain action key</td>
</tr>
<tr>
<td class="name" ><a href="#KeyClear">KeyClear(action)</a></td>
<td class="summary">Clears particular input from action key</td>
</tr>
</table>
<br/>
@ -125,18 +172,135 @@
<dl class="function">
<dt>
<a name = "SetAmbientTrack"></a>
<strong>SetAmbientTrack(name)</strong>
<a name = "HasLineOfSight"></a>
<strong>HasLineOfSight(room1, pos1, pos2)</strong>
</dt>
<dd>
Set and play an ambient track
Determine if there's a line of sight between two points. </p>
<p>i.e. if we run a direct line from one position to another
will any geometry get in the way?</p>
<p>Note: if you use this with Moveable:GetPosition to test if (for example)
two creatures can see one another, you might have to do some extra adjustments.</p>
<p>This is because the "position" for most objects refers to its base, i.e., the floor.
As a solution, you can increase the y-coordinate of this position to correspond to roughly where the
eyes of the creatures would be.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
of track (without file extension) to play
<li><span class="parameter">room1</span>
<span class="types"><span class="type">float</span></span>
ID of the room where the first position is
</li>
<li><span class="parameter">pos1</span>
<span class="types"><span class="type">Vec3</span></span>
first position
</li>
<li><span class="parameter">pos2</span>
<span class="types"><span class="type">Vec3</span></span>
second position
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
is there a direct line of sight between the two positions?
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> flamePlinthPos = flamePlinth:GetPosition() + Vec3(<span class="number">0</span>, flamePlinthHeight, <span class="number">0</span>);
<span class="global">print</span>(Misc.HasLineOfSight(enemyHead:GetRoom(), enemyHead:GetPosition(), flamePlinthPos))</pre>
</ul>
</dd>
<dt>
<a name = "FadeOut"></a>
<strong>FadeOut(speed)</strong>
</dt>
<dd>
Do a full-screen fade-to-black. The screen will remain black until a call to FadeIn.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span>
(default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
</li>
</ul>
</dd>
<dt>
<a name = "FadeIn"></a>
<strong>FadeIn(speed)</strong>
</dt>
<dd>
Do a full-screen fade-in from black.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span>
(default 1.0). Speed in "amount" per second. A value of 1 will make the fade take one second.
</li>
</ul>
</dd>
<dt>
<a name = "SetCineBars"></a>
<strong>SetCineBars(height, speed)</strong>
</dt>
<dd>
Move black cinematic bars in from the top and bottom of the game window.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">height</span>
<span class="types"><span class="type">float</span></span>
<strong>(default 30)</strong> Percentage of the screen to be covered
</li>
<li><span class="parameter">speed</span>
<span class="types"><span class="type">float</span></span>
<strong>(default 30)</strong> Coverage percent per second
</li>
</ul>
</dd>
<dt>
<a name = "SetFOV"></a>
<strong>SetFOV(angle)</strong>
</dt>
<dd>
Set field of view.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">angle</span>
<span class="types"><span class="type">float</span></span>
in degrees (clamped to [10, 170])
</li>
</ul>
@ -169,6 +333,27 @@
</dd>
<dt>
<a name = "SetAmbientTrack"></a>
<strong>SetAmbientTrack(name)</strong>
</dt>
<dd>
Set and play an ambient track
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
of track (without file extension) to play
</li>
</ul>
</dd>
<dt>
<a name = "CalculateDistance"></a>
@ -266,56 +451,6 @@ To be used with <a href="../2 classes/Strings.DisplayString.html#DisplayString:S
</dd>
<dt>
<a name = "HasLineOfSight"></a>
<strong>HasLineOfSight(room1, pos1, pos2)</strong>
</dt>
<dd>
Determine if there's a line of sight between two points. </p>
<p>i.e. if we run a direct line from one position to another
will any geometry get in the way?</p>
<p>Note: if you use this with Moveable:GetPosition to test if (for example)
two creatures can see one another, you might have to do some extra adjustments.</p>
<p>This is because the "position" for most objects refers to its base, i.e., the floor.
As a solution, you can increase the y-coordinate of this position to correspond to roughly where the
eyes of the creatures would be.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">room1</span>
<span class="types"><span class="type">float</span></span>
ID of the room where the first position is
</li>
<li><span class="parameter">pos1</span>
<span class="types"><span class="type">Vec3</span></span>
first position
</li>
<li><span class="parameter">pos2</span>
<span class="types"><span class="type">Vec3</span></span>
second position
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
is there a direct line of sight between the two positions?
</ol>
<h3>Usage:</h3>
<ul>
<pre class="example"><span class="keyword">local</span> flamePlinthPos = flamePlinth:GetPosition() + Vec3(<span class="number">0</span>, flamePlinthHeight, <span class="number">0</span>);
<span class="global">print</span>(Misc.HasLineOfSight(enemyHead:GetRoom(), enemyHead:GetPosition(), flamePlinthPos))</pre>
</ul>
</dd>
<dt>
<a name = "ScreenToPercent"></a>
@ -351,6 +486,144 @@ To be used with <a href="../2 classes/Strings.DisplayString.html#DisplayString:G
</dd>
<dt>
<a name = "Vibrate"></a>
<strong>Vibrate(strength, time)</strong>
</dt>
<dd>
Vibrate gamepad, if possible.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">strength</span>
<span class="types"><span class="type">float</span></span>
</li>
<li><span class="parameter">time</span>
<span class="types"><span class="type">float</span></span>
(in seconds, default: 0.3)
</li>
</ul>
</dd>
<dt>
<a name = "PlaySound"></a>
<strong>PlaySound(sound, position)</strong>
</dt>
<dd>
Play sound effect
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">sound</span>
<span class="types"><span class="type">int</span></span>
ID to play
</li>
<li><span class="parameter">position</span>
<span class="types"><span class="type">Vec3</span></span>
</li>
</ul>
</dd>
<dt>
<a name = "KeyIsHeld"></a>
<strong>KeyIsHeld(action)</strong>
</dt>
<dd>
Check if particular action key is held
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">action</span>
<span class="types"><span class="type">int</span></span>
mapping index to check
</li>
</ul>
</dd>
<dt>
<a name = "KeyIsHit"></a>
<strong>KeyIsHit(action)</strong>
</dt>
<dd>
Check if particular action key was hit (once)
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">action</span>
<span class="types"><span class="type">int</span></span>
mapping index to check
</li>
</ul>
</dd>
<dt>
<a name = "KeyPush"></a>
<strong>KeyPush(action)</strong>
</dt>
<dd>
Emulate pushing of a certain action key
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">action</span>
<span class="types"><span class="type">int</span></span>
mapping index to push
</li>
</ul>
</dd>
<dt>
<a name = "KeyClear"></a>
<strong>KeyClear(action)</strong>
</dt>
<dd>
Clears particular input from action key
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">action</span>
<span class="types"><span class="type">int</span></span>
mapping index to clear
</li>
</ul>
</dd>
</dl>
@ -359,7 +632,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-08-02 21:24:26 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -38,6 +38,7 @@
<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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -289,7 +296,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -38,6 +38,7 @@
<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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -161,7 +168,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -51,6 +51,7 @@
</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>
@ -67,8 +68,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -92,7 +99,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -198,7 +205,7 @@
</li>
<li><span class="parameter">Max</span>
<span class="types"><span class="type">int</span></span>
Distance fog ends (in Sectors)
Distance fog ends (in Sectors)
</li>
</ul>
@ -219,7 +226,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -174,7 +181,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -515,7 +522,7 @@ Must be in the range [1, 127], and equal to or less than the value passed to Set
</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -51,6 +51,7 @@
</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>
@ -67,8 +68,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -92,7 +99,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -135,7 +142,7 @@ an invalid argument.</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -56,6 +56,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -191,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -342,7 +349,7 @@
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">ID</span>
<span class="types"><span class="type">ObjectID</span></span>
<span class="types"><span class="type">ObjID</span></span>
the new ID
</li>
</ul>
@ -364,7 +371,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -252,7 +259,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -104,6 +111,14 @@ associated getters and setters.</td>
<td class="summary">Make the item invisible.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:Explode">Moveable:Explode()</a></td>
<td class="summary">Explode item.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:Shatter">Moveable:Shatter()</a></td>
<td class="summary">Shatter item.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetStatus">Moveable:GetStatus()</a></td>
<td class="summary">Get the status of object.</td>
</tr>
@ -149,12 +164,20 @@ associated getters and setters.</td>
<td class="summary">Change the object's ID.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetState">Moveable:GetState()</a></td>
<td class="summary">Retrieve the index of the current state.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SetState">Moveable:SetState(index)</a></td>
<td class="summary">Set the object's state to the one specified by the given index.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetAnim">Moveable:GetAnim()</a></td>
<td class="summary">Retrieve the index of the current animation.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SetAnim">Moveable:SetAnim(index)</a></td>
<td class="summary">Set the opject's animation to the one specified by the given index.</td>
<td class="summary">Set the object's animation to the one specified by the given index.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetFrame">Moveable:GetFrame()</a></td>
@ -181,6 +204,14 @@ associated getters and setters.</td>
<td class="summary">Set OCB (object code bit) of the moveable</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetColor">Moveable:GetColor()</a></td>
<td class="summary">Get the moveable's color</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SetColor">Moveable:SetColor(color)</a></td>
<td class="summary">Set the moveable's color</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetAIBits">Moveable:GetAIBits()</a></td>
<td class="summary">Get AIBits of object
This will return a table with six values, each corresponding to
@ -191,6 +222,43 @@ associated getters and setters.</td>
<td class="summary">Set AIBits of object
Use this to force a moveable into a certain AI mode or modes, as if a certain nullmesh
(or more than one) had suddenly spawned beneath their feet.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:MeshIsVisible">Moveable:MeshIsVisible(index)</a></td>
<td class="summary">Get state of specified mesh visibility of object
Returns true if specified mesh is visible on an object, and false
if it is not visible.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:ShowMesh">Moveable:ShowMesh(index)</a></td>
<td class="summary">Makes specified mesh visible
Use this to show specified mesh of an object.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:HideMesh">Moveable:HideMesh(index)</a></td>
<td class="summary">Makes specified mesh invisible
Use this to hide specified mesh of an object.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:ShatterMesh">Moveable:ShatterMesh(index)</a></td>
<td class="summary">Shatters specified mesh and makes it invisible
Note that you can re-enable mesh later by using ShowMesh().</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:MeshIsSwapped">Moveable:MeshIsSwapped(index)</a></td>
<td class="summary">Get state of specified mesh swap of object
Returns true if specified mesh is swapped on an object, and false
if it is not swapped.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SwapMesh">Moveable:SwapMesh(index, index, optional)</a></td>
<td class="summary">Set state of specified mesh swap of object
Use this to swap specified mesh of an object.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:UnswapMesh">Moveable:UnswapMesh(index)</a></td>
<td class="summary">Set state of specified mesh swap of object
Use this to bring back original unswapped mesh</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetHitStatus">Moveable:GetHitStatus()</a></td>
@ -214,6 +282,10 @@ associated getters and setters.</td>
<td class="summary">Get the object's position</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetJointPosition">Moveable:GetJointPosition()</a></td>
<td class="summary">Get the object's joint position</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:SetPosition">Moveable:SetPosition(position)</a></td>
<td class="summary">Set the moveable's position
If you are moving a moveable whose behaviour involves knowledge of room geometry,
@ -229,7 +301,7 @@ associated getters and setters.</td>
</tr>
<tr>
<td class="name" ><a href="#Moveable:GetName">Moveable:GetName()</a></td>
<td class="summary">Set the moveable's name (its unique string identifier)
<td class="summary">Get the moveable's name (its unique string identifier)
e.g.</td>
</tr>
<tr>
@ -369,6 +441,34 @@ most can just be ignored (see usage).
</dd>
<dt>
<a name = "Moveable:Explode"></a>
<strong>Moveable:Explode()</strong>
</dt>
<dd>
Explode item. This also kills and disables item.
</dd>
<dt>
<a name = "Moveable:Shatter"></a>
<strong>Moveable:Shatter()</strong>
</dt>
<dd>
Shatter item. This also kills and disables item.
</dd>
<dt>
<a name = "Moveable:GetStatus"></a>
@ -377,10 +477,10 @@ most can just be ignored (see usage).
<dd>
Get the status of object.
possible values:
0 - not active
1 - active
2 - deactivated
3 - invisible
<br />0 - not active
<br />1 - active
<br />2 - deactivated
<br />3 - invisible
@ -610,6 +710,50 @@ baddy:SetOnKilled(<span class="string">"baddyKilled"</span>)</pre>
shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
</ul>
</dd>
<dt>
<a name = "Moveable:GetState"></a>
<strong>Moveable:GetState()</strong>
</dt>
<dd>
Retrieve the index of the current state.
This corresponds to the number shown in the item's state ID field in WadTool.
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">int</span></span>
the index of the active state
</ol>
</dd>
<dt>
<a name = "Moveable:SetState"></a>
<strong>Moveable:SetState(index)</strong>
</dt>
<dd>
Set the object's state to the one specified by the given index.
Performs no bounds checking. <em>Ensure the number given is correct, else
object may end up in corrupted animation state.</em>
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
the index of the desired state
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:GetAnim"></a>
@ -637,9 +781,9 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
<strong>Moveable:SetAnim(index)</strong>
</dt>
<dd>
Set the opject's animation to the one specified by the given index.
Set the object's animation to the one specified by the given index.
Performs no bounds checking. <em>Ensure the number given is correct, else
the program is likely to crash with an unhelpful error message.</em>
object may end up in corrupted animation state.</em>
<h3>Parameters:</h3>
@ -782,6 +926,47 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
</dd>
<dt>
<a name = "Moveable:GetColor"></a>
<strong>Moveable:GetColor()</strong>
</dt>
<dd>
Get the moveable's color
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Color</span></span>
a copy of the moveable's color
</ol>
</dd>
<dt>
<a name = "Moveable:SetColor"></a>
<strong>Moveable:SetColor(color)</strong>
</dt>
<dd>
Set the moveable's color
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">color</span>
<span class="types"><span class="type">Color</span></span>
the new color of the moveable
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:GetAIBits"></a>
@ -840,6 +1025,182 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM)</pre>
sas:SetAIBits({<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>})</pre>
</ul>
</dd>
<dt>
<a name = "Moveable:MeshIsVisible"></a>
<strong>Moveable:MeshIsVisible(index)</strong>
</dt>
<dd>
Get state of specified mesh visibility of object
Returns true if specified mesh is visible on an object, and false
if it is not visible.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
visibility status
</ol>
</dd>
<dt>
<a name = "Moveable:ShowMesh"></a>
<strong>Moveable:ShowMesh(index)</strong>
</dt>
<dd>
Makes specified mesh visible
Use this to show specified mesh of an object.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:HideMesh"></a>
<strong>Moveable:HideMesh(index)</strong>
</dt>
<dd>
Makes specified mesh invisible
Use this to hide specified mesh of an object.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:ShatterMesh"></a>
<strong>Moveable:ShatterMesh(index)</strong>
</dt>
<dd>
Shatters specified mesh and makes it invisible
Note that you can re-enable mesh later by using ShowMesh().
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:MeshIsSwapped"></a>
<strong>Moveable:MeshIsSwapped(index)</strong>
</dt>
<dd>
Get state of specified mesh swap of object
Returns true if specified mesh is swapped on an object, and false
if it is not swapped.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh
</li>
</ul>
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">bool</span></span>
mesh swap status
</ol>
</dd>
<dt>
<a name = "Moveable:SwapMesh"></a>
<strong>Moveable:SwapMesh(index, index, optional)</strong>
</dt>
<dd>
Set state of specified mesh swap of object
Use this to swap specified mesh of an object.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a slot to get meshswap from
</li>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a slot to get meshswap from
</li>
<li><span class="parameter">optional</span>
<span class="types"><span class="type">int</span></span>
) index of a mesh from meshswap slot to use
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:UnswapMesh"></a>
<strong>Moveable:UnswapMesh(index)</strong>
</dt>
<dd>
Set state of specified mesh swap of object
Use this to bring back original unswapped mesh
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">index</span>
<span class="types"><span class="type">int</span></span>
of a mesh to unswap
</li>
</ul>
</dd>
<dt>
<a name = "Moveable:GetHitStatus"></a>
@ -948,6 +1309,26 @@ sas:SetPosition(destinationPosition)</pre>
</dd>
<dt>
<a name = "Moveable:GetJointPosition"></a>
<strong>Moveable:GetJointPosition()</strong>
</dt>
<dd>
Get the object's joint position
<h3>Returns:</h3>
<ol>
<span class="types"><span class="type">Vec3</span></span>
a copy of the moveable's position
</ol>
</dd>
<dt>
<a name = "Moveable:SetPosition"></a>
@ -1019,7 +1400,7 @@ sas:SetPosition(destinationPosition)</pre>
<strong>Moveable:GetName()</strong>
</dt>
<dd>
Set the moveable's name (its unique string identifier)
Get the moveable's name (its unique string identifier)
e.g. "door_back_room" or "cracked_greek_statue"
This corresponds with the "Lua Name" field in an object's properties in Tomb Editor.
@ -1106,7 +1487,7 @@ sas:SetPosition(destinationPosition)</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -254,7 +261,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -252,7 +259,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -350,7 +357,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -55,6 +55,7 @@
</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>
@ -71,8 +72,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -299,7 +306,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -45,6 +45,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -304,7 +311,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -45,6 +45,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -242,7 +249,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -45,6 +45,7 @@
</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>
@ -72,8 +73,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -115,9 +122,7 @@
</tr>
<tr>
<td class="name" ><a href="#__tostring">__tostring(Vec3)</a></td>
<td class="summary">
</td>
<td class="summary">Metafunction; use tostring(myVector)</td>
</tr>
</table>
@ -242,9 +247,7 @@ However, this function would return it as (0, 1, 1).
<strong>__tostring(Vec3)</strong>
</dt>
<dd>
Metafunction; use tostring(myVector)
<h3>Parameters:</h3>
@ -273,7 +276,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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -0,0 +1,155 @@
<!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 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>Contents</h2>
<ul>
<li><a href="#Effects_BlendID_constants">Effects.BlendID constants </a></li>
</ul>
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><strong>Effects.BlendID</strong></li>
<li><a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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.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><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>5 Lua utility modules</h2>
<ul class="nowrap">
<li><a href="../5 lua utility modules/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
<div id="content">
<h1>Enum <code>Effects.BlendID</code></h1>
<p>Constants for blend mode IDs.</p>
<p>
</p>
<h2><a href="#Effects_BlendID_constants">Effects.BlendID constants </a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#CONSTANT_STRING_HERE">CONSTANT_STRING_HERE</a></td>
<td class="summary">Table of blend mode constants (for use with particles).</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header has-description"><a name="Effects_BlendID_constants"></a>Effects.BlendID constants </h2>
<div class="section-description">
<p>The following constants are inside BlendID.</p>
<pre><code>OPAQUE
ALPHATEST
ADDITIVE
NOZTEST
SUBTRACTIVE
WIREFRAME
EXCLUDE
SCREEN
LIGHTEN
ALPHABLEND
</code></pre>
</div>
<dl class="function">
<dt>
<a name = "CONSTANT_STRING_HERE"></a>
<strong>CONSTANT_STRING_HERE</strong>
</dt>
<dd>
Table of blend mode constants (for use with particles).
</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-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -39,10 +39,12 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><strong>Flow.InvID</strong></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li><a href="../4 enums/Objects.ObjID.html">Objects.ObjID</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>
@ -73,6 +75,11 @@
<li><a href="../3 primitive classes/Rotation.html">Rotation</a></li>
<li><a href="../3 primitive classes/Vec3.html">Vec3</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li><a href="../5 lua utility modules/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -350,7 +357,7 @@ EXAMINE_ITEM8_COMBO2
</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -39,10 +39,12 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="../4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li><strong>Objects.ObjID</strong></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>
@ -73,6 +75,11 @@
<li><a href="../3 primitive classes/Rotation.html">Rotation</a></li>
<li><a href="../3 primitive classes/Vec3.html">Vec3</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li><a href="../5 lua utility modules/Timer.html">Timer</a></li>
<li><a href="../5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -224,13 +231,13 @@ MERCENARY_AUTOPISTOLS1
MERCENARY_AUTOPISTOLS2
SNOWMOBILE_GUN
SNOWMOBILE_DRIVER
FLAMETHROWER_GOON
FLAMETHROWER_BADDY
TRIBESMAN_WITH_AX
TRIBESMAN_WITH_DARTS
MP_WITH_STICK
MP_WITH_GUN
GOON1
GOON2
BADDY1
BADDY2
SAS_CAIRO
SAS_DYING
SAS_CAPTAIN
@ -895,8 +902,8 @@ MESHSWAP7
MESHSWAP8
MESHSWAP9
MESHSWAP10
MESHSWAP_GOON1
MESHSWAP_GOON2
MESHSWAP_BADDY1
MESHSWAP_BADDY2
MESHSWAP_MAFIA2
MESHSWAP_IMP
MESHSWAP_HITMAN
@ -1088,7 +1095,7 @@ PANEL_MIDDLE_CORNER
</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -0,0 +1,487 @@
<!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 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>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li><strong>Timer</strong></li>
<li><a href="../5 lua utility modules/Util.html">Util</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.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><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/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li><a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li>
</ul>
</div>
<div id="content">
<h1>Lua utility module <code>Timer</code></h1>
<p>Basic timer - after a specified number of seconds, the specified thing happens.</p>
<p>
<p> Usage:</p>
<pre>
<span class="keyword">local</span> Timer = <span class="global">require</span>(<span class="string">"Timer"</span>)
LevelFuncs.FinishTimer = <span class="keyword">function</span>(healthWhenStarted, victoryMessage)
DoSomething(healthWhenStarted, victoryMessage)
<span class="keyword">end</span>
LevelFuncs.TriggerTimer = <span class="keyword">function</span>(obj)
<span class="keyword">local</span> myTimer = Timer.Create(<span class="string">"my_timer"</span>, <span class="number">5.0</span>, <span class="keyword">false</span>, <span class="keyword">true</span>, <span class="string">"FinishTimer"</span>, Lara:GetHP(), <span class="string">"Well done!"</span>)
myTimer:Start()
<span class="keyword">end</span>
LevelFuncs.OnControlPhase = <span class="keyword">function</span>(dt)
Timer.UpdateAll(dt)
<span class="keyword">end</span>
</pre>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#Create">Create(name, totalTime, loop, showString, func, funcArgs)</a></td>
<td class="summary">Create (but do not start) a new timer.</td>
</tr>
<tr>
<td class="name" ><a href="#Get">Get(name)</a></td>
<td class="summary">Get a timer by its name.</td>
</tr>
<tr>
<td class="name" ><a href="#SetFunction">SetFunction(t, func, funcArgs)</a></td>
<td class="summary">Give the timer a new function and args</td>
</tr>
<tr>
<td class="name" ><a href="#Start">Start(t)</a></td>
<td class="summary">Begin or unpause a timer.</td>
</tr>
<tr>
<td class="name" ><a href="#Pause">Pause(t)</a></td>
<td class="summary">Pause the timer.</td>
</tr>
<tr>
<td class="name" ><a href="#Stop">Stop(t)</a></td>
<td class="summary">Stop the timer.</td>
</tr>
<tr>
<td class="name" ><a href="#GetRemainingTime">GetRemainingTime(t)</a></td>
<td class="summary">Get the remaining time for a timer.</td>
</tr>
<tr>
<td class="name" ><a href="#SetRemainingTime">SetRemainingTime(t, remainingTime)</a></td>
<td class="summary">Set the remaining time for a timer</td>
</tr>
<tr>
<td class="name" ><a href="#GetTotalTime">GetTotalTime(t)</a></td>
<td class="summary">Get the total time for a timer.</td>
</tr>
<tr>
<td class="name" ><a href="#SetTotalTime">SetTotalTime(t, totalTime)</a></td>
<td class="summary">Set the total time for a timer</td>
</tr>
<tr>
<td class="name" ><a href="#SetLooping">SetLooping(t, looping)</a></td>
<td class="summary">Set whether or not the timer loops</td>
</tr>
<tr>
<td class="name" ><a href="#UpdateAll">UpdateAll(dt)</a></td>
<td class="summary">Update all active timers.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "Create"></a>
<strong>Create(name, totalTime, loop, showString, func, funcArgs)</strong>
</dt>
<dd>
Create (but do not start) a new timer.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">name</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
A label to give this timer; used to retrieve the timer later
</li>
<li><span class="parameter">totalTime</span>
<span class="types"><span class="type">number</span></span>
The duration of the timer, in seconds
</li>
<li><span class="parameter">loop</span>
<span class="types"><span class="type">bool</span></span>
if true, the timer will start again immediately after the time has elapsed
</li>
<li><span class="parameter">showString</span>
<span class="types"><span class="type">bool</span></span>
if true, the remaining time, rounded up, will show at the bottom of the screen. <strong>At any given time, only one timer can show its remaining time</strong>.
</li>
<li><span class="parameter">func</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The name of the LevelFunc member to call when the time is up
</li>
<li><span class="parameter">funcArgs</span>
the arguments with which the above function will be called
</li>
</ul>
<h3>Returns:</h3>
<ol>
The timer in its paused state
</ol>
</dd>
<dt>
<a name = "Get"></a>
<strong>Get(name)</strong>
</dt>
<dd>
Get a timer 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.1/manual.html#5.4">string</a></span>
The label that was given to the timer when it was created
</li>
</ul>
<h3>Returns:</h3>
<ol>
The timer
</ol>
</dd>
<dt>
<a name = "SetFunction"></a>
<strong>SetFunction(t, func, funcArgs)</strong>
</dt>
<dd>
Give the timer a new function and args
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
<li><span class="parameter">func</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span>
The name of the LevelFunc member to call when the time is up
</li>
<li><span class="parameter">funcArgs</span>
the arguments with which the above function will be called
</li>
</ul>
</dd>
<dt>
<a name = "Start"></a>
<strong>Start(t)</strong>
</dt>
<dd>
Begin or unpause a timer. If showing the remaining time on-screen, its color will be set to white.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
</ul>
</dd>
<dt>
<a name = "Pause"></a>
<strong>Pause(t)</strong>
</dt>
<dd>
Pause the timer. If showing the remaining time on-screen, its color will be set to yellow.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
</ul>
</dd>
<dt>
<a name = "Stop"></a>
<strong>Stop(t)</strong>
</dt>
<dd>
Stop the timer.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
</ul>
</dd>
<dt>
<a name = "GetRemainingTime"></a>
<strong>GetRemainingTime(t)</strong>
</dt>
<dd>
Get the remaining time for a timer.
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
</ul>
<h3>Returns:</h3>
<ol>
the time in seconds remaining on the clock
</ol>
</dd>
<dt>
<a name = "SetRemainingTime"></a>
<strong>SetRemainingTime(t, remainingTime)</strong>
</dt>
<dd>
Set the remaining time for a timer
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
<li><span class="parameter">remainingTime</span>
<span class="types"><span class="type">number</span></span>
the new time remaining for the timer
</li>
</ul>
</dd>
<dt>
<a name = "GetTotalTime"></a>
<strong>GetTotalTime(t)</strong>
</dt>
<dd>
Get the total time for a timer.
This is the amount of time the timer will start with, as well as when starting a new loop
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
</ul>
<h3>Returns:</h3>
<ol>
the timer's total time
</ol>
</dd>
<dt>
<a name = "SetTotalTime"></a>
<strong>SetTotalTime(t, totalTime)</strong>
</dt>
<dd>
Set the total time for a timer
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
<li><span class="parameter">totalTime</span>
<span class="types"><span class="type">number</span></span>
timer's new total time
</li>
</ul>
</dd>
<dt>
<a name = "SetLooping"></a>
<strong>SetLooping(t, looping)</strong>
</dt>
<dd>
Set whether or not the timer loops
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">t</span>
the timer in question
</li>
<li><span class="parameter">looping</span>
<span class="types"><span class="type">bool</span></span>
whether or not the timer loops
</li>
</ul>
</dd>
<dt>
<a name = "UpdateAll"></a>
<strong>UpdateAll(dt)</strong>
</dt>
<dd>
Update all active timers.
Should be called in LevelFuncs.OnControlPhase
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">dt</span>
<span class="types"><span class="type">number</span></span>
The time in seconds since the last frame
</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-08-01 20:38:26 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -0,0 +1,144 @@
<!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 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>Contents</h2>
<ul>
<li><a href="#Functions">Functions</a></li>
</ul>
<h2>5 Lua utility modules</h2>
<ul class="nowrap">
<li><a href="../5 lua utility modules/Timer.html">Timer</a></li>
<li><strong>Util</strong></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.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><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/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="../4 enums/Effects.BlendID.html">Effects.BlendID</a></li>
<li><a href="../4 enums/Objects.ObjID.html">Objects.ObjID</a></li>
</ul>
</div>
<div id="content">
<h1>Lua utility module <code>Util</code></h1>
<p>Misc Util functions</p>
<p>
</p>
<h2><a href="#Functions">Functions</a></h2>
<table class="function_list">
<tr>
<td class="name" ><a href="#ShortenTENCalls">ShortenTENCalls()</a></td>
<td class="summary">Adds all built-in functions and types to the global environment.</td>
</tr>
</table>
<br/>
<br/>
<h2 class="section-header "><a name="Functions"></a>Functions</h2>
<dl class="function">
<dt>
<a name = "ShortenTENCalls"></a>
<strong>ShortenTENCalls()</strong>
</dt>
<dd>
<p>Adds all built-in functions and types to the global environment.
Put simply, this means that you do not have to write out the full name of a function.
e.g. Instead of writing</p>
<pre><code>local door = TEN.Objects.GetMoveableByName("door_type4_14")
</code></pre>
<p> You can write</p>
<pre><code>local door = GetMoveableByName("door_type4_14")
</code></pre>
</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-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -31,6 +31,7 @@
<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>
@ -64,8 +65,14 @@
<h2>4 Enums</h2>
<ul class="nowrap">
<li><a href="4 enums/Flow.InvID.html">Flow.InvID</a></li>
<li><a href="4 enums/Effects.BlendID.html">Effects.BlendID</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/Timer.html">Timer</a></li>
<li><a href="5 lua utility modules/Util.html">Util</a></li>
</ul>
</div>
@ -100,6 +107,10 @@ Util.ShortenTENCalls()
<h2>1 Modules</h2>
<table class="module_list">
<tr>
<td class="name" ><a href="1 modules/Effects.html">Effects</a></td>
<td class="summary">Functions to generate effects.</td>
</tr>
<tr>
<td class="name" ><a href="1 modules/Flow.html">Flow</a></td>
<td class="summary">Functions for use in Flow.lua, settings.lua and strings.lua</td>
@ -205,17 +216,32 @@ Util.ShortenTENCalls()
<td class="name" ><a href="4 enums/Flow.InvID.html">Flow.InvID</a></td>
<td class="summary">Constants for items that can be used with GetItem and SetItem.</td>
</tr>
<tr>
<td class="name" ><a href="4 enums/Effects.BlendID.html">Effects.BlendID</a></td>
<td class="summary">Constants for blend mode IDs.</td>
</tr>
<tr>
<td class="name" ><a href="4 enums/Objects.ObjID.html">Objects.ObjID</a></td>
<td class="summary">Constants for object IDs.</td>
</tr>
</table>
<h2>5 Lua utility modules</h2>
<table class="module_list">
<tr>
<td class="name" ><a href="5 lua utility modules/Timer.html">Timer</a></td>
<td class="summary">Basic timer - after a specified number of seconds, the specified thing happens.</td>
</tr>
<tr>
<td class="name" ><a href="5 lua utility modules/Util.html">Util</a></td>
<td class="summary">Misc Util functions</td>
</tr>
</table>
</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-05-23 21:24:45 </i>
<i style="float:right;">Last updated 2022-07-31 20:38:24 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -93,6 +93,7 @@
# if modName:find("class") then modName = "Class" end
# if modName:find("Tentable") then modName = "Table" end
# if modName:find("Tenprimitive") then modName = "Primitive Class" end
# if modName:find("Luautil") then modName = "Lua utility module" end
<h1>$(modName) <code>$(module.name)</code></h1>
# end
<p>$(M(module.summary,module))</p>

View file

@ -1,5 +0,0 @@
-- Test level script file
LevelFuncs.OnLoad = function() end
LevelFuncs.OnSave = function() end
LevelFuncs.OnControlPhase = function() end
LevelFuncs.OnEnd = function() end

106
Scripts/EventSequence.lua Normal file
View file

@ -0,0 +1,106 @@
local Timer = require("Timer")
local EventSequence
LevelVars.__TEN_eventSequence = {sequences = {}}
EventSequence = {
Create = function(name, showString, ...)
local obj = {}
local mt = {}
mt.__index = EventSequence
setmetatable(obj, mt)
obj.name = name
LevelVars.__TEN_eventSequence.sequences[name] ={}
local thisES = LevelVars.__TEN_eventSequence.sequences[name]
thisES.name = name
thisES.timesFuncsAndArgs = {...}
local tfa = thisES.timesFuncsAndArgs
thisES.timers = {}
thisES.currentTimer = 1
local prevTimer = nil
local prevFuncName = nil
for i = 1, #tfa, 2 do
local nextTimer = i + 2
local timerIndex = #thisES.timers + 1
local funcName = "__TEN_eventSequence_" .. name .. "_func" .. timerIndex
local timerName = "__TEN_eventSequence_" .. name .. "_timer" .. timerIndex
local nextTimerName = "__TEN_eventSequence_" .. name .. "_timer" .. timerIndex + 1
local funcAndArgs = tfa[i+1]
local func
if type(funcAndArgs) == "string" then
-- we only have a function
func = funcAndArgs
funcAndArgs = {}
else
-- we have a function and possible args
func = table.remove(funcAndArgs, 1)
end
if nextTimer < #tfa then
-- This function must start next timer
-- AND do its function
LevelFuncs[funcName] = function(...)
LevelFuncs[func](...)
Timer.Get(nextTimerName):Start()
thisES.currentTimer = timerIndex + 1
end
else
-- final timer
LevelFuncs[funcName] = function(...)
LevelFuncs[func](...)
Timer.Get(timerName):Stop()
thisES.currentTimer = 1
end
end
local thisTimer = Timer.Create(timerName,
tfa[i], -- time
false,
showString,
funcName,
funcAndArgs -- now with func removed
)
thisES.timers[timerIndex] = timerName
end
return obj
end;
Get = function(name)
if LevelVars.__TEN_eventSequence.sequences[name] then
local obj = {}
local mt = {}
mt.__index = EventSequence
setmetatable(obj, mt)
obj.name = name
return obj
end
return nil
end,
Pause = function(t)
local thisES = LevelVars.__TEN_eventSequence.sequences[t.name]
Timer.Get(thisES.timers[thisES.currentTimer]):Pause()
end,
Stop = function(t)
local thisES = LevelVars.__TEN_eventSequence.sequences[t.name]
Timer.Get(thisES.timers[thisES.currentTimer]):Stop()
end,
Start = function(t)
local thisES = LevelVars.__TEN_eventSequence.sequences[t.name]
Timer.Get(thisES.timers[thisES.currentTimer]):Start()
end;
}
return EventSequence

View file

@ -1,5 +1,7 @@
-- Place in this LUA script all the levels of your game
-- Title is mandatory and must be the first level
-- Title is mandatory and must be the first level.
-- Shorten some of the internal data types.
local Flow = TEN.Flow
local Level = Flow.Level
@ -9,36 +11,54 @@ local InventoryItem = Flow.InventoryItem
local InvID = Flow.InvID
local RotationAxis = Flow.RotationAxis
local ItemAction = Flow.ItemAction
local Fog = Flow.Fog
-- These variables are unused for now.
Flow.SetIntroImagePath("Screens\\main.jpg")
Flow.SetTitleScreenImagePath("Screens\\main.jpg")
-- Flow.SetFarView sets global far view distance in blocks.
-- It will be overwritten by level.farView value, if it is specified.
Flow.SetFarView(20)
--------------------------------------------------
-- Title level
Flow.SetIntroImagePath("Screens\\Main.png")
Flow.SetTitleScreenImagePath("Screens\\Title.png")
Flow.SetFarView(210)
title = Level.new();
title = Level.new()
title.ambientTrack = "108_A8_Coastal";
title.levelFile = "Data\\title.ten";
title.scriptFile = "Scripts\\title.lua";
title.loadScreenFile = "Screens\\rome.jpg";
title.ambientTrack = "108"
title.levelFile = "Data\\title.ten"
title.scriptFile = "Scripts\\title.lua"
title.loadScreenFile = "Screens\\Main.png"
Flow.AddLevel(title);
Flow.AddLevel(title)
-- Test
test = Level.new();
--------------------------------------------------
-- First test level
test = Level.new()
test.nameKey = "level_test"
test.scriptFile = "Scripts\\TestLevel.lua"
test.ambientTrack = "108"
test.levelFile = "Data\\TestLevel.ten"
test.loadScreenFile = "Screens\\rome.jpg"
-- 0 is no weather, 1 is rain, 2 is snow.
-- Strength varies from 0 to 1 (floating-point value, e.g. 0.5 means half-strength).
test.weather = 0
test.weatherStrength = 1
test.nameKey = "level_andrea1";
test.scriptFile = "Scripts\\andrea1.lua";
test.ambientTrack = "108_A8_Coastal";
test.levelFile = "Data\\luatest.ten";
test.loadScreenFile = "Screens\\rome.jpg";
test.weather = 1;
test.weatherStrength = 1;
test.horizon = true
test.farView = 10
test.colAddHorizon = true
test.farView = 20
test.layer1 = Flow.SkyLayer.new(Color.new(255, 0, 0), 15)
test.fog = Flow.Fog.new(Color.new(0, 0, 0), 12, 20)
-- Presets for inventory item placement.
test.objects = {
InventoryItem.new(
@ -92,7 +112,6 @@ test.objects = {
-1,
ItemAction.USE
)
}
};
Flow.AddLevel(test);
Flow.AddLevel(test)

View file

@ -1,26 +1,19 @@
-- TombEngine settings file
-- Created by MontyTRC
-- Place all the engine settings for your game in this Lua script.
-- WARNING: Bad values could make your game unplayable; please follow reference guide attentively.
local Flow = TEN.Flow
local settings = Flow.Settings.new();
settings.screenWidth = 1920;
settings.screenHeight = 1080;
settings.enableDynamicShadows = true;
settings.enableWaterCaustics = true;
settings.windowed = true;
settings.drawingDistance = 102400;
settings.showRendererSteps = false;
settings.showDebugInfo = true;
settings.errorMode = Flow.ErrorMode.WARN;
Flow.SetSettings(settings);
local settings = Flow.Settings.new()
settings.errorMode = Flow.ErrorMode.WARN
Flow.SetSettings(settings)
local anims = Flow.Animations.new();
anims.crawlExtended = true;
anims.crouchRoll = true;
anims.crawlspaceSwandive = true;
anims.monkeyAutoJump = false;
anims.pose = false;
Flow.SetAnimations(anims);
local anims = Flow.Animations.new()
anims.crawlExtended = true
anims.crouchRoll = true
anims.crawlspaceSwandive = true
anims.monkeyAutoJump = false
anims.overhangClimb = false
anims.slideExtended = false
anims.sprintJump = false
anims.pose = false
Flow.SetAnimations(anims)

View file

@ -1139,7 +1139,7 @@ local strings = {
"",
""
},
level_andrea1 = {
level_test = {
"Our test level",
"",
"",

117
Scripts/TestLevel.lua Normal file
View file

@ -0,0 +1,117 @@
-- Test level script file
local Util = require("Util")
Util.ShortenTENCalls()
LevelFuncs.OnLoad = function() end
LevelFuncs.OnSave = function() end
LevelFuncs.OnControlPhase = function() end
LevelFuncs.OnEnd = function() end
-- An example function which prints a string and leaves it on screen for 1 second.
-- Argument should be typed in TE trigger manager window's argument text field.
LevelFuncs.PrintText = function(Triggerer, Argument)
local TestText = DisplayString(Argument, 100, 100, Color.new(250,250,250))
ShowString(TestText, 1)
end
-- Another example function which emits rotating electric halo around object,
-- which triggered it.
local currentX = 0.0
local currentY = 0.0
LevelFuncs.EmitHaloOnActionPush = function(Triggerer)
-- This is a list of all possible keys which can be checked for their pushed/not pushed state.
-- Later we will move them to separate internal file or make them internal TEN constants.
local Keys =
{
Forward = 0,
Back = 1,
Left = 2,
Right = 3,
Crouch = 4,
Sprint = 5,
Walk = 6,
Jump = 7,
Action = 8,
Draw = 9,
Flare = 10,
Look = 11,
Roll = 12,
Inventory = 13,
Pause = 14,
StepLeft = 15,
StepRight = 16
}
-- First argument which is passed to function that is triggered from TE volumes is
-- always an object which triggered it (except cases when triggerer is static mesh or
-- flyby camera). We can directly use Triggerer argument to get some properties from
-- it. In this case, we get position of a root joint (in case of Lara, it is her hips).
local pos = Triggerer:GetJointPosition(0)
-- math.random() is an internal Lua method which returns a value between 2 specified limits,
-- in our case something between 200 and 255. We use it to vary halo intensity a bit.
local color = math.random(200, 255)
local velocity = Vec3(0, 0, 0) -- No velocity
-- Again, we can use velocity to get some value between 60 and 80 to vary rotation rate of
-- a spawned halo particle.
local rot = math.random(60, 80)
-- circleLength is standard mathematical constant for circle length which is later used to
-- get sin/cos value to rotate light and particle around an object.
local circleLength = 3.14 * 2.0
-- Progress currentX and currentY variables to change current X and Y positions of the halo.
currentX = currentX + 0.2
currentY = currentY + 0.1
-- Here we clamp currentX and currentY values to max circle length, because sin/cos operations
-- can't operate out of circle length range.
if (currentX > circleLength) then
currentX = currentX - circleLength;
end
if (currentY > circleLength) then
currentY = currentY - circleLength;
end
local horizontalAmplitude = 384 -- 3 clicks height, where effect wanders about.
local haloRotationDistance = 256 -- rotate on distance 2 clicks around object.
-- Calculate relative offset of a halo using simple sin/cos functions.
local offsetX = math.cos(currentX) * haloRotationDistance
local offsetZ = math.sin(currentX) * haloRotationDistance
local offsetY = math.sin(currentY) * horizontalAmplitude
-- Add relative offsets to joint position.
pos.x = pos.x + offsetX
pos.y = pos.y + offsetY
pos.z = pos.z + offsetZ
-- Play electrical sound.
Misc.PlaySound(197, pos)
-- Emit particle and light. Look into manual for list of arguments.
Effects.EmitParticle(pos, velocity, 2, 1, rot, Color.new(color * 0.5, color * 0.5, color), Color.new(color * 0.2, color * 0.1, color), 2, 16, 64, 1, false, false)
Effects.EmitLight(pos, Color.new(color * 0.5, color * 0.5, color), 7)
end

190
Scripts/Timer.lua Normal file
View file

@ -0,0 +1,190 @@
-----
--- Basic timer - after a specified number of seconds, the specified thing happens.
-- Usage:
-- local Timer = require("Timer")
--
-- LevelFuncs.FinishTimer = function(healthWhenStarted, victoryMessage)
-- DoSomething(healthWhenStarted, victoryMessage)
-- end
--
-- LevelFuncs.TriggerTimer = function(obj)
-- local myTimer = Timer.Create("my_timer", 5.0, false, true, "FinishTimer", Lara:GetHP(), "Well done!")
-- myTimer:Start()
-- end
--
-- LevelFuncs.OnControlPhase = function(dt)
-- Timer.UpdateAll(dt)
-- end
--
-- @luautil Timer
LevelVars.__TEN_timer = {timers = {}}
local Timer
local unpausedColor = Color(255, 255, 255)
local pausedColor = Color(255, 255, 0)
local str = TEN.Strings.DisplayString("TIMER", 0, 0, unpausedColor, false, {TEN.Strings.DisplayStringOption.CENTER, TEN.Strings.DisplayStringOption.SHADOW} )
Timer = {
--- Create (but do not start) a new timer.
-- @string name A label to give this timer; used to retrieve the timer later
-- @number totalTime The duration of the timer, in seconds
-- @bool loop if true, the timer will start again immediately after the time has elapsed
-- @bool showString if true, the remaining time, rounded up, will show at the bottom of the screen. __At any given time, only one timer can show its remaining time__.
-- @string func The name of the LevelFunc member to call when the time is up
-- @param funcArgs the arguments with which the above function will be called
-- @return The timer in its paused state
Create = function(name, totalTime, loop, showString, func, ...)
local obj = {}
local mt = {}
mt.__index = Timer
setmetatable(obj, mt)
obj.name = name
LevelVars.__TEN_timer.timers[name] ={}
local thisTimer = LevelVars.__TEN_timer.timers[name]
thisTimer.name = name
thisTimer.showString = showString
thisTimer.totalTime = totalTime
thisTimer.remainingTime = totalTime
thisTimer.func = func
thisTimer.funcArgs = {...}
thisTimer.loop = loop
thisTimer.active = false
thisTimer.paused = true
return obj
end;
--- Get a timer by its name.
-- @string name The label that was given to the timer when it was created
-- @return The timer
Get = function(name)
if LevelVars.__TEN_timer.timers[name] then
local obj = {}
local mt = {}
mt.__index = Timer
setmetatable(obj, mt)
obj.name = name
return obj
end
return nil
end,
--- Give the timer a new function and args
-- @param t the timer in question
-- @string func The name of the LevelFunc member to call when the time is up
-- @param funcArgs the arguments with which the above function will be called
SetFunction = function(t, func, ...)
local thisTimer = LevelVars.__TEN_timer.timers[t.name]
thisTimer.func = func
thisTimer.funcArgs = {...}
end,
--- Begin or unpause a timer. If showing the remaining time on-screen, its color will be set to white.
-- @param t the timer in question
Start = function(t)
local thisTimer = LevelVars.__TEN_timer.timers[t.name]
if not thisTimer.active then
thisTimer.active = true
end
LevelVars.__TEN_timer.timers[t.name].paused = false
if thisTimer.showString then
str:SetColor(unpausedColor)
end
end;
--- Pause the timer. If showing the remaining time on-screen, its color will be set to yellow.
-- @param t the timer in question
Pause = function(t)
local thisTimer = LevelVars.__TEN_timer.timers[t.name]
thisTimer.paused = true
if thisTimer.showString then
str:SetColor(pausedColor)
end
end,
--- Stop the timer.
-- @param t the timer in question
Stop = function(t)
LevelVars.__TEN_timer.timers[t.name].active = false
end,
--- Get the remaining time for a timer.
-- @param t the timer in question
-- @return the time in seconds remaining on the clock
GetRemainingTime = function(t)
return LevelVars.__TEN_timer.timers[t.name].remainingTime
end,
--- Set the remaining time for a timer
-- @param t the timer in question
-- @number remainingTime the new time remaining for the timer
SetRemainingTime = function(t, remainingTime)
LevelVars.__TEN_timer.timers[t.name].remainingTime = remainingTime
end,
--- Get the total time for a timer.
-- This is the amount of time the timer will start with, as well as when starting a new loop
-- @param t the timer in question
-- @return the timer's total time
GetTotalTime = function(t)
return LevelVars.__TEN_timer.timers[t.name].totalTime
end,
--- Set the total time for a timer
-- @param t the timer in question
-- @number totalTime timer's new total time
SetTotalTime = function(t, totalTime)
LevelVars.__TEN_timer.timers[t.name].totalTime = totalTime
end,
--- Set whether or not the timer loops
-- @param t the timer in question
-- @bool looping whether or not the timer loops
SetLooping = function(t, looping)
LevelVars.__TEN_timer.timers[t.name].loop = looping
end,
--- Update all active timers.
-- Should be called in LevelFuncs.OnControlPhase
-- @number dt The time in seconds since the last frame
UpdateAll = function(dt)
for _, t in pairs(LevelVars.__TEN_timer.timers) do
Timer.Update(t, dt)
end
end;
Update = function(t, dt)
if t.active then
if not t.paused then
t.remainingTime = t.remainingTime - dt
if t.remainingTime <= 0 then
LevelFuncs[t.func](table.unpack(t.funcArgs))
if not t.loop then
t.active = false
else
t.remainingTime = t.remainingTime + t.totalTime
end
end
end
if t.showString then
TEN.Strings.HideString(str)
str:SetKey(tostring(math.ceil(t.remainingTime)))
local myX, myY = PercentToScreen(50, 90)
str:SetPosition(myX, myY)
TEN.Strings.ShowString(str, 1)
end
end
end;
}
return Timer

View file

@ -1,5 +1,10 @@
-- Title script file
local Util = require("Util")
Util.ShortenTENCalls()
LevelFuncs.OnLoad = function() end
LevelFuncs.OnSave = function() end
LevelFuncs.OnControlPhase = function() end
LevelFuncs.OnEnd = function() end
LevelFuncs.OnControlPhase = function() end

View file

@ -1,7 +1,17 @@
-----
--- Misc Util functions
-- @luautil Util
local Util = {}
--- Adds all built-in functions and types to the global environment.
-- Put simply, this means that you do not have to write out the full name of a function.
-- e.g. Instead of writing
-- local door = TEN.Objects.GetMoveableByName("door_type4_14")
-- You can write
-- local door = GetMoveableByName("door_type4_14")
Util.ShortenTENCalls = function()
local ShortenInner
ShortenInner = function(tab)
for k, v in pairs(tab) do
if _G[k] then

View file

@ -462,6 +462,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
bool isWater = TestEnvironment(ENV_FLAG_WATER, item);
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item);
bool isWaterOnHeadspace = false;
int waterDepth = GetWaterDepth(item);
int waterHeight = GetWaterHeight(item);
@ -553,14 +555,15 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
break;
case WaterStatus::Underwater:
if (isWater ||
waterDepth == DEEP_WATER || abs(heightFromWater) >= CLICK(1) ||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE ||
item->Animation.AnimNumber == LA_ONWATER_DIVE)
isWaterOnHeadspace = TestEnvironment(ENV_FLAG_WATER, item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z,
GetCollision(item->Pose.Position.x, item->Pose.Position.y - CLICK(1), item->Pose.Position.z, item->RoomNumber).RoomNumber);
if (waterDepth == NO_HEIGHT || abs(heightFromWater) >= CLICK(1) || isWaterOnHeadspace ||
item->Animation.AnimNumber == LA_UNDERWATER_RESURFACE || item->Animation.AnimNumber == LA_ONWATER_DIVE)
{
if (!isWater)
{
if (waterDepth == DEEP_WATER || abs(heightFromWater) >= CLICK(1))
if (waterDepth == NO_HEIGHT || abs(heightFromWater) >= CLICK(1))
{
SetAnimation(item, LA_FALL_START);
ResetLaraLean(item);

View file

@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_collide.h"
@ -26,6 +27,7 @@
using namespace TEN::Renderer;
using namespace TEN::Input;
using namespace TEN::Control::Volumes;
// -----------------------------
// HELPER FUNCTIONS
@ -77,6 +79,8 @@ bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
if (lara->Vehicle != NO_ITEM)
{
TestVolumes(lara->Vehicle);
switch (g_Level.Items[lara->Vehicle].ObjectNumber)
{
case ID_QUAD:

View file

@ -210,7 +210,7 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
else
{
lara->LeftArm.GunSmoke = 28;
TriggerGunShell(0, ID_GUNSHELL, weaponType); // left hand
TriggerGunShell(0, ID_GUNSHELL, weaponType); // Left hand
lara->LeftArm.GunFlash = weapon->FlashTime;
}

View file

@ -107,6 +107,11 @@ void AlterFOV(int value)
PhdPerspective = g_Configuration.Width / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2);
}
short GetCurrentFOV()
{
return CurrentFOV;
}
inline void RumbleFromBounce()
{
Rumble(std::clamp((float)abs(Camera.bounce) / 70.0f, 0.0f, 0.8f), 0.2f);
@ -1812,13 +1817,13 @@ static bool CheckItemCollideCamera(ItemInfo* item)
std::vector<short> FillCollideableItemList()
{
std::vector<short> itemList;
auto roomList = GetRoomList(Camera.pos.roomNumber);
auto& roomList = g_Level.Rooms[Camera.pos.roomNumber].neighbors;
for (short i = 0; i < g_Level.NumItems; i++)
{
auto item = &g_Level.Items[i];
if (!roomList.count(item->RoomNumber))
if (std::find(roomList.begin(), roomList.end(), item->RoomNumber) == roomList.end())
continue;
if (!CheckItemCollideCamera(&g_Level.Items[i]))
@ -1863,7 +1868,7 @@ static bool CheckStaticCollideCamera(MESH_INFO* mesh)
std::vector<MESH_INFO*> FillCollideableStaticsList()
{
std::vector<MESH_INFO*> staticList;
auto roomList = GetRoomList(Camera.pos.roomNumber);
auto& roomList = g_Level.Rooms[Camera.pos.roomNumber].neighbors;
for (auto i : roomList)
{
@ -2060,48 +2065,36 @@ void UpdateFadeScreenAndCinematicBars()
void HandleOptics()
{
if (!(TrInput & IN_LOOK) || UseSpotCam || TrackCameraInit ||
((LaraItem->Animation.ActiveState != LS_IDLE || LaraItem->Animation.AnimNumber != LA_STAND_IDLE) &&
(!Lara.Control.IsLow || TrInput & IN_CROUCH || LaraItem->Animation.TargetState != LS_CROUCH_IDLE || LaraItem->Animation.AnimNumber != LA_CROUCH_IDLE)))
bool breakOptics = true;
if (!LaserSight && BinocularOn) // Imitate pushing look key in binocular mode
{
if (BinocularRange == 0)
{
if (UseSpotCam || TrackCameraInit)
TrInput &= ~IN_LOOK;
}
else
{
// If any input but optic controls (directions + action), immediately exit binoculars mode.
if (TrInput != IN_NONE && ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE))
BinocularRange = 0;
if (LaserSight)
{
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->MeshBits = ALL_JOINT_BITS;
Lara.Inventory.IsBusy = false;
ResetLaraFlex(LaraItem);
TrInput &= ~IN_LOOK;
}
else
{
TrInput |= IN_LOOK;
DbInput = 0;
}
}
TrInput |= IN_LOOK;
DbInput = 0;
}
else if (BinocularRange == 0)
// We are standing, can use optics.
if (LaraItem->Animation.ActiveState == LS_IDLE || LaraItem->Animation.AnimNumber == LA_STAND_IDLE)
breakOptics = false;
// We are crouching, can use optics.
if ((Lara.Control.IsLow || TrInput & IN_CROUCH) &&
(LaraItem->Animation.TargetState == LS_CROUCH_IDLE || LaraItem->Animation.AnimNumber == LA_CROUCH_IDLE))
breakOptics = false;
// If any input but optic controls (directions + action), immediately exit optics.
if ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE)
breakOptics = true;
// If lasersight, and no look is pressed, exit optics.
if (LaserSight && !(TrInput & IN_LOOK))
breakOptics = true;
if (!LaserSight && !breakOptics && (TrInput == IN_LOOK)) // Engage lasersight, if available.
{
if (Lara.Control.HandStatus == HandStatus::WeaponReady &&
((Lara.Control.Weapon.GunType == LaraWeaponType::Revolver && Lara.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
Lara.Control.Weapon.GunType == LaraWeaponType::HK ||
(Lara.Control.Weapon.GunType == LaraWeaponType::HK ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Revolver && Lara.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Crossbow && Lara.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight)))
{
BinocularRange = 128;
@ -2109,6 +2102,27 @@ void HandleOptics()
BinocularOn = true;
LaserSight = true;
Lara.Inventory.IsBusy = true;
return;
}
}
if (!breakOptics)
return;
// Nothing to process, exit.
if (!BinocularOn && !LaserSight)
return;
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->MeshBits = ALL_JOINT_BITS;
Lara.Inventory.IsBusy = false;
ResetLaraFlex(LaraItem);
TrInput &= ~IN_LOOK;
}

View file

@ -72,6 +72,7 @@ extern float CinematicBarsSpeed;
void LookAt(CAMERA_INFO* cam, short roll);
void AlterFOV(int value);
short GetCurrentFOV();
void InitialiseCamera();
void MoveCamera(GameVector* ideal, int speed);
void ChaseCamera(ItemInfo* item);

View file

@ -103,9 +103,7 @@ bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, I
short numMeshes = 0;
// Collect all the rooms where to check
auto roomsArray = GetRoomList(collidingItem->RoomNumber);
for (auto i : roomsArray)
for (auto i : g_Level.Rooms[collidingItem->RoomNumber].neighbors)
{
auto* room = &g_Level.Rooms[i];
@ -309,7 +307,7 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll)
// g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RENDERER_DEBUG_PAGE::DIMENSION_STATS);
for (auto i : GetRoomList(item->RoomNumber))
for (auto i : g_Level.Rooms[item->RoomNumber].neighbors)
{
short itemNumber = g_Level.Rooms[i].itemNumber;
while (itemNumber != NO_ITEM)
@ -860,7 +858,7 @@ void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
{
coll->HitTallObject = false;
for (auto i : GetRoomList(item->RoomNumber))
for (auto i : g_Level.Rooms[item->RoomNumber].neighbors)
{
for (int j = 0; j < g_Level.Rooms[i].mesh.size(); j++)
{
@ -1725,7 +1723,7 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll)
if (Objects[laraItem->ObjectNumber].intelligent)
return;
for (auto i : GetRoomList(laraItem->RoomNumber))
for (auto i : g_Level.Rooms[laraItem->RoomNumber].neighbors)
{
int nextItem = g_Level.Rooms[i].itemNumber;
while (nextItem != NO_ITEM)

View file

@ -1311,6 +1311,7 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
while (floor->RoomBelow(x, y, z).value_or(NO_ROOM) != NO_ROOM)
{
room = &g_Level.Rooms[floor->RoomBelow(x, y, z).value_or(floor->Room)];
if (TestEnvironment(ENV_FLAG_WATER, room) ||
TestEnvironment(ENV_FLAG_SWAMP, room))
{

View file

@ -464,15 +464,9 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
boxHeight = item->Floor;
auto old = item->Pose.Position;
if (!Objects[item->ObjectNumber].waterCreature)
{
auto roomNumber = GetCollision(item).RoomNumber;
if (roomNumber != item->RoomNumber)
ItemNewRoom(itemNumber, roomNumber);
}
AnimateItem(item);
if (item->Status == ITEM_DEACTIVATED)
{
CreatureDie(itemNumber, false);
@ -779,34 +773,34 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
item->Pose.Orientation.x = 0;
}
if (!Objects[item->ObjectNumber].waterCreature)
{
auto roomNumber = GetCollision(item->Pose.Position.x,
item->Pose.Position.y - CLICK(2),
item->Pose.Position.z,
item->RoomNumber).RoomNumber;
if (roomNumber != item->RoomNumber)
ItemNewRoom(itemNumber, roomNumber);
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, &g_Level.Rooms[roomNumber]))
{
auto bounds = GetBoundsAccurate(item);
auto height = item->Pose.Position.y - GetWaterHeight(item);
if (abs(bounds->Y1 + bounds->Y2) < height)
DoDamage(item, INT_MAX);
}
}
roomNumber = item->RoomNumber;
GetFloor(item->Pose.Position.x, item->Pose.Position.y - CLICK(2), item->Pose.Position.z, &roomNumber);
if (item->RoomNumber != roomNumber)
ItemNewRoom(itemNumber, roomNumber);
CreatureSwitchRoom(itemNumber);
return true;
}
void CreatureSwitchRoom(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];
auto roomNumber = GetCollision(item->Pose.Position.x,
item->Pose.Position.y - CLICK(2),
item->Pose.Position.z,
item->RoomNumber).RoomNumber;
if (roomNumber != item->RoomNumber)
ItemNewRoom(itemNumber, roomNumber);
if (!Objects[item->ObjectNumber].waterCreature &&
TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, &g_Level.Rooms[roomNumber]))
{
auto bounds = GetBoundsAccurate(item);
auto height = item->Pose.Position.y - GetWaterHeight(item);
if (abs(bounds->Y1 + bounds->Y2) < height)
DoDamage(item, INT_MAX);
}
}
void CreatureDie(short itemNumber, bool explode)
{
auto* item = &g_Level.Items[itemNumber];

View file

@ -181,6 +181,7 @@ int StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber);
void CreatureAIInfo(ItemInfo* item, AI_INFO* AI);
TARGET_TYPE CalculateTarget(Vector3Int* target, ItemInfo* item, LOTInfo* LOT);
int CreatureAnimation(short itemNumber, short angle, short tilt);
void CreatureSwitchRoom(short itemNumber);
void AdjustStopperFlag(ItemInfo* item, int direction, bool set);
void InitialiseItemBoxData();

View file

@ -97,7 +97,7 @@ short NextFxFree;
int DrawPhase()
{
g_Renderer.Draw();
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
return Camera.numberFrames;
}
@ -115,16 +115,13 @@ GameStatus ControlPhase(int numFrames, int demoMode)
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
bool firstTime = true;
static int framesCount = 0;
for (framesCount += numFrames; framesCount > 0; framesCount -= 2)
{
GlobalCounter++;
// This might not be the exact amount of time that has passed, but giving it a
// value of 1/30 keeps it in lock-step with the rest of the game logic,
// which assumes 30 iterations per second.
g_GameScript->OnControlPhase(DELTA_TIME);
// Poll the keyboard and update input variables
if (CurrentLevel != 0)
UpdateInput();
@ -137,6 +134,12 @@ GameStatus ControlPhase(int numFrames, int demoMode)
TrInput &= IN_LOOK;
}
// This might not be the exact amount of time that has passed, but giving it a
// value of 1/30 keeps it in lock-step with the rest of the game logic,
// which assumes 30 iterations per second.
g_GameScript->OnControlPhase(DELTA_TIME);
if (CurrentLevel != 0)
{
// Does the player want to enter inventory?
@ -184,7 +187,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
while (g_Gui.GetInventoryMode() == InventoryMode::Pause)
{
g_Gui.DrawInventory();
g_Renderer.SyncRenderer();
g_Renderer.Synchronize();
if (g_Gui.DoPauseMenu() == InventoryResult::ExitToTitle)
return GameStatus::ExitToTitle;
@ -333,7 +336,6 @@ GameStatus ControlPhase(int numFrames, int demoMode)
UpdateShockwaves();
UpdateBeetleSwarm();
UpdateLocusts();
AnimateWaterfalls();
// Rumble screen (like in submarine level of TRC)
if (level->Rumble)
@ -350,6 +352,13 @@ GameStatus ControlPhase(int numFrames, int demoMode)
// Update timers
HealthBarTimer--;
GameTimer++;
// Add renderer objects on the first processed frame
if (firstTime)
{
g_Renderer.Lock();
firstTime = false;
}
}
return GameStatus::None;
@ -416,7 +425,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
g_Renderer.AddString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
});
}
@ -467,7 +476,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
if (status != InventoryResult::None)
break;
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
frames = Camera.numberFrames;
ControlPhase(frames, 0);
}
@ -520,7 +529,7 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
g_GameScript->InitCallbacks();
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
{
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
g_Renderer.AddString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
});
}
@ -635,6 +644,8 @@ void UpdateShatters()
SmashedMesh[SmashedMeshCount]->pos.Position.z,
SmashedMeshRoom[SmashedMeshCount], true);
TestVolumes(SmashedMeshRoom[SmashedMeshCount], SmashedMesh[SmashedMeshCount]);
floor->Stopper = false;
SmashedMesh[SmashedMeshCount] = 0;
} while (SmashedMeshCount != 0);
@ -684,35 +695,6 @@ int GetRandomDraw()
return GenerateInt();
}
bool ExplodeItemNode(ItemInfo *item, int node, int noXZVel, int bits)
{
if (1 << node & item->MeshBits)
{
int number = bits;
if (item->ObjectNumber == ID_SHOOT_SWITCH1 && (CurrentLevel == 4 || CurrentLevel == 7)) // TODO: remove hardcoded think !
SoundEffect(SFX_TR5_SMASH_METAL, &item->Pose);
else if (number == BODY_EXPLODE)
number = -64;
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);
ShatterItem.yRot = item->Pose.Orientation.y;
ShatterItem.bit = 1 << node;
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex + node;
ShatterItem.sphere.x = CreatureSpheres[node].x;
ShatterItem.sphere.y = CreatureSpheres[node].y;
ShatterItem.sphere.z = CreatureSpheres[node].z;
ShatterItem.flags = item->ObjectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
ShatterImpactData.impactDirection = Vector3(0, -1, 0);
ShatterImpactData.impactLocation = {(float)ShatterItem.sphere.x, (float)ShatterItem.sphere.y, (float)ShatterItem.sphere.z};
ShatterObject(&ShatterItem, NULL, number, item->RoomNumber, noXZVel);
item->MeshBits &= ~ShatterItem.bit;
return true;
}
return false;
}
void CleanUp()
{
// Reset oscillator seed

View file

@ -45,8 +45,6 @@ constexpr int MAX_ROOMS = 1024;
constexpr int WIBBLE_SPEED = 4;
constexpr int WIBBLE_MAX = UCHAR_MAX - WIBBLE_SPEED + 1;
constexpr auto FPS = 30;
extern int GameTimer;
extern int RumbleTimer;
extern int GlobalCounter;
@ -84,7 +82,6 @@ int GetRandomDraw();
void KillMoveItems();
void KillMoveEffects();
void UpdateShatters();
bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits);
void CleanUp();

View file

@ -527,6 +527,7 @@ bool DoRayBox(GameVector* start, GameVector* end, BOUNDING_BOX* box, PHD_3DPOS*
ShatterItem.yRot = item->Pose.Orientation.y;
ShatterItem.meshIndex = meshIndex;
ShatterItem.color = item->Color;
ShatterItem.sphere.x = CreatureSpheres[sp].x;
ShatterItem.sphere.y = CreatureSpheres[sp].y;
ShatterItem.sphere.z = CreatureSpheres[sp].z;

View file

@ -100,15 +100,15 @@ int EnableEntityAI(short itemNum, int always, bool makeTarget)
void DisableEntityAI(short itemNumber)
{
ItemInfo* item = &g_Level.Items[itemNumber];
CreatureInfo* creature = (CreatureInfo*)item->Data;
if (creature)
{
creature->ItemNumber = NO_ITEM;
KillItem(creature->AITargetNumber);
ActiveCreatures.erase(std::find(ActiveCreatures.begin(), ActiveCreatures.end(), creature));
item->Data = nullptr;
}
if (!item->IsCreature())
return;
auto* creature = (CreatureInfo*)item->Data;
creature->ItemNumber = NO_ITEM;
KillItem(creature->AITargetNumber);
ActiveCreatures.erase(std::find(ActiveCreatures.begin(), ActiveCreatures.end(), creature));
item->Data = nullptr;
}
void InitialiseSlot(short itemNum, short slot, bool makeTarget)

View file

@ -15,7 +15,6 @@ using TEN::Renderer::g_Renderer;
namespace TEN::Control::Volumes
{
constexpr auto CAM_SIZE = 32;
int CurrentCollidedVolume;
@ -30,9 +29,29 @@ namespace TEN::Control::Volumes
{
auto* volume = &room->triggerVolumes[i];
if ((volume->Activators & activatorType) != activatorType)
if (volume->EventSetIndex == NO_EVENT_SET)
continue;
auto* set = &g_Level.EventSets[volume->EventSetIndex];
if ((set->Activators & activatorType) != activatorType)
continue;
// Determine what to do if volume is busy with another triggerer
if (!std::holds_alternative<nullptr_t>(volume->Triggerer) && volume->Triggerer != triggerer)
{
if (GameTimer - volume->Timeout > VOLUME_BUSY_TIMEOUT)
{
// We are past the busy timeout, reset current triggerer and volume status.
volume->Triggerer = nullptr;
volume->Status = TriggerStatus::Outside;
}
else
// We are in the same frame, triggerer is busy, leave it alone.
continue;
}
bool contains = false;
switch (volume->Type)
@ -56,24 +75,39 @@ namespace TEN::Control::Volumes
if (volume->Status == TriggerStatus::Outside)
{
volume->Triggerer = triggerer;
volume->Timeout = GameTimer;
volume->Status = TriggerStatus::Entering;
if (!volume->OnEnter.empty())
g_GameScript->ExecuteFunction(volume->OnEnter, triggerer);
if (!set->OnEnter.Function.empty() && set->OnEnter.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnEnter.Function, triggerer, set->OnEnter.Argument);
if (set->OnEnter.CallCounter != NO_CALL_COUNTER)
set->OnEnter.CallCounter--;
}
}
else
{
volume->Status = TriggerStatus::Inside;
if (!volume->OnInside.empty())
g_GameScript->ExecuteFunction(volume->OnInside, triggerer);
if (!set->OnInside.Function.empty() && set->OnInside.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnInside.Function, triggerer, set->OnInside.Argument);
if (set->OnInside.CallCounter != NO_CALL_COUNTER)
set->OnInside.CallCounter--;
}
}
}
else
{
if (volume->Status == TriggerStatus::Inside)
{
volume->Triggerer = nullptr;
volume->Status = TriggerStatus::Leaving;
if (!volume->OnLeave.empty())
g_GameScript->ExecuteFunction(volume->OnLeave, triggerer);
if (!set->OnLeave.Function.empty() && set->OnLeave.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnLeave.Function, triggerer, set->OnLeave.Argument);
if (set->OnLeave.CallCounter != NO_CALL_COUNTER)
set->OnLeave.CallCounter--;
}
}
else
volume->Status = TriggerStatus::Outside;

View file

@ -4,6 +4,11 @@
#include "Specific/setup.h"
#include "Renderer/Renderer11.h"
constexpr auto NO_EVENT_SET = -1;
constexpr auto NO_CALL_COUNTER = -1;
constexpr auto VOLUME_BUSY_TIMEOUT = 10;
enum class TriggerStatus
{
Outside,
@ -32,21 +37,18 @@ enum TriggerVolumeActivators
struct TriggerVolume
{
TriggerVolumeType Type;
int EventSetIndex;
Vector3 Position;
Quaternion Rotation;
Vector3 Scale; // x used as radius if type is TriggerVolumeType::Sphere.
std::string OnEnter;
std::string OnInside;
std::string OnLeave;
int Activators;
bool OneShot;
TriggerStatus Status;
BoundingOrientedBox Box;
BoundingSphere Sphere;
TriggerStatus Status = TriggerStatus::Outside;
VolumeTriggerer Triggerer = nullptr;
int Timeout = 0;
};
namespace TEN::Control::Volumes

View file

@ -7,7 +7,33 @@ struct CAMERA_INFO;
namespace TEN::Control::Volumes
{
using VolumeTriggerer = std::variant<
std::nullptr_t,
short,
MESH_INFO*,
CAMERA_INFO *>;
CAMERA_INFO*>;
enum class VolumeEventMode
{
LevelScript,
Constructor
};
struct VolumeEvent
{
VolumeEventMode Mode;
std::string Function;
std::string Argument;
int CallCounter;
};
struct VolumeEventSet
{
std::string Name;
int Activators;
VolumeEvent OnEnter;
VolumeEvent OnLeave;
VolumeEvent OnInside;
};
};

View file

@ -6,6 +6,7 @@
#include "Specific/prng.h"
#include "Specific/setup.h"
#include "Specific/trmath.h"
#include <Game/effects/tomb4fx.h>
using std::vector;
using namespace TEN::Renderer;
@ -18,6 +19,34 @@ MESH_INFO* SmashedMesh[32];
short SmashedMeshRoom[32];
vector<DebrisFragment> DebrisFragments = vector<DebrisFragment>(MAX_DEBRIS);
bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits)
{
if (1 << node & item->MeshBits)
{
int number = bits;
if (number == BODY_EXPLODE)
number = -64;
GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity);
ShatterItem.yRot = item->Pose.Orientation.y;
ShatterItem.bit = 1 << node;
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex + node;
ShatterItem.sphere.x = CreatureSpheres[node].x;
ShatterItem.sphere.y = CreatureSpheres[node].y;
ShatterItem.sphere.z = CreatureSpheres[node].z;
ShatterItem.color = item->Color;
ShatterItem.flags = item->ObjectNumber == ID_CROSSBOW_BOLT ? 0x400 : 0;
ShatterImpactData.impactDirection = Vector3(0, -1, 0);
ShatterImpactData.impactLocation = { (float)ShatterItem.sphere.x, (float)ShatterItem.sphere.y, (float)ShatterItem.sphere.z };
ShatterObject(&ShatterItem, NULL, number, item->RoomNumber, noXZVel);
item->MeshBits &= ~ShatterItem.bit;
return true;
}
return false;
}
DebrisFragment* GetFreeDebrisFragment()
{
for (auto& frag : DebrisFragments)
@ -33,7 +62,6 @@ DebrisFragment* GetFreeDebrisFragment()
void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumber, int noZXVel)
{
int meshIndex = 0;
MESH* fragmentsMesh;
short yRot = 0;
Vector3 pos;
bool isStatic;
@ -53,7 +81,7 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
pos = Vector3(item->sphere.x, item->sphere.y, item->sphere.z);
}
fragmentsMesh = &g_Level.Meshes[meshIndex];
auto fragmentsMesh = &g_Level.Meshes[meshIndex];
for (auto& renderBucket : fragmentsMesh->buckets)
{
@ -85,57 +113,66 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe
{
DebrisFragment* fragment = GetFreeDebrisFragment();
if (!fragment->active)
{
Matrix rotationMatrix = Matrix::CreateFromYawPitchRoll(TO_RAD(yRot), 0, 0);
if (!fragment)
break;
Vector3 pos1 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 0]]];
Vector3 pos2 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 1]]];
Vector3 pos3 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 2]]];
Matrix rotationMatrix = Matrix::CreateFromYawPitchRoll(TO_RAD(yRot), 0, 0);
Vector2 uv1 = poly->textureCoordinates[indices[j * 3 + 0]];
Vector2 uv2 = poly->textureCoordinates[indices[j * 3 + 1]];
Vector2 uv3 = poly->textureCoordinates[indices[j * 3 + 2]];
Vector3 pos1 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 0]]];
Vector3 pos2 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 1]]];
Vector3 pos3 = fragmentsMesh->positions[poly->indices[indices[j * 3 + 2]]];
Vector3 normal1 = poly->normals[indices[j * 3 + 0]];
Vector3 normal2 = poly->normals[indices[j * 3 + 1]];
Vector3 normal3 = poly->normals[indices[j * 3 + 2]];
Vector2 uv1 = poly->textureCoordinates[indices[j * 3 + 0]];
Vector2 uv2 = poly->textureCoordinates[indices[j * 3 + 1]];
Vector2 uv3 = poly->textureCoordinates[indices[j * 3 + 2]];
//Take the average of all 3 local positions
Vector3 localPos = (pos1 + pos2 + pos3) / 3;
Vector3 worldPos = Vector3::Transform(localPos, rotationMatrix);
Vector3 normal1 = poly->normals[indices[j * 3 + 0]];
Vector3 normal2 = poly->normals[indices[j * 3 + 1]];
Vector3 normal3 = poly->normals[indices[j * 3 + 2]];
fragment->worldPosition = worldPos + pos;
Vector3 color1 = fragmentsMesh->colors[poly->indices[indices[j * 3 + 0]]];
Vector3 color2 = fragmentsMesh->colors[poly->indices[indices[j * 3 + 1]]];
Vector3 color3 = fragmentsMesh->colors[poly->indices[indices[j * 3 + 2]]];
fragment->mesh.Positions[0] = pos1 - localPos;
fragment->mesh.Positions[1] = pos2 - localPos;
fragment->mesh.Positions[2] = pos3 - localPos;
//Take the average of all 3 local positions
Vector3 localPos = (pos1 + pos2 + pos3) / 3;
Vector3 worldPos = Vector3::Transform(localPos, rotationMatrix);
fragment->mesh.TextureCoordinates[0] = uv1;
fragment->mesh.TextureCoordinates[1] = uv2;
fragment->mesh.TextureCoordinates[2] = uv3;
fragment->worldPosition = worldPos + pos;
fragment->mesh.Normals[0] = normal1;
fragment->mesh.Normals[1] = normal2;
fragment->mesh.Normals[2] = normal3;
fragment->mesh.Positions[0] = pos1 - localPos;
fragment->mesh.Positions[1] = pos2 - localPos;
fragment->mesh.Positions[2] = pos3 - localPos;
fragment->mesh.blendMode = BLENDMODE_OPAQUE;
fragment->mesh.tex = renderBucket.texture;
fragment->mesh.TextureCoordinates[0] = uv1;
fragment->mesh.TextureCoordinates[1] = uv2;
fragment->mesh.TextureCoordinates[2] = uv3;
fragment->isStatic = isStatic;
fragment->active = true;
fragment->terminalVelocity = 1024;
fragment->gravity = Vector3(0, 7, 0);
fragment->restitution = 0.6f;
fragment->friction = 0.6f;
fragment->linearDrag = .99f;
fragment->angularVelocity = Vector3(GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39);
fragment->angularDrag = GenerateFloat(0.9f, 0.999f);
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
fragment->roomNumber = roomNumber;
fragment->numBounces = 0;
fragment->color = isStatic ? mesh->color : Vector4::One; // FIXME: SHATTER_ITEM must be refactored! -- Lwmte, 15.07.22
}
fragment->mesh.Normals[0] = normal1;
fragment->mesh.Normals[1] = normal2;
fragment->mesh.Normals[2] = normal3;
fragment->mesh.Colors[0] = Vector4(color1.x, color1.y, color1.z, 1.0f);
fragment->mesh.Colors[1] = Vector4(color2.x, color2.y, color2.z, 1.0f);
fragment->mesh.Colors[2] = Vector4(color3.x, color3.y, color3.z, 1.0f);
fragment->mesh.blendMode = renderBucket.blendMode;
fragment->mesh.tex = renderBucket.texture;
fragment->isStatic = isStatic;
fragment->active = true;
fragment->terminalVelocity = 1024;
fragment->gravity = Vector3(0, 7, 0);
fragment->restitution = 0.6f;
fragment->friction = 0.6f;
fragment->linearDrag = .99f;
fragment->angularVelocity = Vector3(GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39, GenerateFloat(-1, 1) * 0.39);
fragment->angularDrag = GenerateFloat(0.9f, 0.999f);
fragment->velocity = CalculateFragmentImpactVelocity(fragment->worldPosition, ShatterImpactData.impactDirection, ShatterImpactData.impactLocation);
fragment->roomNumber = roomNumber;
fragment->numBounces = 0;
fragment->color = isStatic ? mesh->color : item->color;
fragment->lightMode = fragmentsMesh->lightMode;
}
}
}
@ -193,7 +230,10 @@ void UpdateDebris()
{
auto roomNumber = floor->RoomBelow(deb.worldPosition.x, deb.worldPosition.y, deb.worldPosition.z).value_or(NO_ROOM);
if (roomNumber != NO_ROOM)
{
deb.roomNumber = roomNumber;
continue;
}
if (deb.numBounces > 3)
{

View file

@ -29,6 +29,7 @@ struct SHATTER_ITEM
SPHERE sphere;
ITEM_LIGHT* il;
int meshIndex;
Vector4 color;
int bit;
short yRot;
short flags;
@ -46,7 +47,7 @@ struct DebrisMesh
std::array<Vector3, 3> Positions;
std::array<Vector2, 3> TextureCoordinates;
std::array<Vector3, 3> Normals;
std::array<Vector3, 3> Colors;
std::array<Vector4, 3> Colors;
int tex;
};
@ -64,35 +65,13 @@ struct DebrisFragment
float friction;
float restitution;
Vector4 color;
uint32_t roomNumber;
uint32_t numBounces;
LIGHT_MODES lightMode;
int roomNumber;
int numBounces;
bool active;
bool isStatic;
};
struct DEBRIS_STRUCT
{
void* textInfo;
int x;
int y;
int z;
short xyzOffsets1[3];
short dir;
short xyzOffsets2[3];
short speed;
short xyzOffsets3[3];
short yVel;
short gravity;
short roomNumber;
byte on;
byte xRot;
byte yRot;
byte r;
byte g;
byte b;
byte pad[22];
};
extern SHATTER_ITEM ShatterItem;
extern std::vector<DebrisFragment> DebrisFragments;
extern ShatterImpactInfo ShatterImpactData;
@ -100,6 +79,7 @@ extern short SmashedMeshCount;
extern MESH_INFO* SmashedMesh[32];
extern short SmashedMeshRoom[32];
bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits);
void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumber, int noZXVel);
DebrisFragment* GetFreeDebrisFragment();
Vector3 CalculateFragmentImpactVelocity(Vector3 fragmentWorldPosition, Vector3 impactDirection, Vector3 impactLocation);

View file

@ -45,6 +45,7 @@ namespace TEN::Effects::Lightning
if (arc->life > 0)
{
// If/when this behaviour is changed, please modify AddLightningArc accordingly
arc->life -= 2;
if (arc->life)
{
@ -68,7 +69,7 @@ namespace TEN::Effects::Lightning
}
}
void TriggerLightning(Vector3Int* src, Vector3Int* dest, char amplitude, byte r, byte g, byte b, byte life, char flags, char width, char segments)
void TriggerLightning(Vector3Int* src, Vector3Int* dest, unsigned char amplitude, unsigned char r, unsigned char g, unsigned char b, unsigned char life, char flags, char width, char segments)
{
LIGHTNING_INFO arc;
@ -80,16 +81,16 @@ namespace TEN::Effects::Lightning
arc.pos3.y = (src->y + 3 * dest->y) >> 2;
arc.pos3.z = (src->z + 3 * dest->z) >> 2;
arc.pos4 = *dest;
arc.flags = flags;
for (int i = 0; i < 9; i++)
{
if (arc.flags & 2 || i < 6)
arc.interpolation[i] = ((byte)(GetRandomControl() % amplitude) - (byte)(amplitude >> 1));
arc.interpolation[i] = ((unsigned char)(GetRandomControl() % amplitude) - (unsigned char)(amplitude >> 1));
else
arc.interpolation[i] = 0;
}
arc.flags = flags;
arc.r = r;
arc.g = g;
arc.b = b;

View file

@ -52,7 +52,7 @@ namespace TEN::Effects::Lightning
void InitialiseFloatSinCosTable();
void UpdateLightning();
void TriggerLightning(Vector3Int* src, Vector3Int* dest, char amplitude, byte r, byte g, byte b, byte life, char flags, char width, char segments);
void TriggerLightning(Vector3Int* src, Vector3Int* dest, byte amplitude, byte r, byte g, byte b, byte life, char flags, char width, char segments);
void CalcLightningSpline(Vector3Int* pos, short* buffer, LIGHTNING_INFO* arc);
void TriggerLightningGlow(int x, int y, int z, byte size, byte r, byte g, byte b);
}

View file

@ -6,6 +6,7 @@
#include "Game/collision/floordata.h"
#include "Game/effects/effects.h"
#include "Game/effects/bubble.h"
#include "Game/effects/debris.h"
#include "Game/effects/drip.h"
#include "Game/effects/smoke.h"
#include "Game/effects/weather.h"
@ -438,6 +439,7 @@ void UpdateFireSparks()
if (spark->flags & SP_ROTATE)
spark->rotAng = (spark->rotAng + spark->rotAdd) & 0xFFF;
float alpha = fmin(1, fmax(0, 1 - (spark->life / (float)spark->sLife)));
int sprite = (int)Lerp(Objects[ID_FIRE_SPRITES].meshIndex, Objects[ID_FIRE_SPRITES].meshIndex + (-Objects[ID_FIRE_SPRITES].nmeshes) - 1, alpha);
spark->def = sprite;
@ -996,6 +998,7 @@ void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType)
gshell->fallspeed = -48 - (GetRandomControl() & 7);
gshell->objectNumber = objNum;
gshell->counter = (GetRandomControl() & 0x1F) + 60;
if (hand)
{
if (weaponType == LaraWeaponType::Shotgun)
@ -1443,7 +1446,12 @@ void ExplodeVehicle(ItemInfo* laraItem, ItemInfo* vehicle)
void ExplodingDeath(short itemNumber, short flags)
{
ItemInfo* item = &g_Level.Items[itemNumber];
ObjectInfo* obj = &Objects[item->ObjectNumber];
ObjectInfo* obj;
if (item->IsLara() && Objects[ID_LARA_SKIN].loaded)
obj = &Objects[ID_LARA_SKIN];
else
obj = &Objects[item->ObjectNumber];
ANIM_FRAME* frame = GetBestFrame(item);
@ -1503,6 +1511,10 @@ void ExplodingDeath(short itemNumber, short flags)
fx->frameNumber = obj->meshIndex + i;
}
}
else
{
ExplodeItemNode(item, i, 0, 128);
}
}
}

View file

@ -425,7 +425,7 @@ namespace TEN::Effects::Environment
if (!TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, roomNumber))
continue;
if (!IsPointInRoom(PHD_3DPOS(xPos, yPos, zPos), roomNumber))
if (!IsPointInRoom(Vector3Int(xPos, yPos, zPos), roomNumber))
continue;
auto part = WeatherParticle();

View file

@ -790,8 +790,10 @@ void GuiController::HandleDisplaySettingsInput(bool pause)
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.ShadowMode--;
if (CurrentSettings.conf.ShadowMode < SHADOW_NONE) CurrentSettings.conf.ShadowMode = SHADOW_ALL;
if (CurrentSettings.conf.ShadowType == ShadowMode::None)
CurrentSettings.conf.ShadowType = ShadowMode::All;
else
CurrentSettings.conf.ShadowType = ShadowMode(int(CurrentSettings.conf.ShadowType) - 1);
break;
case 3:
@ -823,8 +825,10 @@ void GuiController::HandleDisplaySettingsInput(bool pause)
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.ShadowMode++;
if (CurrentSettings.conf.ShadowMode > SHADOW_ALL) CurrentSettings.conf.ShadowMode = SHADOW_NONE;
if (CurrentSettings.conf.ShadowType == ShadowMode::All)
CurrentSettings.conf.ShadowType = ShadowMode::None;
else
CurrentSettings.conf.ShadowType = ShadowMode(int(CurrentSettings.conf.ShadowType) + 1);
break;
case 3:
@ -951,12 +955,12 @@ void GuiController::HandleControlSettingsInput(bool pause)
if (pause)
{
g_Renderer.RenderInventory();
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
}
else
{
g_Renderer.RenderTitle();
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
int nframes = Camera.numberFrames;
ControlPhase(nframes, 0);
}
@ -2295,7 +2299,7 @@ void GuiController::DoInventory()
if (rings[(int)RingTypes::Ammo]->ringactive)
{
g_Renderer.DrawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (rings[(int)RingTypes::Inventory]->objlistmovement)
return;
@ -2487,12 +2491,12 @@ void GuiController::DoInventory()
{
if (i == current_selected_option)
{
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
ypos += line_height;
}
else
{
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
ypos += line_height;
}
}
@ -2757,7 +2761,7 @@ void GuiController::DrawAmmoSelector()
sprintf(&invTextBuffer[0], "%d x %s", ammo_object_list[n].amount, g_GameFlow->GetString(inventry_objects_list[ammo_object_list[n].invitem].objname));
if (ammo_selector_fade_val)
g_Renderer.DrawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (n == *current_ammo_type)
@ -3013,11 +3017,11 @@ void GuiController::DrawCurrentObjectList(int ringnum)
nummeup = count;
break;
case ID_ROCKET_LAUNCHER_ITEM:
case ID_ROCKET_LAUNCHER_AMMO_ITEM:
nummeup = Lara.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].getCount();
break;
case ID_HARPOON_ITEM:
case ID_HARPOON_AMMO_ITEM:
nummeup = Lara.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].getCount();
break;
@ -3062,7 +3066,7 @@ void GuiController::DrawCurrentObjectList(int ringnum)
else
objmeup = (int)(phd_centery + (REFERENCE_RES_HEIGHT + 1) * 0.0625 * 2.0);
g_Renderer.DrawString(phd_centerx, objmeup, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(phd_centerx, objmeup, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
}
if (!i && !rings[ringnum]->objlistmovement)
@ -3285,7 +3289,7 @@ bool GuiController::CallInventory(bool reset_mode)
SetEnterInventory(NO_ITEM);
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
}
lastInvItem = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;

View file

@ -114,6 +114,11 @@ bool ItemInfo::IsLara()
return this->Data.is<LaraInfo*>();
}
bool ItemInfo::IsCreature()
{
return this->Data.is<CreatureInfo>();
}
void ClearItem(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];

View file

@ -129,6 +129,7 @@ struct ItemInfo
bool TestBits(JointBitType type, int jointIndex);
bool IsLara();
bool IsCreature();
};
void EffectNewRoom(short fxNumber, short roomNumber);

View file

@ -161,11 +161,11 @@ FloorInfo* GetSector(ROOM_INFO* room, int x, int z)
return &room->floor[index];
}
bool IsPointInRoom(PHD_3DPOS const& pos, int roomNumber)
bool IsPointInRoom(Vector3Int pos, int roomNumber)
{
int x = pos.Position.x;
int y = pos.Position.y;
int z = pos.Position.z;
int x = pos.x;
int y = pos.y;
int z = pos.z;
auto* room = &g_Level.Rooms[roomNumber];
int xSector = (x - room->x) / SECTOR(1);
int zSector = (z - room->z) / SECTOR(1);
@ -180,17 +180,27 @@ bool IsPointInRoom(PHD_3DPOS const& pos, int roomNumber)
return false;
}
PHD_3DPOS GetRoomCenter(int roomNumber)
int FindRoomNumber(Vector3Int position)
{
for (int i = 0; i < g_Level.Rooms.size(); i++)
if (IsPointInRoom(position, i))
return i;
return 0;
}
Vector3Int GetRoomCenter(int roomNumber)
{
auto* room = &g_Level.Rooms[roomNumber];
auto halfLength = SECTOR(room->xSize)/2;
auto halfDepth = SECTOR(room->zSize)/2;
auto halfLength = SECTOR(room->xSize) / 2;
auto halfDepth = SECTOR(room->zSize) / 2;
auto halfHeight = (room->maxceiling - room->minfloor) / 2;
PHD_3DPOS center;
center.Position.x = room->x + halfLength;
center.Position.y = room->minfloor + halfHeight;
center.Position.z = room->z + halfDepth;
Vector3Int center;
center.x = room->x + halfLength;
center.y = room->minfloor + halfHeight;
center.z = room->z + halfDepth;
return center;
}
@ -216,3 +226,17 @@ std::set<int> GetRoomList(int roomNumber)
return result;
}
void InitializeNeighborRoomList()
{
for (size_t i = 0; i < g_Level.Rooms.size(); i++)
{
auto* room = &g_Level.Rooms[i];
room->neighbors.clear();
auto roomList = GetRoomList(i);
for (int n : roomList)
room->neighbors.push_back(n);
}
}

View file

@ -97,18 +97,9 @@ struct ROOM_INFO
int z;
int minfloor;
int maxceiling;
std::vector<Vector3> positions;
std::vector<Vector3> normals;
std::vector<Vector3> colors;
std::vector<Vector3> effects;
std::vector<BUCKET> buckets;
std::vector<ROOM_DOOR> doors;
int xSize;
int zSize;
std::vector<FloorInfo> floor;
Vector3 ambient;
std::vector<ROOM_LIGHT> lights;
std::vector<MESH_INFO> mesh;
int flippedRoom;
int flags;
int meshEffect;
@ -117,7 +108,20 @@ struct ROOM_INFO
short itemNumber;
short fxNumber;
bool boundActive;
std::vector<FloorInfo> floor;
std::vector<ROOM_LIGHT> lights;
std::vector<MESH_INFO> mesh;
std::vector<TriggerVolume> triggerVolumes;
std::vector<Vector3> positions;
std::vector<Vector3> normals;
std::vector<Vector3> colors;
std::vector<Vector3> effects;
std::vector<BUCKET> buckets;
std::vector<ROOM_DOOR> doors;
std::vector<int> neighbors; // TODO: Move to level struct
};
constexpr auto NUM_ROOMS = 1024;
@ -133,9 +137,11 @@ void DoFlipMap(short group);
void AddRoomFlipItems(ROOM_INFO* room);
void RemoveRoomFlipItems(ROOM_INFO* room);
bool IsObjectInRoom(short roomNumber, short objectNumber);
bool IsPointInRoom(PHD_3DPOS const& pos, int roomNumber);
PHD_3DPOS GetRoomCenter(int roomNumber);
bool IsPointInRoom(Vector3Int pos, int roomNumber);
int FindRoomNumber(Vector3Int position);
Vector3Int GetRoomCenter(int roomNumber);
int IsRoomOutside(int x, int y, int z);
std::set<int> GetRoomList(int roomNumber);
void InitializeNeighborRoomList();
FloorInfo* GetSector(ROOM_INFO* room, int x, int z);

View file

@ -7,6 +7,8 @@
#include "Game/control/box.h"
#include "Game/control/flipeffect.h"
#include "Game/control/lot.h"
#include "Game/control/volume.h"
#include "Game/control/volumetriggerer.h"
#include "Game/effects/lara_fx.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@ -32,7 +34,7 @@
#include "effects/effects.h"
#include "Objects/ScriptInterfaceObjectsHandler.h"
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Lara;
using namespace TEN::Entities::Switches;
using namespace TEN::Entities::TR4;
@ -691,12 +693,10 @@ bool SaveGame::Save(int slot)
auto serializedItemsOffset = fbb.CreateVector(serializedItems);
std::vector<flatbuffers::Offset<Save::FXInfo>> serializedEffects{};
// TODO: In future, we should save only active FX, not whole array.
// This may come together with Monty's branch merge -- Lwmte, 10.07.22
std::vector<flatbuffers::Offset<Save::FXInfo>> serializedEffects{};
for (auto& effectToSerialize : EffectList)
{
Save::FXInfoBuilder serializedEffect{ fbb };
@ -718,9 +718,24 @@ bool SaveGame::Save(int slot)
auto serializedEffectOffset = serializedEffect.Finish();
serializedEffects.push_back(serializedEffectOffset);
}
auto serializedEffectsOffset = fbb.CreateVector(serializedEffects);
// Event set call counters
std::vector<flatbuffers::Offset<Save::EventSetCallCounters>> serializedEventSetCallCounters{};
for (auto& set : g_Level.EventSets)
{
Save::EventSetCallCountersBuilder serializedEventSetCallCounter{ fbb };
serializedEventSetCallCounter.add_on_enter(set.OnEnter.CallCounter);
serializedEventSetCallCounter.add_on_inside(set.OnInside.CallCounter);
serializedEventSetCallCounter.add_on_leave(set.OnLeave.CallCounter);
auto serializedEventSetCallCounterOffset = serializedEventSetCallCounter.Finish();
serializedEventSetCallCounters.push_back(serializedEventSetCallCounterOffset);
}
auto serializedEventSetCallCountersOffset = fbb.CreateVector(serializedEventSetCallCounters);
// Soundtrack playheads
auto bgmTrackData = GetSoundTrackNameAndPosition(SoundTrackType::BGM);
auto oneshotTrackData = GetSoundTrackNameAndPosition(SoundTrackType::OneShot);
@ -782,8 +797,9 @@ bool SaveGame::Save(int slot)
}
auto flybyCamerasOffset = fbb.CreateVector(flybyCameras);
// Static meshes
// Static meshes and volume states
std::vector<flatbuffers::Offset<Save::StaticMeshInfo>> staticMeshes;
std::vector<flatbuffers::Offset<Save::VolumeState>> volumeStates;
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
auto* room = &g_Level.Rooms[i];
@ -791,17 +807,61 @@ bool SaveGame::Save(int slot)
for (int j = 0; j < room->mesh.size(); j++)
{
Save::StaticMeshInfoBuilder staticMesh{ fbb };
staticMesh.add_position(&Save::Vector3(room->mesh[j].pos.Position.x,
room->mesh[j].pos.Position.y,
room->mesh[j].pos.Position.z));
staticMesh.add_rotation(&Save::Vector3(room->mesh[j].pos.Orientation.x,
room->mesh[j].pos.Orientation.y,
room->mesh[j].pos.Orientation.z));
staticMesh.add_color(&Save::Vector4(room->mesh[j].color.x,
room->mesh[j].color.y,
room->mesh[j].color.z,
room->mesh[j].color.w));
staticMesh.add_flags(room->mesh[j].flags);
staticMesh.add_hit_points(room->mesh[j].HitPoints);
staticMesh.add_room_number(i);
staticMesh.add_number(j);
staticMeshes.push_back(staticMesh.Finish());
}
for (int j = 0; j < room->triggerVolumes.size(); j++)
{
Save::VolumeStateBuilder volumeState{ fbb };
auto& volume = room->triggerVolumes[j];
volumeState.add_room_number(i);
volumeState.add_number(j);
volumeState.add_position(&Save::Vector3(volume.Position.x,
volume.Position.y,
volume.Position.z));
volumeState.add_rotation(&Save::Vector4(volume.Rotation.x,
volume.Rotation.y,
volume.Rotation.z,
volume.Rotation.w));
volumeState.add_scale(&Save::Vector3(volume.Scale.x,
volume.Scale.y,
volume.Scale.z));
int triggerer = -1;
if (std::holds_alternative<short>(volume.Triggerer))
triggerer = std::get<short>(volume.Triggerer);
volumeState.add_triggerer(triggerer);
volumeState.add_state((int)volume.Status);
volumeState.add_timeout((int)volume.Timeout);
volumeStates.push_back(volumeState.Finish());
}
}
auto staticMeshesOffset = fbb.CreateVector(staticMeshes);
auto volumeStatesOffset = fbb.CreateVector(volumeStates);
// Particles
std::vector<flatbuffers::Offset<Save::ParticleInfo>> particles;
@ -1136,6 +1196,7 @@ bool SaveGame::Save(int slot)
sgb.add_flip_status(FlipStatus);
sgb.add_flip_timer(0);
sgb.add_static_meshes(staticMeshesOffset);
sgb.add_volume_states(volumeStatesOffset);
sgb.add_fixed_cameras(camerasOffset);
sgb.add_particles(particleOffset);
sgb.add_bats(batsOffset);
@ -1144,6 +1205,7 @@ bool SaveGame::Save(int slot)
sgb.add_scarabs(scarabsOffset);
sgb.add_sinks(sinksOffset);
sgb.add_flyby_cameras(flybyCamerasOffset);
sgb.add_call_counters(serializedEventSetCallCountersOffset);
if (Lara.Control.Rope.Ptr != -1)
{
@ -1152,7 +1214,6 @@ bool SaveGame::Save(int slot)
sgb.add_alternate_pendulum(alternatePendulumOffset);
}
sgb.add_script_vars(unionVecOffset);
auto sg = sgb.Finish();
@ -1235,27 +1296,63 @@ bool SaveGame::Load(int slot)
{
auto staticMesh = s->static_meshes()->Get(i);
auto room = &g_Level.Rooms[staticMesh->room_number()];
int number = staticMesh->number();
if (i >= room->mesh.size())
break;
room->mesh[number].pos.Position = Vector3Int(staticMesh->position()->x(),
staticMesh->position()->y(),
staticMesh->position()->z());
room->mesh[i].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].pos.Orientation = Vector3Shrt(short(staticMesh->rotation()->x()),
short(staticMesh->rotation()->y()),
short(staticMesh->rotation()->z()));
room->mesh[i].flags = staticMesh->flags();
room->mesh[i].HitPoints = staticMesh->hit_points();
room->mesh[number].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].flags = staticMesh->flags();
room->mesh[number].HitPoints = staticMesh->hit_points();
if (!room->mesh[i].flags)
if (!room->mesh[number].flags)
{
short roomNumber = staticMesh->room_number();
FloorInfo* floor = GetFloor(room->mesh[i].pos.Position.x, room->mesh[i].pos.Position.y, room->mesh[i].pos.Position.z, &roomNumber);
TestTriggers(room->mesh[i].pos.Position.x, room->mesh[i].pos.Position.y, room->mesh[i].pos.Position.z, staticMesh->room_number(), true, 0);
FloorInfo* floor = GetFloor(room->mesh[number].pos.Position.x, room->mesh[number].pos.Position.y, room->mesh[number].pos.Position.z, &roomNumber);
TestTriggers(room->mesh[number].pos.Position.x, room->mesh[number].pos.Position.y, room->mesh[number].pos.Position.z, staticMesh->room_number(), true, 0);
floor->Stopper = false;
}
}
// Volumes
for (int i = 0; i < s->volume_states()->size(); i++)
{
auto volume = s->volume_states()->Get(i);
auto room = &g_Level.Rooms[volume->room_number()];
int number = volume->number();
room->triggerVolumes[number].Position = Vector3(volume->position()->x(),
volume->position()->y(),
volume->position()->z());
room->triggerVolumes[number].Rotation = Vector4(volume->rotation()->x(),
volume->rotation()->y(),
volume->rotation()->z(),
volume->rotation()->w());
room->triggerVolumes[number].Scale = Vector3(volume->scale()->x(),
volume->scale()->y(),
volume->scale()->z());
int triggerer = volume->triggerer();
if (triggerer >= 0)
room->triggerVolumes[number].Triggerer = short(triggerer);
else
room->triggerVolumes[number].Triggerer = nullptr;
room->triggerVolumes[number].Status = TriggerStatus(volume->state());
room->triggerVolumes[number].Timeout = volume->timeout();
}
// Cameras
for (int i = 0; i < s->fixed_cameras()->size(); i++)
{
@ -1651,7 +1748,19 @@ bool SaveGame::Load(int slot)
fx.flag2 = fx_saved->flag2();
}
JustLoaded = 1;
if (g_Level.EventSets.size() == s->call_counters()->size())
{
for (int i = 0; i < s->call_counters()->size(); ++i)
{
auto cc_saved = s->call_counters()->Get(i);
g_Level.EventSets[i].OnEnter.CallCounter = cc_saved->on_enter();
g_Level.EventSets[i].OnInside.CallCounter = cc_saved->on_inside();
g_Level.EventSets[i].OnLeave.CallCounter = cc_saved->on_leave();
}
}
JustLoaded = true;
// Lara
ZeroMemory(Lara.Inventory.Puzzles, NUM_PUZZLES * sizeof(int));

View file

@ -17,9 +17,9 @@ using namespace TEN::Control::Volumes;
constexpr auto MAX_CAMERA = 18;
int TrackCameraInit;
bool TrackCameraInit;
int SpotcamTimer;
int SpotcamPaused;
bool SpotcamPaused;
int SpotcamLoopCnt;
int CameraFade;
Vector3Int LaraFixedPosition;
@ -41,7 +41,6 @@ int CameraZtarget[MAX_CAMERA];
int CameraRoll[MAX_CAMERA];
int CameraFOV[MAX_CAMERA];
int CameraSpeed[MAX_CAMERA];
QUAKE_CAMERA QuakeCam;
int SplineFromCamera;
bool SpotCamFirstLook;
short CurrentSplineCamera;
@ -50,13 +49,14 @@ int LaraHealth;
int LaraAir;
int CurrentSpotcamSequence;
SPOTCAM SpotCam[MAX_SPOTCAMS];
byte SpotCamRemap[MAX_SPOTCAMS];
byte CameraCnt[MAX_SPOTCAMS];
int SpotCamRemap[MAX_SPOTCAMS];
int CameraCnt[MAX_SPOTCAMS];
int NumberSpotcams;
int CheckTrigger = 0;
int UseSpotCam = 0;
int SpotcamDontDrawLara;
int SpotcamOverlay;
bool CheckTrigger = false;
bool UseSpotCam = false;
bool SpotcamDontDrawLara = false;
bool SpotcamOverlay = false;
void ClearSpotCamSequences()
{
@ -171,7 +171,7 @@ void InitialiseSpotCam(short Sequence)
if ((spotcam->flags & SCF_DISABLE_LARA_CONTROLS))
{
Lara.Control.Locked = true;
SetCinematicBars(SPOTCAM_CINEMATIC_BARS_HEIGHT, SPOTCAM_CINEMATIC_BARS_SPEED);
SetCinematicBars(1.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
}
if (spotcam->flags & SCF_TRACKING_CAM)
@ -206,7 +206,6 @@ void InitialiseSpotCam(short Sequence)
}
}
//loc_379F8
CameraXposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].x;
CameraYposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].y;
CameraZposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].z;
@ -219,7 +218,6 @@ void InitialiseSpotCam(short Sequence)
}
else
{
//loc_37AA8
int sp = 0;
if ((spotcam->flags & SCF_CUT_PAN))
{
@ -241,7 +239,6 @@ void InitialiseSpotCam(short Sequence)
if (LastCamera < CurrentSplineCamera)
cn = FirstCamera;
//loc_37B74
CameraXposition[sp + 2] = SpotCam[cn].x;
CameraYposition[sp + 2] = SpotCam[cn].y;
CameraZposition[sp + 2] = SpotCam[cn].z;
@ -265,12 +262,6 @@ void InitialiseSpotCam(short Sequence)
if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
else
{
QuakeCam.spos.boxNumber = 0;
return;
}
}
else
{
@ -329,8 +320,6 @@ void InitialiseSpotCam(short Sequence)
if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
QuakeCam.spos.boxNumber = 0;
}
void CalculateSpotCameras()
@ -392,12 +381,14 @@ void CalculateSpotCameras()
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_IN) &&
CameraFade != CurrentSplineCamera)
{
SetScreenFadeIn(FADE_SCREEN_SPEED);
CameraFade = CurrentSplineCamera;
}
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_OUT) &&
CameraFade != CurrentSplineCamera)
{
SetScreenFadeOut(FADE_SCREEN_SPEED);
CameraFade = CurrentSplineCamera;
}
@ -464,11 +455,12 @@ void CalculateSpotCameras()
else if (!SpotcamTimer)
CurrentSplinePosition += cspeed;
if (!(TrInput & IN_LOOK))
bool lookPressed = (TrInput & IN_LOOK) != 0;
if (!lookPressed)
SpotCamFirstLook = false;
if (s->flags & SCF_DISABLE_BREAKOUT ||
!(TrInput & IN_LOOK))
if ((s->flags & SCF_DISABLE_BREAKOUT) || !lookPressed)
{
Camera.pos.x = cpx;
Camera.pos.y = cpy;
@ -498,28 +490,17 @@ void CalculateSpotCameras()
AlterFOV(cfov);
// WTF?
if (QuakeCam.spos.boxNumber != 0)
{
dx = (Camera.pos.x - QuakeCam.epos.x);
dy = (Camera.pos.y - QuakeCam.epos.y);
dz = (Camera.pos.z - QuakeCam.epos.z);
if (sqrt(SQUARE(dx) * SQUARE(dy) * SQUARE(dz)) < QuakeCam.epos.boxNumber)
{
dz = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber) >> 1;
dy = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber);
if (dy > 0)
{
Camera.pos.x += (GetRandomControl() / dy) - dz;
Camera.pos.y += (GetRandomControl() / dy) - dz;
Camera.pos.z += (GetRandomControl() / dy) - dz;
}
}
}
LookAt(&Camera, croll);
if (SpotCam[CurrentSplineCamera].flags & SCF_OVERLAY)
SpotcamOverlay = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
if (CheckTrigger)
{
CameraType oldType = Camera.type;
@ -541,7 +522,9 @@ void CalculateSpotCameras()
}
if (s->flags & SCF_TRACKING_CAM)
{
TrackCameraInit = true;
}
else if (CurrentSplinePosition > 0x10000 - cspeed)
{
if (SpotCam[CurrentSplineCamera].timer > 0 &&
@ -550,49 +533,7 @@ void CalculateSpotCameras()
if (!SpotcamTimer && !SpotcamPaused)
SpotcamTimer = SpotCam[CurrentSplineCamera].timer >> 3;
}
else if (SpotCam[CurrentSplineCamera].timer < 0)
SpotcamOverlay = 1; // Negative timer = sniper mode?
if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
/* // Weird code which possibly did some shaking over the course of camera
if (SpotCam[CurrentSplineCamera].flags & SCF_STOP_MOVEMENT)
{
if (QuakeCam.spos.boxNumber == 0 || SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.x = SpotCam[CurrentSplineCamera].x;
QuakeCam.spos.y = SpotCam[CurrentSplineCamera].y;
QuakeCam.spos.z = SpotCam[CurrentSplineCamera].z;
if (SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.roomNumber = SpotCam[CurrentSplineCamera].timer << 3;
}
else
{
QuakeCam.spos.roomNumber = 0;
}
QuakeCam.spos.boxNumber = 1;
QuakeCam.epos.x = SpotCam[CurrentSplineCamera + 1].x;
QuakeCam.epos.y = SpotCam[CurrentSplineCamera + 1].y;
QuakeCam.epos.z = SpotCam[CurrentSplineCamera + 1].z;
if (SpotCam[CurrentSplineCamera + 1].timer != -1)
QuakeCam.epos.roomNumber = SpotCam[CurrentSplineCamera + 1].timer << 3;
else
QuakeCam.epos.roomNumber = 0;
QuakeCam.epos.boxNumber = sqrt(((QuakeCam.spos.x - QuakeCam.epos.x) * (QuakeCam.spos.x - QuakeCam.epos.x)) + ((QuakeCam.spos.y - QuakeCam.epos.y) * (QuakeCam.spos.y - QuakeCam.epos.y) + ((QuakeCam.spos.z - QuakeCam.epos.z) * (QuakeCam.spos.z - QuakeCam.epos.z))));
}
else
QuakeCam.spos.boxNumber = 0;
}
*/
if (!SpotcamTimer)
{
CurrentSplinePosition = 0;
@ -617,7 +558,7 @@ void CalculateSpotCameras()
if (SpotCam[CurrentSplineCamera].flags & SCF_DISABLE_LARA_CONTROLS)
{
if (CurrentLevel)
SetCinematicBars(SPOTCAM_CINEMATIC_BARS_HEIGHT, SPOTCAM_CINEMATIC_BARS_SPEED);
SetCinematicBars(1.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
Lara.Control.Locked = true;
}
@ -625,7 +566,7 @@ void CalculateSpotCameras()
int sp2 = 0;
if (SpotCam[CurrentSplineCamera].flags & SCF_CUT_TO_CAM)
{
cn = (SpotCam[CurrentSplineCamera].timer & 0xF) + FirstCamera;
cn = FirstCamera + SpotCam[CurrentSplineCamera].timer;
CameraXposition[1] = SpotCam[cn].x;
CameraYposition[1] = SpotCam[cn].y;
@ -718,9 +659,9 @@ void CalculateSpotCameras()
SetCinematicBars(0.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
UseSpotCam = 0;
UseSpotCam = false;
Lara.Control.Locked = false;
CheckTrigger = 0;
CheckTrigger = false;
Camera.oldType = CameraType::Fixed;
Camera.type = CameraType::Chase;
Camera.speed = 1;
@ -835,6 +776,7 @@ void CalculateSpotCameras()
}
else
{
SetScreenFadeIn(FADE_SCREEN_SPEED);
SetCinematicBars(0.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
UseSpotCam = false;
Lara.Control.Locked = false;

View file

@ -1,15 +1,10 @@
#pragma once
#include "Specific/phd_global.h"
#include "Specific/trmath.h"
constexpr auto MAX_SPOTCAMS = 256;
constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 16.0f / 256.0f;
constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / 256.0f;
struct QUAKE_CAMERA
{
GameVector spos;
GameVector epos;
};
constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16.0f;
constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS;
struct SPOTCAM
{
@ -33,7 +28,7 @@ struct SPOTCAM
enum SPOTCAM_FLAGS
{
SCF_CUT_PAN = (1 << 0), // 0x0001 cut without panning smoothly
SCF_UNUSED = (1 << 1), // 0x0002
SCF_OVERLAY = (1 << 1), // 0x0002 TODO: add vignette
SCF_LOOP_SEQUENCE = (1 << 2), // 0x0004
SCF_TRACKING_CAM = (1 << 3), // 0x0008
SCF_HIDE_LARA = (1 << 4), // 0x0010
@ -51,14 +46,14 @@ enum SPOTCAM_FLAGS
};
extern SPOTCAM SpotCam[MAX_SPOTCAMS];
extern byte SpotCamRemap[MAX_SPOTCAMS];
extern byte CameraCnt[MAX_SPOTCAMS];
extern int SpotCamRemap[MAX_SPOTCAMS];
extern int CameraCnt[MAX_SPOTCAMS];
extern int LastSpotCamSequence;
extern int NumberSpotcams;
extern int UseSpotCam;
extern int SpotcamDontDrawLara;
extern int SpotcamOverlay;
extern int TrackCameraInit;
extern bool UseSpotCam;
extern bool SpotcamDontDrawLara;
extern bool SpotcamOverlay;
extern bool TrackCameraInit;
void ClearSpotCamSequences();
void InitSpotCamSequences();

View file

@ -121,6 +121,7 @@ namespace TEN::Entities::Effects
{
ShatterItem.yRot = fx->pos.Orientation.y;
ShatterItem.meshIndex = fx->frameNumber;
ShatterItem.color = Vector4::One;
ShatterItem.sphere.x = fx->pos.Position.x;
ShatterItem.sphere.y = fx->pos.Position.y;
ShatterItem.sphere.z = fx->pos.Position.z;

View file

@ -64,37 +64,6 @@ void ControlTriggerTriggerer(short itemNumber)
}
}
void AnimateWaterfalls()
{
return;
lastWaterfallY = (lastWaterfallY - 7) & 0x3F;
float y = lastWaterfallY * 0.00390625f;
for (int i = 0; i < 6; i++)
{
if (Objects[ID_WATERFALL1 + i].loaded)
{
OBJECT_TEXTURE* texture = WaterfallTextures[i];
texture->vertices[0].y = y + WaterfallY[i];
texture->vertices[1].y = y + WaterfallY[i];
texture->vertices[2].y = y + WaterfallY[i] + 0.24609375f;
texture->vertices[3].y = y + WaterfallY[i] + 0.24609375f;
if (i < 5)
{
texture++;
texture->vertices[0].y = y + WaterfallY[i];
texture->vertices[1].y = y + WaterfallY[i];
texture->vertices[2].y = y + WaterfallY[i] + 0.24609375f;
texture->vertices[3].y = y + WaterfallY[i] + 0.24609375f;
}
}
}
}
void ControlWaterfall(short itemNumber)
{
auto* item = &g_Level.Items[itemNumber];

View file

@ -10,7 +10,6 @@ void SmashObject(short itemNumber);
void SmashObjectControl(short itemNumber);
void ControlAnimatingSlots(short itemNumber);
void ControlTriggerTriggerer(short itemNumber);
void AnimateWaterfalls();
void ControlWaterfall(short itemNumber);
void TightropeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void HorizontalBarCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);

View file

@ -2,6 +2,7 @@
#include "Objects/Generic/Switches/switch.h"
#include "Game/items.h"
#include "Game/control/lot.h"
#include "Game/effects/debris.h"
#include "Objects/Generic/Object/objects.h"
#include "Game/Lara/lara.h"
#include "Game/animation.h"

View file

@ -110,6 +110,7 @@ void FallingBlockControl(short itemNumber)
// Convert object to shatter item
ShatterItem.yRot = item->Pose.Orientation.y;
ShatterItem.meshIndex = Objects[item->ObjectNumber].meshIndex;
ShatterItem.color = item->Color;
ShatterItem.sphere.x = item->Pose.Position.x;
ShatterItem.sphere.y = item->Pose.Position.y - STEP_SIZE; // So debris won't spawn below floor
ShatterItem.sphere.z = item->Pose.Position.z;

View file

@ -410,7 +410,7 @@ void StartTraps()
auto* object = &Objects[ID_DARTS];
if (object->loaded)
{
object->castsShadow = true;
object->shadowType = ShadowMode::All;
//object->drawRoutine = DrawDart;
object->collision = ObjectCollision;
object->control = DartControl;

View file

@ -29,7 +29,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWolf;
obj->control = WolfControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 6;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 375;
@ -49,7 +49,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->control = BearControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 500;
@ -70,7 +70,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 22;
obj->hitEffect = HIT_BLOOD;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->pivotLength = 250;
obj->radius = 340;
obj->intelligent = true;
@ -87,7 +87,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBigRat;
obj->control = BigRatControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -109,7 +109,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->hitEffect = HIT_BLOOD;
obj->control = NatlaControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 400;
obj->radius = 204;
obj->intelligent = true;
@ -126,7 +126,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = GiantMutantControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 500;
obj->hitEffect = HIT_BLOOD;
obj->radius = 341;
@ -148,7 +148,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = DoppelgangerControl;
//obj->drawRoutine = DrawEvilLara;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 1000;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -164,7 +164,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->control = CentaurControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 120;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 400;

View file

@ -42,7 +42,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = SharkControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -63,7 +63,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = BarracudaControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 12;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -85,7 +85,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseEagle;
obj->control = EagleControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->radius = 204;
@ -104,7 +104,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseEagle;
obj->control = EagleControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->hitEffect = HIT_BLOOD;
obj->radius = 204;
@ -124,7 +124,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->pivotLength = 50;
obj->radius = 204;
obj->intelligent = true;
@ -142,7 +142,7 @@ static void StartEntity(ObjectInfo* obj)
obj->control = YetiControl;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->radius = 128;
obj->pivotLength = 100;
obj->intelligent = true;
@ -161,7 +161,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -192,7 +192,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -223,7 +223,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SilencerControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->biteOffset = 0;
@ -245,7 +245,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerShotgun;
obj->collision = CreatureCollision;
obj->control = WorkerShotgunControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -266,7 +266,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerMachineGun;
obj->collision = CreatureCollision;
obj->control = WorkerMachineGunControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -287,7 +287,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = SmallSpiderControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 5;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = BigSpiderControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -323,7 +323,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = WorkerDualGunControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 150;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -343,7 +343,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = BirdMonsterControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 200;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -362,7 +362,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWorkerFlamethrower;
obj->collision = CreatureCollision;
obj->control = WorkerFlamethrower;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -382,7 +382,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = KnifeThrowerControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -407,7 +407,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryUziControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 45;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -427,7 +427,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryAutoPistolControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -457,7 +457,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MercenaryAutoPistolControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -477,7 +477,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MonkControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -496,7 +496,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCreature;
obj->collision = CreatureCollision;
obj->control = MonkControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 50;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -516,7 +516,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = SwordGuardianControl;
//obj->drawRoutine = DrawStatue;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -539,7 +539,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = SpearGuardianControl;
//obj->drawRoutine = DrawStatue;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -603,7 +603,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->collision = SkidooManCollision;
//obj->drawRoutine = DrawSkidoo; // TODO: recreate renderer for skidoo
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -669,7 +669,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->hitEffect = HIT_RICOCHET;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
obj = &Objects[ID_SNOWMOBILE];
@ -682,7 +682,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveFlags = true;
obj->savePosition = true;
obj->hitEffect = HIT_RICOCHET;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
}

View file

@ -1124,17 +1124,9 @@ namespace TEN::Entities::Vehicles
void KayakToItemCollision(ItemInfo* kayakItem, ItemInfo* laraItem)
{
short roomsToCheck[128];
short numRoomsToCheck = 0;
roomsToCheck[numRoomsToCheck++] = kayakItem->RoomNumber;
auto* room = &g_Level.Rooms[kayakItem->RoomNumber];
for (int i = 0; i < room->doors.size(); i++)
roomsToCheck[numRoomsToCheck++] = room->doors[i].room;
for (int i = 0; i < numRoomsToCheck; i++)
for (auto i : g_Level.Rooms[kayakItem->RoomNumber].neighbors)
{
short itemNum = g_Level.Rooms[roomsToCheck[i]].itemNumber;
short itemNum = g_Level.Rooms[i].itemNumber;
while (itemNum != NO_ITEM)
{

View file

@ -285,9 +285,7 @@ namespace TEN::Entities::Vehicles
static void MinecartToEntityCollision(ItemInfo* minecartItem, ItemInfo* laraItem)
{
auto roomsList = GetRoomList(minecartItem->RoomNumber);
for (auto i : roomsList)
for (auto i : g_Level.Rooms[minecartItem->RoomNumber].neighbors)
{
short itemNumber = g_Level.Rooms[i].itemNumber;

View file

@ -44,7 +44,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = TonyControl;
obj->drawRoutine = S_DrawTonyBoss;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -64,7 +64,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TigerControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -83,7 +83,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCobra;
obj->control = CobraControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -103,7 +103,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = RaptorControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->radius = 341;
@ -125,7 +125,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TribemanAxeControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -145,7 +145,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = TribemanDartsControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -167,7 +167,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 800;
obj->hitEffect = HIT_BLOOD;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->pivotLength = 1800;
obj->radius = 512;
obj->intelligent = true;
@ -185,7 +185,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = ScubaControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->radius = 340;
@ -210,12 +210,12 @@ static void StartEntity(ObjectInfo* obj)
obj->savePosition = true;
}
obj = &Objects[ID_FLAMETHROWER_GOON];
obj = &Objects[ID_FLAMETHROWER_BADDY];
if (obj->loaded)
{
obj->control = FlameThrowerControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 36;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -237,7 +237,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMonkey;
obj->control = MonkeyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -258,7 +258,7 @@ static void StartEntity(ObjectInfo* obj)
{
obj->control = MPGunControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -281,7 +281,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMPStick;
obj->control = MPStickControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 28;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = ShivaControl;
//obj->drawRoutine = DrawStatue;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 0;
@ -326,7 +326,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->control = LondonBossControl;
obj->drawRoutine = S_DrawLondonBoss;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->pivotLength = 50;
obj->HitPoints = 300;
obj->hitEffect = HIT_BLOOD;
@ -347,7 +347,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCivvy;
obj->control = CivvyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -393,7 +393,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
obj = &Objects[ID_RUBBER_BOAT];
@ -407,7 +407,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveFlags = true;
obj->saveAnim = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
@ -421,7 +421,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
@ -434,7 +434,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
@ -443,11 +443,11 @@ static void StartVehicles(ObjectInfo* obj)
{
obj->initialise = BigGunInitialise;
obj->collision = BigGunCollision;
// obj->draw_routine = BigGunDraw;
obj->hitEffect = HIT_RICOCHET;
obj->savePosition = true;
obj->saveFlags = true;
obj->saveAnim = true;
obj->shadowType = ShadowMode::Lara;
}
obj = &Objects[ID_UPV];
@ -456,12 +456,11 @@ static void StartVehicles(ObjectInfo* obj)
obj->initialise = UPVInitialise;
obj->control = UPVEffects;
obj->collision = UPVPlayerCollision;
// obj->drawRoutine = SubDraw;
obj->hitEffect = HIT_RICOCHET;
obj->saveAnim = true;
obj->saveFlags = true;
obj->savePosition = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
}

View file

@ -1,6 +1,7 @@
#include "framework.h"
#include "tr4_horseman.h"
#include "Game/items.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
#include "Specific/setup.h"
#include "Specific/level.h"

View file

@ -6,6 +6,7 @@
#include "Game/animation.h"
#include "Sound/sound.h"
#include "Game/collision/collide_room.h"
#include "Game/effects/debris.h"
void ClockworkBeetleControl(short itemNumber)
{

View file

@ -10,6 +10,7 @@
#include "Specific/input.h"
#include "Game/animation.h"
#include "Game/effects/lightning.h"
#include "Game/effects/debris.h"
using namespace TEN::Input;
using namespace TEN::Effects::Lightning;

View file

@ -3,6 +3,7 @@
#include "Specific/level.h"
#include "Game/collision/sphere.h"
#include "Sound/sound.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/weather.h"

View file

@ -86,7 +86,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSmallScorpion;
obj->control = SmallScorpionControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -105,7 +105,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseScorpion;
obj->control = ScorpionControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -124,7 +124,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHammerhead;
obj->control = HammerheadControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 8;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -144,7 +144,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseWildBoar;
obj->control = WildBoarControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -168,7 +168,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseTr4Dog;
obj->collision = CreatureCollision;
obj->control = Tr4DogControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 18;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -188,7 +188,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBat;
obj->control = BatControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 5;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 10;
@ -207,7 +207,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseAhmet;
obj->control = AhmetControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 80;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 300;
@ -229,7 +229,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaddy;
obj->control = BaddyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -239,7 +239,7 @@ static void StartEntity(ObjectInfo* obj)
obj->saveHitpoints = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->meshSwapSlot = ID_MESHSWAP_GOON1;
obj->meshSwapSlot = ID_MESHSWAP_BADDY1;
obj->zoneType = ZONE_HUMAN_JUMP_AND_MONKEY;
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y;
@ -255,7 +255,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaddy;
obj->control = BaddyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -265,7 +265,7 @@ static void StartEntity(ObjectInfo* obj)
obj->saveHitpoints = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->meshSwapSlot = ID_MESHSWAP_GOON2;
obj->meshSwapSlot = ID_MESHSWAP_BADDY2;
obj->zoneType = ZONE_HUMAN_JUMP_AND_MONKEY;
g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y;
@ -281,7 +281,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSas;
obj->control = SasControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -305,7 +305,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseMummy;
obj->control = MummyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->radius = 170;
@ -330,7 +330,7 @@ static void StartEntity(ObjectInfo* obj)
obj->collision = CreatureCollision;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->pivotLength = 50;
obj->radius = 128;
obj->explodableMeshbits = 0xA00;
@ -349,7 +349,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseKnightTemplar;
obj->control = KnightTemplarControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -371,7 +371,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBigBeetle;
obj->control = BigBeetleControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -391,7 +391,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSetha;
obj->control = SethaControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 500;
obj->hitEffect = HIT_NONE;
obj->pivotLength = 50;
@ -411,7 +411,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -434,7 +434,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -455,7 +455,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseDemigod;
obj->control = DemigodControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 200;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -489,7 +489,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseTroops;
obj->control = TroopsControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -510,7 +510,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSentryGun;
obj->control = SentryGunControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->undead = true;
obj->HitPoints = 30;
obj->hitEffect = HIT_RICOCHET;
@ -535,7 +535,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHarpy;
obj->control = HarpyControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 60;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -553,7 +553,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseGuide;
obj->control = GuideControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = NOT_TARGETABLE;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 0;
@ -574,7 +574,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseCrocodile;
obj->control = CrocodileControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 36;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 300;
@ -598,7 +598,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseSphinx;
obj->control = SphinxControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 1000;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 500;
@ -626,7 +626,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseHorseman;
obj->control = HorsemanControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 25;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 500;
@ -646,7 +646,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -665,7 +665,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -687,7 +687,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = InitialiseBaboon;
obj->control = BaboonControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 200;
@ -709,7 +709,7 @@ static void StartEntity(ObjectInfo* obj)
obj->initialise = TEN::Entities::TR4::InitialiseCrocgod;
obj->control = TEN::Entities::TR4::CrocgodControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = NOT_TARGETABLE;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -815,7 +815,7 @@ static void StartEntity(ObjectInfo* obj)
obj->intelligent = true;
obj->saveHitpoints = true;
obj->pivotLength = 500;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->radius = 512;
obj->HitPoints = 40;
obj->zoneType = ZONE_BASIC;
@ -833,7 +833,7 @@ static void StartEntity(ObjectInfo* obj)
obj->control = VonCroyControl;
obj->collision = CreatureCollision;
obj->pivotLength = 0;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 15;
obj->explodableMeshbits = 0x200000;
obj->intelligent = true;
@ -1162,7 +1162,7 @@ static void StartTrap(ObjectInfo* obj)
obj->control = LaraDoubleControl;
obj->collision = CreatureCollision;
obj->hitEffect = HIT_SMOKE;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 1000;
obj->pivotLength = 50;
obj->radius = 128;
@ -1194,7 +1194,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
@ -1208,7 +1208,7 @@ static void StartVehicles(ObjectInfo* obj)
obj->savePosition = true;
obj->saveAnim = true;
obj->saveFlags = true;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
}
}

View file

@ -1,9 +1,16 @@
#include "framework.h"
#include "tr5_smoke_emitter.h"
#include "Objects/objectslist.h"
#include "Game/camera.h"
#include "Game/items.h"
#include "Game/effects/bubble.h"
#include "Game/effects/effects.h"
#include "Game/control/control.h"
#include "Game/control/trigger.h"
#include "Game/collision/collide_room.h"
#include "Specific/level.h"
#include "Specific/trmath.h"
#include "Objects/objectslist.h"
#include "Renderer/Renderer11Enums.h"
void InitialiseSmokeEmitter(short itemNumber)
@ -27,7 +34,7 @@ void InitialiseSmokeEmitter(short itemNumber)
else
item->Pose.Position.z += CLICK(2);
}
else if (item->ObjectNumber != ID_SMOKE_EMITTER)
else if (item->ObjectNumber != ID_STEAM_EMITTER)
return;
else if (item->TriggerFlags & 8)
{
@ -63,254 +70,193 @@ void InitialiseSmokeEmitter(short itemNumber)
void SmokeEmitterControl(short itemNumber)
{
/*auto* item = &g_Level.Items[itemNumber];
Vector3Int pos = {};
auto* item = &g_Level.Items[itemNumber];
if (!TriggerActive(item))
return;
if (item->objectNumber != ID_SMOKE_EMITTER)
goto LABEL_61;
if (g_Level.Rooms[item->roomNumber].flags & 1)
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber))
{
if (item->itemFlags[0] || !(GetRandomControl() & 0x1F) || item->triggerFlags == 1)
if (item->ItemFlags[0] || !(GetRandomControl() & 0x1F) || item->TriggerFlags == 1)
{
if (!(GetRandomControl() & 3) || item->itemFlags[1])
if (!(GetRandomControl() & 3) || item->ItemFlags[1])
{
Vector3Int pos;
pos.x = (GetRandomControl() & 0x3F) + item->pos.Position.x - 32;
pos.y = item->pos.Position.y - (GetRandomControl() & 0x1F) - 16;
pos.z = (GetRandomControl() & 0x3F) + item->pos.Position.z - 32;
pos.x = (GetRandomControl() & 0x3F) + item->Pose.Position.x - 32;
pos.y = item->Pose.Position.y - (GetRandomControl() & 0x1F) - 16;
pos.z = (GetRandomControl() & 0x3F) + item->Pose.Position.z - 32;
if (item->triggerFlags == 1)
{
CreateBubble(&pos, item->roomNumber, 15, 15, 0, 0, 0, 0);
}
if (item->TriggerFlags == 1)
CreateBubble(&pos, item->RoomNumber, 15, 15, 0, 0, 0, 0);
else
{
CreateBubble(&pos, item->roomNumber, 8, 7, 0, 0, 0, 0);
}
CreateBubble(&pos, item->RoomNumber, 8, 7, 0, 0, 0, 0);
if (item->itemFlags[0])
if (item->ItemFlags[0])
{
item->itemFlags[0]--;
if (!item->itemFlags[0])
item->itemFlags[1] = 0;
item->ItemFlags[0]--;
if (!item->ItemFlags[0])
item->ItemFlags[1] = 0;
}
}
}
else
{
if (!(GetRandomControl() & 0x1F))
{
item->itemFlags[0] = (GetRandomControl() & 3) + 4;
}
}
else if (!(GetRandomControl() & 0x1F))
item->ItemFlags[0] = (GetRandomControl() & 3) + 4;
return;
}
if (!(item->triggerFlags & 8) || item->triggerFlags == 111)
goto LABEL_61;
if (item->triggerFlags & 4)
if (item->ObjectNumber == ID_STEAM_EMITTER && item->TriggerFlags & 8)
{
if (GlobalCounter & 1)
bool normal = false;
if (item->ItemFlags[0])
{
item->ItemFlags[0]--;
if (!item->ItemFlags[0])
item->ItemFlags[1] = (GetRandomControl() & 0x3F) + 30;
normal = true;
if (item->ItemFlags[2])
item->ItemFlags[2] -= 256;
}
else if (item->ItemFlags[2] < 4096)
item->ItemFlags[2] += 256;
if (item->ItemFlags[2])
{
int dx = Camera.pos.x - item->Pose.Position.x;
int dz = Camera.pos.z - item->Pose.Position.z;
if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16))
return;
auto* sptr = GetFreeParticle();
sptr->on = true;
sptr->sR = 96;
sptr->sG = 96;
sptr->sB = 96;
sptr->dR = 48;
sptr->dG = 48;
sptr->dB = 48;
sptr->fadeToBlack = 6;
sptr->colFadeSpeed = (GetRandomControl() & 3) + 6;
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
sptr->life = (GetRandomControl() & 7) + 16;
sptr->sLife = sptr->life;
sptr->x = (GetRandomControl() & 0x3F) + item->Pose.Position.x - 32;
sptr->y = (GetRandomControl() & 0x3F) + item->Pose.Position.y - 32;
sptr->z = (GetRandomControl() & 0x3F) + item->Pose.Position.z - 32;
int size = item->ItemFlags[2];
if (item->ItemFlags[2] == 4096)
size = (GetRandomControl() & 0x7FF) + 2048;
sptr->xVel = (short)((size * phd_sin(item->Pose.Orientation.y - 32768)) / SECTOR(1));
sptr->yVel = -16 - (GetRandomControl() & 0xF);
sptr->zVel = (short)((size * phd_cos(item->Pose.Orientation.y - 32768)) / SECTOR(1));
sptr->friction = 4;
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
if (!(GlobalCounter & 0x03))
sptr->flags |= SP_DAMAGE;
sptr->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
sptr->rotAdd = -8 - (GetRandomControl() & 7);
else
sptr->rotAdd = (GetRandomControl() & 7) + 8;
sptr->scalar = 2;
sptr->gravity = -8 - (GetRandomControl() & 0xF);
sptr->maxYvel = -8 - (GetRandomControl() & 7);
size = (GetRandomControl() & 0x1F) + 128;
sptr->dSize = float(size);
sptr->sSize = sptr->size = sptr->dSize / 2.0f;
if (item->ItemFlags[1])
item->ItemFlags[1]--;
else
item->ItemFlags[0] = item->TriggerFlags >> 4;
}
if (!normal)
return;
}
else
{
if (item->itemFlags[0])
{
item->itemFlags[0]--;
if (!item->itemFlags[0])
item->itemFlags[1] = (GetRandomControl() & 0x3F) + 30;
v41 = 1;
if (item->itemFlags[2])
item->itemFlags[2] -= 256;
if (!item->itemFlags[2])
goto LABEL_61;
}
else
if (!(Wibble & 0x0F) && (item->ObjectNumber != ID_STEAM_EMITTER || !(Wibble & 0x1F)))
{
int dx = Camera.pos.x - item->Pose.Position.x;
int dz = Camera.pos.z - item->Pose.Position.z;
if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16))
return;
auto* sptr = GetFreeParticle();
sptr->on = 1;
sptr->sR = 0;
sptr->sG = 0;
sptr->sB = 0;
sptr->dR = 64;
sptr->dG = 64;
sptr->dB = 64;
if (item->ObjectNumber == ID_SMOKE_EMITTER_BLACK)
{
if (item->itemFlags[2] < 4096)
item->itemFlags[2] += 256;
sptr->dR = 96;
sptr->dG = 96;
sptr->dB = 96;
}
sptr->fadeToBlack = 16;
sptr->colFadeSpeed = (GetRandomControl() & 3) + 8;
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 28;
if (item->ObjectNumber == ID_SMOKE_EMITTER_BLACK)
sptr->blendMode = BLEND_MODES::BLENDMODE_SUBTRACTIVE;
else
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
sptr->x = (GetRandomControl() & 0x3F) + item->Pose.Position.x - 32;
sptr->y = (GetRandomControl() & 0x3F) + item->Pose.Position.y - 32;
sptr->z = (GetRandomControl() & 0x3F) + item->Pose.Position.z - 32;
sptr->xVel = (GetRandomControl() & 0xFF) - 128;
sptr->yVel = -16 - (GetRandomControl() & 0xF);
sptr->zVel = (GetRandomControl() & 0xFF) - 128;
sptr->friction = 3;
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
if (TestEnvironment(RoomEnvFlags::ENV_FLAG_OUTSIDE, item->RoomNumber))
sptr->flags |= SP_WIND;
sptr->rotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
sptr->rotAdd = -8 - (GetRandomControl() & 7);
else
sptr->rotAdd = (GetRandomControl() & 7) + 8;
sptr->scalar = 2;
sptr->gravity = -8 - (GetRandomControl() & 0xF);
sptr->maxYvel = -8 - (GetRandomControl() & 7);
int size = (GetRandomControl() & 0x1F) + 128;
sptr->dSize = float(size);
sptr->sSize = sptr->size = float(size / 4);
if (item->ObjectNumber == ID_STEAM_EMITTER)
{
sptr->gravity /= 2;
sptr->yVel /= 2;
sptr->maxYvel /= 2;
sptr->life += 16;
sptr->sLife += 16;
sptr->dR = 32;
sptr->dG = 32;
sptr->dB = 32;
}
}
int dx = LaraItem->pos.Position.x - item->pos.Position.x;
int dz = LaraItem->pos.Position.z - item->pos.Position.z;
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
{
auto* spark = GetFreeParticle();
spark->on = 1;
spark->dR = 48;
spark->dG = 48;
spark->dB = 48;
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
spark->x = (GetRandomControl() & 0x3F) + item->pos.Position.x - 32;
spark->y = (GetRandomControl() & 0x3F) + item->pos.Position.y - 32;
spark->z = (GetRandomControl() & 0x3F) + item->pos.Position.z - 32;
int flags = item->itemFlags[2];
if (flags == 4096)
{
if (item->triggerFlags & 4)
flags = (GetRandomControl() & 0xFFF) + 256;
else
flags = (GetRandomControl() & 0x7FF) + 2048;
}
if (item->triggerFlags >= 0)
{
spark->xVel = flags * phd_sin(item->pos.Orientation.y - ANGLE(180)) >> W2V_SHIFT;
spark->yVel = -16 - (GetRandomControl() & 0xF);
spark->zVel = flags * phd_cos(item->pos.Orientation.y - ANGLE(180)) >> W2V_SHIFT;
}
else
{
v17 = GetRandomControl();
v18 = v17;
LOWORD(v17) = item->pos.Orientation.y;
f = (v18 & 0x7F) + 2048;
spark->Xvel = v15 * 4 * rcossin_tbl[((v17 + 20480) >> 3) & 0x1FFE] >> 14;
spark->Yvel = -128 - (unsigned __int8)GetRandomControl();
spark->Zvel = v15 * 4 * rcossin_tbl[((((unsigned __int16)item->pos.Orientation.y + 20480) >> 3) & 0x1FFE) + 1] >> 14;
}
spark->Flags = 538;
if (!(GlobalCounter & 3) && !(item->triggerFlags & 4))
spark->Flags = 1562;
spark->RotAng = GetRandomControl() & 0xFFF;
spark->RotAdd = GetRandomControl() & 1 ? -8 - (GetRandomControl() & 7) : (GetRandomControl() & 7) + 8;
spark->Gravity = -8 - (GetRandomControl() & 0xF);
spark->MaxYvel = -8 - (GetRandomControl() & 7);
v20 = (GetRandomControl() & 0x1F) + 128;
if (item->triggerFlags & 4)
{
spark->sB = 0;
spark->sG = 0;
spark->sR = 0;
spark->ColFadeSpeed = 2;
spark->FadeToBlack = 2;
v21 = (GetRandomControl() & 3) + 16;
spark->Life = v21;
spark->sLife = v21;
if (item->triggerFlags >= 0)
{
spark->Xvel *= 4;
spark->Zvel *= 4;
spark->Scalar = 3;
spark->Friction = 4;
}
else
{
spark->Scalar = 1;
spark->Friction = 51;
v15 >>= 1;
}
v22 = v15 * v20 >> 10;
if (v22 > 255)
v22 = 255;
spark->dSize = v22;
spark->sSize = v22 >> 2;
spark->Size = v22 >> 2;
}
else
{
spark->sR = 96;
spark->sG = 96;
spark->sB = 96;
spark->fadeToBlack = 6;
spark->colFadeSpeed = (GetRandomControl() & 3) + 6;
spark->life = spark->sLife = (GetRandomControl() & 7) + 8;
spark->friction = 4 - (item->triggerFlags & 4);
v25 = (((item->triggerFlags & 0xFF) >> 2) & 1) + 2;
spark->dSize = v20;
spark->scalar = (((item->triggerFlags & 0xFF) >> 2) & 1) + 2;
spark->sSize = v20 >> 1;
spark->Size = v20 >> 1;
v26 = item->itemFlags[1];
if (v26)
item->itemFlags[1] = v26 - 1;
else
item->itemFlags[0] = item->triggerFlags >> 4;
}
LOBYTE(v4) = v41;
if (v41)
{
LABEL_61:
LOBYTE(v4) = wibble;
if (!(wibble & 0xF) && (item->objectNumber != 365 || !(wibble & 0x1F)))
{
auto* spark = GetFreeParticle();
spark->on = 1;
spark->sR = 0;
spark->sG = 0;
spark->sB = 0;
spark->dR = 64;
spark->dG = 64;
spark->dB = 64;
spark->fadeToBlack = 16;
spark->colFadeSpeed = (GetRandomControl() & 3) + 8;
spark->life = spark->sLife = (GetRandomControl() & 7) + 28;
if (item->objectNumber == ID_SMOKE_EMITTER_WHITE)
spark->blendMode = BLEND_MODES::BLENDMODE_SUBTRACTIVE;
else
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
spark->x = (GetRandomControl() & 0x3F) + item->pos.Position.x - 32;
spark->y = (GetRandomControl() & 0x3F) + item->pos.Position.y - 32;
spark->z = (GetRandomControl() & 0x3F) + item->pos.Position.z - 32;
if (item->triggerFlags == 111)
{
spark->xVel = 512 * phd_sin(item->pos.Orientation.y - ANGLE(180)) >> W2V_SHIFT;
spark->zVel = 512 * phd_cos(item->pos.Orientation.y - ANGLE(180)) >> W2V_SHIFT;
spark->friction = 5;
}
else
{
spark->xVel = (byte)GetRandomControl() - 128;
spark->zVel = (byte)GetRandomControl() - 128;
spark->friction = 3;
}
v33 = GetRandomControl();
spark->Flags = 538;
spark->Yvel = -16 - (v33 & 0xF);
if (room[item->roomNumber].flags & 8)
spark->Flags = 794;
spark->RotAng = GetRandomControl() & 0xFFF;
if (GetRandomControl() & 1)
spark->RotAdd = -8 - (GetRandomControl() & 7);
else
spark->RotAdd = (GetRandomControl() & 7) + 8;
spark->Scalar = 2;
spark->Gravity = -8 - (GetRandomControl() & 0xF);
spark->MaxYvel = -8 - (GetRandomControl() & 7);
v4 = (GetRandomControl() & 0x1F) + 128;
spark->dSize = v4;
spark->sSize = v4 >> 2;
spark->Size = v4 >> 2;
if (item->objectNumber == 365)
{
v34 = spark->MaxYvel;
v35 = spark->Life;
v36 = spark->sLife + 16;
spark->Gravity >>= 1;
spark->Yvel >>= 1;
spark->MaxYvel = v34 >> 1;
spark->Life = v35 + 16;
LOBYTE(v4) = 32;
spark->sLife = v36;
spark->dR = 32;
spark->dG = 32;
spark->dB = 32;
}
}
return v4;
}
}
return v4;*/
}

View file

@ -3,6 +3,7 @@
#include "Game/items.h"
#include "Game/collision/collide_room.h"
#include "Game/control/box.h"
#include "Game/effects/debris.h"
#include "Game/effects/effects.h"
#include "Specific/setup.h"
#include "Game/animation.h"

View file

@ -206,6 +206,7 @@ void ExplodeFX(FX_INFO* fx, int noXZVel, int bits)
{
ShatterItem.yRot = fx->pos.Orientation.y;
ShatterItem.meshIndex = fx->frameNumber;
ShatterItem.color = Vector4::One;
ShatterItem.sphere.x = fx->pos.Position.x;
ShatterItem.sphere.y = fx->pos.Position.y;
ShatterItem.sphere.z = fx->pos.Position.z;

View file

@ -10,6 +10,7 @@
#include "Game/animation.h"
#include "Game/items.h"
#include "Game/collision/collide_item.h"
#include "Game/effects/debris.h"
using namespace TEN::Input;
using namespace TEN::Entities::Switches;

View file

@ -92,7 +92,7 @@ void RaisingCogControl(short itemNumber)
if (!item->ItemFlags[2])
{
InitialiseSpotCam(item->ItemFlags[2]);
UseSpotCam = 1;
UseSpotCam = true;
}
int flags = 0;

View file

@ -73,9 +73,8 @@ static void StartEntity(ObjectInfo *obj)
if (obj->loaded)
{
obj->initialise = InitialiseLaraLoad;
obj->castsShadow = true;
obj->shadowType = ShadowMode::Lara;
obj->HitPoints = 1000;
obj->drawRoutine = nullptr;
obj->saveAnim = true;
obj->saveFlags = true;
obj->saveHitpoints = true;
@ -89,7 +88,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -113,7 +112,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -141,7 +140,7 @@ static void StartEntity(ObjectInfo *obj)
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->pivotLength = 50;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->radius = 102;
@ -171,7 +170,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -201,7 +200,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->collision = CreatureCollision;
obj->control = GuardControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -231,7 +230,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -261,7 +260,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -293,7 +292,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuard;
obj->control = GuardControl;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -317,7 +316,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseSubmarine;
obj->collision = CreatureCollision;
obj->control = SubmarineControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 200;
@ -340,7 +339,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseChef;
obj->control = ControlChef;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 35;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -365,7 +364,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLion;
obj->collision = CreatureCollision;
obj->control = LionControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 40;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -386,7 +385,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseDoberman;
obj->collision = CreatureCollision;
obj->control = DobermanControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 18;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -406,7 +405,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseTr5Dog;
obj->collision = CreatureCollision;
obj->control = Tr5DogControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -426,7 +425,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseReaper;
obj->collision = CreatureCollision;
obj->control = ReaperControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 10;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -447,7 +446,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseMafia2;
obj->collision = CreatureCollision;
obj->control = Mafia2Control;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 26;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -474,7 +473,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLarson;
obj->collision = CreatureCollision;
obj->control = LarsonControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -498,7 +497,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLarson;
obj->collision = CreatureCollision;
obj->control = LarsonControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 60;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -522,7 +521,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseCyborg;
obj->collision = CreatureCollision;
obj->control = CyborgControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 50;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -549,7 +548,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseSniper;
obj->collision = CreatureCollision;
obj->control = SniperControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 35;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -573,7 +572,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGuardLaser;
obj->collision = CreatureCollision;
//obj->control = GuardControlLaser;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 24;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -598,7 +597,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseHydra;
obj->collision = CreatureCollision;
obj->control = HydraControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 30;
obj->hitEffect = HIT_RICOCHET;
obj->pivotLength = 50;
@ -624,7 +623,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseImp;
obj->collision = CreatureCollision;
obj->control = ImpControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 12;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -650,7 +649,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLightingGuide;
//obj->control = ControlLightingGuide;
obj->drawRoutine = NULL;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->radius = 256;
obj->HitPoints = 16;
obj->pivotLength = 20;
@ -673,7 +672,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseBrownBeast;
obj->collision = CreatureCollision;
obj->control = ControlBrowsBeast;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -697,7 +696,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseLagoonWitch;
obj->collision = CreatureCollision;
obj->control = LagoonWitchControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 20;
@ -723,7 +722,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseInvisibleGhost;
obj->collision = CreatureCollision;
obj->control = InvisibleGhostControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 20;
@ -774,7 +773,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseGladiator;
obj->control = ControlGladiator;
obj->collision = CreatureCollision;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 20;
obj->hitEffect = HIT_BLOOD;
obj->pivotLength = 50;
@ -800,7 +799,7 @@ static void StartEntity(ObjectInfo *obj)
obj->initialise = InitialiseRomanStatue;
obj->collision = CreatureCollision;
obj->control = RomanStatueControl;
obj->castsShadow = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 300;
obj->hitEffect = HIT_SMOKE;
obj->pivotLength = 50;
@ -812,7 +811,6 @@ static void StartEntity(ObjectInfo *obj)
obj->saveHitpoints = true;
obj->meshSwapSlot = ID_MESHSWAP_ROMAN_GOD1 + i;
obj->zoneType = ZONE_HUMAN_CLASSIC;
obj->castShadows = true;
g_Level.Bones[obj->boneIndex + 24] |= ROT_Y;
g_Level.Bones[obj->boneIndex + 24] |= ROT_X;
@ -873,7 +871,7 @@ static void StartEntity(ObjectInfo *obj)
obj->saveAnim = true;
obj->zoneType = ZONE_BASIC;
obj->hitEffect = HIT_RICOCHET;
obj->castShadows = true;
obj->shadowType = ShadowMode::All;
obj->HitPoints = 100;
}
}
@ -997,7 +995,7 @@ static void StartObject(ObjectInfo *obj)
obj->saveFlags = true;
}
obj = &Objects[ID_SMOKE_EMITTER];
obj = &Objects[ID_STEAM_EMITTER];
if (obj->loaded)
{
obj->initialise = InitialiseSmokeEmitter;
@ -1116,7 +1114,7 @@ static void StartTrap(ObjectInfo *obj)
obj->hitEffect = HIT_RICOCHET;
obj->savePosition = true;
obj->saveFlags = true;
obj->castShadows = true;
obj->shadowType = ShadowMode::All;
}
obj = &Objects[ID_CLASSIC_ROLLING_BALL];

View file

@ -133,7 +133,7 @@ enum GAME_OBJECT_ID : short
ID_MERCENARY_AUTOPISTOLS2,
ID_SNOWMOBILE_GUN,
ID_SNOWMOBILE_DRIVER,
ID_FLAMETHROWER_GOON,
ID_FLAMETHROWER_BADDY,
ID_TRIBESMAN_WITH_AX,
ID_TRIBESMAN_WITH_DARTS,
ID_MP_WITH_STICK,
@ -750,7 +750,7 @@ enum GAME_OBJECT_ID : short
/* other effect in-game */
ID_SMOKE_EMITTER_WHITE = 1020,
ID_SMOKE_EMITTER_BLACK,
ID_SMOKE_EMITTER,
ID_STEAM_EMITTER,
ID_LOCUST_EMITTER,
ID_EARTHQUAKE,
ID_BUBBLES, // TR4 - OK
@ -825,8 +825,8 @@ enum GAME_OBJECT_ID : short
ID_MESHSWAP8,
ID_MESHSWAP9,
ID_MESHSWAP10,
ID_MESHSWAP_GOON1,
ID_MESHSWAP_GOON2,
ID_MESHSWAP_BADDY1,
ID_MESHSWAP_BADDY2,
ID_MESHSWAP_MAFIA2 = 1113,
ID_MESHSWAP_IMP,
ID_MESHSWAP_HITMAN,

View file

@ -16,4 +16,6 @@ struct alignas(16) CAnimatedBuffer
std::array<AnimatedFrame, 128> Textures;
uint32_t NumFrames;
uint32_t Fps;
uint32_t Type;
uint32_t padding;
};

View file

@ -4,7 +4,7 @@ struct alignas(16) CItemBuffer
{
Matrix World;
Matrix BonesMatrices[MAX_BONES];
Vector4 Position;
Vector4 Color;
Vector4 AmbientLight;
int BoneLightModes[MAX_BONES];
};

View file

@ -11,6 +11,7 @@ struct alignas(16) CShadowLightBuffer
Matrix LightViewProjections[6];
int CastShadows;
int NumSpheres;
int padding[2];
int ShadowMapSize;
int padding;
Sphere Spheres[16];
};

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