Merge branch 'ten_beta' into very_experimental_input_stuff

This commit is contained in:
Sezz 2022-08-05 14:12:16 +10:00
commit 97152a5bd6
157 changed files with 5531 additions and 4015 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="#KeyHeld">KeyHeld(action)</a></td>
<td class="summary">Check if particular action key is held</td>
</tr>
<tr>
<td class="name" ><a href="#KeyHit">KeyHit(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 = "KeyHeld"></a>
<strong>KeyHeld(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 = "KeyHit"></a>
<strong>KeyHit(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>

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

@ -9,36 +9,36 @@ local InventoryItem = Flow.InventoryItem
local InvID = Flow.InvID
local RotationAxis = Flow.RotationAxis
local ItemAction = Flow.ItemAction
local Fog = Flow.Fog
Flow.SetIntroImagePath("Screens\\Main.png")
Flow.SetTitleScreenImagePath("Screens\\Title.jpg")
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_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.nameKey = "level_test"
test.scriptFile = "Scripts\\TestLevel.lua"
test.ambientTrack = "108"
test.levelFile = "Data\\TestLevel.ten"
test.loadScreenFile = "Screens\\rome.jpg"
test.weather = 0
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)
test.objects = {
InventoryItem.new(
@ -92,7 +92,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",
"",
"",

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

@ -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);
@ -1805,13 +1810,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]))
@ -1856,7 +1861,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)
{

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)
UpdateInputActions();
@ -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?
@ -187,7 +190,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;
@ -330,7 +333,6 @@ GameStatus ControlPhase(int numFrames, int demoMode)
UpdateShockwaves();
UpdateBeetleSwarm();
UpdateLocusts();
AnimateWaterfalls();
// Rumble screen (like in submarine level of TRC)
if (level->Rumble)
@ -347,6 +349,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;
@ -413,7 +422,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);
});
}
@ -464,7 +473,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);
}
@ -517,7 +526,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);
});
}
@ -681,35 +690,6 @@ int GetRandomDraw()
return GenerateInt();
}
bool ExplodeItemNode(ItemInfo *item, int node, int noXZVel, int bits)
{
if (item->MeshBits & (1 << node))
{
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.0f, 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

@ -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

@ -337,11 +337,13 @@ namespace TEN::Gui
CurrentSettings.Configuration.Windowed = !CurrentSettings.Configuration.Windowed;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.ShadowMode--;
if (CurrentSettings.Configuration.ShadowMode < SHADOW_NONE) CurrentSettings.Configuration.ShadowMode = SHADOW_ALL;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (CurrentSettings.Configuration.ShadowType == ShadowMode::None)
CurrentSettings.Configuration.ShadowType = ShadowMode::All;
else
CurrentSettings.Configuration.ShadowType = ShadowMode(int(CurrentSettings.Configuration.ShadowType) - 1);
break;
case 3:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
@ -363,7 +365,6 @@ namespace TEN::Gui
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (CurrentSettings.SelectedScreenResolution < g_Configuration.SupportedScreenResolutions.size() - 1)
CurrentSettings.SelectedScreenResolution++;
break;
case 1:
@ -371,13 +372,13 @@ namespace TEN::Gui
CurrentSettings.Configuration.Windowed = !CurrentSettings.Configuration.Windowed;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.Configuration.ShadowMode++;
if (CurrentSettings.Configuration.ShadowMode > SHADOW_ALL)
CurrentSettings.Configuration.ShadowMode = SHADOW_NONE;
break;
case 2:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
if (CurrentSettings.Configuration.ShadowType == ShadowMode::All)
CurrentSettings.Configuration.ShadowType = ShadowMode::None;
else
CurrentSettings.Configuration.ShadowType = ShadowMode(int(CurrentSettings.Configuration.ShadowType) + 1);
break;
case 3:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
@ -500,12 +501,12 @@ namespace TEN::Gui
if (fromPauseMenu)
{
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 numFrames = Camera.numberFrames;
ControlPhase(numFrames, 0);
}
@ -1866,9 +1867,9 @@ namespace TEN::Gui
{
auto* lara = GetLaraInfo(item);
if (Rings[(int)RingTypes::Ammo]->RingActive)
{
g_Renderer.DrawString(PHD_CENTER_X, PHD_CENTER_Y, g_GameFlow->GetString(OptionStrings[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (Rings[(int)RingTypes::Ammo]->RingActive)
{
g_Renderer.AddString(PHD_CENTER_X, PHD_CENTER_Y, g_GameFlow->GetString(OptionStrings[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (Rings[(int)RingTypes::Inventory]->ObjectListMovement)
return;
@ -2065,12 +2066,12 @@ namespace TEN::Gui
{
if (i == CurrentSelectedOption)
{
g_Renderer.DrawString(PHD_CENTER_X, yPos, CurrentOptions[i].Text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(PHD_CENTER_Y, yPos, CurrentOptions[i].Text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
yPos += LINE_HEIGHT;
}
else
{
g_Renderer.DrawString(PHD_CENTER_X, yPos, CurrentOptions[i].Text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(PHD_CENTER_X, yPos, CurrentOptions[i].Text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
yPos += LINE_HEIGHT;
}
}
@ -2353,7 +2354,7 @@ namespace TEN::Gui
sprintf(&invTextBuffer[0], "%d x %s", AmmoObjectList[n].Amount, g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName));
if (AmmoSelectorFadeVal)
g_Renderer.DrawString(PHD_CENTER_X, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(PHD_CENTER_X, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
if (n == *CurrentAmmoType)
@ -2654,7 +2655,7 @@ namespace TEN::Gui
else
objectMeUp = int(PHD_CENTER_Y + (REFERENCE_RES_HEIGHT + 1) * 0.0625 * 2.0);
g_Renderer.DrawString(PHD_CENTER_X, objectMeUp, textBufferMe, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.AddString(PHD_CENTER_X, objectMeUp, textBufferMe, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
}
if (!i && !Rings[ringIndex]->ObjectListMovement)
@ -2882,7 +2883,7 @@ namespace TEN::Gui
SetEnterInventory(NO_ITEM);
Camera.numberFrames = g_Renderer.SyncRenderer();
Camera.numberFrames = g_Renderer.Synchronize();
LastInvItem = Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem;
UpdateWeaponStatus(item);

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

@ -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)
@ -617,7 +617,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;
}

View file

@ -1,9 +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;
constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16.0f;
constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS;
struct QUAKE_CAMERA
{

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/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

@ -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];
};

View file

@ -3,7 +3,7 @@
struct alignas(16) CStaticBuffer
{
Matrix World;
Vector4 Position;
Vector4 Color;
Vector4 AmbientLight;
int LightMode;
};

View file

@ -50,9 +50,10 @@ namespace TEN::Renderer
for (auto& item : m_items)
{
item.PreviousRoomNumber = NO_ROOM;
item.CurrentRoomNumber = NO_ROOM;
item.PrevRoomNumber = NO_ROOM;
item.RoomNumber = NO_ROOM;
item.ItemNumber = NO_ITEM;
item.LightsToDraw.clear();
}
}
@ -63,7 +64,12 @@ namespace TEN::Renderer
gameCamera.clear();
}
int Renderer11::SyncRenderer()
void Renderer11::Lock()
{
m_Locked = true;
}
int Renderer11::Synchronize()
{
// Sync the renderer
int nf = Sync();
@ -318,9 +324,36 @@ namespace TEN::Renderer
void Renderer11::BindLights(std::vector<RendererLight*>& lights)
{
m_stLights.NumLights = lights.size();
for (int j = 0; j < lights.size(); j++)
memcpy(&m_stLights.Lights[j], lights[j], sizeof(ShaderLight));
BindLights(lights, NO_ROOM, NO_ROOM, 1.0f);
}
void Renderer11::BindLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade)
{
int numLights = 0;
for (int i = 0; i < lights.size(); i++)
{
float fadedCoeff = 1.0f;
// Interpolate lights which don't affect neighbor rooms
if (!lights[i]->AffectNeighbourRooms && roomNumber != NO_ROOM && lights[i]->RoomNumber != NO_ROOM)
{
if (lights[i]->RoomNumber == roomNumber)
fadedCoeff = fade;
else if (lights[i]->RoomNumber == prevRoomNumber)
fadedCoeff = 1.0f - fade;
else
continue;
}
if (fadedCoeff == 0.0f)
continue;
memcpy(&m_stLights.Lights[numLights], lights[i], sizeof(ShaderLight));
m_stLights.Lights[numLights].Intensity *= fadedCoeff;
numLights++;
}
m_stLights.NumLights = numLights;
m_cbLights.updateData(m_stLights, m_context.Get());
BindConstantBufferPS(CB_LIGHTS, m_cbLights.get());
BindConstantBufferVS(CB_LIGHTS, m_cbLights.get());

View file

@ -82,9 +82,11 @@ namespace TEN::Renderer
struct RendererStatic
{
int Id;
int RoomIndex;
int ObjectNumber;
int RoomNumber;
Vector3 Position;
Matrix World;
Vector4 Color;
Vector4 AmbientLight;
std::vector<RendererLight*> LightsToDraw;
};
@ -99,17 +101,20 @@ namespace TEN::Renderer
struct RendererItem
{
int ItemNumber;
int ObjectNumber;
bool DoneAnimations;
Vector3 Position;
Matrix World;
Matrix Translation;
Matrix Rotation;
Matrix Scale;
Matrix AnimationTransforms[MAX_BONES];
std::vector<RendererLight*> LightsToDraw;
int PreviousRoomNumber = NO_ROOM;
int CurrentRoomNumber = NO_ROOM;
int RoomNumber = NO_ROOM;
int PrevRoomNumber = NO_ROOM;
Vector4 Color;
Vector4 AmbientLight;
int AmbientLightSteps;
std::vector<RendererLight*> LightsToDraw;
float LightFade;
};
struct RendererMesh
@ -122,8 +127,9 @@ namespace TEN::Renderer
struct RendererEffect
{
int Id;
FX_INFO* Effect;
int ObjectNumber;
int RoomNumber;
Vector3 Position;
Matrix World;
RendererMesh* Mesh;
std::vector<RendererLight*> LightsToDraw;
@ -139,6 +145,7 @@ namespace TEN::Renderer
std::vector<Matrix> BindPoseTransforms;
std::vector<RendererBone*> LinearizedBones;
bool DoNotDraw;
ShadowMode ShadowType;
bool HasDataInBucket[NUM_BUCKETS];
bool HasDataInAnimatedBucket[NUM_BUCKETS];
@ -406,6 +413,9 @@ namespace TEN::Renderer
int m_screenHeight;
bool m_windowed;
// A flag to prevent extra renderer object addition
bool m_Locked = false;
// Misc
int m_pickupRotation = 0;
@ -421,11 +431,13 @@ namespace TEN::Renderer
short m_boundList[MAX_ROOM_BOUNDS];
short m_boundStart = 0;
short m_boundEnd = 1;
float m_farView = DEFAULT_FAR_VIEW;
RendererRectangle m_outsideClip;
// Private functions
void BindTexture(TEXTURE_REGISTERS registerType, TextureBase* texture, SAMPLER_STATES samplerType);
void BindLights(std::vector<RendererLight*>& lights);
void BindLights(std::vector<RendererLight*>& lights, int roomNumber, int prevRoomNumber, float fade);
void BindRenderTargetAsTexture(TEXTURE_REGISTERS registerType, RenderTarget2D* target, SAMPLER_STATES samplerType);
void BindConstantBufferVS(CONSTANT_BUFFERS constantBufferType, ID3D11Buffer** buffer);
void BindConstantBufferPS(CONSTANT_BUFFERS constantBufferType, ID3D11Buffer** buffer);
@ -439,19 +451,19 @@ namespace TEN::Renderer
void SetRoomBounds(ROOM_DOOR* door, short parentRoomNumber, RenderView& renderView);
void CollectRooms(RenderView& renderView, bool onlyRooms);
void CollectItems(short roomNumber, RenderView& renderView);
void CollectStatics(short roomNumber);
void CollectLights(Vector3Int position, int roomNumber, bool collectShadowLight, std::vector<RendererLight*>& lights);
void CollectLightsForItem(short roomNumber, RendererItem* item, bool collectShadowLight);
void CollectStatics(short roomNumber, RenderView& renderView);
void CollectLights(Vector3 position, float radius, int roomNumber, int prevRoomNumber, bool prioritizeShadowLight, std::vector<RendererLight*>& lights);
void CollectLightsForItem(RendererItem* item);
void CollectLightsForEffect(short roomNumber, RendererEffect* effect);
void CollectLightsForRoom(short roomNumber, RenderView& renderView);
void CalculateAmbientLight(RendererItem* item);
void CollectLightsForCamera();
void CalculateLightFades(RendererItem* item);
void CollectEffects(short roomNumber);
void ClearScene();
void ClearSceneItems();
void ClearDynamicLights();
void ClearShadowMap(RenderView& view);
void ClearShadowMap();
void UpdateItemAnimations(RenderView& view);
void UpdateEffects(RenderView& view);
bool PrintDebugMessage(int x, int y, int alpha, byte r, byte g, byte b, LPCSTR Message);
void InitialiseScreen(int w, int h, bool windowed, HWND handle, bool reset);
@ -467,10 +479,11 @@ namespace TEN::Renderer
void DrawItems(RenderView& view, bool transparent);
void DrawItemsTransparent(RendererTransparentFaceInfo* info, RenderView& view);
void DrawAnimatingItem(RendererItem* item, RenderView& view, bool transparent);
void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, bool transparent);
void DrawBaddyGunflashes(RenderView& view);
void DrawStatics(RenderView& view, bool transparent);
void DrawDarts(RendererItem* item, RenderView& view);
void DrawLara(bool shadowMap, RenderView& view, bool transparent);
void DrawLara(RenderView& view, bool transparent);
void DrawFires(RenderView& view);
void DrawParticles(RenderView& view);
void DrawSmokes(RenderView& view);
@ -524,7 +537,8 @@ namespace TEN::Renderer
void RenderNewInventory();
void RenderToCubemap(const RenderTargetCube& dest, const Vector3& pos, int roomNumber);
void RenderBlobShadows(RenderView& renderView);
void RenderShadowMap(RenderView& view);
void RenderShadowMap(RendererItem* item, RenderView& view);
void RenderItemShadows(RenderView& renderView);
void SetBlendMode(BLEND_MODES blendMode, bool force = false);
void SetDepthState(DEPTH_STATES depthState, bool force = false);
@ -546,7 +560,6 @@ namespace TEN::Renderer
void AddSprite3D(RendererSprite* sprite, Vector3 vtx1, Vector3 vtx2, Vector3 vtx3, Vector3 vtx4, Vector4 color,
float rotation, float scale, Vector2 size, BLEND_MODES blendMode, RenderView& view);
short GetRoomNumberForSpriteTest(Vector3 position);
RendererMesh* GetMesh(int meshIndex);
Texture2D CreateDefaultNormalTexture();
@ -592,6 +605,7 @@ namespace TEN::Renderer
void Create();
void Initialise(int w, int h, bool windowed, HWND handle);
void Draw();
void Lock();
bool PrepareDataForTheRenderer();
void UpdateCameraMatrices(CAMERA_INFO* cam, float roll, float fov, float farView);
void RenderSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view);
@ -603,8 +617,8 @@ namespace TEN::Renderer
void DrawDebugInfo(RenderView& view);
void SwitchDebugPage(bool back);
void DrawPickup(short objectNum);
int SyncRenderer();
void DrawString(int x, int y, const char* string, D3DCOLOR color, int flags);
int Synchronize();
void AddString(int x, int y, const char* string, D3DCOLOR color, int flags);
void FreeRendererData();
void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b);
void RenderLoadingScreen(float percentage);

View file

@ -158,11 +158,13 @@ namespace TEN::Renderer
ROOM_INFO& room = g_Level.Rooms[i];
RendererRoom* r = &m_rooms[i];
r->RoomNumber = i;
r->AmbientLight = Vector4(room.ambient.x, room.ambient.y, room.ambient.z, 1.0f);
r->ItemsToDraw.reserve(MAX_ITEMS_DRAW);
r->EffectsToDraw.reserve(MAX_ITEMS_DRAW);
r->TransparentFacesToDraw.reserve(MAX_TRANSPARENT_FACES_PER_ROOM);
r->Neighbors = room.neighbors;
if (room.mesh.size() > 0)
r->StaticsToDraw.reserve(room.mesh.size());
@ -267,10 +269,6 @@ namespace TEN::Renderer
RendererLight* light = &r->Lights[l];
ROOM_LIGHT* oldLight = &room.lights[l];
// Monty's temp variables for sorting
light->LocalIntensity = 0;
light->Distance = 0;
if (oldLight->type == LIGHT_TYPES::LIGHT_TYPE_SUN)
{
light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b) * oldLight->intensity;
@ -313,6 +311,12 @@ namespace TEN::Renderer
light->Type = LIGHT_TYPE_SPOT;
}
// Monty's temp variables for sorting
light->LocalIntensity = 0;
light->Distance = 0;
light->RoomNumber = i;
light->AffectNeighbourRooms = light->Type != LIGHT_TYPES::LIGHT_TYPE_SUN;
oldLight++;
}
}
@ -363,8 +367,6 @@ namespace TEN::Renderer
moveablesVertices.resize(totalVertices);
moveablesIndices.resize(totalIndices);
lastVertex = 0;
lastIndex = 0;
for (int i = 0; i < MoveablesIds.size(); i++)
@ -377,7 +379,8 @@ namespace TEN::Renderer
m_moveableObjects[MoveablesIds[i]] = RendererObject();
RendererObject &moveable = *m_moveableObjects[MoveablesIds[i]];
moveable.Id = MoveablesIds[i];
moveable.DoNotDraw = (obj->drawRoutine == NULL);
moveable.DoNotDraw = (obj->drawRoutine == nullptr);
moveable.ShadowType = obj->shadowType;
for (int j = 0; j < obj->nmeshes; j++)
{
@ -722,26 +725,7 @@ namespace TEN::Renderer
m_spriteSequences[MoveablesIds[i]] = sequence;
}
}
/*
for (int i = 0; i < 6; i++)
{
if (Objects[ID_WATERFALL1 + i].loaded)
{
// Get the first textured bucket
RendererBucket *bucket = NULL;
for (int j = 0; j < NUM_BUCKETS; j++)
if (m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->buckets[j].Polygons.size() > 0)
bucket = &m_moveableObjects[ID_WATERFALL1 + i]->ObjectMeshes[0]->buckets[j];
if (bucket == NULL)
continue;
OBJECT_TEXTURE *texture = &g_Level.ObjectTextures[bucket->Polygons[0].TextureId];
WaterfallTextures[i] = texture;
WaterfallY[i] = texture->vertices[0].y;
}
}
*/
return true;
}

View file

@ -37,7 +37,7 @@ namespace TEN::Renderer
_vsprintf_l(buffer, message, NULL, args);
va_end(args);
DrawString(10, m_currentY, buffer, 0xFFFFFFFF, PRINTSTRING_OUTLINE);
AddString(10, m_currentY, buffer, 0xFFFFFFFF, PRINTSTRING_OUTLINE);
m_currentY += 20;
}

View file

@ -10,7 +10,6 @@
#include "Game/health.h"
#include "Game/camera.h"
#include "Game/items.h"
#include "Game/spotcam.h"
#include "Game/animation.h"
#include "Game/gui.h"
#include "Game/Lara/lara.h"
@ -52,25 +51,6 @@ namespace TEN::Renderer
static const std::array<LARA_MESHES, 4> sphereMeshes = { LM_HIPS, LM_TORSO, LM_LFOOT, LM_RFOOT };
static const std::array<float, 4> sphereScaleFactors = { 6.0f, 3.2f, 2.8f, 2.8f };
if (!SpotcamDontDrawLara && CurrentLevel != 0)
{
for (auto i = 0; i < sphereMeshes.size(); i++)
{
auto& newSphere = nearestSpheres.emplace_back();
MESH& m = g_Level.Meshes[Lara.MeshPtrs[sphereMeshes[i]]];
Vector3Int pos = { (int)m.sphere.Center.x, (int)m.sphere.Center.y, (int)m.sphere.Center.z };
if (sphereMeshes[i] == LM_LFOOT || sphereMeshes[i] == LM_RFOOT)
{
// Push feet spheres a little bit down
pos.y += 8;
}
GetLaraJointPosition(&pos, sphereMeshes[i]);
newSphere.position = Vector3(pos.x, pos.y, pos.z);
newSphere.radius = m.sphere.Radius * sphereScaleFactors[i];
}
}
for (auto& r : renderView.roomsToDraw)
{
for (auto& i : r->ItemsToDraw)
@ -79,17 +59,41 @@ namespace TEN::Renderer
//Skip everything thats not "alive" or is not a vehicle
if (!Objects[nativeItem.ObjectNumber].castsShadow)
if (Objects[nativeItem.ObjectNumber].shadowType == ShadowMode::None)
continue;
auto bb = GetBoundsAccurate(&nativeItem);
Vector3 center = ((Vector3(bb->X1, bb->Y1, bb->Z1) + Vector3(bb->X2, bb->Y2, bb->Z2)) / 2) +
Vector3(nativeItem.Pose.Position.x, nativeItem.Pose.Position.y, nativeItem.Pose.Position.z);
center.y = nativeItem.Pose.Position.y;
float maxExtent = std::max(bb->X2 - bb->X1, bb->Z2 - bb->Z1);
auto& newSphere = nearestSpheres.emplace_back();
newSphere.position = center;
newSphere.radius = maxExtent;
if (i->ObjectNumber == ID_LARA)
{
for (auto i = 0; i < sphereMeshes.size(); i++)
{
if (!nativeItem.TestBits(JointBitType::Mesh, sphereMeshes[i]))
continue;
MESH& m = g_Level.Meshes[Lara.MeshPtrs[sphereMeshes[i]]];
Vector3Int pos = { (int)m.sphere.Center.x, (int)m.sphere.Center.y, (int)m.sphere.Center.z };
// Push feet spheres a little bit down
if (sphereMeshes[i] == LM_LFOOT || sphereMeshes[i] == LM_RFOOT)
pos.y += 8;
GetLaraJointPosition(&pos, sphereMeshes[i]);
auto& newSphere = nearestSpheres.emplace_back();
newSphere.position = Vector3(pos.x, pos.y, pos.z);
newSphere.radius = m.sphere.Radius * sphereScaleFactors[i];
}
}
else
{
auto bb = GetBoundsAccurate(&nativeItem);
Vector3 center = ((Vector3(bb->X1, bb->Y1, bb->Z1) + Vector3(bb->X2, bb->Y2, bb->Z2)) / 2) +
Vector3(nativeItem.Pose.Position.x, nativeItem.Pose.Position.y, nativeItem.Pose.Position.z);
center.y = nativeItem.Pose.Position.y;
float maxExtent = std::max(bb->X2 - bb->X1, bb->Z2 - bb->Z1);
auto& newSphere = nearestSpheres.emplace_back();
newSphere.position = center;
newSphere.radius = maxExtent;
}
}
}
@ -104,7 +108,6 @@ namespace TEN::Renderer
std::copy(nearestSpheres.begin(), nearestSpheres.begin() + g_Configuration.ShadowMaxBlobs, m_stShadowMap.Spheres);
m_stShadowMap.NumSpheres = g_Configuration.ShadowMaxBlobs;
}
else
{
@ -113,7 +116,7 @@ namespace TEN::Renderer
}
}
void Renderer11::ClearShadowMap(RenderView& renderView)
void Renderer11::ClearShadowMap()
{
for (int step = 0; step < m_shadowMap.RenderTargetView.size(); step++)
{
@ -123,20 +126,23 @@ namespace TEN::Renderer
}
}
void Renderer11::RenderShadowMap(RenderView& renderView)
void Renderer11::RenderShadowMap(RendererItem* item, RenderView& renderView)
{
if (g_Configuration.ShadowMode == SHADOW_NONE)
// Doesn't cast shadow
if (m_moveableObjects[item->ObjectNumber].value().ShadowType == ShadowMode::None)
return;
// Only render for Lara if such setting is active
if (g_Configuration.ShadowType == ShadowMode::Lara && m_moveableObjects[item->ObjectNumber].value().ShadowType != ShadowMode::Lara)
return;
// No shadow light found
if (shadowLight == nullptr)
return;
// Shadow light found but type is incorrect
if (shadowLight->Type != LIGHT_TYPE_POINT && shadowLight->Type != LIGHT_TYPE_SPOT)
return;
// TODO: This condition must become more flexible after beta.
if (SpotcamDontDrawLara || CurrentLevel == 0)
return;
return;
// Reset GPU state
SetBlendMode(BLENDMODE_OPAQUE);
@ -152,11 +158,7 @@ namespace TEN::Renderer
m_context->RSSetViewports(1, &m_shadowMapViewport);
ResetScissor();
//DrawLara(false, true);
Vector3 lightPos = Vector3(shadowLight->Position.x, shadowLight->Position.y, shadowLight->Position.z);
Vector3 itemPos = Vector3(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z);
if (lightPos == itemPos)
if (shadowLight->Position == item->Position)
return;
UINT stride = sizeof(RendererVertex);
@ -172,8 +174,7 @@ namespace TEN::Renderer
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Set texture
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]),
SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE);
// Set camera matrices
@ -181,20 +182,22 @@ namespace TEN::Renderer
Matrix projection;
if (shadowLight->Type == LIGHT_TYPE_POINT)
{
view = Matrix::CreateLookAt(lightPos, lightPos +
view = Matrix::CreateLookAt(shadowLight->Position, shadowLight->Position +
RenderTargetCube::forwardVectors[step] * SECTOR(10),
RenderTargetCube::upVectors[step]);
projection = Matrix::CreatePerspectiveFieldOfView(90.0f, 1.0f, 16.0f, shadowLight->Out);
projection = Matrix::CreatePerspectiveFieldOfView(90.0f * PI / 180.0f, 1.0f, 16.0f, shadowLight->Out);
}
else if (shadowLight->Type == LIGHT_TYPE_SPOT)
{
view = Matrix::CreateLookAt(lightPos,
lightPos - shadowLight->Direction * SECTOR(10),
view = Matrix::CreateLookAt(shadowLight->Position,
shadowLight->Position - shadowLight->Direction * SECTOR(10),
Vector3(0.0f, -1.0f, 0.0f));
projection = Matrix::CreatePerspectiveFieldOfView(shadowLight->OutRange, 1.0f, 16.0f, shadowLight->Out);
// Vertex lighting fades out in 1024-steps. increase angle artificially for a bigger blend radius.
float projectionAngle = shadowLight->OutRange * 1.5f * (PI / 180.0f);
projection = Matrix::CreatePerspectiveFieldOfView(projectionAngle, 1.0f, 16.0f, shadowLight->Out);
}
CCameraMatrixBuffer shadowProjection;
@ -206,28 +209,31 @@ namespace TEN::Renderer
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
RendererObject& laraObj = *m_moveableObjects[ID_LARA];
RendererObject& laraSkin = *m_moveableObjects[ID_LARA_SKIN];
RendererRoom& room = m_rooms[LaraItem->RoomNumber];
RendererObject& obj = *m_moveableObjects[item->ObjectNumber];
RendererObject& skin = item->ObjectNumber == ID_LARA ? *m_moveableObjects[ID_LARA_SKIN] : obj;
RendererRoom& room = m_rooms[item->RoomNumber];
m_stItem.World = m_LaraWorldMatrix;
m_stItem.Position = Vector4(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = room.AmbientLight;
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = GetMesh(Lara.MeshPtrs[k])->LightMode;
m_stItem.World = item->World;
m_stItem.Color = item->Color;
m_stItem.AmbientLight = item->AmbientLight;
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < MAX_BONES; k++)
m_stItem.BoneLightModes[k] = LIGHT_MODES::LIGHT_MODE_STATIC;
m_cbItem.updateData(m_stItem, m_context.Get());
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
for (int k = 0; k < skin.ObjectMeshes.size(); k++)
{
auto* mesh = GetMesh(Lara.MeshPtrs[k]);
auto* mesh = item->ObjectNumber == ID_LARA ? GetMesh(Lara.MeshPtrs[k]) : skin.ObjectMeshes[k];
for (auto& bucket : mesh->Buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
if (bucket.NumVertices == 0)
continue;
if (bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE && bucket.BlendMode != BLEND_MODES::BLENDMODE_ALPHATEST)
continue;
// Draw vertices
@ -237,13 +243,16 @@ namespace TEN::Renderer
}
}
if (item->ObjectNumber != ID_LARA)
continue;
if (m_moveableObjects[ID_LARA_SKIN_JOINTS].has_value())
{
RendererObject& laraSkinJoints = *m_moveableObjects[ID_LARA_SKIN_JOINTS];
auto& laraSkinJoints = *m_moveableObjects[ID_LARA_SKIN_JOINTS];
for (int k = 0; k < laraSkinJoints.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = laraSkinJoints.ObjectMeshes[k];
auto* mesh = laraSkinJoints.ObjectMeshes[k];
for (auto& bucket : mesh->Buckets)
{
@ -258,29 +267,11 @@ namespace TEN::Renderer
}
}
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = laraSkin.ObjectMeshes[k];
for (auto& bucket : mesh->Buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode != BLEND_MODES::BLENDMODE_OPAQUE)
continue;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
}
// Draw items
RendererObject& hairsObj = *m_moveableObjects[ID_LARA_HAIR];
auto& hairsObj = *m_moveableObjects[ID_LARA_HAIR];
// First matrix is Lara's head matrix, then all 6 hairs matrices. Bones are adjusted at load time for accounting this.
m_stItem.World = Matrix::Identity;
m_stItem.BonesMatrices[0] = laraObj.AnimationTransforms[LM_HEAD] * m_LaraWorldMatrix;
m_stItem.BonesMatrices[0] = obj.AnimationTransforms[LM_HEAD] * item->World;
for (int i = 0; i < hairsObj.BindPoseTransforms.size(); i++)
{
@ -297,7 +288,7 @@ namespace TEN::Renderer
for (int k = 0; k < hairsObj.ObjectMeshes.size(); k++)
{
RendererMesh* mesh = hairsObj.ObjectMeshes[k];
auto* mesh = hairsObj.ObjectMeshes[k];
for (auto& bucket : mesh->Buckets)
{
@ -310,7 +301,6 @@ namespace TEN::Renderer
m_numMoveablesDrawCalls++;
}
}
}
}
@ -326,40 +316,41 @@ namespace TEN::Renderer
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
for (int i = 0; i < 24; i++)
for (int i = 0; i < MAX_GUNSHELL; i++)
{
GUNSHELL_STRUCT* gunshell = &Gunshells[i];
if (gunshell->counter > 0)
if (gunshell->counter <= 0)
continue;
ObjectInfo* obj = &Objects[gunshell->objectNumber];
RendererObject& moveableObj = *m_moveableObjects[gunshell->objectNumber];
Matrix translation = Matrix::CreateTranslation(gunshell->pos.Position.x, gunshell->pos.Position.y,
gunshell->pos.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(gunshell->pos.Orientation.y), TO_RAD(gunshell->pos.Orientation.x),
TO_RAD(gunshell->pos.Orientation.z));
Matrix world = rotation * translation;
m_stStatic.World = world;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
RendererMesh* mesh = moveableObj.ObjectMeshes[0];
for (auto& bucket : mesh->Buckets)
{
ObjectInfo* obj = &Objects[gunshell->objectNumber];
RendererObject& moveableObj = *m_moveableObjects[gunshell->objectNumber];
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
continue;
Matrix translation = Matrix::CreateTranslation(gunshell->pos.Position.x, gunshell->pos.Position.y,
gunshell->pos.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(gunshell->pos.Orientation.y), TO_RAD(gunshell->pos.Orientation.x),
TO_RAD(gunshell->pos.Orientation.z));
Matrix world = rotation * translation;
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
m_stStatic.World = world;
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_DYNAMIC;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
BindConstantBufferPS(CB_STATIC, m_cbStatic.get());
RendererMesh* mesh = moveableObj.ObjectMeshes[0];
for (auto& bucket : mesh->Buckets)
{
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
continue;
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
m_numMoveablesDrawCalls++;
}
m_numMoveablesDrawCalls++;
}
}
}
@ -554,10 +545,7 @@ namespace TEN::Renderer
ObjectInfo* obj = &Objects[ID_RATS_EMITTER];
RendererObject& moveableObj = *m_moveableObjects[ID_RATS_EMITTER];
for (int m = 0; m < MAX_BONES; m++)
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
m_stStatic.LightMode = moveableObj.ObjectMeshes[0]->LightMode;
for (int i = 0; i < NUM_RATS; i++)
{
@ -571,10 +559,11 @@ namespace TEN::Renderer
TO_RAD(rat->Pose.Orientation.z));
Matrix world = rotation * translation;
m_stItem.World = world;
m_stItem.Position = Vector4(rat->Pose.Position.x, rat->Pose.Position.y, rat->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = m_rooms[rat->RoomNumber].AmbientLight;
m_cbItem.updateData(m_stItem, m_context.Get());
m_stStatic.World = world;
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = m_rooms[rat->RoomNumber].AmbientLight;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
for (int b = 0; b < mesh->Buckets.size(); b++)
{
@ -606,12 +595,9 @@ namespace TEN::Renderer
{
ObjectInfo* obj = &Objects[ID_BATS_EMITTER];
RendererObject& moveableObj = *m_moveableObjects[ID_BATS_EMITTER];
RendererMesh* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex + (-GlobalCounter & 3));
RendererMesh* mesh = GetMesh(Objects[ID_BATS_EMITTER].meshIndex - (GlobalCounter & 3));
for (int m = 0; m < MAX_BONES; m++)
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
m_stStatic.LightMode = moveableObj.ObjectMeshes[0]->LightMode;
for (int b = 0; b < mesh->Buckets.size(); b++)
{
@ -627,14 +613,15 @@ namespace TEN::Renderer
if (bat->On)
{
Matrix translation = Matrix::CreateTranslation(bat->Pose.Position.x, bat->Pose.Position.y, bat->Pose.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(
TO_RAD(bat->Pose.Orientation.y), TO_RAD(bat->Pose.Orientation.x), TO_RAD(bat->Pose.Orientation.z));
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(bat->Pose.Orientation.y), TO_RAD(bat->Pose.Orientation.x),
TO_RAD(bat->Pose.Orientation.z));
Matrix world = rotation * translation;
m_stItem.World = world;
m_stItem.Position = Vector4(bat->Pose.Position.x, bat->Pose.Position.y, bat->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = m_rooms[bat->RoomNumber].AmbientLight;
m_cbItem.updateData(m_stItem, m_context.Get());
m_stStatic.World = world;
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = m_rooms[bat->RoomNumber].AmbientLight;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
DrawIndexedTriangles(bucket->NumIndices, bucket->StartIndex, 0);
@ -660,10 +647,7 @@ namespace TEN::Renderer
ObjectInfo* obj = &Objects[ID_LITTLE_BEETLE];
RendererObject& moveableObj = *m_moveableObjects[ID_LITTLE_BEETLE];
for (int m = 0; m < MAX_BONES; m++)
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
m_stStatic.LightMode = moveableObj.ObjectMeshes[0]->LightMode;
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
{
@ -672,16 +656,16 @@ namespace TEN::Renderer
if (beetle->On)
{
RendererMesh* mesh = GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
Matrix translation =
Matrix::CreateTranslation(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z);
Matrix translation = Matrix::CreateTranslation(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(beetle->Pose.Orientation.y), TO_RAD(beetle->Pose.Orientation.x),
TO_RAD(beetle->Pose.Orientation.z));
Matrix world = rotation * translation;
m_stItem.World = world;
m_stItem.Position = Vector4(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z, 1.0f);
m_stItem.AmbientLight = m_rooms[beetle->RoomNumber].AmbientLight;
m_cbItem.updateData(m_stItem, m_context.Get());
m_stStatic.World = world;
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = m_rooms[beetle->RoomNumber].AmbientLight;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
for (int b = 0; b < mesh->Buckets.size(); b++)
{
@ -713,11 +697,8 @@ namespace TEN::Renderer
{
ObjectInfo* obj = &Objects[ID_LOCUSTS];
RendererObject& moveableObj = *m_moveableObjects[ID_LOCUSTS];
for (int m = 0; m < MAX_BONES; m++)
memcpy(&m_stItem.BonesMatrices[m], &Matrix::Identity, sizeof(Matrix));
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
m_stStatic.LightMode = moveableObj.ObjectMeshes[0]->LightMode;
for (int i = 0; i < TEN::Entities::TR4::MAX_LOCUSTS; i++)
{
@ -726,16 +707,16 @@ namespace TEN::Renderer
if (locust->on)
{
RendererMesh* mesh = GetMesh(Objects[ID_LOCUSTS].meshIndex + (-locust->counter & 3));
Matrix translation =
Matrix::CreateTranslation(locust->pos.Position.x, locust->pos.Position.y, locust->pos.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(locust->pos.Orientation.y, locust->pos.Orientation.x,
locust->pos.Orientation.z);
Matrix translation = Matrix::CreateTranslation(locust->pos.Position.x, locust->pos.Position.y, locust->pos.Position.z);
Matrix rotation = Matrix::CreateFromYawPitchRoll(TO_RAD(locust->pos.Orientation.y), TO_RAD(locust->pos.Orientation.x),
TO_RAD(locust->pos.Orientation.z));
Matrix world = rotation * translation;
m_stItem.World = world;
m_stItem.Position = Vector4(locust->pos.Position.x, locust->pos.Position.y, locust->pos.Position.z, 1.0f);
m_stItem.AmbientLight = m_rooms[locust->roomNumber].AmbientLight;
m_cbItem.updateData(m_stItem, m_context.Get());
m_stStatic.World = world;
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = m_rooms[locust->roomNumber].AmbientLight;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
for (int b = 0; b < mesh->Buckets.size(); b++)
{
@ -788,6 +769,9 @@ namespace TEN::Renderer
void Renderer11::AddLine3D(Vector3 start, Vector3 end, Vector4 color)
{
if (m_Locked)
return;
RendererLine3D line;
line.Start = start;
@ -799,6 +783,9 @@ namespace TEN::Renderer
void Renderer11::AddSphere(Vector3 center, float radius, Vector4 color)
{
if (m_Locked)
return;
constexpr auto subdivisions = 10;
constexpr auto steps = 6;
constexpr auto step = PI / steps;
@ -842,6 +829,9 @@ namespace TEN::Renderer
void Renderer11::AddBox(Vector3* corners, Vector4 color)
{
if (m_Locked)
return;
for (int i = 0; i < 12; i++)
{
RendererLine3D line;
@ -861,7 +851,6 @@ namespace TEN::Renderer
line.End = corners[0];
break;
case 4: line.Start = corners[4];
line.End = corners[5];
break;
@ -875,7 +864,6 @@ namespace TEN::Renderer
line.End = corners[4];
break;
case 8: line.Start = corners[0];
line.End = corners[4];
break;
@ -897,6 +885,9 @@ namespace TEN::Renderer
void Renderer11::AddBox(Vector3 min, Vector3 max, Vector4 color)
{
if (m_Locked)
return;
for (int i = 0; i < 12; i++)
{
RendererLine3D line;
@ -971,6 +962,9 @@ namespace TEN::Renderer
void Renderer11::AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b)
{
if (m_Locked)
return;
RendererLight dynamicLight = {};
if (falloff >= 8)
@ -986,6 +980,7 @@ namespace TEN::Renderer
dynamicLight.Color = Vector3(r / 255.0f, g / 255.0f, b / 255.0f) * 2.0f;
}
dynamicLight.RoomNumber = NO_ROOM;
dynamicLight.Intensity = 1.0f;
dynamicLight.Position = Vector3(float(x), float(y), float(z));
dynamicLight.Out = falloff * 256.0f;
@ -1006,6 +1001,7 @@ namespace TEN::Renderer
ClearFires();
ClearDynamicLights();
ClearSceneItems();
ClearShadowMap();
m_transparentFaces.clear();
@ -1271,7 +1267,7 @@ namespace TEN::Renderer
}
else
{
BindConstantBufferVS(CB_ANIMATED_TEXTURES, m_cbAnimated.get());;
BindConstantBufferVS(CB_ANIMATED_TEXTURES, m_cbAnimated.get());
m_context->VSSetShader(m_vsRooms_Anim.Get(), nullptr, 0);
}
@ -1288,6 +1284,7 @@ namespace TEN::Renderer
if (shadowLight != nullptr)
{
memcpy(&m_stShadowMap.Light, shadowLight, sizeof(ShaderLight));
m_stShadowMap.ShadowMapSize = g_Configuration.ShadowMapSize;
m_stShadowMap.CastShadows = true;
//m_stShadowMap.ViewProjectionInverse = ViewProjection.Invert();
}
@ -1322,6 +1319,9 @@ namespace TEN::Renderer
RendererAnimatedTextureSet& set = m_animatedTextureSets[info->texture];
m_stAnimated.NumFrames = set.NumTextures;
m_stAnimated.Type = 0;
m_stAnimated.Fps = set.Fps;
for (unsigned char i = 0; i < set.NumTextures; i++)
{
auto& tex = set.Textures[i];
@ -1388,9 +1388,9 @@ namespace TEN::Renderer
SAMPLER_NONE);
m_stStatic.World = info->world;
m_stStatic.Position = Vector4(info->position.x, info->position.y, info->position.z, 1.0f);
m_stStatic.Color = info->room->AmbientLight * info->color;
m_stStatic.LightMode = m_staticObjects[info->staticMesh->Id]->ObjectMeshes[0]->LightMode;
m_stStatic.Color = info->color;
m_stStatic.AmbientLight = info->room->AmbientLight;
m_stStatic.LightMode = m_staticObjects[info->staticMesh->ObjectNumber]->ObjectMeshes[0]->LightMode;
m_cbStatic.updateData(m_stStatic, m_context.Get());
BindConstantBufferVS(CB_STATIC, m_cbStatic.get());
@ -1426,6 +1426,7 @@ namespace TEN::Renderer
void Renderer11::RenderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view)
{
ResetDebugVariables();
m_Locked = false;
using ns = std::chrono::nanoseconds;
using get_time = std::chrono::steady_clock;
@ -1437,21 +1438,12 @@ namespace TEN::Renderer
CollectRooms(view, false);
UpdateLaraAnimations(false);
UpdateItemAnimations(view);
UpdateEffects(view);
m_stAlphaTest.AlphaTest = -1;
m_stAlphaTest.AlphaThreshold = -1;
m_stShadowMap.NumSpheres = 0;
// Setup Lara item
m_items[Lara.ItemNumber].ItemNumber = Lara.ItemNumber;
CalculateAmbientLight(&m_items[Lara.ItemNumber]);
CollectLightsForItem(LaraItem->RoomNumber, &m_items[Lara.ItemNumber], true);
// Prepare the shadow map
ClearShadowMap(view);
RenderShadowMap(view);
RenderBlobShadows(view);
CollectLightsForCamera();
RenderItemShadows(view);
auto time2 = std::chrono::high_resolution_clock::now();
m_timeUpdate = (std::chrono::duration_cast<ns>(time2 - time1)).count() / 1000000;
@ -1508,9 +1500,8 @@ namespace TEN::Renderer
// Draw rooms and objects
DrawRooms(view, false);
DrawStatics(view, false);
DrawLara(false, view, false);
DrawItems(view, false);
DrawStatics(view, false);
DrawEffects(view, false);
DrawGunShells(view);
DrawDebris(view, false);
@ -1550,10 +1541,10 @@ namespace TEN::Renderer
// Here we sort transparent faces and draw them with a simplified shaders for alpha blending
DrawRooms(view, true);
DrawStatics(view, true);
DrawLara(false, view, true);
DrawItems(view, true);
DrawStatics(view, true);
DrawEffects(view, true);
DrawDebris(view, true);
DrawGunFlashes(view);
DrawBaddyGunflashes(view);
@ -1574,7 +1565,6 @@ namespace TEN::Renderer
DrawDebugInfo(view);
DrawAllStrings();
DrawFadeAndBars(target, depthTarget, view);
ClearScene();
@ -1638,46 +1628,101 @@ namespace TEN::Renderer
{
for (auto itemToDraw : room->ItemsToDraw)
{
ItemInfo* nativeItem = &g_Level.Items[itemToDraw->ItemNumber];
RendererRoom& room = m_rooms[nativeItem->RoomNumber];
RendererObject& moveableObj = *m_moveableObjects[nativeItem->ObjectNumber];
if (moveableObj.DoNotDraw)
continue;
short objectNumber = nativeItem->ObjectNumber;
if (objectNumber >= ID_WATERFALL1 && objectNumber <= ID_WATERFALLSS2)
switch (itemToDraw->ObjectNumber)
{
// We'll draw waterfalls later
continue;
}
else if (objectNumber == ID_DARTS)
{
//TODO: for now legacy way, in the future mesh
case ID_LARA:
DrawLara(view, transparent);
break;
case ID_DARTS:
DrawDarts(itemToDraw, view);
}
else
{
break;
case ID_WATERFALL1:
case ID_WATERFALL2:
case ID_WATERFALL3:
case ID_WATERFALL4:
case ID_WATERFALL5:
case ID_WATERFALL6:
case ID_WATERFALLSS1:
case ID_WATERFALLSS2:
DrawWaterfalls(itemToDraw, view, 10, transparent);
continue;
default:
DrawAnimatingItem(itemToDraw, view, transparent);
break;
}
}
}
}
void Renderer11::RenderItemShadows(RenderView& renderView)
{
RenderBlobShadows(renderView);
if (g_Configuration.ShadowType != ShadowMode::None)
{
for (auto room : renderView.roomsToDraw)
for (auto itemToDraw : room->ItemsToDraw)
RenderShadowMap(itemToDraw, renderView);
}
}
void Renderer11::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, bool transparent)
{
// Extremely hacky function to get first rendered face of a waterfall object mesh, calculate
// its texture height and scroll all the textures according to that height.
RendererObject& moveableObj = *m_moveableObjects[item->ObjectNumber];
// No mesh or bucket, abort
if (!moveableObj.ObjectMeshes.size() || !moveableObj.ObjectMeshes[0]->Buckets.size())
return;
// Get first three vertices of a waterfall object, meaning the very first triangle
const auto& v1 = moveablesVertices[moveableObj.ObjectMeshes[0]->Buckets[0].StartVertex + 0];
const auto& v2 = moveablesVertices[moveableObj.ObjectMeshes[0]->Buckets[0].StartVertex + 1];
const auto& v3 = moveablesVertices[moveableObj.ObjectMeshes[0]->Buckets[0].StartVertex + 2];
// Calculate height of the texture by getting min/max UV.y coords of all three vertices
auto minY = std::min(std::min(v1.UV.y, v2.UV.y), v3.UV.y);
auto maxY = std::max(std::max(v1.UV.y, v2.UV.y), v3.UV.y);
auto minX = std::min(std::min(v1.UV.x, v2.UV.x), v3.UV.x);
auto maxX = std::max(std::max(v1.UV.x, v2.UV.x), v3.UV.x);
// Setup animated buffer
m_stAnimated.Fps = fps;
m_stAnimated.NumFrames = 1;
m_stAnimated.Type = 1; // UVRotate
// We need only top/bottom Y coordinate for UVRotate, but we pass whole
// rectangle anyway, in case later we may want to implement different UVRotate modes.
m_stAnimated.Textures[0].topLeft = Vector2(minX, minY);
m_stAnimated.Textures[0].topRight = Vector2(maxX, minY);
m_stAnimated.Textures[0].bottomLeft = Vector2(minX, maxY);
m_stAnimated.Textures[0].bottomRight = Vector2(maxX, maxY);
m_cbAnimated.updateData(m_stAnimated, m_context.Get());
BindConstantBufferPS(CB_ANIMATED_TEXTURES, m_cbAnimated.get());
DrawAnimatingItem(item, view, transparent);
// Reset animated buffer after rendering just in case
m_stAnimated.Fps = m_stAnimated.NumFrames = m_stAnimated.Type = 0;
m_cbAnimated.updateData(m_stAnimated, m_context.Get());
}
void Renderer11::DrawAnimatingItem(RendererItem* item, RenderView& view, bool transparent)
{
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
RendererRoom* room = &m_rooms[nativeItem->RoomNumber];
RendererObject& moveableObj = *m_moveableObjects[nativeItem->ObjectNumber];
ObjectInfo* obj = &Objects[nativeItem->ObjectNumber];
Vector3 itemPosition = Vector3(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z);
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
RendererRoom* room = &m_rooms[item->RoomNumber];
RendererObject& moveableObj = *m_moveableObjects[item->ObjectNumber];
ObjectInfo* obj = &Objects[item->ObjectNumber];
// Bind item main properties
m_stItem.World = item->World;
m_stItem.Position = Vector4(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z, 1.0f);
m_stItem.Color = item->Color;
m_stItem.AmbientLight = item->AmbientLight;
memcpy(m_stItem.BonesMatrices, item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
@ -1688,7 +1733,7 @@ namespace TEN::Renderer
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
// Bind lights touching that item
BindLights(item->LightsToDraw);
BindLights(item->LightsToDraw, item->RoomNumber, item->PrevRoomNumber, item->LightFade);
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
{
@ -1731,8 +1776,8 @@ namespace TEN::Renderer
m_context->PSSetShader(m_psItems.Get(), nullptr, 0);
m_stItem.World = info->item->World;
m_stItem.Position = Vector4(info->position.x, info->position.y, info->position.z, 1.0f);
m_stItem.AmbientLight = info->room->AmbientLight * info->color;
m_stItem.Color = info->color;
m_stItem.AmbientLight = info->item->AmbientLight;
memcpy(m_stItem.BonesMatrices, info->item->AnimationTransforms, sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
m_stItem.BoneLightModes[k] = moveableObj.ObjectMeshes[k]->LightMode;
@ -1741,7 +1786,7 @@ namespace TEN::Renderer
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
BindConstantBufferPS(CB_ITEM, m_cbItem.get());
BindLights(info->item->LightsToDraw);
BindLights(info->item->LightsToDraw, info->item->RoomNumber, info->item->PrevRoomNumber, info->item->LightFade);
// Set texture
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[info->bucket->Texture]),
@ -1795,6 +1840,11 @@ namespace TEN::Renderer
void Renderer11::DrawStatics(RenderView& view, bool transparent)
{
// Static mesh shader is used for all forthcoming renderer routines, so we
// must assign it before any early exits.
m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0);
m_context->PSSetShader(m_psStatics.Get(), nullptr, 0);
// If no static textures are loaded, don't draw anything.
if (m_staticsTextures.size() == 0)
return;
@ -1808,22 +1858,17 @@ namespace TEN::Renderer
m_context->IASetInputLayout(m_inputLayout.Get());
m_context->IASetIndexBuffer(m_staticsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
// Bind shaders
m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0);
m_context->PSSetShader(m_psStatics.Get(), nullptr, 0);
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
for (auto room : view.roomsToDraw)
{
for (auto& msh : room->StaticsToDraw)
{
RendererObject& staticObj = *m_staticObjects[msh.Id];
RendererObject& staticObj = *m_staticObjects[msh.ObjectNumber];
if (staticObj.ObjectMeshes.size() > 0)
{
RendererMesh* mesh = staticObj.ObjectMeshes[0];
auto pos = Vector3::Transform(Vector3::Zero, msh.World);
for (auto& bucket : mesh->Buckets)
{
@ -1857,8 +1902,8 @@ namespace TEN::Renderer
face.info.room = room;
face.info.staticMesh = &msh;
face.info.world = m_stStatic.World;
face.info.position = Vector3(pos.x, pos.y, pos.z);
face.info.color = Vector4(msh.AmbientLight.x, msh.AmbientLight.y, msh.AmbientLight.z, msh.AmbientLight.w);
face.info.position = msh.Position;
face.info.color = msh.Color;
face.info.blendMode = bucket.BlendMode;
face.info.bucket = &bucket;
room->TransparentFacesToDraw.push_back(face);
@ -1867,8 +1912,8 @@ namespace TEN::Renderer
else
{
m_stStatic.World = msh.World;
m_stStatic.Position = Vector4(pos.x, pos.y, pos.z, 1);
m_stStatic.Color = msh.AmbientLight;
m_stStatic.Color = msh.Color;
m_stStatic.AmbientLight = room->AmbientLight;
m_stStatic.LightMode = mesh->LightMode;
m_cbStatic.updateData(m_stStatic, m_context.Get());
@ -1937,6 +1982,7 @@ namespace TEN::Renderer
if (shadowLight != nullptr)
{
memcpy(&m_stShadowMap.Light, shadowLight, sizeof(ShaderLight));
m_stShadowMap.ShadowMapSize = g_Configuration.ShadowMapSize;
m_stShadowMap.CastShadows = true;
BindTexture(TEXTURE_SHADOW_MAP, &m_shadowMap, SAMPLER_SHADOW_MAP);
@ -2060,6 +2106,7 @@ namespace TEN::Renderer
RendererAnimatedTextureSet& set = m_animatedTextureSets[bucket.Texture];
m_stAnimated.NumFrames = set.NumTextures;
m_stAnimated.Type = 0;
m_stAnimated.Fps = set.Fps;
for (unsigned char j = 0; j < set.NumTextures; j++)
@ -2171,8 +2218,6 @@ namespace TEN::Renderer
m_context->VSSetShader(m_vsSky.Get(), nullptr, 0);
m_context->PSSetShader(m_psSky.Get(), nullptr, 0);
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
BindTexture(TEXTURE_COLOR_MAP, &m_skyTexture, SAMPLER_ANISOTROPIC_CLAMP);
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
@ -2190,6 +2235,7 @@ namespace TEN::Renderer
m_stStatic.World = (rotation * translation);
m_stStatic.Color = weather.SkyColor();
m_stStatic.AmbientLight = Vector4::One;
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC;
m_cbStatic.updateData(m_stStatic, m_context.Get());
@ -2213,8 +2259,8 @@ namespace TEN::Renderer
RendererObject& moveableObj = *m_moveableObjects[ID_HORIZON];
m_stStatic.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
m_stStatic.Position = Vector4::Zero;
m_stStatic.Color = Vector4::One;
m_stStatic.AmbientLight = Vector4::One;
m_stStatic.LightMode = LIGHT_MODES::LIGHT_MODE_STATIC;
m_cbStatic.updateData(m_stStatic, m_context.Get());
@ -2236,6 +2282,7 @@ namespace TEN::Renderer
SAMPLER_NONE);
SetBlendMode(bucket.BlendMode);
SetAlphaTest(bucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE, ALPHA_TEST_THRESHOLD);
// Draw vertices
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
@ -2293,7 +2340,7 @@ namespace TEN::Renderer
face.info.texture = bucket.Texture;
face.info.room = room;
face.info.item = itemToDraw;
face.info.color = itemToDraw->AmbientLight;
face.info.color = itemToDraw->Color;
face.info.blendMode = bucket.BlendMode;
face.info.bucket = &bucket;
room->TransparentFacesToDraw.push_back(face);

View file

@ -302,7 +302,7 @@ namespace TEN::Renderer
m_stPostProcessBuffer.ViewportWidth = m_screenWidth;
m_stPostProcessBuffer.ViewportHeight = m_screenHeight;
m_stPostProcessBuffer.ScreenFadeFactor = ScreenFadeCurrent;
m_stPostProcessBuffer.CinematicBarsHeight = CinematicBarsHeight;
m_stPostProcessBuffer.CinematicBarsHeight = Smoothstep(CinematicBarsHeight) * SPOTCAM_CINEMATIC_BARS_HEIGHT;
m_cbPostProcessBuffer.updateData(m_stPostProcessBuffer, m_context.Get());
BindConstantBufferPS(CB_POSTPROCESS, m_cbPostProcessBuffer.get());

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