Merge branch 'master' into states_tier_3

This commit is contained in:
Sezz 2022-08-15 15:41:10 +10:00
commit bb33101480
128 changed files with 2029 additions and 2604 deletions

View file

@ -2,18 +2,26 @@ Version 1.0.1
=============
- Added antialiasing support.
- Fixed some issues with shimmying between diagonal ledges and walls.
- Fixed rope transparency.
- Fixed objects disappearing under certain angles at the edges of the screen.
- Fixed incorrect polerope grabbing.
- Fixed camera behaviour with pushable blocks.
- Fixed minecart unduck on inclines.
- Fixed quadbike dismount with jump key and allow to shoot big gun with action key.
- Fixed rollingball incorrectly killing Lara in water and in jump.
- Fixed resurfacing on underwater death.
- Fixed ripples not appearing on water connections higher than room bottom.
- Fix some issues with shimmying between diagonal ledges and walls.
- Fix rope transparency.
- Fix objects disappearing under certain angles at the edges of the screen.
- Fix incorrect polerope and jumpswitch grabbing.
- Fix camera behaviour with pushable blocks.
- Fix minecart unduck on inclines.
- Fix quadbike dismount with jump key and allow to shoot big gun with action key.
- Fix static meshes having wrong colors on savegame reload.
- Fix rollingball incorrectly killing Lara in water and in jump.
- Fix resurfacing on underwater death.
- Fix ripples not appearing on water connections higher than room bottom.
- Fix several problems with ropes (stumbling, rope length, etc).
- Fix several problems with teeth spikes.
- Fix crashes when loading image files are missing.
- Disable trigger check for puzzle holes.
- Clear locusts and other swarm enemies on level reload.
- Prevent title music audio from starting in a random place.
- Update harpoon speed on room change.
- Enable second sky layer rendering.
- Preserve inventory and flare on level jumps.
- Timer.Create now lets you choose the units to display remaining time.
- Fatal script errors now boot you to the title (it will crash if the title itself has these errors).
- SetFarView has been removed, and Flow.Level.farView is now uncapped.

View file

@ -16,7 +16,9 @@ local version = "1.0.1"
project = "TombEngine"
title = "TombEngine " .. version .. " Lua API"
description = "TombEngine " .. version .. " scripting interface"
full_description = [[Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse. At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on the wiki at https://github.com/MontyTRC89/TombEngine/wiki.
full_description = [[Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse.
At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on the wiki <a href="https://github.com/Stranger1992/Tomb-Engine-Demo-Levels/wiki">here</a>.
####Module Hierarchy (boring but important)
Other than the "special tables" (GameVars, LevelVars and LevelFuncs), every module described herein is held in a master table called TEN.
For example, to call GetMoveableByName, you would have to do:

View file

@ -0,0 +1,340 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<head>
<title>TombEngine 1.0.1 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>EventSequence</strong></li>
<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>
<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>EventSequence</code></h1>
<p>Event sequence - a chain of functions to call at specified times, modeled after TRNG's organizers.</p>
<p>
<p> Example usage:</p>
<pre>
<span class="keyword">local</span> EventSequence = <span class="global">require</span>(<span class="string">"EventSequence"</span>)
<span class="comment">-- These will be called by the sequence
</span>LevelFuncs.HealLara = <span class="keyword">function</span>()
Lara:SetHP(Lara:GetHP()+<span class="number">10</span>)
<span class="keyword">end</span>
<span class="keyword">local</span> nSpawned = <span class="number">0</span>
LevelFuncs.SpawnBaddy = <span class="keyword">function</span>(baddy, name, pos)
<span class="keyword">local</span> myBaddy = TEN.Objects.Moveable(baddy, name..nSpawned, pos, <span class="keyword">nil</span>, <span class="number">0</span>)
myBaddy:Enable()
nSpawned = nSpawned + <span class="number">1</span>
<span class="keyword">end</span>
<span class="comment">-- This function triggers the sequence
</span>LevelFuncs.TriggerSequence = <span class="keyword">function</span>(obj)
<span class="keyword">local</span> posSteve = TEN.Objects.GetMoveableByName(<span class="string">"stevePosNullmesh"</span>):GetPosition()
<span class="keyword">local</span> posChris = TEN.Objects.GetMoveableByName(<span class="string">"chrisPosNullmesh"</span>):GetPosition()
<span class="keyword">local</span> mySeq = EventSequence.Create(<span class="string">"my_seq"</span>,
<span class="keyword">false</span>, <span class="comment">-- does not loop
</span> {seconds = <span class="keyword">true</span>, deciseconds = <span class="keyword">true</span>}, <span class="comment">-- timer format, see Timer for details
</span> <span class="number">6</span>, <span class="comment">-- seconds until call the function specified in next arg
</span> <span class="string">"HealLara"</span>, <span class="comment">-- first function to call. If we don't need to pass any arguments, we can just give the func name as a string
</span> <span class="number">2.1</span>, <span class="comment">-- seconds until the next function, after the previous one has been called
</span> {<span class="string">"SpawnBaddy"</span>, TEN.Objects.ObjID.BADDY1, <span class="string">"steve"</span>, posSteve}, <span class="comment">-- if we DO want to pass arguments to the function to be called, we give a table with the name of the function ("SpawnBaddy" in this case) followed by the args to pass to it
</span> <span class="number">0.5</span>,
{<span class="string">"SpawnBaddy"</span>, TEN.Objects.ObjID.SAS_CAIRO, <span class="string">"chris"</span>, posChris},
<span class="number">1</span>,
<span class="string">"HealLara"</span>)
<span class="comment">-- event sequences are inactive to begin with and so need to be started
</span> mySeq:Start()
<span class="keyword">end</span>
<span class="comment">-- EventSequence runs on Timer, so this call is required
</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, loop, timerFormat[, ...])</a></td>
<td class="summary">Create (but do not start) a new event sequence.</td>
</tr>
<tr>
<td class="name" ><a href="#Get">Get(name)</a></td>
<td class="summary">Get an event sequence by its name.</td>
</tr>
<tr>
<td class="name" ><a href="#mySequence:SetPaused">mySequence:SetPaused(p)</a></td>
<td class="summary">Pause or unpause the sequence.</td>
</tr>
<tr>
<td class="name" ><a href="#mySequence:IsPaused">mySequence:IsPaused()</a></td>
<td class="summary">Get whether or not the sequence is paused</td>
</tr>
<tr>
<td class="name" ><a href="#mySequence:Start">mySequence:Start()</a></td>
<td class="summary">Begin or unpause a sequence.</td>
</tr>
<tr>
<td class="name" ><a href="#mySequence:Stop">mySequence:Stop()</a></td>
<td class="summary">Stop the sequence.</td>
</tr>
<tr>
<td class="name" ><a href="#mySequence:IsActive">mySequence:IsActive()</a></td>
<td class="summary">Get whether or not the sequence is active</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, loop, timerFormat[, ...])</strong>
</dt>
<dd>
Create (but do not start) a new event sequence.
<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 the sequence; used to retrieve the timer later as well as internally by TEN.
</li>
<li><span class="parameter">loop</span>
<span class="types"><span class="type">bool</span></span>
if true, the sequence will start again from its first timer once its final function has been called
</li>
<li><span class="parameter">timerFormat</span>
<span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> or <span class="type">bool</span></span>
same as in Timer. This is mainly for debugging. <strong>This will not work properly if another sequence or timer is showing a countdown.</strong>
</li>
<li><span class="parameter">...</span>
a variable number of pairs of arguments - a time in seconds, followed by the function (must be defined in the LevelFuncs table) to call once the time has elapsed, followed by another duration in seconds, another function name, etc. You can specify a function either by its name as a string, or by a table with the function name as the first member, followed by its arguments (see above example).
(<em>optional</em>)
</li>
</ul>
<h3>Returns:</h3>
<ol>
The inactive sequence.
</ol>
</dd>
<dt>
<a name = "Get"></a>
<strong>Get(name)</strong>
</dt>
<dd>
Get an event sequence 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 sequence when it was created
</li>
</ul>
<h3>Returns:</h3>
<ol>
The sequence
</ol>
</dd>
<dt>
<a name = "mySequence:SetPaused"></a>
<strong>mySequence:SetPaused(p)</strong>
</dt>
<dd>
Pause or unpause the sequence. If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused).
<h3>Parameters:</h3>
<ul>
<li><span class="parameter">p</span>
<span class="types"><span class="type">bool</span></span>
if true, the sequence will be paused; if false, it will be unpaused
</li>
</ul>
</dd>
<dt>
<a name = "mySequence:IsPaused"></a>
<strong>mySequence:IsPaused()</strong>
</dt>
<dd>
Get whether or not the sequence is paused
<h3>Returns:</h3>
<ol>
true if the timer is paused, false if otherwise
</ol>
</dd>
<dt>
<a name = "mySequence:Start"></a>
<strong>mySequence:Start()</strong>
</dt>
<dd>
Begin or unpause a sequence. If showing the remaining time on-screen, its color will be set to white.
</dd>
<dt>
<a name = "mySequence:Stop"></a>
<strong>mySequence:Stop()</strong>
</dt>
<dd>
Stop the sequence.
</dd>
<dt>
<a name = "mySequence:IsActive"></a>
<strong>mySequence:IsActive()</strong>
</dt>
<dd>
Get whether or not the sequence is active
<h3>Returns:</h3>
<ol>
true if the sequence is active, false if otherwise
</ol>
</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-11 22:43:52 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>

View file

@ -81,7 +81,9 @@
<h2>TombEngine 1.0.1 scripting interface</h2>
<p>Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse. At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on the wiki at https://github.com/MontyTRC89/TombEngine/wiki.</p>
<p>Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse.</p>
<p>At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on the wiki <a href="https://github.com/Stranger1992/Tomb-Engine-Demo-Levels/wiki">here</a>.</p>
<h4>Module Hierarchy (boring but important)</h4>
<p>Other than the "special tables" (GameVars, LevelVars and LevelFuncs), every module described herein is held in a master table called TEN.
For example, to call GetMoveableByName, you would have to do:</p>
@ -246,7 +248,7 @@ Util.ShortenTENCalls()
</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-11 22:43:52 </i>
<i style="float:right;">Last updated 2022-08-14 20:33:42 </i>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>

View file

@ -506,22 +506,22 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (item->Animation.ActiveState == LS_SWAN_DIVE)
{
SetAnimation(item, LA_SWANDIVE_DIVE);
item->Animation.Velocity.y /= 2.0f;
item->Pose.Orientation.x = -ANGLE(45.0f);
item->Animation.VerticalVelocity *= 2;
lara->Control.HandStatus = HandStatus::Free;
}
else if (item->Animation.ActiveState == LS_FREEFALL_DIVE)
{
SetAnimation(item, LA_SWANDIVE_DIVE);
item->Animation.Velocity.y /= 2.0f;
item->Pose.Orientation.x = -ANGLE(85.0f);
item->Animation.VerticalVelocity *= 2;
lara->Control.HandStatus = HandStatus::Free;
}
else
{
SetAnimation(item, LA_FREEFALL_DIVE);
item->Animation.Velocity.y = (item->Animation.Velocity.y / 8.0f) * 3.0f;
item->Pose.Orientation.x = -ANGLE(45.0f);
item->Animation.VerticalVelocity = item->Animation.VerticalVelocity / 2 * 3;
}
ResetLaraFlex(item);
@ -582,8 +582,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
ResetLaraLean(item);
ResetLaraFlex(item);
item->Animation.IsAirborne = true;
item->Animation.Velocity = item->Animation.VerticalVelocity / 4;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = item->Animation.Velocity.y;
item->Animation.Velocity.y = 0.0f;
lara->Control.WaterStatus = WaterStatus::Dry;
}
else
@ -591,8 +591,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_UNDERWATER_RESURFACE);
//ResetLaraLean(item);
ResetLaraFlex(item);
item->Animation.Velocity.y = 0.0f;
item->Pose.Position.y = waterHeight;
item->Animation.VerticalVelocity = 0;
lara->Control.WaterStatus = WaterStatus::TreadWater;
UpdateItemRoom(item, -(STEPUP_HEIGHT - 3));
@ -606,8 +606,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
//ResetLaraLean(item);
item->Pose.Orientation.x -= ANGLE(90.0f);
ResetLaraFlex(item);
item->Animation.Velocity.y = 0.0f;
item->Pose.Position.y = waterHeight + 1;
item->Animation.VerticalVelocity = 0;
lara->Control.WaterStatus = WaterStatus::TreadWater;
UpdateItemRoom(item, 0);
@ -623,7 +623,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
{
SetAnimation(item, LA_FALL_START);
item->Animation.IsAirborne = true;
item->Animation.Velocity = item->Animation.VerticalVelocity / 4;
item->Animation.Velocity.z = item->Animation.Velocity.y;
lara->Control.WaterStatus = WaterStatus::Dry;
}
else
@ -634,7 +634,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
ResetLaraLean(item);
ResetLaraFlex(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0.0f;
}
ResetLaraLean(item, 6.0f);
@ -650,9 +650,9 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_ONWATER_IDLE);
ResetLaraLean(item);
ResetLaraFlex(item);
item->Pose.Position.y += 1 - heightFromWater;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0.0f;
item->Pose.Position.y += 1 - heightFromWater;
lara->Control.WaterStatus = WaterStatus::TreadWater;
UpdateItemRoom(item, 0);
@ -818,14 +818,13 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
}
lara->ExtraVelocity = Vector3Int();
// Handle Lara collision.
if (lara->Vehicle == NO_ITEM)
lara_collision_routines[item->Animation.ActiveState](item, coll);
}
dbU = KeyMap[OIS::KeyCode::KC_U] ? true : false;
// Handle weapons.
LaraGun(item);
@ -894,15 +893,13 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
LaraWaterCurrent(item, coll);
AnimateLara(item);
TranslateItem(item, lara->Control.MoveAngle, item->Animation.VerticalVelocity / 4);
TranslateItem(item, lara->Control.MoveAngle, item->Animation.Velocity.y);
DoObjectCollision(item, coll);
if (lara->Vehicle == NO_ITEM)
lara_collision_routines[item->Animation.ActiveState](item, coll);
lara->ExtraVelocity = Vector3Int();
UpdateItemRoom(item, LARA_RADIUS);
LaraGun(item);
@ -987,15 +984,13 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
LaraWaterCurrent(item, coll);
AnimateLara(item);
TranslateItem(item, item->Pose.Orientation, item->Animation.VerticalVelocity / 4);
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.y);
DoObjectCollision(item, coll);
if (/*lara->ExtraAnim == -1 &&*/ lara->Vehicle == NO_ITEM)
lara_collision_routines[item->Animation.ActiveState](item, coll);
lara->ExtraVelocity = Vector3Int();
UpdateItemRoom(item, 0);
LaraGun(item);
@ -1029,7 +1024,7 @@ void LaraCheat(ItemInfo* item, CollisionInfo* coll)
lara->Control.WaterStatus = WaterStatus::Dry;
}
LaraInitialiseMeshes(item);
InitialiseLaraMeshes(item);
item->HitPoints = LARA_HEALTH_MAX;
lara->Control.HandStatus = HandStatus::Free;
}

View file

@ -2,11 +2,11 @@
#include "Game/control/control.h"
#include "Game/Lara/lara_struct.h"
struct ItemInfo;
struct CollisionInfo;
struct ItemInfo;
#define LARA_GRAB_THRESHOLD ANGLE(40.0f)
#define FRONT_ARC ANGLE(90.0f) // TODO: Check use.
#define FRONT_ARC ANGLE(90.0f) // TODO: Check use.
// Lean rates
#define LARA_LEAN_RATE ANGLE(1.5f)
@ -54,32 +54,31 @@ constexpr int LARA_RADIUS = 100;
constexpr int LARA_RADIUS_CRAWL = 200;
constexpr int LARA_RADIUS_UNDERWATER = 300;
constexpr int LARA_RADIUS_DEATH = 400;
constexpr int LARA_VELOCITY = 12;
constexpr int LARA_VELOCITY = 12; // TODO: Float.
// TODO: Convert velocities to floats and eliminate the format conversion that goes on with these values. @Sezz
constexpr int LARA_SWIM_VELOCITY_ACCEL = 2 * 4;
constexpr int LARA_SWIM_VELOCITY_DECEL = 1.5f * 4;
constexpr int LARA_TREAD_VELOCITY_MAX = 17.5f * 4;
constexpr int LARA_SWIM_VELOCITY_MAX = 50 * 4;
constexpr int LARA_SWIM_INTERTIA_VELOCITY_MIN = 33.5f * 4;
constexpr auto LARA_FREEFALL_VELOCITY = 131.0f;
constexpr auto LARA_DAMAGE_VELOCITY = 141.0f;
constexpr auto LARA_DEATH_VELOCITY = 155.0f;
constexpr auto LARA_DIVE_DEATH_VELOCITY = 134.0f;
constexpr auto LARA_TERMINAL_VELOCITY = CLICK(10);
constexpr int LARA_FREEFALL_VELOCITY = 131;
constexpr int LARA_DAMAGE_VELOCITY = 141;
constexpr int LARA_DEATH_VELOCITY = 155;
constexpr int LARA_DIVE_DEATH_VELOCITY = 134;
constexpr int LARA_TERMINAL_VELOCITY = CLICK(10);
constexpr auto LARA_SWIM_VELOCITY_ACCEL = 2.0f;
constexpr auto LARA_SWIM_VELOCITY_DECEL = 1.5f;
constexpr auto LARA_TREAD_VELOCITY_MAX = 17.5f;
constexpr auto LARA_SWIM_VELOCITY_MAX = 50.0f;
constexpr auto LARA_SWIM_INTERTIA_VELOCITY_MIN = 33.5f;
constexpr auto LARA_POSITION_ADJUST_MAX_TIME = FPS * 3; // 30 frames * 3 = 3 seconds allowed for position adjustment.
constexpr auto LARA_POSE_TIME = FPS * 30; // 30 frames * 30 = 30 seconds to AFK pose.
constexpr auto LARA_RUN_JUMP_TIME = 22; // Frames to count before a running jump is possible.
constexpr auto LARA_SPRINT_JUMP_TIME = 50; // Frames to count before a sprint jump is possible.
constexpr float LARA_HEALTH_MAX = 1000.0f;
constexpr float LARA_HEALTH_CRITICAL = LARA_HEALTH_MAX / 4.0f;
constexpr float LARA_AIR_MAX = 1800.0f;
constexpr float LARA_AIR_CRITICAL = LARA_AIR_MAX / 4.0f;
constexpr float LARA_SPRINT_ENERGY_MAX = 120.0f;
constexpr float LARA_POISON_POTENCY_MAX = 64.0f;
constexpr auto LARA_HEALTH_MAX = 1000.0f;
constexpr auto LARA_HEALTH_CRITICAL = LARA_HEALTH_MAX / 4.0f;
constexpr auto LARA_AIR_MAX = 1800.0f;
constexpr auto LARA_AIR_CRITICAL = LARA_AIR_MAX / 4.0f;
constexpr auto LARA_SPRINT_ENERGY_MAX = 120.0f;
constexpr auto LARA_POISON_POTENCY_MAX = 64.0f;
extern LaraInfo Lara;
extern ItemInfo* LaraItem;

View file

@ -180,7 +180,7 @@ void lara_col_walk_forward(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -311,7 +311,7 @@ void lara_col_run_forward(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -597,8 +597,8 @@ void lara_col_idle(ItemInfo* item, CollisionInfo* coll)
bool isSwamp = TestEnvironment(ENV_FLAG_SWAMP, item);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
lara->Control.MoveAngle = (item->Animation.Velocity >= 0) ? item->Pose.Orientation.y : (item->Pose.Orientation.y + ANGLE(180.0f));
item->Animation.Velocity.y = 0;
lara->Control.MoveAngle = (item->Animation.Velocity.z >= 0) ? item->Pose.Orientation.y : (item->Pose.Orientation.y + ANGLE(180.0f));
coll->Setup.LowerFloorBound = isSwamp ? NO_LOWER_BOUND : STEPUP_HEIGHT;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -700,7 +700,7 @@ void lara_col_run_back(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
coll->Setup.BlockFloorSlopeDown = true;
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
@ -1068,7 +1068,7 @@ void lara_col_walk_back(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = (lara->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : STEPUP_HEIGHT;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -1268,7 +1268,7 @@ void lara_col_step_right(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(90.0f);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = (lara->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : CLICK(0.8f);
coll->Setup.UpperFloorBound = -CLICK(0.8f);
coll->Setup.LowerCeilingBound = 0;
@ -1359,7 +1359,7 @@ void lara_col_step_left(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y - ANGLE(90.0f);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = (lara->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : CLICK(0.8f);
coll->Setup.UpperFloorBound = -CLICK(0.8f);
coll->Setup.LowerCeilingBound = 0;
@ -1431,7 +1431,7 @@ void lara_col_roll_back(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -1501,7 +1501,7 @@ void lara_col_roll_forward(ItemInfo* item, CollisionInfo* coll)
lara->Control.MoveAngle = item->Pose.Orientation.y;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = 0;
@ -1803,7 +1803,7 @@ void lara_col_sprint_dive(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
lara->Control.MoveAngle = (item->Animation.Velocity >= 0) ? item->Pose.Orientation.y : item->Pose.Orientation.y + ANGLE(180.0f);
lara->Control.MoveAngle = (item->Animation.Velocity.z >= 0) ? item->Pose.Orientation.y : item->Pose.Orientation.y + ANGLE(180.0f);
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = BAD_JUMP_CEILING;
@ -1819,7 +1819,7 @@ void lara_col_sprint_dive(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.Velocity < 0)
if (item->Animation.Velocity.z < 0)
lara->Control.MoveAngle = item->Pose.Orientation.y; // ???
ShiftItem(item, coll);

View file

@ -37,16 +37,16 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_JUMP)
{
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL * 2;
if (item->Animation.VerticalVelocity > LARA_SWIM_VELOCITY_MAX * 2)
item->Animation.VerticalVelocity = LARA_SWIM_VELOCITY_MAX * 2;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL * 2;
if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX * 2)
item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX * 2;
}
else
{
if (item->Animation.VerticalVelocity >= LARA_SWIM_VELOCITY_ACCEL)
item->Animation.VerticalVelocity -= item->Animation.VerticalVelocity / 8;
if (item->Animation.Velocity.y >= LARA_SWIM_VELOCITY_ACCEL)
item->Animation.Velocity.y -= item->Animation.Velocity.y / 8;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
@ -68,7 +68,7 @@ void LaraCheatyBits(ItemInfo* item)
if (lara->Control.WaterStatus != WaterStatus::FlyCheat)
{
SetAnimation(item, LA_DOZY);
item->Animation.VerticalVelocity = 30;
item->Animation.Velocity.y = 30;
item->Animation.IsAirborne = false;
item->Pose.Orientation.x = ANGLE(30.0f);
item->HitPoints = LARA_HEALTH_MAX;

View file

@ -990,7 +990,7 @@ bool LaraCheckForLetGo(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
if (TrInput & IN_ACTION && item->HitPoints > 0 || item->Animation.AnimNumber == LA_ONWATER_TO_LADDER) // Can't let go on this anim
@ -1000,8 +1000,8 @@ bool LaraCheckForLetGo(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_FALL_START);
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.z = 2;
item->Animation.Velocity.y = 1;
item->Animation.IsAirborne = true;
lara->Control.HandStatus = HandStatus::Free;
return true;

View file

@ -32,7 +32,7 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
{
ShiftItem(item, coll);
item->Animation.TargetState = LS_IDLE;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
return true;
}
@ -65,25 +65,25 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT)
{
if (!lara->Control.CanClimbLadder || item->Animation.Velocity != 2)
if (!lara->Control.CanClimbLadder || item->Animation.Velocity.z != 2)
{
if (coll->Middle.Floor <= CLICK(1))
{
SetAnimation(item, LA_LAND);
LaraSnapToHeight(item, coll);
}
else if (abs(item->Animation.Velocity) > 47)
else if (abs(item->Animation.Velocity.z) > 47)
{
// TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
Rumble(0.5f, 0.15f);
}
item->Animation.Velocity /= 4;
item->Animation.Velocity.z /= 4;
lara->Control.MoveAngle += ANGLE(180.0f);
if (item->Animation.VerticalVelocity <= 0)
item->Animation.VerticalVelocity = 1;
if (item->Animation.Velocity.y <= 0)
item->Animation.Velocity.y = 1;
}
return true;
@ -101,18 +101,18 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
case CT_TOP:
case CT_TOP_FRONT:
if (item->Animation.VerticalVelocity <= 0)
item->Animation.VerticalVelocity = 1;
if (item->Animation.Velocity.y <= 0)
item->Animation.Velocity.y = 1;
break;
case CT_CLAMP:
TranslateItem(item, item->Pose.Orientation.y + ANGLE(180.0f), CLICK(1.5f), 0, 0);
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
coll->Middle.Floor = 0;
if (item->Animation.VerticalVelocity <= 0)
item->Animation.VerticalVelocity = 16;
if (item->Animation.Velocity.y <= 0)
item->Animation.Velocity.y = 16;
break;
}
@ -135,23 +135,23 @@ void LaraSlideEdgeJump(ItemInfo* item, CollisionInfo* coll)
break;
case CT_FRONT:
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
break;
case CT_TOP:
case CT_TOP_FRONT:
if (item->Animation.VerticalVelocity <= 0)
item->Animation.VerticalVelocity = 1;
if (item->Animation.Velocity.y <= 0)
item->Animation.Velocity.y = 1;
break;
case CT_CLAMP:
TranslateItem(item, item->Pose.Orientation.y + ANGLE(180.0f), CLICK(1.5f), 0, 0);
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
coll->Middle.Floor = 0;
if (item->Animation.VerticalVelocity <= 0)
item->Animation.VerticalVelocity = 16;
if (item->Animation.Velocity.y <= 0)
item->Animation.Velocity.y = 16;
break;
}
@ -164,7 +164,7 @@ bool LaraDeflectEdgeCrawl(ItemInfo* item, CollisionInfo* coll)
{
ShiftItem(item, coll);
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.IsAirborne = false;
return true;
}
@ -201,7 +201,7 @@ bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll)
ShiftItem(item, coll);
item->Animation.TargetState = LS_MONKEY_IDLE;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.IsAirborne = false;
return true;
}
@ -406,7 +406,7 @@ void LaraResetGravityStatus(ItemInfo* item, CollisionInfo* coll)
if (coll->Middle.Floor <= STEPUP_HEIGHT)
{
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
@ -458,7 +458,7 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
if (coll->CollisionType & (CT_FRONT | CT_TOP | CT_TOP_FRONT | CT_CLAMP) ||
coll->Middle.Floor < 0 && coll->Middle.FloorSlope)
{
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Pose.Position = coll->Setup.OldPosition;
}
else if (coll->CollisionType == CT_LEFT)
@ -531,7 +531,7 @@ void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
item->Pose.Orientation.x -= 45;
else
{
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
flag = 1;
}
}
@ -568,7 +568,7 @@ void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
break;
case CT_TOP_FRONT:
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
flag = 1;
break;
@ -584,7 +584,7 @@ void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
case CT_CLAMP:
item->Pose.Position = coll->Setup.OldPosition;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
flag = 2;
break;
}
@ -665,12 +665,12 @@ void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll)
else if (item->Pose.Orientation.x < -ANGLE(35.0f))
item->Pose.Orientation.x -= ANGLE(1.0f);
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
else if (coll->CollisionType == CT_TOP)
item->Pose.Orientation.x -= ANGLE(1.0f);
else if (coll->CollisionType == CT_TOP_FRONT)
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
else if (coll->CollisionType == CT_LEFT)
item->Pose.Orientation.y += ANGLE(5.0f);
else if (coll->CollisionType == CT_RIGHT)
@ -697,8 +697,8 @@ bool TestLaraHitCeiling(CollisionInfo* coll)
void SetLaraHitCeiling(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
item->Pose.Position = coll->Setup.OldPosition;
}

View file

@ -108,7 +108,7 @@ void lara_col_crouch_idle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
lara->Control.KeepLow = TestLaraKeepLow(item, coll);
lara->Control.IsLow = true;
@ -171,7 +171,7 @@ void lara_col_crouch_roll(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
lara->Control.KeepLow = TestLaraKeepLow(item, coll);
lara->Control.IsLow = true;
@ -193,7 +193,7 @@ void lara_col_crouch_roll(ItemInfo* item, CollisionInfo* coll)
{
SetLaraFallAnimation(item);
lara->Control.HandStatus = HandStatus::Free;
item->Animation.Velocity /= 3; // Truncate speed to prevent flying off.
item->Animation.Velocity.z /= 3; // Truncate speed to prevent flying off.
return;
}
@ -471,7 +471,7 @@ void lara_col_crawl_idle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
lara->Control.KeepLow = TestLaraKeepLow(item, coll);
lara->Control.IsLow = true;
@ -560,7 +560,7 @@ void lara_col_crawl_forward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
lara->Control.KeepLow = TestLaraKeepLow(item, coll);
lara->Control.IsLow = true;
@ -648,7 +648,7 @@ void lara_col_crawl_back(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
lara->Control.KeepLow = TestLaraKeepLow(item, coll);
lara->Control.IsLow = true;
@ -858,8 +858,8 @@ void lara_col_crawl_to_hang(ItemInfo* item, CollisionInfo* coll)
GetCollisionInfo(coll, item);
item->Animation.IsAirborne = true;
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.z = 2;
item->Animation.Velocity.y = 1;
item->Pose.Position.y += coll->Front.Floor - GetBoundsAccurate(item)->Y1 - 20;
lara->Control.HandStatus = HandStatus::Busy;
}

View file

@ -30,7 +30,7 @@ void FlareControl(short itemNumber)
return;
}
if (flareItem->Animation.VerticalVelocity)
if (flareItem->Animation.Velocity.y)
{
flareItem->Pose.Orientation.x -= ANGLE(5.0f);
flareItem->Pose.Orientation.z += ANGLE(5.0f);
@ -42,9 +42,9 @@ void FlareControl(short itemNumber)
}
auto velocity = Vector3Int(
flareItem->Animation.Velocity * phd_sin(flareItem->Pose.Orientation.y),
flareItem->Animation.VerticalVelocity,
flareItem->Animation.Velocity * phd_cos(flareItem->Pose.Orientation.y)
flareItem->Animation.Velocity.z * phd_sin(flareItem->Pose.Orientation.y),
flareItem->Animation.Velocity.y,
flareItem->Animation.Velocity.z * phd_cos(flareItem->Pose.Orientation.y)
);
auto oldPos = flareItem->Pose.Position;
@ -53,20 +53,20 @@ void FlareControl(short itemNumber)
if (TestEnvironment(ENV_FLAG_WATER, flareItem) ||
TestEnvironment(ENV_FLAG_SWAMP, flareItem))
{
flareItem->Animation.VerticalVelocity += (5 - flareItem->Animation.VerticalVelocity) / 2;
flareItem->Animation.Velocity += (5 - flareItem->Animation.Velocity) / 2;
flareItem->Animation.Velocity.y += (5 - flareItem->Animation.Velocity.y) / 2;
flareItem->Animation.Velocity.z += (5 - flareItem->Animation.Velocity.z) / 2;
}
else
flareItem->Animation.VerticalVelocity += 6;
flareItem->Animation.Velocity.y += 6;
flareItem->Pose.Position.y += flareItem->Animation.VerticalVelocity;
flareItem->Pose.Position.y += flareItem->Animation.Velocity.y;
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, velocity.x, velocity.y, velocity.z);
int& life = flareItem->Data;
life &= 0x7FFF;
if (life >= FLARE_LIFE_MAX)
{
if (!flareItem->Animation.VerticalVelocity && !flareItem->Animation.Velocity)
if (!flareItem->Animation.Velocity.y && !flareItem->Animation.Velocity.z)
{
KillItem(itemNumber);
return;
@ -330,17 +330,17 @@ void CreateFlare(ItemInfo* laraItem, GAME_OBJECT_ID objectNumber, bool thrown)
if (thrown)
{
flareItem->Animation.Velocity = laraItem->Animation.Velocity + 50;
flareItem->Animation.VerticalVelocity = laraItem->Animation.VerticalVelocity - 50;
flareItem->Animation.Velocity.z = laraItem->Animation.Velocity.z + 50;
flareItem->Animation.Velocity.y = laraItem->Animation.Velocity.y - 50;
}
else
{
flareItem->Animation.Velocity = laraItem->Animation.Velocity + 10;
flareItem->Animation.VerticalVelocity = laraItem->Animation.VerticalVelocity + 50;
flareItem->Animation.Velocity.z = laraItem->Animation.Velocity.z + 10;
flareItem->Animation.Velocity.y = laraItem->Animation.Velocity.y + 50;
}
if (landed)
flareItem->Animation.Velocity /= 2;
flareItem->Animation.Velocity.z /= 2;
if (objectNumber == ID_FLARE_ITEM)
{

View file

@ -128,7 +128,7 @@ void lara_col_hang_idle(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
lara->Control.MoveAngle = item->Pose.Orientation.y;
coll->Setup.Mode = CollisionProbeMode::FreeFlat;

View file

@ -62,7 +62,7 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
// Reset crawl flex.
if (!(TrInput & IN_LOOK) && coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM && // HACK
(!item->Animation.Velocity || (item->Animation.Velocity && !(TrInput & (IN_LEFT | IN_RIGHT)))))
(!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(TrInput & (IN_LEFT | IN_RIGHT)))))
{
ResetLaraFlex(item, 12.0f);
}
@ -163,7 +163,7 @@ void EaseOutLaraHeight(ItemInfo* item, int height)
// Translate Lara to new height.
static constexpr int rate = 50;
int threshold = std::max(abs(item->Animation.Velocity) * 1.5f, CLICK(0.25f) / 4);
int threshold = std::max(abs(item->Animation.Velocity.z) * 1.5f, CLICK(0.25f) / 4);
int sign = std::copysign(1, height);
if (TestEnvironment(ENV_FLAG_SWAMP, item) && height > 0)
@ -292,17 +292,17 @@ void DoLaraTightropeBalanceRegen(ItemInfo* item)
void DoLaraFallDamage(ItemInfo* item)
{
if (item->Animation.VerticalVelocity >= LARA_DAMAGE_VELOCITY)
if (item->Animation.Velocity.y >= LARA_DAMAGE_VELOCITY)
{
if (item->Animation.VerticalVelocity >= LARA_DEATH_VELOCITY)
if (item->Animation.Velocity.y >= LARA_DEATH_VELOCITY)
item->HitPoints = 0;
else USE_FEATURE_IF_CPP20([[likely]])
{
float base = item->Animation.VerticalVelocity - (LARA_DAMAGE_VELOCITY - 1);
float base = item->Animation.Velocity.y - (LARA_DAMAGE_VELOCITY - 1);
item->HitPoints -= LARA_HEALTH_MAX * (pow(base, 2) / 196);
}
float rumblePower = ((float)item->Animation.VerticalVelocity / (float)LARA_DEATH_VELOCITY) * 0.7f;
float rumblePower = ((float)item->Animation.Velocity.y / (float)LARA_DEATH_VELOCITY) * 0.7f;
Rumble(rumblePower, 0.3f);
}
}
@ -472,8 +472,8 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
lara->Control.Subsuit.VerticalVelocity = ceil((15 / 16) * lara->Control.Subsuit.VerticalVelocity - 1);
}
lara->Control.Subsuit.Velocity[0] = -4 * item->Animation.VerticalVelocity;
lara->Control.Subsuit.Velocity[1] = -4 * item->Animation.VerticalVelocity;
lara->Control.Subsuit.Velocity[0] = -4 * item->Animation.Velocity.y;
lara->Control.Subsuit.Velocity[1] = -4 * item->Animation.Velocity.y;
if (lara->Control.Subsuit.XRot >= lara->Control.Subsuit.DXRot)
{
@ -533,7 +533,7 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
void ModulateLaraLean(ItemInfo* item, CollisionInfo* coll, short baseRate, short maxAngle)
{
if (!item->Animation.Velocity)
if (!item->Animation.Velocity.z)
return;
float axisCoeff = AxisMap[InputAxis::MoveHorizontal];
@ -550,7 +550,7 @@ void ModulateLaraCrawlFlex(ItemInfo* item, short baseRate, short maxAngle)
{
auto* lara = GetLaraInfo(item);
if (!item->Animation.Velocity)
if (!item->Animation.Velocity.z)
return;
float axisCoeff = AxisMap[InputAxis::MoveHorizontal];
@ -589,11 +589,11 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
g_Renderer.PrintDebugMessage("%d", slideVelocity);
lara->ExtraVelocity.x += slideVelocity;
lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
//lara->ExtraVelocity.x += slideVelocity;
//lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
}
else
lara->ExtraVelocity.x += minVelocity;
//else
//lara->ExtraVelocity.x += minVelocity;
}
void SetLaraJumpDirection(ItemInfo* item, CollisionInfo* coll)
@ -682,8 +682,8 @@ void SetContextWaterClimbOut(ItemInfo* item, CollisionInfo* coll, WaterClimbOutT
item->Animation.ActiveState = LS_ONWATER_EXIT;
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
lara->ProjectedFloorHeight = climbOutContext.Height;
lara->TargetOrientation = Vector3Shrt(0, coll->NearestLedgeAngle, 0);
lara->Control.TurnRate.y = 0;
@ -694,8 +694,8 @@ void SetContextWaterClimbOut(ItemInfo* item, CollisionInfo* coll, WaterClimbOutT
void SetLaraLand(ItemInfo* item, CollisionInfo* coll)
{
//item->IsAirborne = false; // TODO: Removing this avoids an unusual landing bug Core had worked around in an obscure way. I hope to find a proper solution. @Sezz 2022.02.18
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
LaraSnapToHeight(item, coll);
}
@ -704,14 +704,14 @@ void SetLaraFallAnimation(ItemInfo* item)
{
SetAnimation(item, LA_FALL_START);
item->Animation.IsAirborne = true;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
void SetLaraFallBackAnimation(ItemInfo* item)
{
SetAnimation(item, LA_FALL_BACK);
item->Animation.IsAirborne = true;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
void SetLaraMonkeyFallAnimation(ItemInfo* item)
@ -729,8 +729,8 @@ void SetLaraMonkeyRelease(ItemInfo* item)
auto* lara = GetLaraInfo(item);
item->Animation.IsAirborne = true;
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.z = 2;
item->Animation.Velocity.y = 1;
lara->Control.TurnRate.y = 0;
lara->Control.HandStatus = HandStatus::Free;
}
@ -826,8 +826,8 @@ void SetLaraHang(ItemInfo* item)
ResetLaraFlex(item);
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
lara->Control.HandStatus = HandStatus::Busy;
lara->ExtraTorsoRot = Vector3Shrt();
}
@ -848,8 +848,8 @@ void SetLaraHangReleaseAnimation(ItemInfo* item)
}
item->Animation.IsAirborne = true;
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.z = 2;
item->Animation.Velocity.y = 1;
lara->Control.HandStatus = HandStatus::Free;
}
@ -861,8 +861,8 @@ void SetLaraCornerAnimation(ItemInfo* item, CollisionInfo* coll, bool flip)
{
SetAnimation(item, LA_FALL_START);
item->Animation.IsAirborne = true;
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.z = 2;
item->Animation.Velocity.y = 1;
item->Pose.Position.y += CLICK(1);
item->Pose.Orientation.y += lara->NextCornerPos.Orientation.y / 2;
lara->Control.HandStatus = HandStatus::Free;
@ -888,7 +888,7 @@ void SetLaraSwimDiveAnimation(ItemInfo* item)
SetAnimation(item, LA_ONWATER_DIVE);
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.VerticalVelocity = LARA_SWIM_VELOCITY_MAX * 0.4f;
item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX * 0.4f;
item->Pose.Orientation.x = -ANGLE(45.0f);
lara->Control.WaterStatus = WaterStatus::Underwater;
}

View file

@ -4,16 +4,21 @@
#include "Game/health.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_flare.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_tests.h"
#include "Specific/level.h"
#include "Specific/setup.h"
void InitialiseLara(int restore)
void InitialiseLara(bool restore)
{
if (Lara.ItemNumber == NO_ITEM)
return;
LaraInfo lBackup = {};
if (restore)
memcpy(&lBackup, &Lara, sizeof(LaraInfo));
short itemNumber = Lara.ItemNumber;
LaraItem->Data = &Lara;
@ -21,11 +26,6 @@ void InitialiseLara(int restore)
LaraItem->Location.roomNumber = LaraItem->RoomNumber;
LaraItem->Location.yNumber = LaraItem->Pose.Position.y;
LaraInfo backup = {};
if (restore)
memcpy(&backup, &Lara, sizeof(LaraInfo));
ZeroMemory(&Lara, sizeof(LaraInfo));
Lara.Context = PlayerContext(LaraItem, &LaraCollision);
@ -56,7 +56,7 @@ void InitialiseLara(int restore)
Lara.Control.Weapon.LastGunType = Lara.Control.Weapon.GunType = Lara.Control.Weapon.RequestGunType = weapon;
LaraInitialiseMeshes(LaraItem);
InitialiseLaraMeshes(LaraItem);
if (weapon == LaraWeaponType::Pistol)
{
@ -87,20 +87,16 @@ void InitialiseLara(int restore)
Lara.Inventory.HasBinoculars = true;
if (!restore)
{
if (Objects[ID_FLARE_INV_ITEM].loaded)
Lara.Inventory.TotalFlares = 3;
Lara.Inventory.TotalSmallMedipacks = 3;
Lara.Inventory.TotalLargeMedipacks = 1;
}
if (restore)
InitialiseLaraLevelJump(itemNumber, &lBackup);
else
InitialiseLaraDefaultInventory();
InitialiseLaraAnims(LaraItem);
Lara.Inventory.BeetleLife = 3;
}
void LaraInitialiseMeshes(ItemInfo* item)
void InitialiseLaraMeshes(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
@ -138,7 +134,7 @@ void InitialiseLaraAnims(ItemInfo* item)
if (TestEnvironment(ENV_FLAG_WATER, item))
{
lara->Control.WaterStatus = WaterStatus::Underwater;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
SetAnimation(item, LA_UNDERWATER_IDLE);
}
else
@ -153,3 +149,38 @@ void InitialiseLaraLoad(short itemNum)
Lara.ItemNumber = itemNum;
LaraItem = &g_Level.Items[itemNum];
}
void InitialiseLaraLevelJump(short itemNum, LaraInfo* lBackup)
{
auto* item = &g_Level.Items[itemNum];
auto* lara = GetLaraInfo(item);
// Restore inventory.
// It restores even puzzle/key items, to reset them, a ResetHub analog must be made.
lara->Inventory = lBackup->Inventory;
memcpy(&lara->Weapons, &lBackup->Weapons, sizeof(CarriedWeaponInfo) * int(LaraWeaponType::NumWeapons));
// If no flare present, quit
if (lBackup->Control.Weapon.GunType != LaraWeaponType::Flare)
return;
// Restore flare
lara->LeftArm = lBackup->LeftArm;
lara->RightArm = lBackup->RightArm;
lara->Control.HandStatus = lBackup->Control.HandStatus;
lara->Control.Weapon = lBackup->Control.Weapon;
lara->Flare = lBackup->Flare;
DrawFlareMeshes(item);
}
void InitialiseLaraDefaultInventory()
{
if (Objects[ID_FLARE_INV_ITEM].loaded)
Lara.Inventory.TotalFlares = 3;
if (Objects[ID_SMALLMEDI_ITEM].loaded)
Lara.Inventory.TotalSmallMedipacks = 3;
if (Objects[ID_BIGMEDI_ITEM].loaded)
Lara.Inventory.TotalLargeMedipacks = 1;
}

View file

@ -1,7 +1,9 @@
#pragma once
#include "Game/Lara/lara_struct.h"
void InitialiseLara(int restore);
void LaraInitialiseMeshes(ItemInfo* item);
void InitialiseLara(bool restore);
void InitialiseLaraMeshes(ItemInfo* item);
void InitialiseLaraAnims(ItemInfo* item);
void InitialiseLaraLoad(short itemNumber);
void InitialiseLaraLevelJump(short itemNum, LaraInfo* lBackup);
void InitialiseLaraDefaultInventory();

View file

@ -76,7 +76,7 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -111,7 +111,7 @@ void lara_col_jump_forward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
lara->Control.MoveAngle = (item->Animation.Velocity > 0) ? item->Pose.Orientation.y : item->Pose.Orientation.y + ANGLE(180.0f);
lara->Control.MoveAngle = (item->Animation.Velocity.z > 0) ? item->Pose.Orientation.y : item->Pose.Orientation.y + ANGLE(180.0f);
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = BAD_JUMP_CEILING;
@ -121,18 +121,18 @@ void lara_col_jump_forward(ItemInfo* item, CollisionInfo* coll)
LaraDeflectEdgeJump(item, coll);
// TODO: Why??
lara->Control.MoveAngle = (item->Animation.Velocity < 0) ? item->Pose.Orientation.y : lara->Control.MoveAngle;
lara->Control.MoveAngle = (item->Animation.Velocity.z < 0) ? item->Pose.Orientation.y : lara->Control.MoveAngle;
}
// State: LS_FREEFALL (9)
// Collision: lara_col_freefall()
void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.Velocity = item->Animation.Velocity * 0.95f;
item->Animation.Velocity.z = item->Animation.Velocity.z * 0.95f;
ModulateLaraTurnRateY(item, 0, 0, 0);
if (item->Animation.VerticalVelocity == LARA_DEATH_VELOCITY &&
if (item->Animation.Velocity.y == LARA_DEATH_VELOCITY &&
item->HitPoints > 0)
{
SoundEffect(SFX_TR4_LARA_FALL, &item->Pose);
@ -210,7 +210,7 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -416,7 +416,7 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -472,7 +472,7 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -529,7 +529,7 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -584,7 +584,7 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -592,23 +592,23 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_FORWARD)
{
item->Animation.Velocity += 2;
if (item->Animation.Velocity > 5)
item->Animation.Velocity = 5;
item->Animation.Velocity.z += 2;
if (item->Animation.Velocity.z > 5)
item->Animation.Velocity.z = 5;
}
else if (TrInput & IN_BACK)
{
item->Animation.Velocity -= 2;
if (item->Animation.Velocity < -5)
item->Animation.Velocity = -5;
item->Animation.Velocity.z -= 2;
if (item->Animation.Velocity.z < -5)
item->Animation.Velocity.z = -5;
}
else
item->Animation.Velocity = (item->Animation.Velocity < 0) ? -2 : 2;
item->Animation.Velocity.z = (item->Animation.Velocity.z < 0) ? -2 : 2;
if (item->Animation.Velocity < 0)
if (item->Animation.Velocity.z < 0)
{
// TODO: Holding BACK + LEFT/RIGHT results in Lara flexing more.
item->Pose.Orientation.x += std::min<short>(LARA_LEAN_RATE / 3, abs(ANGLE(item->Animation.Velocity) - item->Pose.Orientation.x) / 3);
item->Pose.Orientation.x += std::min<short>(LARA_LEAN_RATE / 3, abs(ANGLE(item->Animation.Velocity.z) - item->Pose.Orientation.x) / 3);
lara->ExtraHeadRot.y += (ANGLE(10.0f) - item->Pose.Orientation.z) / 3;
}
@ -626,7 +626,7 @@ void lara_col_jump_up(ItemInfo* item, CollisionInfo* coll)
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
coll->Setup.LowerCeilingBound = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = (item->Animation.Velocity >= 0) ? lara->Control.MoveAngle : lara->Control.MoveAngle + ANGLE(180.0f);
coll->Setup.ForwardAngle = (item->Animation.Velocity.z >= 0) ? lara->Control.MoveAngle : lara->Control.MoveAngle + ANGLE(180.0f);
coll->Setup.Mode = CollisionProbeMode::FreeForward;
GetCollisionInfo(coll, item);
@ -638,7 +638,7 @@ void lara_col_jump_up(ItemInfo* item, CollisionInfo* coll)
coll->CollisionType == CT_TOP_FRONT ||
coll->CollisionType == CT_CLAMP)
{
item->Animation.VerticalVelocity = 1;
item->Animation.Velocity.y = 1;
}
ShiftItem(item, coll);
@ -679,7 +679,7 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL;
return;
@ -721,7 +721,7 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
SetLaraLand(item, coll);
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL_DIVE;
return;
@ -758,7 +758,7 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
return;
}
if (item->Animation.VerticalVelocity >= LARA_FREEFALL_VELOCITY)
if (item->Animation.Velocity.y >= LARA_FREEFALL_VELOCITY)
{
item->Animation.TargetState = LS_FREEFALL_DIVE;
return;
@ -796,7 +796,7 @@ void lara_col_swan_dive(ItemInfo* item, CollisionInfo* coll)
// Collision: lara_col_freefall_dive()
void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.Velocity = item->Animation.Velocity * 0.95f;
item->Animation.Velocity.z = item->Animation.Velocity.z * 0.95f;
coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpasm = false;
@ -815,7 +815,7 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
if (TestLaraLand(item, coll))
{
if (item->Animation.VerticalVelocity >= LARA_DIVE_DEATH_VELOCITY ||
if (item->Animation.Velocity.y >= LARA_DIVE_DEATH_VELOCITY ||
item->HitPoints <= 0)
{
item->Animation.TargetState = LS_DEATH;

View file

@ -285,8 +285,8 @@ void lara_as_horizontal_bar_leap(ItemInfo* item, CollisionInfo* coll)
else
distance = (barItem->TriggerFlags % 100) - 2;
item->Animation.Velocity = (20 * distance) + 58;
item->Animation.VerticalVelocity = -(20 * distance + 64);
item->Animation.Velocity.z = (20 * distance) + 58;
item->Animation.Velocity.y = -(20 * distance + 64);
}
if (TestLastFrame(item))
@ -400,7 +400,7 @@ void lara_as_tightrope_fall(ItemInfo* item, CollisionInfo* coll)
else if (item->Animation.AnimNumber == LA_TIGHTROPE_FALL_RIGHT)
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(90.0f), CLICK(1));
item->Animation.VerticalVelocity = 10;
item->Animation.Velocity.y = 10;
}
}
@ -491,7 +491,7 @@ void lara_as_tightrope_fall(ItemInfo* item, CollisionInfo* coll)
item->Animation.AnimNumber = LA_FREEFALL;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.VerticalVelocity = 81;
item->Animation.Velocity.y = 81;
Camera.targetspeed = 16;
}
}
@ -598,7 +598,7 @@ void lara_col_rope_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION)
{
UpdateRopeSwing(item);
RopeSwingCollision(item, coll);
RopeSwingCollision(item, coll, false);
if (TrInput & IN_SPRINT)
{
@ -632,7 +632,7 @@ void lara_col_rope_swing(ItemInfo* item, CollisionInfo* coll)
Camera.targetDistance = SECTOR(2);
UpdateRopeSwing(item);
RopeSwingCollision(item, coll);
RopeSwingCollision(item, coll, true);
if (item->Animation.AnimNumber == LA_ROPE_SWING)
{
@ -896,7 +896,7 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll)
}
item->Animation.TargetState = LS_POLE_IDLE;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
return;
}
@ -921,20 +921,20 @@ void lara_col_pole_down(ItemInfo* item, CollisionInfo* coll)
// TODO: Pitch modulation might be a fun idea.
if (item->Animation.AnimNumber == LA_POLE_DOWN_END)
item->Animation.VerticalVelocity -= 8;
item->Animation.Velocity.y -= 8;
else
item->Animation.VerticalVelocity += 1;
item->Animation.Velocity.y += 1;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
else if (item->Animation.VerticalVelocity > 64)
item->Animation.VerticalVelocity = 64;
if (item->Animation.Velocity.y < 0)
item->Animation.Velocity.y = 0;
else if (item->Animation.Velocity.y > 64)
item->Animation.Velocity.y = 64;
// TODO: Do something about that ugly snap at the bottom.
if ((coll->Middle.Floor + item->Animation.VerticalVelocity) < 0)
if ((coll->Middle.Floor + item->Animation.Velocity.y) < 0)
item->Pose.Position.y += coll->Middle.Floor;
else if (TestLaraPoleCollision(item, coll, false))
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Pose.Position.y += item->Animation.Velocity.y;
}
// State: LS_POLE_TURN_CLOCKWISE (102)
@ -1058,8 +1058,8 @@ void lara_as_zip_line(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_JUMP_FORWARD;
AnimateLara(item);
item->Animation.Velocity = 100;
item->Animation.VerticalVelocity = 40;
item->Animation.Velocity.z = 100;
item->Animation.Velocity.y = 40;
item->Animation.IsAirborne = true;
lara->Control.MoveAngle = item->Pose.Orientation.y;
}

View file

@ -61,7 +61,7 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
}
auto* item = &g_Level.Items[lara->Control.Weapon.WeaponItem];
bool running = (weaponType == LaraWeaponType::HK && laraItem->Animation.Velocity != 0);
bool running = (weaponType == LaraWeaponType::HK && laraItem->Animation.Velocity.z != 0.0f);
static bool reloadHarpoonGun = false;
reloadHarpoonGun = (lara->Weapons[(int)weaponType].Ammo->hasInfinite() || weaponType != LaraWeaponType::HarpoonGun) ? false : reloadHarpoonGun;
@ -488,8 +488,8 @@ void FireHarpoon(ItemInfo* laraItem)
}
item->Pose.Orientation.z = 0;
item->Animation.Velocity = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x);
item->Animation.VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x);
item->Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x);
item->Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x);
item->HitPoints = HARPOON_TIME;
Rumble(0.2f, 0.1f);
@ -519,8 +519,8 @@ void HarpoonBoltControl(short itemNumber)
if (item->Pose.Orientation.x < -ANGLE(90.0f))
item->Pose.Orientation.x = -ANGLE(90.0f);
item->Animation.VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x);
item->Animation.Velocity = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x);
item->Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x);
item->Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x);
aboveWater = true;
}
else
@ -529,12 +529,12 @@ void HarpoonBoltControl(short itemNumber)
if (Wibble & 4)
CreateBubble((Vector3Int*)&item->Pose, item->RoomNumber, 0, 0, BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0);
item->Animation.VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x) / 2;
item->Animation.Velocity = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x) / 2;
item->Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x) / 2;
item->Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(item->Pose.Orientation.x) / 2;
aboveWater = false;
}
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
}
else
{
@ -707,8 +707,8 @@ void FireGrenade(ItemInfo* laraItem)
item->Pose.Orientation.y += lara->ExtraTorsoRot.y;
}
item->Animation.Velocity = GRENADE_VELOCITY;
item->Animation.VerticalVelocity = -CLICK(2) * phd_sin(item->Pose.Orientation.x);
item->Animation.Velocity.z = GRENADE_VELOCITY;
item->Animation.Velocity.y = -CLICK(2) * phd_sin(item->Pose.Orientation.x);
item->Animation.ActiveState = item->Pose.Orientation.x;
item->Animation.TargetState = item->Pose.Orientation.y;
item->Animation.RequiredState = 0;
@ -781,8 +781,8 @@ void GrenadeControl(short itemNumber)
newGrenade->Pose.Orientation.x = (GetRandomControl() & 0x3FFF) + ANGLE(45);
newGrenade->Pose.Orientation.y = GetRandomControl() * 2;
newGrenade->Pose.Orientation.z = 0;
newGrenade->Animation.Velocity = 64;
newGrenade->Animation.VerticalVelocity = -64 * phd_sin(newGrenade->Pose.Orientation.x);
newGrenade->Animation.Velocity.z = 64.0f;
newGrenade->Animation.Velocity.y = -64.0f * phd_sin(newGrenade->Pose.Orientation.x);
newGrenade->Animation.ActiveState = newGrenade->Pose.Orientation.x;
newGrenade->Animation.TargetState = newGrenade->Pose.Orientation.y;
newGrenade->Animation.RequiredState = 0;
@ -819,36 +819,36 @@ void GrenadeControl(short itemNumber)
{
aboveWater = false;
someFlag = false;
item->Animation.VerticalVelocity += (5 - item->Animation.VerticalVelocity) >> 1;
item->Animation.Velocity -= item->Animation.Velocity >> 2;
item->Animation.Velocity.y += (5.0f - item->Animation.Velocity.y) / 2.0f;
item->Animation.Velocity.z -= item->Animation.Velocity.z / 4.0f;
if (item->Animation.Velocity)
if (item->Animation.Velocity.z)
{
item->Pose.Orientation.z += (((item->Animation.Velocity >> 4) + 3) * ANGLE(1.0f));
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 16.0f) + 3.0f) * ANGLE(1.0f));
if (item->Animation.RequiredState)
item->Pose.Orientation.y += (((item->Animation.Velocity >> 2) + 3) * ANGLE(1.0f));
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 4.0f) + 3.0f) * ANGLE(1.0f));
else
item->Pose.Orientation.x += (((item->Animation.Velocity >> 2) + 3) * ANGLE(1.0f));
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 4.0f) + 3.0f) * ANGLE(1.0f));
}
}
else
{
aboveWater = true;
someFlag = true;
item->Animation.VerticalVelocity += 3;
item->Animation.Velocity.y += 3.0f;
if (item->Animation.Velocity)
if (item->Animation.Velocity.z)
{
item->Pose.Orientation.z += (((item->Animation.Velocity >> 2) + 7) * ANGLE(1.0f));
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 4.0f) + 7.0f) * ANGLE(1.0f));
if (item->Animation.RequiredState)
item->Pose.Orientation.y += (((item->Animation.Velocity >> 1) + 7) * ANGLE(1.0f));
item->Pose.Orientation.y += (short((item->Animation.Velocity.z / 2.0f) + 7.0f) * ANGLE(1.0f));
else
item->Pose.Orientation.x += (((item->Animation.Velocity >> 1) + 7) * ANGLE(1.0f));
item->Pose.Orientation.x += (short((item->Animation.Velocity.z / 2.0f) + 7.0f) * ANGLE(1.0f));
}
}
// Trigger fire and smoke sparks in the direction of motion
if (item->Animation.Velocity && aboveWater)
if (item->Animation.Velocity.z && aboveWater)
{
Matrix world = Matrix::CreateFromYawPitchRoll(
TO_RAD(item->Pose.Orientation.y - ANGLE(180.0f)),
@ -866,9 +866,9 @@ void GrenadeControl(short itemNumber)
// Update grenade position
auto velocity = Vector3Int(
item->Animation.Velocity * phd_sin(item->Animation.TargetState),
item->Animation.VerticalVelocity,
item->Animation.Velocity * phd_cos(item->Animation.TargetState)
item->Animation.Velocity.z * phd_sin(item->Animation.TargetState),
item->Animation.Velocity.y,
item->Animation.Velocity.z * phd_cos(item->Animation.TargetState)
);
item->Pose.Position += velocity;
@ -1131,7 +1131,7 @@ void FireRocket(ItemInfo* laraItem)
item->Pose.Orientation.y += lara->ExtraTorsoRot.y;
}
item->Animation.Velocity = 512 >> 5;
item->Animation.Velocity.z = 512.0f / 32.0f;
item->ItemFlags[0] = 0;
AddActiveItem(itemNumber);
@ -1156,25 +1156,25 @@ void RocketControl(short itemNumber)
bool abovewater = false;
if (TestEnvironment(ENV_FLAG_WATER, item->RoomNumber))
{
if (item->Animation.Velocity > (ROCKET_VELOCITY / 4))
item->Animation.Velocity -= item->Animation.Velocity / 4;
if (item->Animation.Velocity.z > (ROCKET_VELOCITY / 4.0f))
item->Animation.Velocity.z -= item->Animation.Velocity.z / 4.0f;
else
{
item->Animation.Velocity += (item->Animation.Velocity / 4) + 4;
item->Animation.Velocity.z += (item->Animation.Velocity.z / 4.0f) + 4.0f;
if (item->Animation.Velocity > (ROCKET_VELOCITY / 4))
item->Animation.Velocity = ROCKET_VELOCITY / 4;
if (item->Animation.Velocity.z > (ROCKET_VELOCITY / 4.0f))
item->Animation.Velocity.z = ROCKET_VELOCITY / 4.0f;
}
item->Pose.Orientation.z += (((item->Animation.Velocity / 8) + 3) * ANGLE(1.0f));
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 8.0f) + 3.0f) * ANGLE(1.0f));
abovewater = false;
}
else
{
if (item->Animation.Velocity < ROCKET_VELOCITY)
item->Animation.Velocity += (item->Animation.Velocity / 4) + 4;
if (item->Animation.Velocity.z < ROCKET_VELOCITY)
item->Animation.Velocity.z += (item->Animation.Velocity.z / 4.0f) + 4.0f;
item->Pose.Orientation.z += (((item->Animation.Velocity / 4) + 7) * ANGLE(1.0f));
item->Pose.Orientation.z += (short((item->Animation.Velocity.z / 4.0f) + 7.0f) * ANGLE(1.0f));
abovewater = true;
}
@ -1207,7 +1207,7 @@ void RocketControl(short itemNumber)
}
// Update rocket's position
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
bool explode = false;
bool hitRoom = false;
@ -1415,7 +1415,7 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
}
}
item->Animation.Velocity = 512;
item->Animation.Velocity.z = 512.0f;
AddActiveItem(itemNumber);
@ -1458,8 +1458,8 @@ void CrossbowBoltControl(short itemNumber)
{
auto bubblePos = item->Pose.Position;
if (item->Animation.Velocity > 64)
item->Animation.Velocity -= (item->Animation.Velocity >> 4);
if (item->Animation.Velocity.z > 64.0f)
item->Animation.Velocity.z -= item->Animation.Velocity.z / 16.0f;
if (GlobalCounter & 1)
CreateBubble(&bubblePos, item->RoomNumber, 4, 7, 0, 0, 0, 0);
@ -1469,7 +1469,7 @@ void CrossbowBoltControl(short itemNumber)
else
aboveWater = true;
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
auto probe = GetCollision(item);

View file

@ -1264,7 +1264,6 @@ struct LaraInfo
Vector3Shrt ExtraHeadRot;
Vector3Shrt ExtraTorsoRot;
Vector3Int ExtraVelocity;
short WaterCurrentActive;
Vector3Int WaterCurrentPull;

View file

@ -41,9 +41,9 @@ void lara_as_surface_idle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.Velocity.y < 0)
item->Animation.Velocity.y = 0;
if (item->HitPoints <= 0)
{
@ -152,9 +152,9 @@ void lara_as_surface_swim_forward(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_ONWATER_FORWARD;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.Velocity.y > LARA_TREAD_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_TREAD_VELOCITY_MAX;
}
return;
@ -201,9 +201,9 @@ void lara_as_surface_swim_left(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_ONWATER_LEFT;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.Velocity.y > LARA_TREAD_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_TREAD_VELOCITY_MAX;
return;
@ -247,9 +247,9 @@ void lara_as_surface_swim_right(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_ONWATER_RIGHT;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.Velocity.y > LARA_TREAD_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_TREAD_VELOCITY_MAX;
return;
}
@ -289,9 +289,9 @@ void lara_as_surface_swim_back(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_ONWATER_BACK;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.Velocity.y > LARA_TREAD_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_TREAD_VELOCITY_MAX;
return;
}

View file

@ -53,9 +53,9 @@ void lara_as_underwater_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_JUMP)
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.Velocity.y < 0.0f)
item->Animation.Velocity.y = 0.0f;
if (lara->Control.HandStatus == HandStatus::Busy)
lara->Control.HandStatus = HandStatus::Free;
@ -91,9 +91,9 @@ void lara_as_underwater_swim_forward(ItemInfo* item, CollisionInfo* coll)
else
ModulateLaraSubsuitSwimTurnRates(item);
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_SWIM_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_SWIM_VELOCITY_MAX;
item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX)
item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX;
if (!(TrInput & IN_JUMP))
item->Animation.TargetState = LS_UNDERWATER_INERTIA;
@ -132,11 +132,11 @@ void lara_as_underwater_inertia(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_JUMP)
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.Velocity.y < 0.0f)
item->Animation.Velocity.y = 0.0f;
if (item->Animation.VerticalVelocity < LARA_SWIM_INTERTIA_VELOCITY_MIN)
if (item->Animation.Velocity.y < LARA_SWIM_INTERTIA_VELOCITY_MIN)
item->Animation.TargetState = LS_UNDERWATER_IDLE;
}
@ -155,9 +155,9 @@ void lara_as_underwater_death(ItemInfo* item, CollisionInfo* coll)
lara->Control.CanLook = false;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.Velocity.y < 0.0f)
item->Animation.Velocity.y = 0.0f;
if (item->Pose.Orientation.x < -ANGLE(2.0f) ||
item->Pose.Orientation.x > ANGLE(2.0f))
@ -195,7 +195,7 @@ void lara_col_underwater_death(ItemInfo* item, CollisionInfo* coll)
// Collision: lara_col_underwater_roll_180()
void lara_as_underwater_roll_180(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0.0f;
}
// State: LS_UNDERWATER_ROLL (66)

View file

@ -218,7 +218,7 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
coll->Middle.Ceiling < 0 && coll->CollisionType == CT_FRONT && !coll->HitStatic &&
abs(verticalShift) < SLOPE_DIFFERENCE && TestValidLedgeAngle(item, coll))
{
if (item->Animation.Velocity != 0)
if (item->Animation.Velocity.z != 0)
SnapItemToLedge(item, coll);
item->Pose.Position.y += verticalShift;
@ -352,7 +352,7 @@ bool TestLaraHangOnClimbableWall(ItemInfo* item, CollisionInfo* coll)
if (!lara->Control.CanClimbLadder)
return false;
if (item->Animation.VerticalVelocity < 0)
if (item->Animation.Velocity.y < 0)
return false;
// HACK: Climb wall tests are highly fragile and depend on quadrant shifts.
@ -800,8 +800,8 @@ bool TestLaraWaterStepOut(ItemInfo* item, CollisionInfo* coll)
UpdateItemRoom(item, -(STEPUP_HEIGHT - 3));
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
item->Pose.Orientation.x = 0;
item->Pose.Orientation.z = 0;
lara->Control.WaterStatus = WaterStatus::Wade;
@ -867,8 +867,8 @@ bool TestLaraLadderClimbOut(ItemInfo* item, CollisionInfo* coll) // NEW function
AnimateLara(item);
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
item->Pose.Position.y -= 10; // Otherwise she falls back into the water.
item->Pose.Orientation = Vector3Shrt(0, facing, 0);
lara->Control.TurnRate.y = 0;
@ -886,7 +886,7 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
if (waterDepth == NO_HEIGHT)
{
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Pose.Position = coll->Setup.OldPosition;
}
// Height check was at CLICK(2) before but changed to this
@ -899,8 +899,8 @@ void TestLaraWaterDepth(ItemInfo* item, CollisionInfo* coll)
item->Pose.Orientation.x = 0;
item->Pose.Orientation.z = 0;
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
lara->Control.WaterStatus = WaterStatus::Wade;
}
}
@ -1115,8 +1115,8 @@ bool TestLaraLand(ItemInfo* item, CollisionInfo* coll)
int heightFromFloor = GetCollision(item).Position.Floor - item->Pose.Position.y;
if (item->Animation.IsAirborne &&
item->Animation.VerticalVelocity >= 0 &&
(heightFromFloor <= item->Animation.VerticalVelocity ||
item->Animation.Velocity.y >= 0 &&
(heightFromFloor <= item->Animation.Velocity.y ||
TestEnvironment(ENV_FLAG_SWAMP, item)))
{
return true;
@ -1974,20 +1974,20 @@ WaterClimbOutTestResult TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* col
LedgeHangTestResult TestLaraLedgeHang(ItemInfo* item, CollisionInfo* coll)
{
int y = item->Pose.Position.y - coll->Setup.Height;
auto probeFront = GetCollision(item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius), -coll->Setup.Height + std::min(item->Animation.VerticalVelocity, 0));
auto probeFront = GetCollision(item, item->Pose.Orientation.y, OFFSET_RADIUS(coll->Setup.Radius), -coll->Setup.Height + std::min(item->Animation.Velocity.y, 0.0f));
auto probeMiddle = GetCollision(item);
if (!TestValidLedge(item, coll, true))
return LedgeHangTestResult{ false };
int sign = copysign(1, item->Animation.VerticalVelocity);
int sign = copysign(1, item->Animation.Velocity.y);
if (
// TODO: Will need to modify this when ledge grabs are made to occur from control functions.
(probeFront.Position.Floor * sign) >= (y * sign) && // Ledge is lower/higher than player's current position.
(probeFront.Position.Floor * sign) <= ((y + item->Animation.VerticalVelocity) * sign) && // Ledge is higher/lower than player's projected position.
(probeFront.Position.Floor * sign) >= (y * sign) && // Ledge is lower/higher than player's current position.
(probeFront.Position.Floor * sign) <= ((y + item->Animation.Velocity.y) * sign) && // Ledge is higher/lower than player's projected position.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) >= CLICK(0.1f) && // Adequate hand room.
abs(probeFront.Position.Floor - probeMiddle.Position.Floor) >= LARA_HEIGHT_STRETCH) // Ledge high enough.
abs(probeFront.Position.Ceiling - probeFront.Position.Floor) >= CLICK(0.1f) && // Adequate hand room.
abs(probeFront.Position.Floor - probeMiddle.Position.Floor) >= LARA_HEIGHT_STRETCH) // Ledge high enough.
{
return LedgeHangTestResult{ true, probeFront.Position.Floor };
}

View file

@ -2,14 +2,12 @@
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/control/flipeffect.h"
#include "Game/collision/collide_room.h"
#include "Game/control/flipeffect.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_helpers.h"
#include "Objects/Generic/Object/rope.h"
#include "Renderer/Renderer11.h"
#include "Sound/sound.h"
#include "Specific/level.h"
@ -50,12 +48,12 @@ void AnimateLara(ItemInfo* item)
case COMMAND_JUMP_VELOCITY:
item->Animation.IsAirborne = true;
item->Animation.VerticalVelocity = *(cmd++);
item->Animation.Velocity = *(cmd++);
item->Animation.Velocity.y = *(cmd++);
item->Animation.Velocity.z = *(cmd++);
if (lara->Control.CalculatedJumpVelocity)
{
item->Animation.VerticalVelocity = lara->Control.CalculatedJumpVelocity;
item->Animation.Velocity.y = lara->Control.CalculatedJumpVelocity;
lara->Control.CalculatedJumpVelocity = 0;
}
@ -64,6 +62,7 @@ void AnimateLara(ItemInfo* item)
case COMMAND_ATTACK_READY:
if (lara->Control.HandStatus != HandStatus::Special)
lara->Control.HandStatus = HandStatus::Free;
break;
case COMMAND_SOUND_FX:
@ -147,65 +146,50 @@ void AnimateLara(ItemInfo* item)
}
}
int lateral = anim->Xvelocity;
if (anim->Xacceleration)
lateral += anim->Xacceleration * (item->Animation.FrameNumber - anim->frameBase);
item->Animation.LateralVelocity = lateral >>= 16;
int frameCount = (anim->frameEnd - anim->frameBase) + 1;
int currentFrame = item->Animation.FrameNumber - anim->frameBase;
if (item->Animation.IsAirborne)
{
if (TestEnvironment(ENV_FLAG_SWAMP, item))
{
item->Animation.Velocity -= item->Animation.Velocity >> 3;
if (abs(item->Animation.Velocity) < 8)
item->Animation.Velocity.z -= item->Animation.Velocity.z / 8.0f;
if (abs(item->Animation.Velocity.z) < 8.0f)
{
item->Animation.IsAirborne = false;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0.0f;
}
if (item->Animation.VerticalVelocity > 128)
item->Animation.VerticalVelocity /= 2;
item->Animation.VerticalVelocity -= item->Animation.VerticalVelocity / 4;
if (item->Animation.Velocity.y > 128.0f)
item->Animation.Velocity.y /= 2.0f;
item->Animation.Velocity.y -= item->Animation.Velocity.y / 4.0f;
if (item->Animation.VerticalVelocity < 4)
item->Animation.VerticalVelocity = 4;
item->Pose.Position.y += item->Animation.VerticalVelocity;
if (item->Animation.Velocity.y < 4.0f)
item->Animation.Velocity.y = 4.0f;
item->Pose.Position.y += item->Animation.Velocity.y;
}
else
{
int velocity = (anim->velocity + anim->acceleration * (item->Animation.FrameNumber - anim->frameBase - 1));
item->Animation.Velocity -= velocity >> 16;
item->Animation.Velocity += (velocity + anim->acceleration) >> 16;
item->Animation.VerticalVelocity += (item->Animation.VerticalVelocity >= 128 ? 1 : GRAVITY);
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.z += (anim->VelocityEnd.z - anim->VelocityStart.z) / frameCount;
item->Animation.Velocity.y += item->Animation.Velocity.y >= 128.0f ? 1.0f : GRAVITY;
item->Pose.Position.y += item->Animation.Velocity.y;
}
}
else
{
int velocity;
if (lara->Control.WaterStatus == WaterStatus::Wade && TestEnvironment(ENV_FLAG_SWAMP, item))
{
velocity = (anim->velocity >> 1);
if (anim->acceleration)
velocity += (anim->acceleration * (item->Animation.FrameNumber - anim->frameBase)) >> 2;
}
item->Animation.Velocity.z = (anim->VelocityStart.z / 2.0f) + ((((anim->VelocityEnd.z - anim->VelocityStart.z) / frameCount) * currentFrame) / 4.0f);
else
{
velocity = anim->velocity;
if (anim->acceleration)
velocity += anim->acceleration * (item->Animation.FrameNumber - anim->frameBase);
}
item->Animation.Velocity = velocity >> 16;
item->Pose.Position.y += lara->ExtraVelocity.y;
item->Animation.Velocity.z = anim->VelocityStart.z + (((anim->VelocityEnd.z - anim->VelocityStart.z) / frameCount) * currentFrame);
}
item->Animation.Velocity.x = anim->VelocityStart.x + (((anim->VelocityEnd.x - anim->VelocityStart.x) / frameCount) * currentFrame);
if (lara->Control.Rope.Ptr != -1)
DelAlignLaraToRope(item);
if (!lara->Control.IsMoving)
TranslateItem(item, lara->Control.MoveAngle, item->Animation.Velocity + lara->ExtraVelocity.x, 0, item->Animation.LateralVelocity + lara->ExtraVelocity.z);
TranslateItem(item, lara->Control.MoveAngle, item->Animation.Velocity.z, 0.0f, item->Animation.Velocity.x);
// Update matrices
g_Renderer.UpdateLaraAnimations(true);
@ -243,8 +227,8 @@ void AnimateItem(ItemInfo* item)
break;
case COMMAND_JUMP_VELOCITY:
item->Animation.VerticalVelocity = *(cmd++);
item->Animation.Velocity = *(cmd++);
item->Animation.Velocity.y = *(cmd++);
item->Animation.Velocity.z = *(cmd++);
item->Animation.IsAirborne = true;
break;
@ -350,29 +334,21 @@ void AnimateItem(ItemInfo* item)
}
}
int lateral = 0;
int frameCount = (anim->frameEnd - anim->frameBase) + 1;
int currentFrame = item->Animation.FrameNumber - anim->frameBase;
if (item->Animation.IsAirborne)
{
item->Animation.VerticalVelocity += (item->Animation.VerticalVelocity >= 128 ? 1 : 6);
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.y += (item->Animation.Velocity.y >= 128.0f) ? 1.0f : 6.0f;
item->Pose.Position.y += item->Animation.Velocity.y;
}
else
{
int velocity = anim->velocity;
if (anim->acceleration)
velocity += anim->acceleration * (item->Animation.FrameNumber - anim->frameBase);
item->Animation.Velocity = velocity >> 16;
lateral = anim->Xvelocity;
if (anim->Xacceleration)
lateral += anim->Xacceleration * (item->Animation.FrameNumber - anim->frameBase);
lateral >>= 16;
item->Animation.Velocity.z = anim->VelocityStart.z + (((anim->VelocityEnd.z - anim->VelocityStart.z) / frameCount) * currentFrame);
item->Animation.Velocity.x = anim->VelocityStart.x + (((anim->VelocityEnd.x - anim->VelocityStart.x) / frameCount) * currentFrame);
}
TranslateItem(item, item->Pose.Orientation.y, item->Animation.Velocity, 0, lateral);
TranslateItem(item, item->Pose.Orientation.y, item->Animation.Velocity.z, 0.0f, item->Animation.Velocity.x);
// Update matrices.
short itemNumber = item - g_Level.Items.data();
@ -420,9 +396,9 @@ bool TestLastFrame(ItemInfo* item, int animNumber)
return (item->Animation.FrameNumber >= anim->frameEnd);
}
void TranslateItem(ItemInfo* item, short angle, float forward, float vertical, float lateral)
void TranslateItem(ItemInfo* item, short angle, float forward, float down, float right)
{
item->Pose.Position = TranslateVector(item->Pose.Position, angle, forward, vertical, lateral);
item->Pose.Position = TranslateVector(item->Pose.Position, angle, forward, down, right);
}
void TranslateItem(ItemInfo* item, Vector3Shrt orient, float distance)
@ -430,6 +406,11 @@ void TranslateItem(ItemInfo* item, Vector3Shrt orient, float distance)
item->Pose.Position = TranslateVector(item->Pose.Position, orient, distance);
}
void TranslateItem(ItemInfo* item, Vector3 direction, float distance)
{
item->Pose.Position = TranslateVector(item->Pose.Position, direction, distance);
}
void SetAnimation(ItemInfo* item, int animIndex, int frameToStart)
{
int index = Objects[item->ObjectNumber].animIndex + animIndex;
@ -518,7 +499,7 @@ int GetFrame(ItemInfo* item, ANIM_FRAME* framePtr[], int* rate)
int frame = item->Animation.FrameNumber;
auto* anim = &g_Level.Anims[item->Animation.AnimNumber];
framePtr[0] = framePtr[1] = &g_Level.Frames[anim->framePtr];
int rate2 = *rate = anim->interpolation & 0x00ff;
int rate2 = *rate = anim->Interpolation & 0x00ff;
frame -= anim->frameBase;
int first = frame / rate2;

View file

@ -32,14 +32,16 @@ struct RANGE_STRUCT
struct ANIM_STRUCT
{
int framePtr;
int interpolation;
int Interpolation;
int ActiveState;
int velocity;
int acceleration;
int Xvelocity;
int Xacceleration;
// CONVENTION: +X is right, +Y is down, +Z is forward.
Vector3 VelocityStart = Vector3::Zero;
Vector3 VelocityEnd = Vector3::Zero;
int frameBase;
int frameEnd;
int jumpAnimNum;
int jumpFrameNum;
int numberChanges;
@ -59,13 +61,13 @@ enum ANIMCOMMAND_TYPES
COMMAND_EFFECT
};
struct BONE_MUTATOR
struct BoneMutator
{
Vector3 Scale = Vector3::One;
Vector3 Offset = Vector3::Zero;
Vector3 Rotation = Vector3::Zero;
Vector3 Scale = Vector3::One;
bool IsEmpty() { return (Scale == Vector3::One) && (Offset == Vector3::Zero) && (Rotation == Vector3::Zero); };
bool IsEmpty() { return (Offset == Vector3::Zero) && (Rotation == Vector3::Zero) && (Scale == Vector3::One); };
};
void AnimateLara(ItemInfo* item);
@ -74,8 +76,9 @@ void AnimateItem(ItemInfo* item);
bool HasStateDispatch(ItemInfo* item, int targetState = -1);
bool TestLastFrame(ItemInfo* item, int animNumber = -1);
void TranslateItem(ItemInfo* item, short angle, float forward, float vertical = 0.0f, float lateral = 0.0f);
void TranslateItem(ItemInfo* item, short angle, float forward, float down = 0.0f, float right = 0.0f);
void TranslateItem(ItemInfo* item, Vector3Shrt orient, float distance);
void TranslateItem(ItemInfo* item, Vector3 direction, float distance);
void SetAnimation(ItemInfo* item, int animIndex, int frameToStart = 0);
int GetCurrentRelativeFrameNumber(ItemInfo* item);

View file

@ -1266,7 +1266,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
else
item->Pose.Orientation.y = ANGLE(180.0f) - item->Pose.Orientation.y;
item->Animation.Velocity /= 2;
item->Animation.Velocity.z /= 2;
// Put item back in its last position.
item->Pose.Position.x = x;
@ -1278,7 +1278,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
{
// Need to know which direction the slope is.
item->Animation.Velocity -= (item->Animation.Velocity / 4);
item->Animation.Velocity.z -= (item->Animation.Velocity.z / 4);
// Hit angle = ANGLE(90.0f)
if (collResult.FloorTilt.x < 0 && ((abs(collResult.FloorTilt.x)) - (abs(collResult.FloorTilt.y)) >= 2))
@ -1286,14 +1286,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(180.0f))
{
item->Pose.Orientation.y = ANGLE(90.0f) + (ANGLE(270.0f) - (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity -= collResult.FloorTilt.x * 2;
item->Animation.Velocity.z -= collResult.FloorTilt.x * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(90.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(270.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1308,10 +1308,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = ANGLE(270.0f)
@ -1320,14 +1320,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) < ANGLE(180.0f))
{
item->Pose.Orientation.y = ANGLE(270.0f) + (ANGLE(90.0f) - (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += collResult.FloorTilt.x * 2;
item->Animation.Velocity.z += collResult.FloorTilt.x * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(270.0f) || (unsigned short)item->Pose.Orientation.y < ANGLE(90.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1342,10 +1342,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = 0
@ -1354,14 +1354,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(90.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(270.0f))
{
item->Pose.Orientation.y = ANGLE(180.0f) - item->Pose.Orientation.y - 1;
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity -= collResult.FloorTilt.y * 2;
item->Animation.Velocity.z -= collResult.FloorTilt.y * 2;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(180.0f))
{
@ -1377,10 +1377,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = ANGLE(180.0f)
@ -1389,14 +1389,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(270.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(90.0f))
{
item->Pose.Orientation.y = ANGLE(180.0f) - item->Pose.Orientation.y - 1;
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += collResult.FloorTilt.y * 2;
item->Animation.Velocity.z += collResult.FloorTilt.y * 2;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(180.0f))
{
@ -1412,10 +1412,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
else if (collResult.FloorTilt.x < 0 && collResult.FloorTilt.y < 0) // Hit angle = 0x2000
@ -1423,14 +1423,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(135.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(315.0f))
{
item->Pose.Orientation.y = ANGLE(45.0f) + (ANGLE(225.0f) - (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += -collResult.FloorTilt.x + -collResult.FloorTilt.y;
item->Animation.Velocity.z += -collResult.FloorTilt.x + -collResult.FloorTilt.y;
if ((unsigned short)item->Pose.Orientation.y > ANGLE(45.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(225.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1445,10 +1445,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = ANGLE(135.0f)
@ -1457,14 +1457,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(225.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(45.0f))
{
item->Pose.Orientation.y = ANGLE(135.0f) + (ANGLE(315.0f) - (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += (-collResult.FloorTilt.x) + collResult.FloorTilt.y;
item->Animation.Velocity.z += (-collResult.FloorTilt.x) + collResult.FloorTilt.y;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(315.0f) && (unsigned short)item->Pose.Orientation.y > ANGLE(135.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1479,10 +1479,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = ANGLE(225.5f)
@ -1491,14 +1491,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(315.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(135.0f))
{
item->Pose.Orientation.y = ANGLE(225.5f) + (ANGLE(45.0f) - (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += collResult.FloorTilt.x + collResult.FloorTilt.y;
item->Animation.Velocity.z += collResult.FloorTilt.x + collResult.FloorTilt.y;
if ((unsigned short)item->Pose.Orientation.y < ANGLE(45.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(225.5f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1513,10 +1513,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
// Hit angle = ANGLE(315.0f)
@ -1525,14 +1525,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (((unsigned short)item->Pose.Orientation.y) > ANGLE(45.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(225.5f))
{
item->Pose.Orientation.y = ANGLE(315.0f) + (ANGLE(135.0f)- (unsigned short)item->Pose.Orientation.y - 1);
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity / 2;
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y / 2;
}
else
{
if (item->Animation.Velocity < 32)
if (item->Animation.Velocity.z < 32)
{
item->Animation.Velocity += collResult.FloorTilt.x + (-collResult.FloorTilt.y);
item->Animation.Velocity.z += collResult.FloorTilt.x + (-collResult.FloorTilt.y);
if ((unsigned short)item->Pose.Orientation.y < ANGLE(135.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(315.0f))
{
item->Pose.Orientation.y -= ANGLE(22.5f);
@ -1547,10 +1547,10 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
}
}
if (item->Animation.VerticalVelocity > 0)
item->Animation.VerticalVelocity = -(item->Animation.VerticalVelocity / 2);
if (item->Animation.Velocity.y > 0)
item->Animation.Velocity.y = -(item->Animation.Velocity.y / 2);
else
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
@ -1562,34 +1562,34 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
else
{
// Hit the floor; bounce and slow down.
if (item->Animation.VerticalVelocity > 0)
if (item->Animation.Velocity.y > 0)
{
if (item->Animation.VerticalVelocity > 16)
if (item->Animation.Velocity.y > 16)
{
if (item->ObjectNumber == ID_GRENADE)
item->Animation.VerticalVelocity = -(item->Animation.VerticalVelocity - (item->Animation.VerticalVelocity / 2));
item->Animation.Velocity.y = -(item->Animation.Velocity.y - (item->Animation.Velocity.y / 2));
else
{
item->Animation.VerticalVelocity = -(item->Animation.VerticalVelocity / 2);
if (item->Animation.VerticalVelocity < -100)
item->Animation.VerticalVelocity = -100;
item->Animation.Velocity.y = -(item->Animation.Velocity.y / 2);
if (item->Animation.Velocity.y < -100)
item->Animation.Velocity.y = -100;
}
}
else
{
// Roll on floor.
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
if (item->ObjectNumber == ID_GRENADE)
{
item->Animation.RequiredState = 1;
item->Pose.Orientation.x = 0;
item->Animation.Velocity--;
item->Animation.Velocity.z--;
}
else
item->Animation.Velocity -= 3;
item->Animation.Velocity.z -= 3;
if (item->Animation.Velocity < 0)
item->Animation.Velocity = 0;
if (item->Animation.Velocity.z < 0)
item->Animation.Velocity.z = 0;
}
}
@ -1613,34 +1613,34 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
if (item->Pose.Position.y >= oldCollResult.Position.Floor)
{
// Hit the floor; bounce and slow down.
if (item->Animation.VerticalVelocity > 0)
if (item->Animation.Velocity.y > 0)
{
if (item->Animation.VerticalVelocity > 16)
if (item->Animation.Velocity.y > 16)
{
if (item->ObjectNumber == ID_GRENADE)
item->Animation.VerticalVelocity = -(item->Animation.VerticalVelocity - (item->Animation.VerticalVelocity / 2));
item->Animation.Velocity.y = -(item->Animation.Velocity.y - (item->Animation.Velocity.y / 2));
else
{
item->Animation.VerticalVelocity = -(item->Animation.VerticalVelocity / 4);
if (item->Animation.VerticalVelocity < -100)
item->Animation.VerticalVelocity = -100;
item->Animation.Velocity.y = -(item->Animation.Velocity.y / 4);
if (item->Animation.Velocity.y < -100)
item->Animation.Velocity.y = -100;
}
}
else
{
// Roll on floor.
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
if (item->ObjectNumber == ID_GRENADE)
{
item->Animation.RequiredState = 1;
item->Pose.Orientation.x = 0;
item->Animation.Velocity--;
item->Animation.Velocity.z--;
}
else
item->Animation.Velocity -= 3;
item->Animation.Velocity.z -= 3;
if (item->Animation.Velocity < 0)
item->Animation.Velocity = 0;
if (item->Animation.Velocity.z < 0)
item->Animation.Velocity.z = 0;
}
}
@ -1673,9 +1673,9 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
item->Pose.Orientation.y = 0x8000 - item->Pose.Orientation.y;
if (item->ObjectNumber == ID_GRENADE)
item->Animation.Velocity -= item->Animation.Velocity / 8;
item->Animation.Velocity.z -= item->Animation.Velocity.z / 8;
else
item->Animation.Velocity /= 2;
item->Animation.Velocity.z /= 2;
// Put item back in its last position.
item->Pose.Position.x = x;
@ -1685,8 +1685,8 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv,
else
item->Pose.Position.y = collResult.Position.Ceiling;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity;
if (item->Animation.Velocity.y < 0)
item->Animation.Velocity.y = -item->Animation.Velocity.y;
}
}
}
@ -1778,7 +1778,7 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll)
if (item->HitPoints <= 0 || item->HitPoints == NOT_TARGETABLE)
continue;
if (harmless || abs(laraItem->Animation.Velocity) < VEHICLE_COLLISION_TERMINAL_VELOCITY)
if (harmless || abs(laraItem->Animation.Velocity.z) < VEHICLE_COLLISION_TERMINAL_VELOCITY)
{
// If vehicle is harmless or speed is too low, just push the enemy.
ItemPushItem(laraItem, item, coll, false, 0);
@ -1791,7 +1791,7 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll)
DoLotsOfBlood(item->Pose.Position.x,
laraItem->Pose.Position.y - CLICK(1),
item->Pose.Position.z,
laraItem->Animation.Velocity,
laraItem->Animation.Velocity.z,
laraItem->Pose.Orientation.y,
item->RoomNumber, 3);
}
@ -1823,7 +1823,7 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll)
// HACK: Shatter statics only by non-harmless vehicles.
if (!playerCollision &&
!harmless && abs(laraItem->Animation.Velocity) > VEHICLE_COLLISION_TERMINAL_VELOCITY &&
!harmless && abs(laraItem->Animation.Velocity.z) > VEHICLE_COLLISION_TERMINAL_VELOCITY &&
StaticObjects[mesh->staticNumber].shatterType != SHT_NONE)
{
SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh);

View file

@ -321,13 +321,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
tfLocation = GetRoom(item->Location, x, y, z);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
tcLocation = GetRoom(item->Location, x, y - item->Animation.VerticalVelocity, z);
tcLocation = GetRoom(item->Location, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(tcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -357,13 +357,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
tfLocation = GetRoom(tfLocation, x, y, z);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.VerticalVelocity, z);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(tcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -428,13 +428,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
lrfLocation = GetRoom(item->Location, x, y, z);
height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT);
lrcLocation = GetRoom(item->Location, x, y - item->Animation.VerticalVelocity, z);
lrcLocation = GetRoom(item->Location, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(lrcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -481,13 +481,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
tfLocation = GetRoom(tfLocation, x, y, z);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.VerticalVelocity, z);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(tcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -539,13 +539,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
lrfLocation = GetRoom(item->Location, x, y, z);
height = GetFloorHeight(lrfLocation, x, z).value_or(NO_HEIGHT);
lrcLocation = GetRoom(item->Location, x, y - item->Animation.VerticalVelocity, z);
lrcLocation = GetRoom(item->Location, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(lrcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -592,13 +592,13 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
tfLocation = GetRoom(tfLocation, x, y, z);
height = GetFloorHeight(tfLocation, x, z).value_or(NO_HEIGHT);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.VerticalVelocity, z);
tcLocation = GetRoom(tcLocation, x, y - item->Animation.Velocity.y, z);
ceiling = GetCeilingHeight(tcLocation, x, z).value_or(NO_HEIGHT);
}
else
{
height = collResult.Position.Floor;
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.VerticalVelocity, z);
ceiling = GetCeiling(collResult.Block, x, y - item->Animation.Velocity.y, z);
}
if (height != NO_HEIGHT) height -= (playerCollision ? yPos : y);
if (ceiling != NO_HEIGHT) ceiling -= y;
@ -719,7 +719,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
if (coll->TriangleAtLeft() && !coll->MiddleLeft.FloorSlope)
{
// HACK: Force slight push-out to the left side to avoid stucking
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity);
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity.z);
coll->Shift.x = coll->Setup.OldPosition.x - xPos;
coll->Shift.z = coll->Setup.OldPosition.z - zPos;
@ -771,7 +771,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
if (coll->TriangleAtRight() && !coll->MiddleRight.FloorSlope)
{
// HACK: Force slight push-out to the right side to avoid stucking
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity);
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity.z);
coll->Shift.x = coll->Setup.OldPosition.x - xPos;
coll->Shift.z = coll->Setup.OldPosition.z - zPos;
@ -1455,8 +1455,8 @@ int GetWaterHeight(ItemInfo* item)
short GetSurfaceSteepnessAngle(float xTilt, float zTilt)
{
short stepAngleIncrement = ANGLE(45.0f) / 4;
return (short)sqrt(pow(xTilt * stepAngleIncrement, 2) + pow(zTilt * stepAngleIncrement, 2));
short qtrBlockAngleIncrement = ANGLE(45.0f) / 4;
return (short)sqrt(pow(xTilt * qtrBlockAngleIncrement, 2) + pow(zTilt * qtrBlockAngleIncrement, 2));
}
short GetSurfaceAspectAngle(float xTilt, float zTilt)

View file

@ -266,8 +266,8 @@ void CreatureKill(ItemInfo* item, int killAnim, int killState, int laraKillState
LaraItem->Pose = item->Pose;
LaraItem->Animation.IsAirborne = false;
LaraItem->Animation.Velocity = 0;
LaraItem->Animation.VerticalVelocity = 0;
LaraItem->Animation.Velocity.z = 0;
LaraItem->Animation.Velocity.y = 0;
if (item->RoomNumber != LaraItem->RoomNumber)
ItemNewRoom(Lara.ItemNumber, item->RoomNumber);
@ -309,7 +309,7 @@ short CreatureEffect(ItemInfo* item, BITE_INFO* bite, std::function<CreatureEffe
auto pos = Vector3Int(bite->x, bite->y, bite->z);
GetJointAbsPosition(item, &pos, bite->meshNum);
return func(pos.x, pos.y, pos.z, item->Animation.Velocity, item->Pose.Orientation.y, item->RoomNumber);
return func(pos.x, pos.y, pos.z, item->Animation.Velocity.z, item->Pose.Orientation.y, item->RoomNumber);
}
void CreatureUnderwater(ItemInfo* item, int depth)
@ -428,7 +428,7 @@ short CreatureTurn(ItemInfo* item, short maxTurn)
int x = creature->Target.x - item->Pose.Position.x;
int z = creature->Target.z - item->Pose.Position.z;
angle = phd_atan(z, x) - item->Pose.Orientation.y;
int range = (item->Animation.Velocity * 16384) / maxTurn;
int range = (item->Animation.Velocity.z * 16384) / maxTurn;
int distance = pow(x, 2) + pow(z, 2);
if (angle > FRONT_ARC || angle < -FRONT_ARC && distance < pow(range, 2))
@ -629,7 +629,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
}
short biffAngle;
if (item->ObjectNumber != ID_TYRANNOSAUR && item->Animation.Velocity && item->HitPoints > 0)
if (item->ObjectNumber != ID_TYRANNOSAUR && item->Animation.Velocity.z && item->HitPoints > 0)
biffAngle = CreatureCreature(itemNumber);
else
biffAngle = 0;
@ -704,7 +704,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt)
floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber);
item->Floor = GetFloorHeight(floor, item->Pose.Position.x, y, item->Pose.Position.z);
angle = (item->Animation.Velocity) ? phd_atan(item->Animation.Velocity, -dy) : 0;
angle = (item->Animation.Velocity.z) ? phd_atan(item->Animation.Velocity.z, -dy) : 0;
if (angle < -ANGLE(20.0f))
angle = -ANGLE(20.0f);
else if (angle > ANGLE(20.0f))
@ -1490,13 +1490,13 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI)
if (enemy == LaraItem)
{
vector.x = enemy->Pose.Position.x + enemy->Animation.Velocity * PREDICTIVE_SCALE_FACTOR * phd_sin(Lara.Control.MoveAngle) - item->Pose.Position.x - object->pivotLength * phd_sin(item->Pose.Orientation.y);
vector.z = enemy->Pose.Position.z + enemy->Animation.Velocity * PREDICTIVE_SCALE_FACTOR * phd_cos(Lara.Control.MoveAngle) - item->Pose.Position.z - object->pivotLength * phd_cos(item->Pose.Orientation.y);
vector.x = enemy->Pose.Position.x + enemy->Animation.Velocity.z * PREDICTIVE_SCALE_FACTOR * phd_sin(Lara.Control.MoveAngle) - item->Pose.Position.x - object->pivotLength * phd_sin(item->Pose.Orientation.y);
vector.z = enemy->Pose.Position.z + enemy->Animation.Velocity.z * PREDICTIVE_SCALE_FACTOR * phd_cos(Lara.Control.MoveAngle) - item->Pose.Position.z - object->pivotLength * phd_cos(item->Pose.Orientation.y);
}
else
{
vector.x = enemy->Pose.Position.x + enemy->Animation.Velocity * PREDICTIVE_SCALE_FACTOR * phd_sin(enemy->Pose.Orientation.y) - item->Pose.Position.x - object->pivotLength * phd_sin(item->Pose.Orientation.y);
vector.z = enemy->Pose.Position.z + enemy->Animation.Velocity * PREDICTIVE_SCALE_FACTOR * phd_cos(enemy->Pose.Orientation.y) - item->Pose.Position.z - object->pivotLength * phd_cos(item->Pose.Orientation.y);
vector.x = enemy->Pose.Position.x + enemy->Animation.Velocity.z * PREDICTIVE_SCALE_FACTOR * phd_sin(enemy->Pose.Orientation.y) - item->Pose.Position.x - object->pivotLength * phd_sin(item->Pose.Orientation.y);
vector.z = enemy->Pose.Position.z + enemy->Animation.Velocity.z * PREDICTIVE_SCALE_FACTOR * phd_cos(enemy->Pose.Orientation.y) - item->Pose.Position.z - object->pivotLength * phd_cos(item->Pose.Orientation.y);
}
vector.y = item->Pose.Position.y - enemy->Pose.Position.y;

View file

@ -370,11 +370,12 @@ unsigned CALLBACK GameMain(void *)
TimeInit();
if (g_GameFlow->IntroImagePath.empty())
throw TENScriptException("Intro image path is not set.");
// Do a fixed time title image
g_Renderer.RenderTitleImage();
if (g_GameFlow->IntroImagePath.empty())
TENLog("Intro image path is not set.", LogLevel::Warning);
else
g_Renderer.RenderTitleImage();
// Execute the LUA gameflow and play the game
g_GameFlow->DoFlow();
@ -717,6 +718,9 @@ void CleanUp()
DisableBubbles();
DisableDebris();
// Clear swarm enemies
ClearSwarmEnemies(nullptr);
// Clear soundtrack masks
ClearSoundTrackMasks();
}

View file

@ -22,6 +22,7 @@
#include "Objects/TR5/Emitter/tr5_spider_emitter.h"
#include "Objects/TR5/Emitter/tr5_rats_emitter.h"
#include "Objects/TR5/Object/tr5_pushableblock.h"
#include "Objects/Effects/tr4_locusts.h"
using std::function;
using namespace TEN::Effects::Footprints;
@ -85,6 +86,7 @@ void ClearSwarmEnemies(ItemInfo* item)
ClearSpiders();
ClearRats();
ClearBeetleSwarm();
ClearLocusts();
}
void FlashOrange(ItemInfo* item)

View file

@ -42,7 +42,7 @@ void TriggerChaffEffects(int flareAge)
vel.y = vect.y - pos.y;
vel.z = vect.z - pos.z;
TriggerChaffEffects(LaraItem, &pos, &vel, LaraItem->Animation.Velocity, (bool)(g_Level.Rooms[LaraItem->RoomNumber].flags & ENV_FLAG_WATER), flareAge);
TriggerChaffEffects(LaraItem, &pos, &vel, LaraItem->Animation.Velocity.z, (bool)(g_Level.Rooms[LaraItem->RoomNumber].flags & ENV_FLAG_WATER), flareAge);
}
void TriggerChaffEffects(ItemInfo* Item, int age)
@ -66,7 +66,7 @@ void TriggerChaffEffects(ItemInfo* Item, int age)
vel.y = world.Translation().y;
vel.z = world.Translation().z;
TriggerChaffEffects(Item, &pos, &vel, Item->Animation.Velocity, (bool)(g_Level.Rooms[Item->RoomNumber].flags & ENV_FLAG_WATER), age);
TriggerChaffEffects(Item, &pos, &vel, Item->Animation.Velocity.z, (bool)(g_Level.Rooms[Item->RoomNumber].flags & ENV_FLAG_WATER), age);
}
void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int speed, bool isUnderwater, int age)

View file

@ -1228,7 +1228,7 @@ void WadeSplash(ItemInfo* item, int wh, int wd)
if (item->Pose.Position.y + frame->boundingBox.Y2 < wh)
return;
if (item->Animation.VerticalVelocity <= 0 || wd >= 474 || SplashCount != 0)
if (item->Animation.Velocity.y <= 0 || wd >= 474 || SplashCount != 0)
{
if (!(Wibble & 0xF))
{
@ -1247,7 +1247,7 @@ void WadeSplash(ItemInfo* item, int wh, int wd)
SplashSetup.x = item->Pose.Position.x;
SplashSetup.z = item->Pose.Position.z;
SplashSetup.innerRadius = 16;
SplashSetup.splashPower = item->Animation.Velocity;
SplashSetup.splashPower = item->Animation.Velocity.z;
SetupSplash(&SplashSetup, probe1.RoomNumber);
SplashCount = 16;
}
@ -1265,7 +1265,7 @@ void Splash(ItemInfo* item)
SplashSetup.y = waterHeight - 1;
SplashSetup.x = item->Pose.Position.x;
SplashSetup.z = item->Pose.Position.z;
SplashSetup.splashPower = item->Animation.VerticalVelocity;
SplashSetup.splashPower = item->Animation.Velocity.y;
SplashSetup.innerRadius = 64;
SetupSplash(&SplashSetup, roomNumber);
}

View file

@ -49,7 +49,7 @@ struct FX_INFO
short fallspeed;
int frameNumber;
short counter;
short shade;
Vector4 color;
short flag1;
short flag2;
};

View file

@ -1506,7 +1506,7 @@ void ExplodingDeath(short itemNumber, short flags)
}
fx->objectNumber = ID_BODY_PART;
fx->shade = 16912;
fx->color = item->Color;
fx->flag2 = flags;
fx->frameNumber = obj->meshIndex + i;
}

View file

@ -106,39 +106,24 @@ namespace TEN::Effects::Environment
void EnvironmentController::UpdateSky(ScriptInterfaceLevel* level)
{
if (level->GetSkyLayerEnabled(0))
for (int i = 0; i < 2; i++)
{
SkyPosition1 += level->GetSkyLayerSpeed(0);
if (SkyPosition1 <= SKY_POSITION_LIMIT)
{
if (SkyPosition1 < 0)
SkyPosition1 += SKY_POSITION_LIMIT;
}
else
{
SkyPosition1 -= SKY_POSITION_LIMIT;
}
}
if (!level->GetSkyLayerEnabled(i))
continue;
if (level->GetSkyLayerEnabled(1))
{
SkyPosition2 += level->GetSkyLayerSpeed(1);
if (SkyPosition2 <= SKY_POSITION_LIMIT)
SkyCurrentPosition[i] += level->GetSkyLayerSpeed(i);
if (SkyCurrentPosition[i] <= SKY_POSITION_LIMIT)
{
if (SkyPosition2 < 0)
SkyPosition2 += SKY_POSITION_LIMIT;
if (SkyCurrentPosition[i] < 0)
SkyCurrentPosition[i] += SKY_POSITION_LIMIT;
}
else
{
SkyPosition2 -= SKY_POSITION_LIMIT;
}
SkyCurrentPosition[i] -= SKY_POSITION_LIMIT;
}
}
void EnvironmentController::UpdateStorm(ScriptInterfaceLevel* level)
{
auto color = Vector4(level->GetSkyLayerColor(0).GetR() / 255.0f, level->GetSkyLayerColor(0).GetG() / 255.0f, level->GetSkyLayerColor(0).GetB() / 255.0f, 1.0f);
if (level->HasStorm())
{
if (StormCount || StormRand)
@ -154,16 +139,26 @@ namespace TEN::Effects::Environment
StormCount = (rand() & 0x1F) + 16;
StormTimer = (rand() & 3) + 12;
}
auto flashBrightness = StormSkyColor / 255.0f;
auto r = std::clamp(color.x + flashBrightness, 0.0f, 1.0f);
auto g = std::clamp(color.y + flashBrightness, 0.0f, 1.0f);
auto b = std::clamp(color.z + flashBrightness, 0.0f, 1.0f);
SkyCurrentColor = Vector4(r, g, b, color.w);
}
else
SkyCurrentColor = color;
for (int i = 0; i < 2; i++)
{
auto color = Vector4(level->GetSkyLayerColor(i).GetR() / 255.0f,
level->GetSkyLayerColor(i).GetG() / 255.0f,
level->GetSkyLayerColor(i).GetB() / 255.0f, 1.0f);
if (level->HasStorm())
{
auto flashBrightness = StormSkyColor / 255.0f;
auto r = std::clamp(color.x + flashBrightness, 0.0f, 1.0f);
auto g = std::clamp(color.y + flashBrightness, 0.0f, 1.0f);
auto b = std::clamp(color.z + flashBrightness, 0.0f, 1.0f);
SkyCurrentColor[i] = Vector4(r, g, b, color.w);
}
else
SkyCurrentColor[i] = color;
}
}
void EnvironmentController::UpdateLightning()

View file

@ -31,9 +31,8 @@ namespace TEN::Effects::Environment
Vector3 Wind() { return Vector3(WindX / 2.0f, 0, WindZ / 2.0f); }
Vector3 FlashColor() { return FlashColorBase * sin(FlashProgress * PI / 2.0f); }
Vector4 SkyColor() { return SkyCurrentColor; }
short SkyLayer1Position() { return SkyPosition1; }
short SkyLayer2Position() { return SkyPosition2; }
Vector4 SkyColor(int index) { return SkyCurrentColor[std::clamp(index, 0, 1)]; }
short SkyPosition(int index) { return SkyCurrentPosition[std::clamp(index, 0, 1)]; }
void Flash(int r, int g, int b, float speed);
void Update();
@ -46,9 +45,8 @@ namespace TEN::Effects::Environment
std::vector<WeatherParticle> Particles;
// Sky
Vector4 SkyCurrentColor = Vector4::Zero;
short SkyPosition1 = 0;
short SkyPosition2 = 0;
Vector4 SkyCurrentColor[2] = {};
short SkyCurrentPosition[2] = {};
// Wind
int WindX = 0;

View file

@ -374,7 +374,7 @@ short CreateNewEffect(short roomNum)
room->fxNumber = fxNumber;
fx->nextActive = NextFxActive;
NextFxActive = fxNumber;
fx->shade = GRAY555;
fx->color = Vector4::One;
}
return fxNumber;
@ -457,8 +457,8 @@ void InitialiseItem(short itemNumber)
item->Pose.Orientation.z = 0;
item->Pose.Orientation.x = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.Velocity.z = 0;
item->ItemFlags[3] = 0;
item->ItemFlags[2] = 0;

View file

@ -1,8 +1,8 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "Game/animation.h"
#include "Game/itemdata/itemdata.h"
#include "Specific/newtypes.h"
@ -10,12 +10,6 @@
enum GAME_OBJECT_ID : short;
// used by fx->shade !
#define RGB555(r, g, b) ((r << 7) & 0x7C00 | (g << 2) & 0x3E0 | (b >> 3) & 0x1F)
#define WHITE555 RGB555(255, 255, 255)
#define GRAY555 RGB555(128, 128, 128)
#define BLACK555 RGB555( 0, 0, 0)
constexpr auto NO_ITEM = -1;
constexpr auto NOT_TARGETABLE = -16384;
constexpr auto NUM_ITEMS = 1024;
@ -61,17 +55,15 @@ enum class JointBitType
struct EntityAnimationData
{
int AnimNumber;
int FrameNumber;
int ActiveState;
int TargetState;
int RequiredState; // TODO: Phase out this weird feature.
int AnimNumber = -1;
int FrameNumber = -1;
int ActiveState = -1;
int TargetState = -1;
int RequiredState = -1; // TODO: Phase out this weird feature.
bool IsAirborne;
int Velocity;
int VerticalVelocity;
int LateralVelocity;
std::vector<BONE_MUTATOR> Mutator;
bool IsAirborne = false;
Vector3 Velocity = Vector3::Zero; // CONVENTION: +X is right, +Y is down, +Z is forward.
std::vector<BoneMutator> Mutator = {};
};
//todo we need to find good "default states" for a lot of these - squidshire 25/05/2022

View file

@ -103,7 +103,7 @@ void ControlMissile(short fxNumber)
LaraItem->HitStatus = 1;
fx->pos.Orientation.y = LaraItem->Pose.Orientation.y;
fx->speed = LaraItem->Animation.Velocity;
fx->speed = LaraItem->Animation.Velocity.z;
fx->frameNumber = fx->counter = 0;
}
@ -178,7 +178,7 @@ short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber
fx->speed = SHARD_VELOCITY;
fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_SHARD;
fx->shade = 14 * 256;
fx->color = Vector4::One;
ShootAtLara(fx);
}
@ -201,7 +201,7 @@ short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
fx->speed = ROCKET_VELOCITY;
fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_BOMB;
fx->shade = 16 * 256;
fx->color = Vector4::One;
ShootAtLara(fx);
}
@ -224,7 +224,7 @@ short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber
fx->speed = NATLA_GUN_VELOCITY;
fx->frameNumber = 0;
fx->objectNumber = ID_PROJ_NATLA;
fx->shade = 16 * 256;
fx->color = Vector4::One;
ShootAtLara(fx);
}

View file

@ -22,7 +22,7 @@ bool ShotLara(ItemInfo* item, AI_INFO* AI, BITE_INFO* gun, short extraRotation,
if (AI->distance <= pow(MAX_VISIBILITY_DISTANCE, 2) && Targetable(item, AI))
{
int distance = phd_sin(AI->enemyFacing) * enemy->Animation.Velocity * pow(MAX_VISIBILITY_DISTANCE, 2) / 300;
int distance = phd_sin(AI->enemyFacing) * enemy->Animation.Velocity.z * pow(MAX_VISIBILITY_DISTANCE, 2) / 300;
distance = pow(distance, 2) + AI->distance;
if (distance <= pow(MAX_VISIBILITY_DISTANCE, 2))
{

View file

@ -345,7 +345,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
getThisItemPlease = itemNumber;
laraItem->Animation.AnimNumber = LA_UNDERWATER_PICKUP_FLARE;
laraItem->Animation.ActiveState = LS_PICKUP_FLARE;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
}
else
{
@ -773,8 +773,8 @@ void PickupControl(short itemNumber)
switch (triggerFlags)
{
case 5:
item->Animation.VerticalVelocity += 6;
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.y += 6;
item->Pose.Position.y += item->Animation.Velocity.y;
roomNumber = item->RoomNumber;
GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
@ -782,10 +782,10 @@ void PickupControl(short itemNumber)
if (item->Pose.Position.y > item->ItemFlags[0])
{
item->Pose.Position.y = item->ItemFlags[0];
if (item->Animation.VerticalVelocity <= 64)
if (item->Animation.Velocity.y <= 64)
item->TriggerFlags &= 0xC0;
else
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 2;
item->Animation.Velocity.y = -item->Animation.Velocity.y / 4;
}
if (item->RoomNumber != roomNumber)

View file

@ -102,6 +102,46 @@ Save::Position FromPHD(PHD_3DPOS const& src)
};
}
Save::Vector3 FromVector3(Vector3 vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector3 FromVector3(Vector3Int vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector3 FromVector3(Vector3Shrt vec)
{
return Save::Vector3(vec.x, vec.y, vec.z);
}
Save::Vector4 FromVector4(Vector4 vec)
{
return Save::Vector4(vec.x, vec.y, vec.z, vec.w);
}
Vector3Shrt ToVector3Shrt(const Save::Vector3* vec)
{
return Vector3Shrt(short(vec->x()), short(vec->y()), short(vec->z()));
}
Vector3Int ToVector3Int(const Save::Vector3* vec)
{
return Vector3Int(int(vec->x()), int(vec->y()), int(vec->z()));
}
Vector3 ToVector3(const Save::Vector3* vec)
{
return Vector3(vec->x(), vec->y(), vec->z());
}
Vector4 ToVector4(const Save::Vector4* vec)
{
return Vector4(vec->x(), vec->y(), vec->z(), vec->w());
}
bool SaveGame::Save(int slot)
{
auto fileName = std::string(SAVEGAME_PATH) + "savegame." + std::to_string(slot);
@ -196,17 +236,6 @@ bool SaveGame::Save(int slot)
wet.push_back(Lara.Wet[i] == 1);
auto wetOffset = fbb.CreateVector(wet);
Save::Vector3 nextCornerPos = Save::Vector3(Lara.NextCornerPos.Position.x, Lara.NextCornerPos.Position.y, Lara.NextCornerPos.Position.z);
Save::Vector3 nextCornerRot = Save::Vector3(Lara.NextCornerPos.Orientation.x, Lara.NextCornerPos.Orientation.y, Lara.NextCornerPos.Orientation.z);
Save::Vector3 leftArmRotation = Save::Vector3(Lara.LeftArm.Orientation.x, Lara.LeftArm.Orientation.y, Lara.LeftArm.Orientation.z);
Save::Vector3 rightArmRotation = Save::Vector3(Lara.RightArm.Orientation.x, Lara.RightArm.Orientation.y, Lara.RightArm.Orientation.z);
Save::Vector3 extraHeadRot = Save::Vector3(Lara.ExtraHeadRot.x, Lara.ExtraHeadRot.y, Lara.ExtraHeadRot.z);
Save::Vector3 extraTorsoRot = Save::Vector3(Lara.ExtraTorsoRot.x, Lara.ExtraTorsoRot.y, Lara.ExtraTorsoRot.z);
Save::Vector3 extraVelocity = Save::Vector3(Lara.ExtraVelocity.x, Lara.ExtraVelocity.y, Lara.ExtraVelocity.z);
Save::Vector3 waterCurrentPull = Save::Vector3(Lara.WaterCurrentPull.x, Lara.WaterCurrentPull.y, Lara.WaterCurrentPull.z);
std::vector<int> laraTargetAngles{};
laraTargetAngles.push_back(Lara.TargetArmOrient.y);
laraTargetAngles.push_back(Lara.TargetArmOrient.x);
@ -230,7 +259,7 @@ bool SaveGame::Save(int slot)
leftArm.add_frame_base(Lara.LeftArm.FrameBase);
leftArm.add_frame_number(Lara.LeftArm.FrameNumber);
leftArm.add_locked(Lara.LeftArm.Locked);
leftArm.add_rotation(&leftArmRotation);
leftArm.add_rotation(&FromVector3(Lara.LeftArm.Orientation));
auto leftArmOffset = leftArm.Finish();
Save::ArmInfoBuilder rightArm{ fbb };
@ -240,7 +269,7 @@ bool SaveGame::Save(int slot)
rightArm.add_frame_base(Lara.RightArm.FrameBase);
rightArm.add_frame_number(Lara.RightArm.FrameNumber);
rightArm.add_locked(Lara.RightArm.Locked);
rightArm.add_rotation(&rightArmRotation);
rightArm.add_rotation(&FromVector3(Lara.RightArm.Orientation));
auto rightArmOffset = rightArm.Finish();
Save::FlareDataBuilder flare{ fbb };
@ -397,12 +426,10 @@ bool SaveGame::Save(int slot)
lara.add_burn_blue(Lara.BurnBlue);
lara.add_burn_smoke(Lara.BurnSmoke);
lara.add_control(controlOffset);
lara.add_next_corner_position(&nextCornerPos);
lara.add_next_corner_rotation(&nextCornerRot);
lara.add_next_corner_pose(&FromPHD(Lara.NextCornerPos));
lara.add_extra_anim(Lara.ExtraAnim);
lara.add_extra_head_rot(&extraHeadRot);
lara.add_extra_torso_rot(&extraTorsoRot);
lara.add_extra_velocity(&extraVelocity);
lara.add_extra_head_rot(&FromVector3(Lara.ExtraHeadRot));
lara.add_extra_torso_rot(&FromVector3(Lara.ExtraTorsoRot));
lara.add_flare(flareOffset);
lara.add_highest_location(Lara.HighestLocation);
lara.add_hit_direction(Lara.HitDirection);
@ -424,7 +451,7 @@ bool SaveGame::Save(int slot)
lara.add_torch(torchOffset);
lara.add_vehicle(Lara.Vehicle);
lara.add_water_current_active(Lara.WaterCurrentActive);
lara.add_water_current_pull(&waterCurrentPull);
lara.add_water_current_pull(&FromVector3(Lara.WaterCurrentPull));
lara.add_water_surface_dist(Lara.WaterSurfaceDist);
lara.add_weapons(carriedWeaponsOffset);
lara.add_wet(wetOffset);
@ -563,13 +590,7 @@ bool SaveGame::Save(int slot)
kayakBuilder.add_front_vertical_velocity(kayak->FrontVerticalVelocity);
kayakBuilder.add_left_right_count(kayak->LeftRightPaddleCount);
kayakBuilder.add_left_vertical_velocity(kayak->LeftVerticalVelocity);
kayakBuilder.add_old_pos(&Save::Position(
kayak->OldPose.Position.x,
kayak->OldPose.Position.y,
kayak->OldPose.Position.z,
kayak->OldPose.Orientation.x,
kayak->OldPose.Orientation.y,
kayak->OldPose.Orientation.z));
kayakBuilder.add_old_pos(&FromPHD(kayak->OldPose));
kayakBuilder.add_right_vertical_velocity(kayak->RightVerticalVelocity);
kayakBuilder.add_true_water(kayak->TrueWater);
kayakBuilder.add_turn(kayak->Turn);
@ -592,22 +613,7 @@ bool SaveGame::Save(int slot)
intOffset = ib.Finish();
}
Save::Position position = Save::Position(
(int32_t)itemToSerialize.Pose.Position.x,
(int32_t)itemToSerialize.Pose.Position.y,
(int32_t)itemToSerialize.Pose.Position.z,
(int32_t)itemToSerialize.Pose.Orientation.x,
(int32_t)itemToSerialize.Pose.Orientation.y,
(int32_t)itemToSerialize.Pose.Orientation.z);
Save::Vector4 color = Save::Vector4(
itemToSerialize.Color.x,
itemToSerialize.Color.y,
itemToSerialize.Color.z,
itemToSerialize.Color.w);
Save::ItemBuilder serializedItem{ fbb };
serializedItem.add_next_item(itemToSerialize.NextItem);
serializedItem.add_next_item_active(itemToSerialize.NextActive);
serializedItem.add_anim_number(itemToSerialize.Animation.AnimNumber - obj->animIndex);
@ -615,7 +621,6 @@ bool SaveGame::Save(int slot)
serializedItem.add_box_number(itemToSerialize.BoxNumber);
serializedItem.add_carried_item(itemToSerialize.CarriedItem);
serializedItem.add_active_state(itemToSerialize.Animation.ActiveState);
serializedItem.add_vertical_velocity(itemToSerialize.Animation.VerticalVelocity);
serializedItem.add_flags(itemToSerialize.Flags);
serializedItem.add_floor(itemToSerialize.Floor);
serializedItem.add_frame_number(itemToSerialize.Animation.FrameNumber);
@ -624,12 +629,12 @@ bool SaveGame::Save(int slot)
serializedItem.add_item_flags(itemFlagsOffset);
serializedItem.add_mesh_bits(itemToSerialize.MeshBits);
serializedItem.add_object_id(itemToSerialize.ObjectNumber);
serializedItem.add_position(&position);
serializedItem.add_pose(&FromPHD(itemToSerialize.Pose));
serializedItem.add_required_state(itemToSerialize.Animation.RequiredState);
serializedItem.add_room_number(itemToSerialize.RoomNumber);
serializedItem.add_velocity(itemToSerialize.Animation.Velocity);
serializedItem.add_velocity(&FromVector3(itemToSerialize.Animation.Velocity));
serializedItem.add_timer(itemToSerialize.Timer);
serializedItem.add_color(&color);
serializedItem.add_color(&FromVector4(itemToSerialize.Color));
serializedItem.add_touch_bits(itemToSerialize.TouchBits);
serializedItem.add_trigger_flags(itemToSerialize.TriggerFlags);
serializedItem.add_triggered((itemToSerialize.Flags & (TRIGGERED | CODE_BITS | ONESHOT)) != 0);
@ -700,9 +705,8 @@ bool SaveGame::Save(int slot)
for (auto& effectToSerialize : EffectList)
{
Save::FXInfoBuilder serializedEffect{ fbb };
auto savedPos = FromPHD(effectToSerialize.pos);
serializedEffect.add_pos(&savedPos);
serializedEffect.add_pose(&FromPHD(effectToSerialize.pos));
serializedEffect.add_room_number(effectToSerialize.roomNumber);
serializedEffect.add_object_number(effectToSerialize.objectNumber);
serializedEffect.add_next_fx(effectToSerialize.nextFx);
@ -711,7 +715,7 @@ bool SaveGame::Save(int slot)
serializedEffect.add_fall_speed(effectToSerialize.fallspeed);
serializedEffect.add_frame_number(effectToSerialize.frameNumber);
serializedEffect.add_counter(effectToSerialize.counter);
serializedEffect.add_shade(effectToSerialize.shade);
serializedEffect.add_color(&FromVector4(effectToSerialize.color));
serializedEffect.add_flag1(effectToSerialize.flag1);
serializedEffect.add_flag2(effectToSerialize.flag2);
@ -808,18 +812,8 @@ bool SaveGame::Save(int slot)
{
Save::StaticMeshInfoBuilder staticMesh{ fbb };
staticMesh.add_position(&Save::Vector3(room->mesh[j].pos.Position.x,
room->mesh[j].pos.Position.y,
room->mesh[j].pos.Position.z));
staticMesh.add_rotation(&Save::Vector3(room->mesh[j].pos.Orientation.x,
room->mesh[j].pos.Orientation.y,
room->mesh[j].pos.Orientation.z));
staticMesh.add_color(&Save::Vector4(room->mesh[j].color.x,
room->mesh[j].color.y,
room->mesh[j].color.z,
room->mesh[j].color.w));
staticMesh.add_pose(&FromPHD(room->mesh[j].pos));
staticMesh.add_color(&FromVector4(room->mesh[j].color));
staticMesh.add_flags(room->mesh[j].flags);
staticMesh.add_hit_points(room->mesh[j].HitPoints);
@ -837,18 +831,9 @@ bool SaveGame::Save(int slot)
volumeState.add_room_number(i);
volumeState.add_number(j);
volumeState.add_position(&Save::Vector3(volume.Position.x,
volume.Position.y,
volume.Position.z));
volumeState.add_rotation(&Save::Vector4(volume.Rotation.x,
volume.Rotation.y,
volume.Rotation.z,
volume.Rotation.w));
volumeState.add_scale(&Save::Vector3(volume.Scale.x,
volume.Scale.y,
volume.Scale.z));
volumeState.add_position(&FromVector3(volume.Position));
volumeState.add_rotation(&FromVector4(volume.Rotation));
volumeState.add_scale(&FromVector3(volume.Scale));
int triggerer = -1;
if (std::holds_alternative<short>(volume.Triggerer))
@ -916,86 +901,66 @@ bool SaveGame::Save(int slot)
}
auto particleOffset = fbb.CreateVector(particles);
// Particle enemies
std::vector<flatbuffers::Offset<Save::BatInfo>> bats;
// Swarm enemies
std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> bats;
for (int i = 0; i < NUM_BATS; i++)
{
auto* bat = &Bats[i];
Save::BatInfoBuilder batInfo{ fbb };
Save::SwarmObjectInfoBuilder batInfo{ fbb };
batInfo.add_counter(bat->Counter);
batInfo.add_flags(bat->Counter);
batInfo.add_on(bat->On);
batInfo.add_room_number(bat->RoomNumber);
batInfo.add_x(bat->Pose.Position.x);
batInfo.add_y(bat->Pose.Position.y);
batInfo.add_z(bat->Pose.Position.z);
batInfo.add_x_rot(bat->Pose.Orientation.x);
batInfo.add_y_rot(bat->Pose.Orientation.y);
batInfo.add_z_rot(bat->Pose.Orientation.z);
batInfo.add_pose(&FromPHD(bat->Pose));
bats.push_back(batInfo.Finish());
}
auto batsOffset = fbb.CreateVector(bats);
std::vector<flatbuffers::Offset<Save::SpiderInfo>> spiders;
std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> spiders;
for (int i = 0; i < NUM_SPIDERS; i++)
{
auto* spider = &Spiders[i];
Save::SpiderInfoBuilder spiderInfo{ fbb };
Save::SwarmObjectInfoBuilder spiderInfo{ fbb };
spiderInfo.add_flags(spider->Flags);
spiderInfo.add_on(spider->On);
spiderInfo.add_room_number(spider->RoomNumber);
spiderInfo.add_x(spider->Pose.Position.x);
spiderInfo.add_y(spider->Pose.Position.y);
spiderInfo.add_z(spider->Pose.Position.z);
spiderInfo.add_x_rot(spider->Pose.Orientation.x);
spiderInfo.add_y_rot(spider->Pose.Orientation.y);
spiderInfo.add_z_rot(spider->Pose.Orientation.z);
spiderInfo.add_pose(&FromPHD(spider->Pose));
spiders.push_back(spiderInfo.Finish());
}
auto spidersOffset = fbb.CreateVector(spiders);
std::vector<flatbuffers::Offset<Save::RatInfo>> rats;
std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> rats;
for (int i = 0; i < NUM_RATS; i++)
{
auto* rat = &Rats[i];
Save::RatInfoBuilder ratInfo{ fbb };
Save::SwarmObjectInfoBuilder ratInfo{ fbb };
ratInfo.add_flags(rat->Flags);
ratInfo.add_on(rat->On);
ratInfo.add_room_number(rat->RoomNumber);
ratInfo.add_x(rat->Pose.Position.x);
ratInfo.add_y(rat->Pose.Position.y);
ratInfo.add_z(rat->Pose.Position.z);
ratInfo.add_x_rot(rat->Pose.Orientation.x);
ratInfo.add_y_rot(rat->Pose.Orientation.y);
ratInfo.add_z_rot(rat->Pose.Orientation.z);
ratInfo.add_pose(&FromPHD(rat->Pose));
rats.push_back(ratInfo.Finish());
}
auto ratsOffset = fbb.CreateVector(rats);
std::vector<flatbuffers::Offset<Save::ScarabInfo>> scarabs;
std::vector<flatbuffers::Offset<Save::SwarmObjectInfo>> scarabs;
for (int i = 0; i < NUM_BATS; i++)
{
auto* beetle = &BeetleSwarm[i];
Save::ScarabInfoBuilder scarabInfo{ fbb };
Save::SwarmObjectInfoBuilder scarabInfo{ fbb };
scarabInfo.add_flags(beetle->Flags);
scarabInfo.add_on(beetle->On);
scarabInfo.add_room_number(beetle->RoomNumber);
scarabInfo.add_x(beetle->Pose.Position.x);
scarabInfo.add_y(beetle->Pose.Position.y);
scarabInfo.add_z(beetle->Pose.Position.z);
scarabInfo.add_x_rot(beetle->Pose.Orientation.x);
scarabInfo.add_y_rot(beetle->Pose.Orientation.y);
scarabInfo.add_z_rot(beetle->Pose.Orientation.z);
scarabInfo.add_pose(&FromPHD(beetle->Pose));
scarabs.push_back(scarabInfo.Finish());
}
@ -1012,42 +977,27 @@ bool SaveGame::Save(int slot)
std::vector<const Save::Vector3*> segments;
for (int i = 0; i < ROPE_SEGMENTS; i++)
segments.push_back(&Save::Vector3(
rope->segment[i].x,
rope->segment[i].y,
rope->segment[i].z));
segments.push_back(&FromVector3(rope->segment[i]));
auto segmentsOffset = fbb.CreateVector(segments);
std::vector<const Save::Vector3*> velocities;
for (int i = 0; i < ROPE_SEGMENTS; i++)
velocities.push_back(&Save::Vector3(
rope->velocity[i].x,
rope->velocity[i].y,
rope->velocity[i].z));
velocities.push_back(&FromVector3(rope->velocity[i]));
auto velocitiesOffset = fbb.CreateVector(velocities);
std::vector<const Save::Vector3*> normalisedSegments;
for (int i = 0; i < ROPE_SEGMENTS; i++)
normalisedSegments.push_back(&Save::Vector3(
rope->normalisedSegment[i].x,
rope->normalisedSegment[i].y,
rope->normalisedSegment[i].z));
normalisedSegments.push_back(&FromVector3(rope->normalisedSegment[i]));
auto normalisedSegmentsOffset = fbb.CreateVector(normalisedSegments);
std::vector<const Save::Vector3*> meshSegments;
for (int i = 0; i < ROPE_SEGMENTS; i++)
meshSegments.push_back(&Save::Vector3(
rope->meshSegment[i].x,
rope->meshSegment[i].y,
rope->meshSegment[i].z));
meshSegments.push_back(&FromVector3(rope->meshSegment[i]));
auto meshSegmentsOffset = fbb.CreateVector(meshSegments);
std::vector<const Save::Vector3*> coords;
for (int i = 0; i < ROPE_SEGMENTS; i++)
coords.push_back(&Save::Vector3(
rope->coords[i].x,
rope->coords[i].y,
rope->coords[i].z));
coords.push_back(&FromVector3(rope->coords[i]));
auto coordsOffset = fbb.CreateVector(coords);
Save::RopeBuilder ropeInfo{ fbb };
@ -1058,36 +1008,21 @@ bool SaveGame::Save(int slot)
ropeInfo.add_normalised_segments(normalisedSegmentsOffset);
ropeInfo.add_coords(coordsOffset);
ropeInfo.add_coiled(rope->coiled);
ropeInfo.add_position(&Save::Vector3(
rope->position.x,
rope->position.y,
rope->position.z));
ropeInfo.add_position(&FromVector3(rope->position));
ropeInfo.add_segment_length(rope->segmentLength);
ropeOffset = ropeInfo.Finish();
Save::PendulumBuilder pendulumInfo{ fbb };
pendulumInfo.add_node(CurrentPendulum.node);
pendulumInfo.add_position(&Save::Vector3(
CurrentPendulum.position.x,
CurrentPendulum.position.y,
CurrentPendulum.position.z));
pendulumInfo.add_velocity(&Save::Vector3(
CurrentPendulum.velocity.x,
CurrentPendulum.velocity.y,
CurrentPendulum.velocity.z));
pendulumInfo.add_position(&FromVector3(CurrentPendulum.position));
pendulumInfo.add_velocity(&FromVector3(CurrentPendulum.velocity));
pendulumOffset = pendulumInfo.Finish();
Save::PendulumBuilder alternatePendulumInfo{ fbb };
alternatePendulumInfo.add_node(AlternatePendulum.node);
alternatePendulumInfo.add_position(&Save::Vector3(
AlternatePendulum.position.x,
AlternatePendulum.position.y,
AlternatePendulum.position.z));
alternatePendulumInfo.add_velocity(&Save::Vector3(
AlternatePendulum.velocity.x,
AlternatePendulum.velocity.y,
AlternatePendulum.velocity.z));
alternatePendulumInfo.add_position(&FromVector3(AlternatePendulum.position));
alternatePendulumInfo.add_velocity(&FromVector3(AlternatePendulum.velocity));
alternatePendulumOffset = alternatePendulumInfo.Finish();
}
@ -1298,18 +1233,8 @@ bool SaveGame::Load(int slot)
auto room = &g_Level.Rooms[staticMesh->room_number()];
int number = staticMesh->number();
room->mesh[number].pos.Position = Vector3Int(staticMesh->position()->x(),
staticMesh->position()->y(),
staticMesh->position()->z());
room->mesh[number].pos.Orientation = Vector3Shrt(short(staticMesh->rotation()->x()),
short(staticMesh->rotation()->y()),
short(staticMesh->rotation()->z()));
room->mesh[number].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].pos = ToPHD(staticMesh->pose());
room->mesh[number].color = ToVector4(staticMesh->color());
room->mesh[number].flags = staticMesh->flags();
room->mesh[number].HitPoints = staticMesh->hit_points();
@ -1330,18 +1255,9 @@ bool SaveGame::Load(int slot)
auto room = &g_Level.Rooms[volume->room_number()];
int number = volume->number();
room->triggerVolumes[number].Position = Vector3(volume->position()->x(),
volume->position()->y(),
volume->position()->z());
room->triggerVolumes[number].Rotation = Vector4(volume->rotation()->x(),
volume->rotation()->y(),
volume->rotation()->z(),
volume->rotation()->w());
room->triggerVolumes[number].Scale = Vector3(volume->scale()->x(),
volume->scale()->y(),
volume->scale()->z());
room->triggerVolumes[number].Position = ToVector3(volume->position());
room->triggerVolumes[number].Rotation = ToVector4(volume->rotation());
room->triggerVolumes[number].Scale = ToVector3(volume->scale());
int triggerer = volume->triggerer();
if (triggerer >= 0)
@ -1410,17 +1326,10 @@ bool SaveGame::Load(int slot)
g_GameScriptEntities->TryAddColliding(i);
item->Pose.Position.x = savedItem->position()->x_pos();
item->Pose.Position.y = savedItem->position()->y_pos();
item->Pose.Position.z = savedItem->position()->z_pos();
item->Pose.Orientation.x = savedItem->position()->x_rot();
item->Pose.Orientation.y = savedItem->position()->y_rot();
item->Pose.Orientation.z = savedItem->position()->z_rot();
item->Pose = ToPHD(savedItem->pose());
item->RoomNumber = savedItem->room_number();
item->Animation.Velocity = savedItem->velocity();
item->Animation.VerticalVelocity = savedItem->vertical_velocity();
item->Animation.Velocity = ToVector3(savedItem->velocity());
if (item->ObjectNumber == ID_LARA && !dynamicItem)
{
@ -1454,10 +1363,7 @@ bool SaveGame::Load(int slot)
item->Flags = savedItem->flags();
// Color
item->Color = Vector4(savedItem->color()->x(),
savedItem->color()->y(),
savedItem->color()->z(),
savedItem->color()->w());
item->Color = ToVector4(savedItem->color());
// Carried item
item->CarriedItem = savedItem->carried_item();
@ -1591,12 +1497,7 @@ bool SaveGame::Load(int slot)
kayak->FrontVerticalVelocity = savedKayak->front_vertical_velocity();
kayak->LeftRightPaddleCount = savedKayak->left_right_count();
kayak->LeftVerticalVelocity = savedKayak->left_vertical_velocity();
kayak->OldPose.Position.x = savedKayak->old_pos()->x_pos();
kayak->OldPose.Position.y = savedKayak->old_pos()->y_pos();
kayak->OldPose.Position.z = savedKayak->old_pos()->z_pos();
kayak->OldPose.Orientation.x = savedKayak->old_pos()->x_rot();
kayak->OldPose.Orientation.y = savedKayak->old_pos()->y_rot();
kayak->OldPose.Orientation.z = savedKayak->old_pos()->z_rot();
kayak->OldPose = ToPHD(savedKayak->old_pos());
kayak->RightVerticalVelocity = savedKayak->right_vertical_velocity();
kayak->TrueWater = savedKayak->true_water();
kayak->Turn = savedKayak->turn();
@ -1669,14 +1570,9 @@ bool SaveGame::Load(int slot)
auto* bat = &Bats[i];
bat->On = batInfo->on();
bat->Counter = batInfo->counter();
bat->Counter = batInfo->flags();
bat->RoomNumber = batInfo->room_number();
bat->Pose.Position.x = batInfo->x();
bat->Pose.Position.y = batInfo->y();
bat->Pose.Position.z = batInfo->z();
bat->Pose.Orientation.x = batInfo->x_rot();
bat->Pose.Orientation.y = batInfo->y_rot();
bat->Pose.Orientation.z = batInfo->z_rot();
bat->Pose = ToPHD(batInfo->pose());
}
for (int i = 0; i < s->rats()->size(); i++)
@ -1687,12 +1583,7 @@ bool SaveGame::Load(int slot)
rat->On = ratInfo->on();
rat->Flags = ratInfo->flags();
rat->RoomNumber = ratInfo->room_number();
rat->Pose.Position.x = ratInfo->x();
rat->Pose.Position.y = ratInfo->y();
rat->Pose.Position.z = ratInfo->z();
rat->Pose.Orientation.x = ratInfo->x_rot();
rat->Pose.Orientation.y = ratInfo->y_rot();
rat->Pose.Orientation.z = ratInfo->z_rot();
rat->Pose = ToPHD(ratInfo->pose());
}
for (int i = 0; i < s->spiders()->size(); i++)
@ -1703,28 +1594,18 @@ bool SaveGame::Load(int slot)
spider->On = spiderInfo->on();
spider->Flags = spiderInfo->flags();
spider->RoomNumber = spiderInfo->room_number();
spider->Pose.Position.x = spiderInfo->x();
spider->Pose.Position.y = spiderInfo->y();
spider->Pose.Position.z = spiderInfo->z();
spider->Pose.Orientation.x = spiderInfo->x_rot();
spider->Pose.Orientation.y = spiderInfo->y_rot();
spider->Pose.Orientation.z = spiderInfo->z_rot();
spider->Pose = ToPHD(spiderInfo->pose());
}
for (int i = 0; i < s->scarabs()->size(); i++)
{
auto beetleInfo = s->scarabs()->Get(i);
auto* Beetle = &BeetleSwarm[i];
auto* beetle = &BeetleSwarm[i];
Beetle->On = beetleInfo->on();
Beetle->Flags = beetleInfo->flags();
Beetle->RoomNumber = beetleInfo->room_number();
Beetle->Pose.Position.x = beetleInfo->x();
Beetle->Pose.Position.y = beetleInfo->y();
Beetle->Pose.Position.z = beetleInfo->z();
Beetle->Pose.Orientation.x = beetleInfo->x_rot();
Beetle->Pose.Orientation.y = beetleInfo->y_rot();
Beetle->Pose.Orientation.z = beetleInfo->z_rot();
beetle->On = beetleInfo->on();
beetle->Flags = beetleInfo->flags();
beetle->RoomNumber = beetleInfo->room_number();
beetle->Pose = ToPHD(beetleInfo->pose());
}
NextFxFree = s->next_fx_free();
@ -1734,7 +1615,7 @@ bool SaveGame::Load(int slot)
{
auto& fx = EffectList[i];
auto fx_saved = s->fxinfos()->Get(i);
fx.pos = ToPHD(fx_saved->pos());
fx.pos = ToPHD(fx_saved->pose());
fx.roomNumber = fx_saved->room_number();
fx.objectNumber = fx_saved->object_number();
fx.nextFx = fx_saved->next_fx();
@ -1743,7 +1624,7 @@ bool SaveGame::Load(int slot)
fx.fallspeed = fx_saved->fall_speed();
fx.frameNumber = fx_saved->frame_number();
fx.counter = fx_saved->counter();
fx.shade = fx_saved->shade();
fx.color = ToVector4(fx_saved->color());
fx.flag1 = fx_saved->flag1();
fx.flag2 = fx_saved->flag2();
}
@ -1865,9 +1746,6 @@ bool SaveGame::Load(int slot)
Lara.ExtraTorsoRot.z = s->lara()->extra_torso_rot()->x();
Lara.ExtraTorsoRot.y = s->lara()->extra_torso_rot()->y();
Lara.ExtraTorsoRot.z = s->lara()->extra_torso_rot()->z();
Lara.ExtraVelocity.x = s->lara()->extra_velocity()->x();
Lara.ExtraVelocity.y = s->lara()->extra_velocity()->y();
Lara.ExtraVelocity.z = s->lara()->extra_velocity()->z();
Lara.WaterCurrentActive = s->lara()->water_current_active();
Lara.WaterCurrentPull.x = s->lara()->water_current_pull()->x();
Lara.WaterCurrentPull.y = s->lara()->water_current_pull()->y();
@ -1901,18 +1779,10 @@ bool SaveGame::Load(int slot)
Lara.LeftArm.FrameBase = s->lara()->left_arm()->frame_base();
Lara.LeftArm.FrameNumber = s->lara()->left_arm()->frame_number();
Lara.LeftArm.Locked = s->lara()->left_arm()->locked();
Lara.LeftArm.Orientation.x = s->lara()->left_arm()->rotation()->x();
Lara.LeftArm.Orientation.y = s->lara()->left_arm()->rotation()->y();
Lara.LeftArm.Orientation.z = s->lara()->left_arm()->rotation()->z();
Lara.LeftArm.Orientation = ToVector3Shrt(s->lara()->left_arm()->rotation());
Lara.Location = s->lara()->location();
Lara.LocationPad = s->lara()->location_pad();
Lara.NextCornerPos = PHD_3DPOS(
s->lara()->next_corner_position()->x(),
s->lara()->next_corner_position()->y(),
s->lara()->next_corner_position()->z(),
s->lara()->next_corner_rotation()->x(),
s->lara()->next_corner_rotation()->y(),
s->lara()->next_corner_rotation()->z());
Lara.NextCornerPos = ToPHD(s->lara()->next_corner_pose());
Lara.PoisonPotency = s->lara()->poison_potency();
Lara.ProjectedFloorHeight = s->lara()->projected_floor_height();
Lara.RightArm.AnimNumber = s->lara()->right_arm()->anim_number();
@ -1921,9 +1791,7 @@ bool SaveGame::Load(int slot)
Lara.RightArm.FrameBase = s->lara()->right_arm()->frame_base();
Lara.RightArm.FrameNumber = s->lara()->right_arm()->frame_number();
Lara.RightArm.Locked = s->lara()->right_arm()->locked();
Lara.RightArm.Orientation.x = s->lara()->right_arm()->rotation()->x();
Lara.RightArm.Orientation.y = s->lara()->right_arm()->rotation()->y();
Lara.RightArm.Orientation.z = s->lara()->right_arm()->rotation()->z();
Lara.RightArm.Orientation = ToVector3Shrt(s->lara()->right_arm()->rotation());
Lara.Torch.IsLit = s->lara()->torch()->is_lit();
Lara.Torch.State = (TorchState)s->lara()->torch()->state();
Lara.Control.Rope.Segment = s->lara()->control()->rope()->segment();
@ -2001,61 +1869,25 @@ bool SaveGame::Load(int slot)
for (int i = 0; i < ROPE_SEGMENTS; i++)
{
rope->segment[i] = Vector3Int(
s->rope()->segments()->Get(i)->x(),
s->rope()->segments()->Get(i)->y(),
s->rope()->segments()->Get(i)->z());
rope->normalisedSegment[i] = Vector3Int(
s->rope()->normalised_segments()->Get(i)->x(),
s->rope()->normalised_segments()->Get(i)->y(),
s->rope()->normalised_segments()->Get(i)->z());
rope->meshSegment[i] = Vector3Int(
s->rope()->mesh_segments()->Get(i)->x(),
s->rope()->mesh_segments()->Get(i)->y(),
s->rope()->mesh_segments()->Get(i)->z());
rope->coords[i] = Vector3Int(
s->rope()->coords()->Get(i)->x(),
s->rope()->coords()->Get(i)->y(),
s->rope()->coords()->Get(i)->z());
rope->velocity[i] = Vector3Int(
s->rope()->velocities()->Get(i)->x(),
s->rope()->velocities()->Get(i)->y(),
s->rope()->velocities()->Get(i)->z());
rope->segment[i] = ToVector3Int(s->rope()->segments()->Get(i));
rope->normalisedSegment[i] = ToVector3Int(s->rope()->normalised_segments()->Get(i));
rope->meshSegment[i] = ToVector3Int(s->rope()->mesh_segments()->Get(i));
rope->coords[i] = ToVector3Int(s->rope()->coords()->Get(i));
rope->velocity[i] = ToVector3Int(s->rope()->velocities()->Get(i));
}
rope->coiled = s->rope()->coiled();
rope->active = s->rope()->active();
rope->position = Vector3Int(
s->rope()->position()->x(),
s->rope()->position()->y(),
s->rope()->position()->z());
CurrentPendulum.position = Vector3Int(
s->pendulum()->position()->x(),
s->pendulum()->position()->y(),
s->pendulum()->position()->z());
CurrentPendulum.velocity = Vector3Int(
s->pendulum()->velocity()->x(),
s->pendulum()->velocity()->y(),
s->pendulum()->velocity()->z());
rope->position = ToVector3Int(s->rope()->position());
CurrentPendulum.position = ToVector3Int(s->pendulum()->position());
CurrentPendulum.velocity = ToVector3Int(s->pendulum()->velocity());
CurrentPendulum.node = s->pendulum()->node();
CurrentPendulum.rope = rope;
AlternatePendulum.position = Vector3Int(
s->alternate_pendulum()->position()->x(),
s->alternate_pendulum()->position()->y(),
s->alternate_pendulum()->position()->z());
AlternatePendulum.velocity = Vector3Int(
s->alternate_pendulum()->velocity()->x(),
s->alternate_pendulum()->velocity()->y(),
s->alternate_pendulum()->velocity()->z());
AlternatePendulum.position = ToVector3Int(s->alternate_pendulum()->position());
AlternatePendulum.velocity = ToVector3Int(s->alternate_pendulum()->velocity());
AlternatePendulum.node = s->alternate_pendulum()->node();
AlternatePendulum.rope = rope;

View file

@ -15,7 +15,7 @@ namespace TEN::Entities::TR4
{
LOCUST_INFO Locusts[MAX_LOCUSTS];
int CreateLocust(void)
int CreateLocust()
{
for (int i = 0; i < MAX_LOCUSTS; i++)
{
@ -112,7 +112,7 @@ namespace TEN::Entities::TR4
}
}
void UpdateLocusts(void)
void UpdateLocusts()
{
for (int i = 0; i < MAX_LOCUSTS; i++)
{
@ -208,7 +208,13 @@ namespace TEN::Entities::TR4
}
}
void DrawLocust(void)
void ClearLocusts()
{
for (int i = 0; i < MAX_LOCUSTS; i++)
Locusts[i].on = false;
}
void DrawLocust()
{
// TODO: no render for the locusts !
}

View file

@ -15,17 +15,19 @@ struct LOCUST_INFO
BYTE counter;
};
namespace TEN::Entities::TR4 {
namespace TEN::Entities::TR4
{
constexpr auto MAX_LOCUSTS = 64;
constexpr auto LOCUST_LARA_DAMAGE = 3;
constexpr auto LOCUST_ENTITY_DAMAGE = 1;
extern LOCUST_INFO Locusts[MAX_LOCUSTS];
extern int CreateLocust(void);
extern int CreateLocust();
extern void SpawnLocust(ItemInfo* item);
extern void InitialiseLocust(short itemNumber);
extern void LocustControl(short itemNumber);
extern void UpdateLocusts(void);
extern void DrawLocust(void);
extern void UpdateLocusts();
extern void ClearLocusts();
extern void DrawLocust();
}

View file

@ -54,7 +54,7 @@ namespace TEN::Entities::Doors
if (MoveLaraPosition(&UnderwaterDoorPos, doorItem, laraItem))
{
SetAnimation(laraItem, LA_UNDERWATER_DOOR_OPEN);
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
doorItem->Status = ITEM_ACTIVE;
AddActiveItem(itemNumber);

View file

@ -84,7 +84,7 @@ namespace TEN::Entities::Generic
}
else if (TrInput & IN_DRAW &&
!LaraItem->Animation.IsAirborne &&
!LaraItem->Animation.VerticalVelocity &&
!LaraItem->Animation.Velocity.y &&
LaraItem->Animation.ActiveState != LS_JUMP_PREPARE &&
LaraItem->Animation.ActiveState != LS_JUMP_UP &&
LaraItem->Animation.ActiveState != LS_JUMP_FORWARD &&
@ -203,21 +203,21 @@ namespace TEN::Entities::Generic
{
auto* item = &g_Level.Items[itemNumber];
if (item->Animation.VerticalVelocity)
if (item->Animation.Velocity.y)
{
item->Pose.Orientation.x -= ANGLE(5.0f);
item->Pose.Orientation.z += ANGLE(5.0f);
}
else if (!item->Animation.Velocity)
else if (!item->Animation.Velocity.z)
{
item->Pose.Orientation.x = 0;
item->Pose.Orientation.z = 0;
}
auto velocity = Vector3Int(
item->Animation.Velocity * phd_sin(item->Pose.Orientation.y),
item->Animation.VerticalVelocity,
item->Animation.Velocity * phd_cos(item->Pose.Orientation.y)
item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.y),
item->Animation.Velocity.y,
item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.y)
);
auto oldPos = item->Pose.Position;
@ -226,16 +226,16 @@ namespace TEN::Entities::Generic
if (TestEnvironment(ENV_FLAG_WATER, item) ||
TestEnvironment(ENV_FLAG_SWAMP, item))
{
item->Animation.VerticalVelocity += (5 - item->Animation.VerticalVelocity) / 2;
item->Animation.Velocity += (5 - item->Animation.Velocity) / 2;
item->Animation.Velocity.y += (5 - item->Animation.Velocity.y) / 2;
item->Animation.Velocity.z += (5 - item->Animation.Velocity.z) / 2;
if (item->ItemFlags[3] != 0)
item->ItemFlags[3] = 0;
}
else
item->Animation.VerticalVelocity += 6;
item->Animation.Velocity.y += 6;
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Pose.Position.y += item->Animation.Velocity.y;
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, velocity.x, velocity.y, velocity.z);
// Collide with entities.
@ -255,7 +255,7 @@ namespace TEN::Entities::Generic
ItemPushStatic(item, CollidedMeshes[0], &LaraCollision);
}
item->Animation.Velocity = -int(item->Animation.Velocity / 1.5f);
item->Animation.Velocity.z = -int(item->Animation.Velocity.z / 1.5f);
}
if (item->ItemFlags[3])

View file

@ -81,7 +81,7 @@ void CeilingTrapDoorCollision(short itemNumber, ItemInfo* laraItem, CollisionInf
laraItem->Pose.Orientation.y += ANGLE(180.0f);
ResetLaraFlex(laraItem);
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.IsAirborne = false;
laraItem->Animation.AnimNumber = LA_TRAPDOOR_CEILING_OPEN;
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;

View file

@ -186,7 +186,7 @@ void HorizontalBarCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo*
laraItem->Animation.ActiveState = LS_MISC_CONTROL;
laraItem->Animation.AnimNumber = LA_SWINGBAR_GRAB;
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
laraItem->Animation.VerticalVelocity = false;
laraItem->Animation.Velocity.y = false;
laraItem->Animation.IsAirborne = false;
ResetLaraFlex(barItem);

View file

@ -75,7 +75,7 @@ namespace TEN::Entities::Generic
else if (TrInput & IN_ACTION && isLara &&
laraInfo->Control.HandStatus == HandStatus::Free &&
laraItem->Animation.IsAirborne &&
laraItem->Animation.VerticalVelocity > (int)laraInfo->Control.HandStatus && // ?????
laraItem->Animation.Velocity.y > (int)laraInfo->Control.HandStatus && // ?????
laraItem->Animation.ActiveState == LS_REACH || laraItem->Animation.ActiveState == LS_JUMP_UP)
{
if (TestBoundsCollide(poleItem, laraItem, 100) &&
@ -102,7 +102,7 @@ namespace TEN::Entities::Generic
}
laraItem->Animation.ActiveState = LS_POLE_IDLE;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.IsAirborne = false;
laraInfo->Control.HandStatus = HandStatus::Busy;
poleItem->Pose.Orientation.y = rot;

View file

@ -63,15 +63,11 @@ namespace TEN::Entities::Generic
else
rope->coiled = 0;
int l = 0;
int sum = 0;
int il = 3145728;
for (int i = 0; i < ROPE_SEGMENTS; ++i)
{
rope->segment[i].x = (int64_t)sum * pos2->x >> FP_SHIFT;
rope->segment[i].y = (int64_t)sum * pos2->x >> FP_SHIFT;
rope->segment[i].z = (int64_t)sum * pos2->z >> FP_SHIFT;
rope->segment[i].x = (long long)(rope->segmentLength * i) * pos2->x >> FP_SHIFT;
rope->segment[i].y = (long long)(rope->segmentLength * i) * pos2->y >> FP_SHIFT;
rope->segment[i].z = (long long)(rope->segmentLength * i) * pos2->z >> FP_SHIFT;
rope->velocity[i].x = 0;
rope->velocity[i].y = 0;
@ -79,17 +75,13 @@ namespace TEN::Entities::Generic
if (item->TriggerFlags == -1)
{
rope->segment[i].x = l;
rope->segment[i].x = 1024 * i;
rope->segment[i].y >>= 4;
rope->velocity[i].x = 16384;
rope->velocity[i].y = il;
rope->velocity[i].y = 131072 * (ROPE_SEGMENTS - i);
rope->velocity[i].z = 16384;
}
l += 1024;
sum += rope->segmentLength;
il -= 131072;
}
rope->active = 0;
@ -182,7 +174,7 @@ namespace TEN::Entities::Generic
laraInfo->Control.HandStatus == HandStatus::Free &&
(laraItem->Animation.ActiveState == LS_REACH || laraItem->Animation.ActiveState == LS_JUMP_UP) &&
laraItem->Animation.IsAirborne &&
laraItem->Animation.VerticalVelocity > 0&&
laraItem->Animation.Velocity.y > 0.0f &&
rope->active)
{
auto* frame = GetBoundsAccurate(laraItem);
@ -210,7 +202,7 @@ namespace TEN::Entities::Generic
}
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.IsAirborne = false;
laraInfo->Control.HandStatus = HandStatus::Busy;
@ -224,7 +216,7 @@ namespace TEN::Entities::Generic
CurrentPendulum.velocity.y = 0;
CurrentPendulum.velocity.z = 0;
ApplyVelocityToRope(segment, laraItem->Pose.Orientation.y, 16 * laraItem->Animation.Velocity);
ApplyVelocityToRope(segment, laraItem->Pose.Orientation.y, 16 * laraItem->Animation.Velocity.z);
}
}
}
@ -606,7 +598,7 @@ namespace TEN::Entities::Generic
}
}
bool RopeSwingCollision(ItemInfo* item, CollisionInfo* coll)
bool RopeSwingCollision(ItemInfo* item, CollisionInfo* coll, bool testForStumble)
{
auto* lara = GetLaraInfo(item);
@ -614,13 +606,17 @@ namespace TEN::Entities::Generic
coll->Setup.ForwardAngle = lara->Control.Rope.Direction ? item->Pose.Orientation.y : -item->Pose.Orientation.y;
GetCollisionInfo(coll, item);
bool stumble = (coll->CollisionType != CollisionType::CT_NONE || coll->HitStatic);
bool stumble = testForStumble &&
((coll->CollisionType != CollisionType::CT_NONE &&
coll->CollisionType != CollisionType::CT_TOP &&
coll->CollisionType != CollisionType::CT_TOP_FRONT) ||
coll->HitStatic);
if (stumble ||
TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber) ||
TestEnvironment(RoomEnvFlags::ENV_FLAG_SWAMP, item->RoomNumber))
{
item->Pose.Position = coll->Setup.OldPosition;
ShiftItem(item, coll);
FallFromRope(item, stumble);
return true;
}
@ -634,13 +630,13 @@ namespace TEN::Entities::Generic
{
if (item->Pose.Orientation.x >= 0)
{
item->Animation.VerticalVelocity = -112;
item->Animation.Velocity = item->Pose.Orientation.x / 128;
item->Animation.Velocity.y = -112;
item->Animation.Velocity.z = item->Pose.Orientation.x / 128;
}
else
{
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = -20;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = -20;
}
item->Pose.Orientation.x = 0;
@ -664,13 +660,13 @@ namespace TEN::Entities::Generic
void FallFromRope(ItemInfo* item, bool stumble)
{
item->Animation.Velocity = abs(CurrentPendulum.velocity.x >> FP_SHIFT) + abs(CurrentPendulum.velocity.z >> FP_SHIFT) >> 1;
item->Animation.Velocity.z = abs(CurrentPendulum.velocity.x >> FP_SHIFT) + abs(CurrentPendulum.velocity.z >> FP_SHIFT) >> 1;
item->Pose.Orientation.x = 0;
item->Pose.Position.y += 320;
SetAnimation(item, stumble ? LA_JUMP_WALL_SMASH_START : LA_FALL_START);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = true;
auto* lara = GetLaraInfo(item);
@ -679,7 +675,7 @@ namespace TEN::Entities::Generic
if (stumble)
{
item->Animation.Velocity = -item->Animation.Velocity;
item->Animation.Velocity.z = -item->Animation.Velocity.z;
DoDamage(item, 0);
}
}

View file

@ -60,5 +60,5 @@ namespace TEN::Entities::Generic
void JumpOffRope(ItemInfo* item);
void FallFromRope(ItemInfo* item, bool stumble = false);
void LaraClimbRope(ItemInfo* item, CollisionInfo* coll);
bool RopeSwingCollision(ItemInfo* item, CollisionInfo* coll);
bool RopeSwingCollision(ItemInfo* item, CollisionInfo* coll, bool testForStumble);
}

View file

@ -33,7 +33,7 @@ namespace TEN::Entities::Switches
if (TrInput & IN_ACTION &&
(laraItem->Animation.ActiveState == LS_REACH || laraItem->Animation.ActiveState == LS_JUMP_UP) &&
(laraItem->Status || laraItem->Animation.IsAirborne) &&
laraItem->Animation.VerticalVelocity > 0 &&
laraItem->Animation.Velocity.y > 0 &&
laraInfo->Control.HandStatus == HandStatus::Free &&
!switchItem->Animation.ActiveState)
{
@ -43,7 +43,7 @@ namespace TEN::Entities::Switches
laraItem->Animation.ActiveState = LS_SWITCH_DOWN;
laraItem->Animation.AnimNumber = LA_JUMPSWITCH_PULL;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
laraItem->Animation.IsAirborne = false;
laraInfo->Control.HandStatus = HandStatus::Busy;

View file

@ -75,7 +75,7 @@ namespace TEN::Entities::Switches
{
if (MoveLaraPosition(&UnderwaterSwitchPos, switchItem, laraItem))
{
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.TargetState = LS_SWITCH_DOWN;
do
@ -136,7 +136,7 @@ namespace TEN::Entities::Switches
if (flag)
{
SetAnimation(laraItem, LA_UNDERWATER_CEILING_SWITCH_PULL);
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
lara->Control.IsMoving = false;
lara->Control.HandStatus = HandStatus::Busy;
switchItem->Animation.TargetState = SWITCH_ON;

View file

@ -26,10 +26,10 @@ namespace TEN::Entities::Traps
int oldX = item->Pose.Position.x;
int oldZ = item->Pose.Position.z - 1000;
int velocity = item->Animation.Velocity * phd_cos(item->Pose.Orientation.x);
int velocity = item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.x);
item->Pose.Position.x += velocity * phd_sin(item->Pose.Orientation.y);
item->Pose.Position.y -= item->Animation.Velocity * phd_sin(item->Pose.Orientation.x);
item->Pose.Position.y -= item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.x);
item->Pose.Position.z += velocity * phd_cos(item->Pose.Orientation.y);
short roomNumber = item->RoomNumber;
@ -105,7 +105,7 @@ namespace TEN::Entities::Traps
dartItem->Pose.Orientation.x = 0;
dartItem->Pose.Orientation.y = item->Pose.Orientation.y + -ANGLE(180);
dartItem->Animation.Velocity = 256;
dartItem->Animation.Velocity.z = 256;
int xf = 0;
int zf = 0;

View file

@ -47,7 +47,7 @@ void WreckingBallCollision(short itemNumber, ItemInfo* l, CollisionInfo* coll)
y = l->Pose.Position.y;
z = l->Pose.Position.z;
test = (x & 1023) > 256 && (x & 1023) < 768 && (z & 1023) > 256 && (z & 1023) < 768;
damage = item->Animation.VerticalVelocity > 0 ? 96 : 0;
damage = item->Animation.Velocity.y > 0 ? 96 : 0;
if (ItemPushItem(item, l, coll, coll->Setup.EnableSpasm, 1))
{
if (test)
@ -225,28 +225,28 @@ void WreckingBallControl(short itemNumber)
{
SoundEffect(SFX_TR5_BASE_CLAW_DROP, &item->Pose);
++item->ItemFlags[1];
item->Animation.VerticalVelocity = 6;
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.y = 6;
item->Pose.Position.y += item->Animation.Velocity.y;
}
}
else if (item->ItemFlags[1] == 2)
{
item->Animation.VerticalVelocity += 24;
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.y += 24;
item->Pose.Position.y += item->Animation.Velocity.y;
room = item->RoomNumber;
height = GetFloorHeight(GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &room), item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
if (height < item->Pose.Position.y)
{
item->Pose.Position.y = height;
if (item->Animation.VerticalVelocity > 48)
if (item->Animation.Velocity.y > 48)
{
BounceCamera(item, 64, 8192);
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
item->Animation.Velocity.y = -item->Animation.Velocity.y / 8;
}
else
{
++item->ItemFlags[1];
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
}
else if (height - item->Pose.Position.y < 1536 && item->Animation.ActiveState)
@ -256,23 +256,23 @@ void WreckingBallControl(short itemNumber)
}
else if (item->ItemFlags[1] == 3)
{
item->Animation.VerticalVelocity -= 3;
item->Pose.Position.y += item->Animation.VerticalVelocity;
item->Animation.Velocity.y -= 3;
item->Pose.Position.y += item->Animation.Velocity.y;
if (item->Pose.Position.y < item2->Pose.Position.y + 1644)
{
StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP);
item->ItemFlags[0] = 1;
item->Pose.Position.y = item2->Pose.Position.y + 1644;
if (item->Animation.VerticalVelocity < -32)
if (item->Animation.Velocity.y < -32)
{
SoundEffect(SFX_TR5_BASE_CLAW_TOP_IMPACT, &item->Pose, SoundEnvironment::Land, 1.0f, 0.5f);
item->Animation.VerticalVelocity = -item->Animation.VerticalVelocity >> 3;
item->Animation.Velocity.y = -item->Animation.Velocity.y / 8;
BounceCamera(item, 16, 8192);
}
else
{
item->ItemFlags[1] = -1;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->ItemFlags[0] = 0;
}
}

View file

@ -78,8 +78,7 @@ void PuzzleHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* co
laraItem->Animation.ActiveState == LS_IDLE &&
laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
laraInfo->Control.HandStatus == HandStatus::Free &&
!BinocularRange &&
GetKeyTrigger(&g_Level.Items[itemNumber])) ||
!BinocularRange) ||
(laraInfo->Control.IsMoving &&
laraInfo->InteractedItem == itemNumber))
{

View file

@ -65,27 +65,27 @@ namespace TEN::Entities::TR1
if (item->Pose.Orientation.x < -ANGLE(90.0f))
item->Pose.Orientation.x = -ANGLE(90.0f);
item->Animation.Velocity = CENTAUR_PROJECTILE_SPEED * phd_cos(item->Pose.Orientation.x);
item->Animation.VerticalVelocity = -CENTAUR_PROJECTILE_SPEED * phd_sin(item->Pose.Orientation.x);
item->Animation.Velocity.z = CENTAUR_PROJECTILE_SPEED * phd_cos(item->Pose.Orientation.x);
item->Animation.Velocity.y = -CENTAUR_PROJECTILE_SPEED * phd_sin(item->Pose.Orientation.x);
aboveWater = true;
}
else
{
item->Animation.VerticalVelocity += 3;
item->Animation.Velocity.y += 3;
aboveWater = true;
if (item->Animation.Velocity)
if (item->Animation.Velocity.z)
{
item->Pose.Orientation.z += ((item->Animation.Velocity / 4) + 7) * ANGLE(1.0f);
item->Pose.Orientation.z += ((item->Animation.Velocity.z / 4) + 7) * ANGLE(1.0f);
if (item->Animation.RequiredState)
item->Pose.Orientation.y += ((item->Animation.Velocity / 2) + 7) * ANGLE(1.0f);
item->Pose.Orientation.y += ((item->Animation.Velocity.z / 2) + 7) * ANGLE(1.0f);
else
item->Pose.Orientation.x += ((item->Animation.Velocity / 2) + 7) * ANGLE(1.0f);
item->Pose.Orientation.x += ((item->Animation.Velocity.z / 2) + 7) * ANGLE(1.0f);
}
}
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z);
auto probe = GetCollision(item);
@ -164,8 +164,8 @@ namespace TEN::Entities::TR1
projectileItem->Pose.Orientation = Vector3Shrt(0, centaurItem->Pose.Orientation.y, 0 );
projectileItem->Animation.Velocity = CENTAUR_PROJECTILE_SPEED * phd_cos(projectileItem->Pose.Orientation.x);
projectileItem->Animation.VerticalVelocity = -CENTAUR_PROJECTILE_SPEED * phd_cos(projectileItem->Pose.Orientation.x);
projectileItem->Animation.Velocity.z = CENTAUR_PROJECTILE_SPEED * phd_cos(projectileItem->Pose.Orientation.x);
projectileItem->Animation.Velocity.y = -CENTAUR_PROJECTILE_SPEED * phd_cos(projectileItem->Pose.Orientation.x);
projectileItem->ItemFlags[0] = 1;
AddActiveItem(itemNumber);

View file

@ -95,8 +95,8 @@ namespace TEN::Entities::TR1
!LaraItem->Animation.IsAirborne)
{
SetAnimation(item, LA_JUMP_WALL_SMASH_START);
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = true;
item->Data = -1;
item->Pose.Position.y += 50;
@ -114,7 +114,7 @@ namespace TEN::Entities::TR1
item->Pose.Position.y = item->Floor;
TestTriggers(item, true);
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
item->Animation.TargetState = LS_DEATH;
item->Animation.RequiredState = LS_DEATH;

View file

@ -89,7 +89,7 @@ namespace TEN::Entities::TR1
if (item->Pose.Position.y < item->Floor)
{
item->Animation.IsAirborne = true;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
}
else
{

View file

@ -107,8 +107,8 @@ static void createExplosion(ItemInfo* item)
explosionItem->Pose.Orientation.y = 0;
explosionItem->Pose.Orientation.x = 0;
explosionItem->Pose.Orientation.z = 0;
explosionItem->Animation.Velocity = 0;
explosionItem->Animation.VerticalVelocity = 0;
explosionItem->Animation.Velocity.z = 0;
explosionItem->Animation.Velocity.y = 0;
InitialiseItem(ExplosionIndex);
AddActiveItem(ExplosionIndex);
@ -195,8 +195,8 @@ void DragonCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
laraItem->Pose = item->Pose;
laraItem->Animation.IsAirborne = false;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
if (item->RoomNumber != laraItem->RoomNumber)
ItemNewRoom(Lara.ItemNumber, item->RoomNumber);

View file

@ -63,7 +63,7 @@ void EagleControl(short itemNumber)
if (item->Pose.Position.y > item->Floor)
{
item->Pose.Position.y = item->Floor;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
item->Animation.TargetState = 5;
}
@ -82,7 +82,7 @@ void EagleControl(short itemNumber)
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.ActiveState = 4;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
item->Animation.IsAirborne = true;
break;
}

View file

@ -66,7 +66,7 @@ void KnifeControl(short fxNumber)
DoDamage(LaraItem, 50);
fx->pos.Orientation.y = LaraItem->Pose.Orientation.y;
fx->speed = LaraItem->Animation.Velocity;
fx->speed = LaraItem->Animation.Velocity.z;
fx->frameNumber = fx->counter = 0;
SoundEffect(SFX_TR2_CRUNCH2, &fx->pos);

View file

@ -82,13 +82,13 @@ void SkidooManCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* col
if (coll->Setup.EnableObjectPush)
{
if (item->Animation.Velocity > 0)
if (item->Animation.Velocity.z > 0)
ItemPushItem(item, laraItem, coll, coll->Setup.EnableSpasm, 0);
else
ItemPushItem(item, laraItem, coll, 0, 0);
}
if (Lara.Vehicle == NO_ITEM && item->Animation.Velocity > 0)
if (Lara.Vehicle == NO_ITEM && item->Animation.Velocity.z > 0)
{
DoDamage(laraItem, 100);
}
@ -221,7 +221,7 @@ void SkidooManControl(short riderItemNumber)
{
creatureInfo->JointRotation[0] = (creatureInfo->JointRotation[0] == 1) ? 2 : 1;
DoSnowEffect(item);
SoundEffect(SFX_TR2_VEHICLE_SNOWMOBILE_IDLE, &item->Pose, SoundEnvironment::Land, 0.5f + item->Animation.Velocity / 100.0f); // SKIDOO_MAX_VELOCITY. TODO: Check actual sound!
SoundEffect(SFX_TR2_VEHICLE_SNOWMOBILE_IDLE, &item->Pose, SoundEnvironment::Land, 0.5f + item->Animation.Velocity.z / 100.0f); // SKIDOO_MAX_VELOCITY. TODO: Check actual sound!
}
CreatureAnimation(itemNumber, angle, 0);
@ -240,8 +240,8 @@ void SkidooManControl(short riderItemNumber)
riderItem->Animation.FrameNumber = item->Animation.FrameNumber + (g_Level.Anims[riderItem->Animation.AnimNumber].frameBase - g_Level.Anims[item->Animation.AnimNumber].frameBase);
}
else if (riderItem->Status == ITEM_DEACTIVATED &&
item->Animation.Velocity == 0 &&
item->Animation.VerticalVelocity == 0)
item->Animation.Velocity.z == 0 &&
item->Animation.Velocity.y == 0)
{
RemoveActiveItem(riderItemNumber);
riderItem->Collidable = false;

View file

@ -36,7 +36,7 @@ void KillerStatueControl(short itemNumber)
int y = LaraItem->Pose.Position.y - GetRandomControl() / 44;
int d = (GetRandomControl() - SECTOR(16)) / 8 + LaraItem->Pose.Orientation.y;
DoBloodSplat(x, y, z, LaraItem->Animation.Velocity, d, LaraItem->RoomNumber);
DoBloodSplat(x, y, z, LaraItem->Animation.Velocity.z, d, LaraItem->RoomNumber);
}
AnimateItem(item);

View file

@ -43,7 +43,7 @@ void SpinningBladeControl(short itemNumber)
if (item->TouchBits)
{
DoDamage(LaraItem, 100);
DoLotsOfBlood(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - CLICK(2), LaraItem->Pose.Position.z, (short)(item->Animation.Velocity * 2), LaraItem->Pose.Orientation.y, LaraItem->RoomNumber, 2);
DoLotsOfBlood(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - CLICK(2), LaraItem->Pose.Position.z, (short)(item->Animation.Velocity.z * 2), LaraItem->Pose.Orientation.y, LaraItem->RoomNumber, 2);
}
SoundEffect(SFX_TR2_ROLLING_BLADE, &item->Pose);

View file

@ -18,14 +18,14 @@ void SpringBoardControl(short itemNumber)
return;
if (LaraItem->Animation.ActiveState == LS_WALK_BACK || LaraItem->Animation.ActiveState == LS_RUN_BACK)
LaraItem->Animation.Velocity = -LaraItem->Animation.Velocity;
LaraItem->Animation.Velocity.z = -LaraItem->Animation.Velocity.z;
LaraItem->Animation.AnimNumber = LA_FALL_START;
LaraItem->Animation.FrameNumber = g_Level.Anims[LaraItem->Animation.AnimNumber].frameBase;
LaraItem->Animation.ActiveState = LS_JUMP_FORWARD;
LaraItem->Animation.TargetState = LS_JUMP_FORWARD;
LaraItem->Animation.IsAirborne = true;
LaraItem->Animation.VerticalVelocity = -240;
LaraItem->Animation.Velocity.y = -240;
item->Animation.TargetState = 1;
}

View file

@ -236,16 +236,16 @@ namespace TEN::Entities::Vehicles
if (skidooItem->Pose.Position.y == skidooItem->Floor)
{
laraItem->Animation.TargetState = LS_DEATH;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = SKIDOO_DAMAGE_START + SKIDOO_DAMAGE_LENGTH;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = SKIDOO_DAMAGE_START + SKIDOO_DAMAGE_LENGTH;
ExplodeVehicle(laraItem, skidooItem);
}
else
{
laraItem->Animation.TargetState = LS_FREEFALL;
laraItem->Pose.Position.y -= 200;
laraItem->Animation.Velocity = skidooItem->Animation.Velocity;
laraItem->Animation.VerticalVelocity = skidooItem->Animation.VerticalVelocity;
laraItem->Animation.Velocity.z = skidooItem->Animation.Velocity.z;
laraItem->Animation.Velocity.y = skidooItem->Animation.Velocity.y;
SoundEffect(SFX_TR4_LARA_FALL, &laraItem->Pose);
}
@ -343,8 +343,8 @@ namespace TEN::Entities::Vehicles
skidoo->LeftVerticalVelocity = DoSkidooDynamics(heightFrontLeft, skidoo->LeftVerticalVelocity, (int*)&frontLeft.y);
skidoo->RightVerticalVelocity = DoSkidooDynamics(heightFrontRight, skidoo->RightVerticalVelocity, (int*)&frontRight.y);
skidooItem->Animation.VerticalVelocity = DoSkidooDynamics(height, skidooItem->Animation.VerticalVelocity, (int*)&skidooItem->Pose.Position.y);
skidooItem->Animation.Velocity = DoVehicleWaterMovement(skidooItem, laraItem, skidooItem->Animation.Velocity, SKIDOO_RADIUS, &skidoo->TurnRate);
skidooItem->Animation.Velocity.y = DoSkidooDynamics(height, skidooItem->Animation.Velocity.y, (int*)&skidooItem->Pose.Position.y);
skidooItem->Animation.Velocity.z = DoVehicleWaterMovement(skidooItem, laraItem, skidooItem->Animation.Velocity.z, SKIDOO_RADIUS, &skidoo->TurnRate);
height = (frontLeft.y + frontRight.y) / 2;
short xRot = phd_atan(SKIDOO_FRONT, skidooItem->Pose.Position.y - height);
@ -409,11 +409,11 @@ namespace TEN::Entities::Vehicles
skidooItem->Animation.FrameNumber = g_Level.Anims[skidooItem->Animation.AnimNumber].frameBase;
}
if (skidooItem->Animation.Velocity && skidooItem->Floor == skidooItem->Pose.Position.y)
if (skidooItem->Animation.Velocity.z && skidooItem->Floor == skidooItem->Pose.Position.y)
{
DoSnowEffect(skidooItem);
if (skidooItem->Animation.Velocity < 50)
if (skidooItem->Animation.Velocity.z < 50)
DoSnowEffect(skidooItem);
}
@ -429,9 +429,9 @@ namespace TEN::Entities::Vehicles
if (skidooItem->Pose.Position.y >= (height - CLICK(1)))
{
*pitch = skidooItem->Animation.Velocity + (height - skidooItem->Pose.Position.y);
*pitch = skidooItem->Animation.Velocity.z + (height - skidooItem->Pose.Position.y);
if (TrInput & IN_LOOK && skidooItem->Animation.Velocity == 0)
if (TrInput & IN_LOOK && skidooItem->Animation.Velocity.z == 0)
LookUpDown(laraItem);
if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT))
@ -439,12 +439,12 @@ namespace TEN::Entities::Vehicles
if (TrInput & VEHICLE_IN_REVERSE)
{
if (skidooItem->Animation.Velocity > 0)
skidooItem->Animation.Velocity -= SKIDOO_VELOCITY_BRAKE_DECEL;
if (skidooItem->Animation.Velocity.z > 0)
skidooItem->Animation.Velocity.z -= SKIDOO_VELOCITY_BRAKE_DECEL;
else
{
if (skidooItem->Animation.Velocity > -SKIDOO_REVERSE_VELOCITY_MAX)
skidooItem->Animation.Velocity -= SKIDOO_REVERSE_VELOCITY_ACCEL;
if (skidooItem->Animation.Velocity.z > -SKIDOO_REVERSE_VELOCITY_MAX)
skidooItem->Animation.Velocity.z -= SKIDOO_REVERSE_VELOCITY_ACCEL;
drive = true;
}
@ -458,29 +458,29 @@ namespace TEN::Entities::Vehicles
else
maxVelocity = SKIDOO_NORMAL_VELOCITY_MAX;
if (skidooItem->Animation.Velocity < maxVelocity)
skidooItem->Animation.Velocity += (SKIDOO_VELOCITY_ACCEL / 2) + (SKIDOO_VELOCITY_ACCEL * (skidooItem->Animation.Velocity / (2 * maxVelocity)));
else if (skidooItem->Animation.Velocity > (maxVelocity + SKIDOO_VELOCITY_DECEL))
skidooItem->Animation.Velocity -= SKIDOO_VELOCITY_DECEL;
if (skidooItem->Animation.Velocity.z < maxVelocity)
skidooItem->Animation.Velocity.z += (SKIDOO_VELOCITY_ACCEL / 2) + (SKIDOO_VELOCITY_ACCEL * (skidooItem->Animation.Velocity.z / (2 * maxVelocity)));
else if (skidooItem->Animation.Velocity.z > (maxVelocity + SKIDOO_VELOCITY_DECEL))
skidooItem->Animation.Velocity.z -= SKIDOO_VELOCITY_DECEL;
drive = true;
}
else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) &&
skidooItem->Animation.Velocity >= 0 &&
skidooItem->Animation.Velocity < SKIDOO_TURN_VELOCITY_MAX)
skidooItem->Animation.Velocity.z >= 0 &&
skidooItem->Animation.Velocity.z < SKIDOO_TURN_VELOCITY_MAX)
{
skidooItem->Animation.Velocity = SKIDOO_TURN_VELOCITY_MAX;
skidooItem->Animation.Velocity.z = SKIDOO_TURN_VELOCITY_MAX;
drive = true;
}
else if (skidooItem->Animation.Velocity > SKIDOO_VELOCITY_DECEL)
else if (skidooItem->Animation.Velocity.z > SKIDOO_VELOCITY_DECEL)
{
skidooItem->Animation.Velocity -= SKIDOO_VELOCITY_DECEL;
skidooItem->Animation.Velocity.z -= SKIDOO_VELOCITY_DECEL;
if ((GetRandomControl() & 0x7f) < skidooItem->Animation.Velocity)
if ((GetRandomControl() & 0x7f) < skidooItem->Animation.Velocity.z)
drive = true;
}
else
skidooItem->Animation.Velocity = 0;
skidooItem->Animation.Velocity.z = 0;
}
else if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE))
{
@ -496,7 +496,7 @@ namespace TEN::Entities::Vehicles
auto* skidoo = GetSkidooInfo(skidooItem);
if (laraItem->Animation.ActiveState != SKIDOO_STATE_FALL &&
skidooItem->Animation.VerticalVelocity > 0 &&
skidooItem->Animation.Velocity.y > 0 &&
skidooItem->Pose.Position.y != skidooItem->Floor &&
!dead)
{
@ -540,25 +540,25 @@ namespace TEN::Entities::Vehicles
TestSkidooDismountOK(skidooItem, SKIDOO_STATE_DISMOUNT_RIGHT))
{
laraItem->Animation.TargetState = SKIDOO_STATE_DISMOUNT_RIGHT;
skidooItem->Animation.Velocity = 0;
skidooItem->Animation.Velocity.z = 0;
}
else if (TrInput & VEHICLE_IN_LEFT &&
TestSkidooDismountOK(skidooItem, SKIDOO_STATE_DISMOUNT_LEFT))
{
laraItem->Animation.TargetState = SKIDOO_STATE_DISMOUNT_LEFT;
skidooItem->Animation.Velocity = 0;
skidooItem->Animation.Velocity.z = 0;
}
}
else if (TrInput & VEHICLE_IN_LEFT)
{
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
laraItem->Animation.TargetState = SKIDOO_STATE_LEFT;
else
laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT;
}
else if (TrInput & VEHICLE_IN_RIGHT)
{
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT;
else
laraItem->Animation.TargetState = SKIDOO_STATE_LEFT;
@ -569,21 +569,21 @@ namespace TEN::Entities::Vehicles
break;
case SKIDOO_STATE_DRIVE:
if (skidooItem->Animation.Velocity == 0)
if (skidooItem->Animation.Velocity.z == 0)
laraItem->Animation.TargetState = SKIDOO_STATE_IDLE;
if (dead)
laraItem->Animation.TargetState = SKIDOO_STATE_FALLOFF;
else if (TrInput & VEHICLE_IN_LEFT)
{
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
laraItem->Animation.TargetState = SKIDOO_STATE_LEFT;
else
laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT;
}
else if (TrInput & VEHICLE_IN_RIGHT)
{
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT;
else
laraItem->Animation.TargetState = SKIDOO_STATE_LEFT;
@ -592,7 +592,7 @@ namespace TEN::Entities::Vehicles
break;
case SKIDOO_STATE_LEFT:
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
{
if (!(TrInput & VEHICLE_IN_LEFT))
laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE;
@ -606,7 +606,7 @@ namespace TEN::Entities::Vehicles
break;
case SKIDOO_STATE_RIGHT:
if (skidooItem->Animation.Velocity >= 0)
if (skidooItem->Animation.Velocity.z >= 0)
{
if (!(TrInput & VEHICLE_IN_RIGHT))
laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE;
@ -620,14 +620,14 @@ namespace TEN::Entities::Vehicles
break;
case SKIDOO_STATE_FALL:
if (skidooItem->Animation.VerticalVelocity <= 0 ||
if (skidooItem->Animation.Velocity.y <= 0 ||
skidoo->LeftVerticalVelocity <= 0 ||
skidoo->RightVerticalVelocity <= 0)
{
laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE;
SoundEffect(SFX_TR2_VEHICLE_IMPACT3, &skidooItem->Pose);
}
else if (skidooItem->Animation.VerticalVelocity > (SKIDOO_DAMAGE_START + SKIDOO_DAMAGE_LENGTH))
else if (skidooItem->Animation.Velocity.y > (SKIDOO_DAMAGE_START + SKIDOO_DAMAGE_LENGTH))
laraItem->Animation.TargetState = SKIDOO_STATE_JUMP_OFF;
break;
@ -803,12 +803,12 @@ namespace TEN::Entities::Vehicles
{
skidooItem->Pose.Position.z += z;
skidooItem->Pose.Position.x += x;
skidooItem->Animation.Velocity -= 50;
skidooItem->Animation.Velocity.z -= 50;
}
else if (z)
{
skidooItem->Pose.Position.z += z;
skidooItem->Animation.Velocity -= 50;
skidooItem->Animation.Velocity.z -= 50;
if (z > 0)
return (skidooItem->Pose.Position.x - pos->x);
@ -818,7 +818,7 @@ namespace TEN::Entities::Vehicles
else if (x)
{
skidooItem->Pose.Position.x += x;
skidooItem->Animation.Velocity -= 50;
skidooItem->Animation.Velocity.z -= 50;
if (x > 0)
return (pos->z - skidooItem->Pose.Position.z);
@ -829,7 +829,7 @@ namespace TEN::Entities::Vehicles
{
skidooItem->Pose.Position.z += old->z - pos->z;
skidooItem->Pose.Position.x += old->x - pos->x;
skidooItem->Animation.Velocity -= 50;
skidooItem->Animation.Velocity.z -= 50;
}
}
@ -887,7 +887,7 @@ namespace TEN::Entities::Vehicles
else
skidooItem->Pose.Orientation.y += skidoo->TurnRate + skidoo->ExtraRotation;
TranslateItem(skidooItem, skidoo->MomentumAngle, skidooItem->Animation.Velocity);
TranslateItem(skidooItem, skidoo->MomentumAngle, skidooItem->Animation.Velocity.z);
int slip = SKIDOO_SLIP * phd_sin(skidooItem->Pose.Orientation.x);
if (abs(slip) > (SKIDOO_SLIP / 2))
@ -938,19 +938,19 @@ namespace TEN::Entities::Vehicles
if (collide)
{
int newVelocity = (skidooItem->Pose.Position.z - oldPos.z) * phd_cos(skidoo->MomentumAngle) + (skidooItem->Pose.Position.x - oldPos.x) * phd_sin(skidoo->MomentumAngle);
if (skidooItem->Animation.Velocity > (SKIDOO_NORMAL_VELOCITY_MAX + SKIDOO_VELOCITY_ACCEL) &&
newVelocity < (skidooItem->Animation.Velocity - 10))
if (skidooItem->Animation.Velocity.z > (SKIDOO_NORMAL_VELOCITY_MAX + SKIDOO_VELOCITY_ACCEL) &&
newVelocity < (skidooItem->Animation.Velocity.z - 10))
{
DoDamage(laraItem, (skidooItem->Animation.Velocity - newVelocity) / 2);
DoDamage(laraItem, (skidooItem->Animation.Velocity.z - newVelocity) / 2);
}
if (skidooItem->Animation.Velocity > 0 && newVelocity < skidooItem->Animation.Velocity)
skidooItem->Animation.Velocity = (newVelocity < 0) ? 0 : newVelocity;
else if (skidooItem->Animation.Velocity < 0 && newVelocity > skidooItem->Animation.Velocity)
skidooItem->Animation.Velocity = (newVelocity > 0) ? 0 : newVelocity;
if (skidooItem->Animation.Velocity.z > 0 && newVelocity < skidooItem->Animation.Velocity.z)
skidooItem->Animation.Velocity.z = (newVelocity < 0) ? 0 : newVelocity;
else if (skidooItem->Animation.Velocity.z < 0 && newVelocity > skidooItem->Animation.Velocity.z)
skidooItem->Animation.Velocity.z = (newVelocity > 0) ? 0 : newVelocity;
if (skidooItem->Animation.Velocity < SKIDOO_REVERSE_VELOCITY_MAX)
skidooItem->Animation.Velocity = SKIDOO_REVERSE_VELOCITY_MAX;
if (skidooItem->Animation.Velocity.z < SKIDOO_REVERSE_VELOCITY_MAX)
skidooItem->Animation.Velocity.z = SKIDOO_REVERSE_VELOCITY_MAX;
}
return collide;

View file

@ -172,8 +172,8 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position.y -= 5;
laraItem->Pose.Orientation = Vector3Shrt(0, speedboatItem->Pose.Orientation.y, 0);
laraItem->Animation.IsAirborne = false;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
lara->Control.WaterStatus = WaterStatus::Dry;
AnimateItem(laraItem);
@ -225,8 +225,8 @@ namespace TEN::Entities::Vehicles
SetAnimation(laraItem, LA_JUMP_FORWARD);
laraItem->Animation.IsAirborne = true;
laraItem->Animation.Velocity = 40;
laraItem->Animation.VerticalVelocity = -50;
laraItem->Animation.Velocity.z = 40;
laraItem->Animation.Velocity.y = -50;
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.z = 0;
lara->Vehicle = NO_ITEM;
@ -456,8 +456,8 @@ namespace TEN::Entities::Vehicles
speedboatItem->Pose.Orientation.y += speedboat->TurnRate + speedboat->ExtraRotation;
speedboat->LeanAngle = speedboat->TurnRate * 6;
speedboatItem->Pose.Position.x += speedboatItem->Animation.Velocity * phd_sin(speedboatItem->Pose.Orientation.y);
speedboatItem->Pose.Position.z += speedboatItem->Animation.Velocity * phd_cos(speedboatItem->Pose.Orientation.y);
speedboatItem->Pose.Position.x += speedboatItem->Animation.Velocity.z * phd_sin(speedboatItem->Pose.Orientation.y);
speedboatItem->Pose.Position.z += speedboatItem->Animation.Velocity.z * phd_cos(speedboatItem->Pose.Orientation.y);
int slip = SPEEDBOAT_SLIP_SIDE * phd_sin(speedboatItem->Pose.Orientation.z);
if (!slip && speedboatItem->Pose.Orientation.z)
@ -521,29 +521,29 @@ namespace TEN::Entities::Vehicles
{
newVelocity = (speedboatItem->Pose.Position.z - old.z) * phd_cos(speedboatItem->Pose.Orientation.y) + (speedboatItem->Pose.Position.x - old.x) * phd_sin(speedboatItem->Pose.Orientation.y);
if (lara->Vehicle == itemNumber && speedboatItem->Animation.Velocity > SPEEDBOAT_NORMAL_VELOCITY_MAX + SPEEDBOAT_VELOCITY_ACCEL && newVelocity < speedboatItem->Animation.Velocity - 10)
if (lara->Vehicle == itemNumber && speedboatItem->Animation.Velocity.z > SPEEDBOAT_NORMAL_VELOCITY_MAX + SPEEDBOAT_VELOCITY_ACCEL && newVelocity < speedboatItem->Animation.Velocity.z - 10)
{
DoDamage(laraItem, speedboatItem->Animation.Velocity);
DoDamage(laraItem, speedboatItem->Animation.Velocity.z);
SoundEffect(SFX_TR4_LARA_INJURY, &laraItem->Pose);
newVelocity /= 2;
speedboatItem->Animation.Velocity /= 2;
speedboatItem->Animation.Velocity.z /= 2;
}
if (slip)
{
if (speedboatItem->Animation.Velocity <= SPEEDBOAT_NORMAL_VELOCITY_MAX + 10)
speedboatItem->Animation.Velocity = newVelocity;
if (speedboatItem->Animation.Velocity.z <= SPEEDBOAT_NORMAL_VELOCITY_MAX + 10)
speedboatItem->Animation.Velocity.z = newVelocity;
}
else
{
if (speedboatItem->Animation.Velocity > 0 && newVelocity < speedboatItem->Animation.Velocity)
speedboatItem->Animation.Velocity = newVelocity;
else if (speedboatItem->Animation.Velocity < 0 && newVelocity > speedboatItem->Animation.Velocity)
speedboatItem->Animation.Velocity = newVelocity;
if (speedboatItem->Animation.Velocity.z > 0 && newVelocity < speedboatItem->Animation.Velocity.z)
speedboatItem->Animation.Velocity.z = newVelocity;
else if (speedboatItem->Animation.Velocity.z < 0 && newVelocity > speedboatItem->Animation.Velocity.z)
speedboatItem->Animation.Velocity.z = newVelocity;
}
if (speedboatItem->Animation.Velocity < -SPEEDBOAT_REVERSE_VELOCITY_MAX)
speedboatItem->Animation.Velocity = -SPEEDBOAT_REVERSE_VELOCITY_MAX;
if (speedboatItem->Animation.Velocity.z < -SPEEDBOAT_REVERSE_VELOCITY_MAX)
speedboatItem->Animation.Velocity.z = -SPEEDBOAT_REVERSE_VELOCITY_MAX;
}
return collide;
@ -559,7 +559,7 @@ namespace TEN::Entities::Vehicles
if (speedboatItem->Pose.Position.y >= speedboat->Water - CLICK(0.5f) && speedboat->Water != NO_HEIGHT)
{
if (!(TrInput & VEHICLE_IN_DISMOUNT) && !(TrInput & IN_LOOK) ||
speedboatItem->Animation.Velocity)
speedboatItem->Animation.Velocity.z)
{
if (TrInput & VEHICLE_IN_LEFT && !(TrInput & VEHICLE_IN_REVERSE) ||
TrInput & VEHICLE_IN_RIGHT && TrInput & VEHICLE_IN_REVERSE)
@ -592,10 +592,10 @@ namespace TEN::Entities::Vehicles
if (TrInput & VEHICLE_IN_REVERSE)
{
if (speedboatItem->Animation.Velocity > 0)
speedboatItem->Animation.Velocity -= SPEEDBOAT_VELOCITY_BRAKE_DECEL;
else if (speedboatItem->Animation.Velocity > -SPEEDBOAT_REVERSE_VELOCITY_MAX)
speedboatItem->Animation.Velocity -= SPEEDBOAT_REVERSE_VELOCITY_DECEL;
if (speedboatItem->Animation.Velocity.z > 0)
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_BRAKE_DECEL;
else if (speedboatItem->Animation.Velocity.z > -SPEEDBOAT_REVERSE_VELOCITY_MAX)
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_REVERSE_VELOCITY_DECEL;
}
else if (TrInput & VEHICLE_IN_ACCELERATE)
{
@ -604,39 +604,39 @@ namespace TEN::Entities::Vehicles
else
maxVelocity = (TrInput & VEHICLE_IN_SLOW) ? SPEEDBOAT_SLOW_VELOCITY_MAX : SPEEDBOAT_NORMAL_VELOCITY_MAX;
if (speedboatItem->Animation.Velocity < maxVelocity)
speedboatItem->Animation.Velocity += (SPEEDBOAT_VELOCITY_ACCEL / 2) + (SPEEDBOAT_VELOCITY_ACCEL * (speedboatItem->Animation.Velocity / (maxVelocity * 2)));
else if (speedboatItem->Animation.Velocity > (maxVelocity + SPEEDBOAT_VELOCITY_DECEL))
speedboatItem->Animation.Velocity -= SPEEDBOAT_VELOCITY_DECEL;
if (speedboatItem->Animation.Velocity.z < maxVelocity)
speedboatItem->Animation.Velocity.z += (SPEEDBOAT_VELOCITY_ACCEL / 2) + (SPEEDBOAT_VELOCITY_ACCEL * (speedboatItem->Animation.Velocity.z / (maxVelocity * 2)));
else if (speedboatItem->Animation.Velocity.z > (maxVelocity + SPEEDBOAT_VELOCITY_DECEL))
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_DECEL;
}
else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) &&
speedboatItem->Animation.Velocity >= 0 &&
speedboatItem->Animation.Velocity < SPEEDBOAT_VELOCITY_MIN)
speedboatItem->Animation.Velocity.z >= 0 &&
speedboatItem->Animation.Velocity.z < SPEEDBOAT_VELOCITY_MIN)
{
if (!(TrInput & VEHICLE_IN_DISMOUNT) &&
speedboatItem->Animation.Velocity == 0)
speedboatItem->Animation.Velocity = SPEEDBOAT_VELOCITY_MIN;
speedboatItem->Animation.Velocity.z == 0)
speedboatItem->Animation.Velocity.z = SPEEDBOAT_VELOCITY_MIN;
}
else if (speedboatItem->Animation.Velocity > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity -= SPEEDBOAT_VELOCITY_DECEL;
else if (speedboatItem->Animation.Velocity.z > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_DECEL;
else
speedboatItem->Animation.Velocity = 0;
speedboatItem->Animation.Velocity.z = 0;
}
else
{
if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) &&
speedboatItem->Animation.Velocity >= 0 &&
speedboatItem->Animation.Velocity < SPEEDBOAT_VELOCITY_MIN)
speedboatItem->Animation.Velocity.z >= 0 &&
speedboatItem->Animation.Velocity.z < SPEEDBOAT_VELOCITY_MIN)
{
if (speedboatItem->Animation.Velocity == 0 && !(TrInput & VEHICLE_IN_DISMOUNT))
speedboatItem->Animation.Velocity = SPEEDBOAT_VELOCITY_MIN;
if (speedboatItem->Animation.Velocity.z == 0 && !(TrInput & VEHICLE_IN_DISMOUNT))
speedboatItem->Animation.Velocity.z = SPEEDBOAT_VELOCITY_MIN;
}
else if (speedboatItem->Animation.Velocity > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity -= SPEEDBOAT_VELOCITY_DECEL;
else if (speedboatItem->Animation.Velocity.z > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_DECEL;
else
speedboatItem->Animation.Velocity = 0;
speedboatItem->Animation.Velocity.z = 0;
if (TrInput & IN_LOOK && speedboatItem->Animation.Velocity == 0)
if (TrInput & IN_LOOK && speedboatItem->Animation.Velocity.z == 0)
LookUpDown(laraItem);
}
}
@ -657,7 +657,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.ActiveState = laraItem->Animation.TargetState = SPEEDBOAT_STATE_DEATH;
}
}
else if (speedboatItem->Pose.Position.y < speedboat->Water - CLICK(0.5f) && speedboatItem->Animation.VerticalVelocity > 0)
else if (speedboatItem->Pose.Position.y < speedboat->Water - CLICK(0.5f) && speedboatItem->Animation.Velocity.y > 0)
{
if (laraItem->Animation.ActiveState != SPEEDBOAT_STATE_FALL)
{
@ -682,7 +682,7 @@ namespace TEN::Entities::Vehicles
case SPEEDBOAT_STATE_IDLE:
if (TrInput & VEHICLE_IN_DISMOUNT)
{
if (speedboatItem->Animation.Velocity == 0)
if (speedboatItem->Animation.Velocity.z == 0)
{
if (TrInput & VEHICLE_IN_RIGHT && TestSpeedboatDismount(speedboatItem, speedboatItem->Pose.Orientation.y + ANGLE(90.0f)))
laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_RIGHT;
@ -691,7 +691,7 @@ namespace TEN::Entities::Vehicles
}
}
if (speedboatItem->Animation.Velocity > 0)
if (speedboatItem->Animation.Velocity.z > 0)
laraItem->Animation.TargetState = SPEEDBOAT_STATE_MOVING;
break;
@ -704,7 +704,7 @@ namespace TEN::Entities::Vehicles
else if (TrInput & VEHICLE_IN_RIGHT)
laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_LEFT;
}
else if (speedboatItem->Animation.Velocity <= 0)
else if (speedboatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = SPEEDBOAT_STATE_IDLE;
break;
@ -714,7 +714,7 @@ namespace TEN::Entities::Vehicles
break;
//case SPEEDBOAT_TURN_RATE_ACCELR:
if (speedboatItem->Animation.Velocity <= 0)
if (speedboatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = SPEEDBOAT_STATE_IDLE;
else if (!(TrInput & VEHICLE_IN_RIGHT))
laraItem->Animation.TargetState = SPEEDBOAT_STATE_MOVING;
@ -722,7 +722,7 @@ namespace TEN::Entities::Vehicles
break;
case SPEEDBOAT_STATE_TURN_LEFT:
if (speedboatItem->Animation.Velocity <= 0)
if (speedboatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = SPEEDBOAT_STATE_IDLE;
else if (!(TrInput & VEHICLE_IN_LEFT))
laraItem->Animation.TargetState = SPEEDBOAT_STATE_MOVING;
@ -788,7 +788,7 @@ namespace TEN::Entities::Vehicles
bool noTurn = true;
bool drive = false;
bool idle = !speedboatItem->Animation.Velocity;
bool idle = !speedboatItem->Animation.Velocity.z;
if (lara->Vehicle == itemNumber && laraItem->HitPoints > 0)
{
@ -807,10 +807,10 @@ namespace TEN::Entities::Vehicles
}
else
{
if (speedboatItem->Animation.Velocity > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity -= SPEEDBOAT_VELOCITY_DECEL;
if (speedboatItem->Animation.Velocity.z > SPEEDBOAT_VELOCITY_DECEL)
speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_DECEL;
else
speedboatItem->Animation.Velocity = 0;
speedboatItem->Animation.Velocity.z = 0;
}
if (noTurn)
@ -831,11 +831,11 @@ namespace TEN::Entities::Vehicles
speedboat->LeftVerticalVelocity = DoSpeedboatDynamics(heightFrontLeft, speedboat->LeftVerticalVelocity, (int*)&frontLeft.y);
speedboat->RightVerticalVelocity = DoSpeedboatDynamics(heightFrontRight, speedboat->RightVerticalVelocity, (int*)&frontRight.y);
speedboatItem->Animation.VerticalVelocity = DoSpeedboatDynamics(speedboat->Water, speedboatItem->Animation.VerticalVelocity, (int*)&speedboatItem->Pose.Position.y);
speedboatItem->Animation.Velocity.y = DoSpeedboatDynamics(speedboat->Water, speedboatItem->Animation.Velocity.y, (int*)&speedboatItem->Pose.Position.y);
auto ofs = speedboatItem->Animation.VerticalVelocity;
if (ofs - speedboatItem->Animation.VerticalVelocity > 32 && speedboatItem->Animation.VerticalVelocity == 0 && water != NO_HEIGHT)
SpeedboatSplash(speedboatItem, ofs - speedboatItem->Animation.VerticalVelocity, water);
auto ofs = speedboatItem->Animation.Velocity.y;
if (ofs - speedboatItem->Animation.Velocity.y > 32 && speedboatItem->Animation.Velocity.y == 0 && water != NO_HEIGHT)
SpeedboatSplash(speedboatItem, ofs - speedboatItem->Animation.Velocity.y, water);
probe.Position.Floor = (frontLeft.y + frontRight.y);
if (probe.Position.Floor < 0)
@ -878,13 +878,13 @@ namespace TEN::Entities::Vehicles
Camera.targetElevation = -ANGLE(20.0f);
Camera.targetDistance = SECTOR(2);
auto pitch = speedboatItem->Animation.Velocity;
auto pitch = speedboatItem->Animation.Velocity.z;
speedboat->Pitch += (pitch - speedboat->Pitch) / 4;
if (drive)
{
bool accelerating = idle && abs(speedboatItem->Animation.Velocity) > 4;
bool moving = (abs(speedboatItem->Animation.Velocity) > 8 || speedboat->TurnRate);
bool accelerating = idle && abs(speedboatItem->Animation.Velocity.z) > 4;
bool moving = (abs(speedboatItem->Animation.Velocity.z) > 8 || speedboat->TurnRate);
int fx = accelerating ? SFX_TR2_VEHICLE_SPEEDBOAT_ACCELERATE : (moving ? SFX_TR2_VEHICLE_SPEEDBOAT_MOVING : SFX_TR2_VEHICLE_SPEEDBOAT_IDLE);
float pitch = idle ? 1.0f : 1.0f + speedboat->Pitch / (float)SPEEDBOAT_NORMAL_VELOCITY_MAX / 4.0f;
SoundEffect(fx, &speedboatItem->Pose, SoundEnvironment::Land, pitch);
@ -898,7 +898,7 @@ namespace TEN::Entities::Vehicles
speedboatItem->Pose.Orientation.z += speedboat->LeanAngle;
}
if (speedboatItem->Animation.Velocity && (water - 5) == speedboatItem->Pose.Position.y)
if (speedboatItem->Animation.Velocity.z && (water - 5) == speedboatItem->Pose.Position.y)
{
auto room = probe.Block->RoomBelow(speedboatItem->Pose.Position.x, speedboatItem->Pose.Position.z).value_or(NO_ROOM);
if (room != NO_ROOM && (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, room) || TestEnvironment(RoomEnvFlags::ENV_FLAG_SWAMP, room)))

View file

@ -113,7 +113,7 @@ namespace TEN::Entities::TR3
if (AI.distance > pow(COBRA_SLEEP_RANGE, 2))
item->Animation.TargetState = COBRA_STATE_SLEEP;
else if (LaraItem->HitPoints > 0 &&
((AI.ahead && AI.distance < pow(COBRA_ATTACK_RANGE, 2)) || item->HitStatus || LaraItem->Animation.Velocity > PLAYER_DISTURB_VELOCITY))
((AI.ahead && AI.distance < pow(COBRA_ATTACK_RANGE, 2)) || item->HitStatus || LaraItem->Animation.Velocity.z > PLAYER_DISTURB_VELOCITY))
{
item->Animation.TargetState = COBRA_STATE_ATTACK;
}

View file

@ -47,7 +47,7 @@ namespace TEN::Entities::TR3
harpoonItem->Pose.Orientation.x = 0;
harpoonItem->Pose.Orientation.y = yRot;
harpoonItem->Animation.Velocity = 150;
harpoonItem->Animation.Velocity.z = 150;
AddActiveItem(harpoonItemNumber);
harpoonItem->Status = ITEM_ACTIVE;
@ -69,10 +69,10 @@ namespace TEN::Entities::TR3
int ox = item->Pose.Position.x;
int oz = item->Pose.Position.z;
int velocity = item->Animation.Velocity * phd_cos(item->Pose.Orientation.x);
int velocity = item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.x);
item->Pose.Position.z += velocity * phd_cos(item->Pose.Orientation.y);
item->Pose.Position.x += velocity * phd_sin(item->Pose.Orientation.y);
item->Pose.Position.y += -item->Animation.Velocity * phd_sin(item->Pose.Orientation.x);
item->Pose.Position.y += -item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.x);
auto probe = GetCollision(item);
@ -201,7 +201,7 @@ namespace TEN::Entities::TR3
if (!creature->Flags)
{
ShootHarpoon(item, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->Animation.Velocity, item->Pose.Orientation.y, item->RoomNumber);
ShootHarpoon(item, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->Animation.Velocity.z, item->Pose.Orientation.y, item->RoomNumber);
creature->Flags = 1;
}
@ -242,7 +242,7 @@ namespace TEN::Entities::TR3
if (!creature->Flags)
{
ShootHarpoon(item, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->Animation.Velocity, item->Pose.Orientation.y, item->RoomNumber);
ShootHarpoon(item, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->Animation.Velocity.z, item->Pose.Orientation.y, item->RoomNumber);
creature->Flags = 1;
}

View file

@ -129,7 +129,7 @@ namespace TEN::Entities::TR3
item->Animation.TargetState = 1;
else if (AI.bite && AI.distance < pow(SECTOR(1.5f), 2))
{
if (LaraItem->Animation.Velocity == 0)
if (LaraItem->Animation.Velocity.z == 0)
item->Animation.TargetState = 1;
else
item->Animation.TargetState = 7;

View file

@ -97,7 +97,7 @@ namespace TEN::Entities::TR3
fx->pos.Orientation.z = 0;
fx->objectNumber = ID_TONY_BOSS_FLAME;
fx->speed = flame.speed;
fx->shade = 0;
fx->color = Vector4::Zero;
fx->flag1 = flame.type;
fx->flag2 = (GetRandomControl() & 3) + 1;

View file

@ -317,7 +317,7 @@ namespace TEN::Entities::TR3
InitialiseItem(dartItemNumber);
dartItem->Pose.Orientation = angles;
dartItem->Animation.Velocity = CLICK(1);
dartItem->Animation.Velocity.z = CLICK(1);
AddActiveItem(dartItemNumber);

View file

@ -112,8 +112,8 @@ void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
// laraItem->Animation.ActiveState = EXTRA_TRAINKILL;
// laraItem->Animation.TargetState = EXTRA_TRAINKILL;
laraItem->Pose.Orientation.y = trainItem->Pose.Orientation.y;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.IsAirborne = false;
DoDamage(laraItem, INT_MAX);

View file

@ -129,7 +129,7 @@ namespace TEN::Entities::Vehicles
InitialiseItem(itemNumber);
projectileItem->Animation.Velocity = 16;
projectileItem->Animation.Velocity.z = 16;
projectileItem->Pose.Orientation = Vector3Shrt(
-((bigGun->XOrientFrame - 32) * ANGLE(1.0f)),
bigGunItem->Pose.Orientation.y,

View file

@ -225,8 +225,8 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position = kayakItem->Pose.Position;
laraItem->Pose.Orientation = Vector3Shrt(0, kayakItem->Pose.Orientation.y, 0);
laraItem->Animation.IsAirborne = false;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
lara->Control.WaterStatus = WaterStatus::Dry;
kayak->WaterHeight = kayakItem->Pose.Position.y;
kayak->Flags = 0;
@ -258,7 +258,7 @@ namespace TEN::Entities::Vehicles
if (waterHeight != NO_HEIGHT)
{
short angle1, angle2;
if (kayakItem->Animation.Velocity < 0)
if (kayakItem->Animation.Velocity.z < 0)
{
if (!rotate)
{
@ -604,8 +604,8 @@ namespace TEN::Entities::Vehicles
int leftHeight = GetVehicleWaterHeight(kayakItem, KAYAK_Z, -KAYAK_X, false, &leftPos);
int rightHeight = GetVehicleWaterHeight(kayakItem, KAYAK_Z, KAYAK_X, false, &rightPos);
kayakItem->Pose.Position.x += kayakItem->Animation.Velocity * phd_sin(kayakItem->Pose.Orientation.y);
kayakItem->Pose.Position.z += kayakItem->Animation.Velocity * phd_cos(kayakItem->Pose.Orientation.y);
kayakItem->Pose.Position.x += kayakItem->Animation.Velocity.z * phd_sin(kayakItem->Pose.Orientation.y);
kayakItem->Pose.Position.z += kayakItem->Animation.Velocity.z * phd_cos(kayakItem->Pose.Orientation.y);
kayakItem->Pose.Orientation.y += kayak->TurnRate;
KayakDoCurrent(kayakItem, laraItem);
@ -614,7 +614,7 @@ namespace TEN::Entities::Vehicles
kayak->RightVerticalVelocity = KayakDoDynamics(rightHeight, kayak->RightVerticalVelocity, &rightPos.y);
kayak->FrontVerticalVelocity = KayakDoDynamics(frontHeight, kayak->FrontVerticalVelocity, &frontPos.y);
kayakItem->Animation.VerticalVelocity = KayakDoDynamics(kayak->WaterHeight, kayakItem->Animation.VerticalVelocity, &kayakItem->Pose.Position.y);
kayakItem->Animation.Velocity.y = KayakDoDynamics(kayak->WaterHeight, kayakItem->Animation.Velocity.y, &kayakItem->Pose.Position.y);
int height2 = (leftPos.y + rightPos.y) / 2;
int x = phd_atan(1024, kayakItem->Pose.Position.y - frontPos.y);
@ -1051,13 +1051,13 @@ namespace TEN::Entities::Vehicles
GetLaraJointPosition(&vec, LM_HIPS);
SetAnimation(laraItem, LA_JUMP_FORWARD);
laraItem->Animation.IsAirborne = true;
laraItem->Animation.Velocity = 40;
laraItem->Animation.VerticalVelocity = -50;
laraItem->Pose.Position = vec;
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.y = kayakItem->Pose.Orientation.y - ANGLE(90.0f);
laraItem->Pose.Orientation.z = 0;
laraItem->Animation.Velocity.z = 40;
laraItem->Animation.Velocity.y = -50;
laraItem->Animation.IsAirborne = true;
lara->Control.HandStatus = HandStatus::Free;
lara->Vehicle = NO_ITEM;
kayak->LeftRightPaddleCount = 0;
@ -1078,8 +1078,8 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Orientation.y = kayakItem->Pose.Orientation.y + ANGLE(90.0f);
laraItem->Pose.Orientation.z = 0;
laraItem->Animation.IsAirborne = true;
laraItem->Animation.Velocity = 40;
laraItem->Animation.VerticalVelocity = -50;
laraItem->Animation.Velocity.z = 40;
laraItem->Animation.Velocity.y = -50;
lara->Control.HandStatus = HandStatus::Free;
lara->Vehicle = NO_ITEM;
kayak->LeftRightPaddleCount = 0;
@ -1104,7 +1104,7 @@ namespace TEN::Entities::Vehicles
else if (kayak->Velocity < -KAYAK_VELOCITY_MAX)
kayak->Velocity = -KAYAK_VELOCITY_MAX;
kayakItem->Animation.Velocity = kayak->Velocity / VEHICLE_VELOCITY_SCALE;
kayakItem->Animation.Velocity.z = kayak->Velocity / VEHICLE_VELOCITY_SCALE;
if (kayak->TurnRate >= 0)
{
@ -1148,7 +1148,7 @@ namespace TEN::Entities::Vehicles
{
if (TestBoundsCollide(item, kayakItem, KAYAK_TO_ENTITY_RADIUS))
{
DoLotsOfBlood(laraItem->Pose.Position.x, laraItem->Pose.Position.y - STEP_SIZE, laraItem->Pose.Position.z, kayakItem->Animation.Velocity, kayakItem->Pose.Orientation.y, laraItem->RoomNumber, 3);
DoLotsOfBlood(laraItem->Pose.Position.x, laraItem->Pose.Position.y - STEP_SIZE, laraItem->Pose.Position.z, kayakItem->Animation.Velocity.z, kayakItem->Pose.Orientation.y, laraItem->RoomNumber, 3);
DoDamage(laraItem, 5);
}
}
@ -1177,8 +1177,8 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.ActiveState = 12; // TODO
laraItem->Animation.TargetState = 12;
laraItem->Animation.IsAirborne = false;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->HitPoints = -1;
AnimateItem(laraItem);
@ -1198,7 +1198,7 @@ namespace TEN::Entities::Vehicles
if (TrInput & IN_LOOK)
LookUpDown(laraItem);
int ofs = kayakItem->Animation.VerticalVelocity;
int ofs = kayakItem->Animation.Velocity.y;
KayakUserInput(kayakItem, laraItem);
KayakToBackground(kayakItem, laraItem);
@ -1220,11 +1220,11 @@ namespace TEN::Entities::Vehicles
kayak->TrueWater = true;
}
if ((ofs - kayakItem->Animation.VerticalVelocity) > 128 &&
kayakItem->Animation.VerticalVelocity == 0 &&
if ((ofs - kayakItem->Animation.Velocity.y) > 128 &&
kayakItem->Animation.Velocity.y == 0 &&
water != NO_HEIGHT)
{
int damage = ofs - kayakItem->Animation.VerticalVelocity;
int damage = ofs - kayakItem->Animation.Velocity.y;
if (damage > 160)
DoDamage(laraItem, (damage - 160) * 8);
}
@ -1259,7 +1259,7 @@ namespace TEN::Entities::Vehicles
if (Wibble & 7)
{
if (!kayak->TrueWater && kayakItem->Animation.VerticalVelocity < 20)
if (!kayak->TrueWater && kayakItem->Animation.Velocity.y < 20)
{
Vector3Int dest;
char cnt = 0;
@ -1280,7 +1280,7 @@ namespace TEN::Entities::Vehicles
}
}
if (!kayakItem->Animation.Velocity &&
if (!kayakItem->Animation.Velocity.z &&
!lara->WaterCurrentPull.x &&
!lara->WaterCurrentPull.z)
{

View file

@ -365,7 +365,7 @@ namespace TEN::Entities::Vehicles
{
if (minecart->Velocity < MINECART_STOP_VELOCITY_MAX)
{
minecartItem->Animation.Velocity = 0;
minecartItem->Animation.Velocity.z = 0;
minecart->Velocity = 0;
minecart->Flags |= MINECART_FLAG_STOPPED | MINECART_FLAG_CONTROL;
return;
@ -449,11 +449,11 @@ namespace TEN::Entities::Vehicles
minecart->Velocity = MINECART_VELOCITY_MIN;
minecart->Velocity -= minecart->Gradient * 4;
minecartItem->Animation.Velocity = minecart->Velocity / VEHICLE_VELOCITY_SCALE;
minecartItem->Animation.Velocity.z = minecart->Velocity / VEHICLE_VELOCITY_SCALE;
if (minecartItem->Animation.Velocity < MINECART_ANIM_VELOCITY_MIN)
if (minecartItem->Animation.Velocity.z < MINECART_ANIM_VELOCITY_MIN)
{
minecartItem->Animation.Velocity = MINECART_ANIM_VELOCITY_MIN;
minecartItem->Animation.Velocity.z = MINECART_ANIM_VELOCITY_MIN;
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP);
if (minecart->VerticalVelocity)
@ -468,12 +468,12 @@ namespace TEN::Entities::Vehicles
if (minecart->VerticalVelocity)
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP);
else
SoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP, &minecartItem->Pose, SoundEnvironment::Land, 1.0f + ((float)minecartItem->Animation.Velocity / SECTOR(8))); // TODO: check actual sound!
SoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP, &minecartItem->Pose, SoundEnvironment::Land, 1.0f + ((float)minecartItem->Animation.Velocity.z / SECTOR(8))); // TODO: check actual sound!
}
if (minecart->Flags & (MINECART_FLAG_TURNING_LEFT | MINECART_FLAG_TURNING_RIGHT))
{
minecart->TurnLen += minecartItem->Animation.Velocity * 3;
minecart->TurnLen += minecartItem->Animation.Velocity.z * 3;
if (minecart->TurnLen > ANGLE(90.0f))
{
if (minecart->Flags & MINECART_FLAG_TURNING_LEFT)
@ -538,7 +538,7 @@ namespace TEN::Entities::Vehicles
}
}
else
TranslateItem(minecartItem, minecartItem->Pose.Orientation.y, minecartItem->Animation.Velocity);
TranslateItem(minecartItem, minecartItem->Pose.Orientation.y, minecartItem->Animation.Velocity.z);
minecart->FloorHeightMiddle = GetVehicleHeight(minecartItem, 0, 0, true, &Vector3Int());
@ -574,9 +574,9 @@ namespace TEN::Entities::Vehicles
{
short val = minecartItem->Pose.Orientation.y & 16383;
if (minecart->Flags & MINECART_FLAG_TURNING_RIGHT)
minecartItem->Pose.Orientation.z = -(val * minecartItem->Animation.Velocity) / 512;
minecartItem->Pose.Orientation.z = -(val * minecartItem->Animation.Velocity.z) / 512;
else
minecartItem->Pose.Orientation.z = ((ANGLE(90.0f) - val) * minecartItem->Animation.Velocity) / 512;
minecartItem->Pose.Orientation.z = ((ANGLE(90.0f) - val) * minecartItem->Animation.Velocity.z) / 512;
}
else
minecartItem->Pose.Orientation.z -= minecartItem->Pose.Orientation.z / 8;
@ -836,7 +836,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.FrameNumber == GetFrameNumber(minecartItem, 34) + 28)
{
laraItem->Animation.FrameNumber = GetFrameNumber(minecartItem, 34) + 28;
minecartItem->Animation.Velocity = 0;
minecartItem->Animation.Velocity.z = 0;
minecart->Velocity = 0;
minecart->Flags = (minecart->Flags & ~MINECART_FLAG_CONTROL) | MINECART_FLAG_NO_ANIM;
}
@ -863,7 +863,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
laraItem->Animation.ActiveState = MINECART_STATE_TURN_DEATH;
laraItem->Animation.TargetState = MINECART_STATE_TURN_DEATH;
minecartItem->Animation.Velocity = 0;
minecartItem->Animation.Velocity.z = 0;
minecart->Velocity = 0;
minecart->Flags = (minecart->Flags & ~MINECART_FLAG_CONTROL) | MINECART_FLAG_STOPPED | MINECART_FLAG_DEAD;
return;
@ -883,7 +883,7 @@ namespace TEN::Entities::Vehicles
laraItem->Animation.ActiveState = MINECART_STATE_WALL_DEATH;
laraItem->Animation.TargetState = MINECART_STATE_WALL_DEATH;
laraItem->HitPoints = -1;
minecartItem->Animation.Velocity = 0;
minecartItem->Animation.Velocity.z = 0;
minecart->Velocity = 0;
minecart->Flags = (minecart->Flags & ~MINECART_FLAG_CONTROL) | (MINECART_FLAG_STOPPED | MINECART_FLAG_DEAD);
return;
@ -906,7 +906,7 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position.x,
laraItem->Pose.Position.y - CLICK(3),
laraItem->Pose.Position.z,
minecartItem->Animation.Velocity,
minecartItem->Animation.Velocity.z,
minecartItem->Pose.Orientation.y,
laraItem->RoomNumber,
3);

View file

@ -293,7 +293,7 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position = pos;
laraItem->Animation.IsAirborne = true;
laraItem->Animation.VerticalVelocity = quadBikeItem->Animation.VerticalVelocity;
laraItem->Animation.Velocity.y = quadBikeItem->Animation.Velocity.y;
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.z = 0;
laraItem->HitPoints = 0;
@ -305,8 +305,8 @@ namespace TEN::Entities::Vehicles
else if (laraItem->Animation.ActiveState == QBIKE_STATE_FALL_DEATH)
{
laraItem->Animation.TargetState = LS_DEATH;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = DAMAGE_START + DAMAGE_LENGTH;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = DAMAGE_START + DAMAGE_LENGTH;
quadBike->Flags |= QBIKE_FLAG_DEAD;
return false;
@ -547,9 +547,9 @@ namespace TEN::Entities::Vehicles
auto probe = GetCollision(quadBikeItem);
int speed = 0;
if (quadBikeItem->Pose.Position.y >= probe.Position.Floor)
speed = quadBikeItem->Animation.Velocity * phd_cos(quadBikeItem->Pose.Orientation.x);
speed = quadBikeItem->Animation.Velocity.z * phd_cos(quadBikeItem->Pose.Orientation.x);
else
speed = quadBikeItem->Animation.Velocity;
speed = quadBikeItem->Animation.Velocity.z;
TranslateItem(quadBikeItem, quadBike->MomentumAngle, speed);
@ -832,7 +832,7 @@ namespace TEN::Entities::Vehicles
case QBIKE_STATE_FALL:
if (quadBikeItem->Pose.Position.y == quadBikeItem->Floor)
laraItem->Animation.TargetState = QBIKE_STATE_LAND;
else if (quadBikeItem->Animation.VerticalVelocity > TERMINAL_VERTICAL_VELOCITY)
else if (quadBikeItem->Animation.Velocity.y > TERMINAL_VERTICAL_VELOCITY)
quadBike->Flags |= QBIKE_FLAG_FALLING;
break;
@ -1019,7 +1019,7 @@ namespace TEN::Entities::Vehicles
quadBike->Revs = 0;
}
quadBikeItem->Animation.Velocity = quadBike->Velocity / VEHICLE_VELOCITY_SCALE;
quadBikeItem->Animation.Velocity.z = quadBike->Velocity / VEHICLE_VELOCITY_SCALE;
if (quadBike->EngineRevs > 0x7000)
quadBike->EngineRevs = -0x2000;
@ -1184,7 +1184,7 @@ namespace TEN::Entities::Vehicles
quadBike->LeftVerticalVelocity = DoQuadDynamics(floorHeightLeft, quadBike->LeftVerticalVelocity, (int*)&frontLeft.y);
quadBike->RightVerticalVelocity = DoQuadDynamics(floorHeightRight, quadBike->RightVerticalVelocity, (int*)&frontRight.y);
quadBikeItem->Animation.VerticalVelocity = DoQuadDynamics(probe.Position.Floor, quadBikeItem->Animation.VerticalVelocity, (int*)&quadBikeItem->Pose.Position.y);
quadBikeItem->Animation.Velocity.y = DoQuadDynamics(probe.Position.Floor, quadBikeItem->Animation.Velocity.y, (int*)&quadBikeItem->Pose.Position.y);
quadBike->Velocity = DoVehicleWaterMovement(quadBikeItem, laraItem, quadBike->Velocity, QBIKE_RADIUS, &quadBike->TurnRate);
probe.Position.Floor = (frontLeft.y + frontRight.y) / 2;
@ -1238,11 +1238,11 @@ namespace TEN::Entities::Vehicles
pos.z = QuadBikeEffectsPositions[i].z;
GetJointAbsPosition(quadBikeItem, &pos, QuadBikeEffectsPositions[i].meshNum);
angle = quadBikeItem->Pose.Orientation.y + ((i == 0) ? 0x9000 : 0x7000);
if (quadBikeItem->Animation.Velocity > 32)
if (quadBikeItem->Animation.Velocity.z > 32)
{
if (quadBikeItem->Animation.Velocity < 64)
if (quadBikeItem->Animation.Velocity.z < 64)
{
speed = 64 - quadBikeItem->Animation.Velocity;
speed = 64 - quadBikeItem->Animation.Velocity.z;
TriggerQuadExhaustSmoke(pos.x, pos.y, pos.z, angle, speed, 1);
}
}

View file

@ -172,8 +172,8 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position.y -= 5;
laraItem->Pose.Orientation = Vector3Shrt(0, rBoatItem->Pose.Orientation.y, 0);
laraItem->Animation.IsAirborne = false;
laraItem->Animation.Velocity = 0;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.z = 0;
laraItem->Animation.Velocity.y = 0;
lara->Control.WaterStatus = WaterStatus::Dry;
AnimateItem(laraItem);
@ -371,10 +371,10 @@ namespace TEN::Entities::Vehicles
rBoatItem->Pose.Orientation.y += rBoat->TurnRate + rBoat->ExtraRotation;
rBoat->LeanAngle = rBoat->TurnRate * 6;
rBoatItem->Pose.Position.z += rBoatItem->Animation.Velocity * phd_cos(rBoatItem->Pose.Orientation.y);
rBoatItem->Pose.Position.x += rBoatItem->Animation.Velocity * phd_sin(rBoatItem->Pose.Orientation.y);
if (rBoatItem->Animation.Velocity >= 0)
rBoat->PropellerRotation += (rBoatItem->Animation.Velocity * ANGLE(3.0f)) + ANGLE(2.0f);
rBoatItem->Pose.Position.z += rBoatItem->Animation.Velocity.z * phd_cos(rBoatItem->Pose.Orientation.y);
rBoatItem->Pose.Position.x += rBoatItem->Animation.Velocity.z * phd_sin(rBoatItem->Pose.Orientation.y);
if (rBoatItem->Animation.Velocity.z >= 0)
rBoat->PropellerRotation += (rBoatItem->Animation.Velocity.z * ANGLE(3.0f)) + ANGLE(2.0f);
else
rBoat->PropellerRotation += ANGLE(33.0f);
@ -444,30 +444,30 @@ namespace TEN::Entities::Vehicles
int newVelocity = (rBoatItem->Pose.Position.z - old.z) * phd_cos(rBoatItem->Pose.Orientation.y) + (rBoatItem->Pose.Position.x - old.x) * phd_sin(rBoatItem->Pose.Orientation.y);
if (lara->Vehicle == itemNumber &&
rBoatItem->Animation.Velocity > (RBOAT_NORMAL_VELOCITY_MAX + RBOAT_VELOCITY_ACCEL) &&
newVelocity < rBoatItem->Animation.Velocity - 10)
rBoatItem->Animation.Velocity.z > (RBOAT_NORMAL_VELOCITY_MAX + RBOAT_VELOCITY_ACCEL) &&
newVelocity < rBoatItem->Animation.Velocity.z - 10)
{
DoDamage(laraItem, rBoatItem->Animation.Velocity);
DoDamage(laraItem, rBoatItem->Animation.Velocity.z);
SoundEffect(SFX_TR4_LARA_INJURY, &laraItem->Pose);
newVelocity /= 2;
rBoatItem->Animation.Velocity /= 2;
rBoatItem->Animation.Velocity.z /= 2;
}
if (slip)
{
if (rBoatItem->Animation.Velocity <= RBOAT_NORMAL_VELOCITY_MAX + 10)
rBoatItem->Animation.Velocity = newVelocity;
if (rBoatItem->Animation.Velocity.z <= RBOAT_NORMAL_VELOCITY_MAX + 10)
rBoatItem->Animation.Velocity.z = newVelocity;
}
else
{
if (rBoatItem->Animation.Velocity > 0 && newVelocity < rBoatItem->Animation.Velocity)
rBoatItem->Animation.Velocity = newVelocity;
else if (rBoatItem->Animation.Velocity < 0 && newVelocity > rBoatItem->Animation.Velocity)
rBoatItem->Animation.Velocity = newVelocity;
if (rBoatItem->Animation.Velocity.z > 0 && newVelocity < rBoatItem->Animation.Velocity.z)
rBoatItem->Animation.Velocity.z = newVelocity;
else if (rBoatItem->Animation.Velocity.z < 0 && newVelocity > rBoatItem->Animation.Velocity.z)
rBoatItem->Animation.Velocity.z = newVelocity;
}
if (rBoatItem->Animation.Velocity < -RBOAT_REVERSE_VELOCITY_MAX)
rBoatItem->Animation.Velocity = -RBOAT_REVERSE_VELOCITY_MAX;
if (rBoatItem->Animation.Velocity.z < -RBOAT_REVERSE_VELOCITY_MAX)
rBoatItem->Animation.Velocity.z = -RBOAT_REVERSE_VELOCITY_MAX;
}
return collide;
@ -508,7 +508,7 @@ namespace TEN::Entities::Vehicles
if (rBoatItem->Pose.Position.y >= (rBoat->Water - 128) &&
rBoat->Water != NO_HEIGHT)
{
if (!(TrInput & VEHICLE_IN_DISMOUNT) && !(TrInput & IN_LOOK) || rBoatItem->Animation.Velocity)
if (!(TrInput & VEHICLE_IN_DISMOUNT) && !(TrInput & IN_LOOK) || rBoatItem->Animation.Velocity.z)
{
if ((TrInput & VEHICLE_IN_LEFT && !(TrInput & VEHICLE_IN_REVERSE)) ||
(TrInput & VEHICLE_IN_RIGHT && TrInput & VEHICLE_IN_REVERSE))
@ -541,10 +541,10 @@ namespace TEN::Entities::Vehicles
if (TrInput & VEHICLE_IN_REVERSE)
{
if (rBoatItem->Animation.Velocity > 0)
rBoatItem->Animation.Velocity -= RBOAT_VELOCITY_BRAKE_DECEL;
else if (rBoatItem->Animation.Velocity > -RBOAT_REVERSE_VELOCITY_MAX)
rBoatItem->Animation.Velocity -= RBOAT_REVERSE_VELOCITY_DECEL;
if (rBoatItem->Animation.Velocity.z > 0)
rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_BRAKE_DECEL;
else if (rBoatItem->Animation.Velocity.z > -RBOAT_REVERSE_VELOCITY_MAX)
rBoatItem->Animation.Velocity.z -= RBOAT_REVERSE_VELOCITY_DECEL;
}
else if (TrInput & VEHICLE_IN_ACCELERATE)
{
@ -554,39 +554,39 @@ namespace TEN::Entities::Vehicles
else
maxVelocity = (TrInput & VEHICLE_IN_SLOW) ? RBOAT_SLOW_VELOCITY_MAX : RBOAT_NORMAL_VELOCITY_MAX;
if (rBoatItem->Animation.Velocity < maxVelocity)
rBoatItem->Animation.Velocity += (RBOAT_VELOCITY_ACCEL / 2 + 1) + (RBOAT_VELOCITY_ACCEL * rBoatItem->Animation.Velocity) / (maxVelocity * 2);
else if (rBoatItem->Animation.Velocity > (maxVelocity + RBOAT_VELOCITY_DECEL))
rBoatItem->Animation.Velocity -= RBOAT_VELOCITY_DECEL;
if (rBoatItem->Animation.Velocity.z < maxVelocity)
rBoatItem->Animation.Velocity.z += (RBOAT_VELOCITY_ACCEL / 2 + 1) + (RBOAT_VELOCITY_ACCEL * rBoatItem->Animation.Velocity.z) / (maxVelocity * 2);
else if (rBoatItem->Animation.Velocity.z > (maxVelocity + RBOAT_VELOCITY_DECEL))
rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_DECEL;
}
else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) &&
rBoatItem->Animation.Velocity >= 0 &&
rBoatItem->Animation.Velocity < RBOAT_VELOCITY_MIN)
rBoatItem->Animation.Velocity.z >= 0 &&
rBoatItem->Animation.Velocity.z < RBOAT_VELOCITY_MIN)
{
if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity == 0)
rBoatItem->Animation.Velocity = RBOAT_VELOCITY_MIN;
if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity.z == 0)
rBoatItem->Animation.Velocity.z = RBOAT_VELOCITY_MIN;
}
else if (rBoatItem->Animation.Velocity > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity -= RBOAT_VELOCITY_DECEL;
else if (rBoatItem->Animation.Velocity.z > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_DECEL;
else
rBoatItem->Animation.Velocity = 0;
rBoatItem->Animation.Velocity.z = 0;
}
else
{
if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) &&
rBoatItem->Animation.Velocity >= 0 &&
rBoatItem->Animation.Velocity < RBOAT_VELOCITY_MIN)
rBoatItem->Animation.Velocity.z >= 0 &&
rBoatItem->Animation.Velocity.z < RBOAT_VELOCITY_MIN)
{
if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity == 0)
rBoatItem->Animation.Velocity = RBOAT_VELOCITY_MIN;
if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity.z == 0)
rBoatItem->Animation.Velocity.z = RBOAT_VELOCITY_MIN;
}
else if (rBoatItem->Animation.Velocity > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity -= RBOAT_VELOCITY_DECEL;
else if (rBoatItem->Animation.Velocity.z > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_DECEL;
else
rBoatItem->Animation.Velocity = 0;
rBoatItem->Animation.Velocity.z = 0;
if (TrInput & IN_LOOK && rBoatItem->Animation.Velocity == 0)
if (TrInput & IN_LOOK && rBoatItem->Animation.Velocity.z == 0)
LookUpDown(laraItem);
}
}
@ -641,7 +641,7 @@ namespace TEN::Entities::Vehicles
}
}
else if (rBoatItem->Pose.Position.y < (rBoat->Water - CLICK(0.5f)) &&
rBoatItem->Animation.VerticalVelocity > 0)
rBoatItem->Animation.Velocity.y > 0)
{
if (laraItem->Animation.ActiveState != RBOAT_STATE_FALL)
{
@ -668,7 +668,7 @@ namespace TEN::Entities::Vehicles
case RBOAT_STATE_IDLE:
if (TrInput & VEHICLE_IN_DISMOUNT)
{
if (rBoatItem->Animation.Velocity == 0)
if (rBoatItem->Animation.Velocity.z == 0)
{
if (TrInput & IN_RIGHT && TestRubberBoatDismount(laraItem, rBoatItem->Pose.Orientation.y + ANGLE(90.0f)))
laraItem->Animation.TargetState = RBOAT_STATE_JUMP_RIGHT;
@ -677,13 +677,13 @@ namespace TEN::Entities::Vehicles
}
}
if (rBoatItem->Animation.Velocity > 0)
if (rBoatItem->Animation.Velocity.z > 0)
laraItem->Animation.TargetState = RBOAT_STATE_MOVING;
break;
case RBOAT_STATE_MOVING:
if (rBoatItem->Animation.Velocity <= 0)
if (rBoatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = RBOAT_STATE_IDLE;
if (TrInput & VEHICLE_IN_RIGHT)
@ -698,7 +698,7 @@ namespace TEN::Entities::Vehicles
break;
case RBOAT_STATE_TURN_RIGHT:
if (rBoatItem->Animation.Velocity <= 0)
if (rBoatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = RBOAT_STATE_IDLE;
else if (!(TrInput & VEHICLE_IN_RIGHT))
laraItem->Animation.TargetState = RBOAT_STATE_MOVING;
@ -706,7 +706,7 @@ namespace TEN::Entities::Vehicles
break;
case RBOAT_STATE_TURN_LEFT:
if (rBoatItem->Animation.Velocity <= 0)
if (rBoatItem->Animation.Velocity.z <= 0)
laraItem->Animation.TargetState = RBOAT_STATE_IDLE;
else if (!(TrInput & VEHICLE_IN_LEFT))
laraItem->Animation.TargetState = RBOAT_STATE_MOVING;
@ -798,8 +798,8 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.z = 0;
laraItem->Animation.IsAirborne = true;
laraItem->Animation.Velocity = 20;
laraItem->Animation.VerticalVelocity = -40;
laraItem->Animation.Velocity.z = 20;
laraItem->Animation.Velocity.y = -40;
lara->Vehicle = NO_ITEM;
int x = laraItem->Pose.Position.x + 360 * phd_sin(laraItem->Pose.Orientation.y);
@ -866,10 +866,10 @@ namespace TEN::Entities::Vehicles
}
else
{
if (rBoatItem->Animation.Velocity > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity -= RBOAT_VELOCITY_DECEL;
if (rBoatItem->Animation.Velocity.z > RBOAT_VELOCITY_DECEL)
rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_DECEL;
else
rBoatItem->Animation.Velocity = 0;
rBoatItem->Animation.Velocity.z = 0;
}
if (noTurn)
@ -892,8 +892,8 @@ namespace TEN::Entities::Vehicles
rBoat->LeftVerticalVelocity = DoRubberBoatDynamics(heightFrontLeft, rBoat->LeftVerticalVelocity, (int*)&frontLeft.y);
rBoat->RightVerticalVelocity = DoRubberBoatDynamics(heightFrontRight, rBoat->RightVerticalVelocity, (int*)&frontRight.y);
ofs = rBoatItem->Animation.VerticalVelocity;
rBoatItem->Animation.VerticalVelocity = DoRubberBoatDynamics(rBoat->Water, rBoatItem->Animation.VerticalVelocity, (int*)&rBoatItem->Pose.Position.y);
ofs = rBoatItem->Animation.Velocity.y;
rBoatItem->Animation.Velocity.y = DoRubberBoatDynamics(rBoat->Water, rBoatItem->Animation.Velocity.y, (int*)&rBoatItem->Pose.Position.y);
height = frontLeft.y + frontRight.y;
if (height < 0)
@ -944,10 +944,10 @@ namespace TEN::Entities::Vehicles
rBoatItem->Pose.Orientation.z += rBoat->LeanAngle;
}
pitch = rBoatItem->Animation.Velocity;
pitch = rBoatItem->Animation.Velocity.z;
rBoat->Pitch += ((pitch - rBoat->Pitch) / 4);
if (rBoatItem->Animation.Velocity > 8)
if (rBoatItem->Animation.Velocity.z > 8)
SoundEffect(SFX_TR3_VEHICLE_RUBBERBOAT_MOVING, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_NORMAL_VELOCITY_MAX);
else if (drive)
SoundEffect(SFX_TR3_VEHICLE_RUBBERBOAT_IDLE, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_NORMAL_VELOCITY_MAX);
@ -969,11 +969,11 @@ namespace TEN::Entities::Vehicles
probedRoomNumber = GetCollision(prop.x, prop.y, prop.z, rBoatItem->RoomNumber).RoomNumber;
if (rBoatItem->Animation.Velocity &&
if (rBoatItem->Animation.Velocity.z &&
height < prop.y &&
height != NO_HEIGHT)
{
TriggerRubberBoatMist(prop.x, prop.y, prop.z, abs(rBoatItem->Animation.Velocity), rBoatItem->Pose.Orientation.y + 0x8000, 0);
TriggerRubberBoatMist(prop.x, prop.y, prop.z, abs(rBoatItem->Animation.Velocity.z), rBoatItem->Pose.Orientation.y + 0x8000, 0);
if ((GetRandomControl() & 1) == 0)
{
PHD_3DPOS pos;

View file

@ -250,8 +250,8 @@ namespace TEN::Entities::Vehicles
harpoonItem->Pose.Orientation = Vector3Shrt(UPVItem->Pose.Orientation.x, UPVItem->Pose.Orientation.y, 0);
// TODO: Huh?
harpoonItem->Animation.VerticalVelocity = -UPV_HARPOON_VELOCITY * phd_sin(harpoonItem->Pose.Orientation.x);
harpoonItem->Animation.Velocity = UPV_HARPOON_VELOCITY * phd_cos(harpoonItem->Pose.Orientation.x);
harpoonItem->Animation.Velocity.y = -UPV_HARPOON_VELOCITY * phd_sin(harpoonItem->Pose.Orientation.x);
harpoonItem->Animation.Velocity.z = UPV_HARPOON_VELOCITY * phd_cos(harpoonItem->Pose.Orientation.x);
harpoonItem->HitPoints = HARPOON_TIME;
harpoonItem->ItemFlags[0] = 1;
@ -741,7 +741,7 @@ namespace TEN::Entities::Vehicles
laraItem->Pose.Position = Vector3Int(LPos.x, LPos.y, LPos.z);
SetAnimation(laraItem, LA_UNDERWATER_IDLE);
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Animation.IsAirborne = false;
laraItem->Pose.Orientation.x = laraItem->Pose.Orientation.z = 0;
@ -778,7 +778,7 @@ namespace TEN::Entities::Vehicles
SetAnimation(laraItem, LA_ONWATER_IDLE);
laraItem->Animation.IsAirborne = false;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
laraItem->Pose.Orientation.x = 0;
laraItem->Pose.Orientation.z = 0;
@ -814,12 +814,12 @@ namespace TEN::Entities::Vehicles
SetAnimation(laraItem, LA_UNDERWATER_DEATH, 17);
laraItem->Animation.IsAirborne = false;
laraItem->Animation.VerticalVelocity = 0;
laraItem->Animation.Velocity.y = 0;
UPV->Flags |= UPV_FLAG_DEAD;
}
UPVItem->Animation.Velocity = 0;
UPVItem->Animation.Velocity.z = 0;
break;
}
@ -889,7 +889,7 @@ namespace TEN::Entities::Vehicles
{
UPVControl(UPVItem, laraItem);
UPVItem->Animation.Velocity = UPV->Velocity / VEHICLE_VELOCITY_SCALE;
UPVItem->Animation.Velocity.z = UPV->Velocity / VEHICLE_VELOCITY_SCALE;
UPVItem->Pose.Orientation += UPV->TurnRate;
if (UPVItem->Pose.Orientation.x > UPV_X_ORIENT_MAX)
@ -900,7 +900,7 @@ namespace TEN::Entities::Vehicles
if (!(TrInput & IN_LEFT ) && !(TrInput & IN_RIGHT))
ResetVehicleLean(UPVItem, 12.0f);
TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity);
TranslateItem(UPVItem, UPVItem->Pose.Orientation, UPVItem->Animation.Velocity.z);
}
int newHeight = GetCollision(UPVItem).Position.Floor;
@ -909,8 +909,8 @@ namespace TEN::Entities::Vehicles
if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Pose.Position.y - UPV_HEIGHT / 2) ||
(newHeight == NO_HEIGHT) || (waterHeight == NO_HEIGHT))
{
UPVItem->Animation.Velocity = 0;
UPVItem->Pose.Position = oldPos.Position;
UPVItem->Animation.Velocity.z = 0;
}
UPVItem->Floor = probe.Position.Floor;
@ -1004,7 +1004,7 @@ namespace TEN::Entities::Vehicles
DoVehicleCollision(UPVItem, UPV_RADIUS);
if (UPV->Flags & UPV_FLAG_CONTROL)
SoundEffect(SFX_TR3_VEHICLE_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always, 1.0f + (float)UPVItem->Animation.Velocity / 96.0f);
SoundEffect(SFX_TR3_VEHICLE_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always, 1.0f + (float)UPVItem->Animation.Velocity.z / 96.0f);
UPVItem->Animation.AnimNumber = Objects[ID_UPV].animIndex + (laraItem->Animation.AnimNumber - Objects[ID_UPV_LARA_ANIMS].animIndex);
UPVItem->Animation.FrameNumber = g_Level.Anims[UPVItem->Animation.AnimNumber].frameBase + (laraItem->Animation.FrameNumber - g_Level.Anims[laraItem->Animation.AnimNumber].frameBase);
@ -1028,8 +1028,8 @@ namespace TEN::Entities::Vehicles
UPV->TurnRate.x = 0;
SetAnimation(UPVItem, UPV_ANIM_IDLE);
UPVItem->Animation.VerticalVelocity = 0;
UPVItem->Animation.Velocity = 0;
UPVItem->Animation.Velocity.y = 0;
UPVItem->Animation.Velocity.z = 0;
UPVItem->Animation.IsAirborne = true;
AnimateItem(UPVItem);

View file

@ -444,7 +444,7 @@ namespace TEN::Entities::TR4
if (item->Pose.Position.y >= item->Floor)
{
item->Pose.Position.y = item->Floor;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
}
@ -461,7 +461,7 @@ namespace TEN::Entities::TR4
if (item->Pose.Position.y >= item->Floor)
{
item->Pose.Position.y = item->Floor;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.IsAirborne = false;
item->Animation.TargetState = BADDY_STATE_FREEFALL_LAND_DEATH;
}
@ -478,7 +478,7 @@ namespace TEN::Entities::TR4
item->Animation.AnimNumber = Objects[objectNumber].animIndex + BADDY_ANIM_MONKEY_TO_FREEFALL;
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.ActiveState = BADDY_STATE_MONKEY_TO_FREEFALL;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
break;
default:
@ -1033,8 +1033,8 @@ namespace TEN::Entities::TR4
{
SetAnimation(LaraItem, LA_JUMP_UP);
LaraItem->Animation.IsAirborne = true;
LaraItem->Animation.VerticalVelocity = 2;
LaraItem->Animation.VerticalVelocity = 1;
LaraItem->Animation.Velocity.y = 2;
LaraItem->Animation.Velocity.y = 1;
LaraItem->Pose.Position.y += CLICK(0.75f);
Lara.Control.HandStatus = HandStatus::Free;
currentCreature->Flags = 1;

View file

@ -160,7 +160,7 @@ namespace TEN::Entities::TR4
item->Animation.ActiveState = BAT_STATE_DEATH_FALL;
item->Animation.TargetState = BAT_STATE_DEATH_FALL;
item->Animation.IsAirborne = true;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
}
}

View file

@ -98,14 +98,14 @@ namespace TEN::Entities::TR4
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.ActiveState = BBEETLE_STATE_DEATH_START;
item->Animation.IsAirborne = true;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
}
}
else if (item->Pose.Position.y >= item->Floor)
{
item->Pose.Position.y = item->Floor;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
item->Animation.TargetState = BBEETLE_STATE_DEATH_END;
}
}

View file

@ -706,8 +706,8 @@ namespace TEN::Entities::TR4
!Lara.Location)
{
SetAnimation(LaraItem, LA_FALL_START);
LaraItem->Animation.Velocity = 2;
LaraItem->Animation.VerticalVelocity = 1;
LaraItem->Animation.Velocity.z = 2;
LaraItem->Animation.Velocity.y = 1;
ResetLaraFlex(LaraItem);
LaraItem->HitStatus = true;

View file

@ -51,8 +51,8 @@ namespace TEN::Entities::TR4
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
grenadeItem->Animation.RequiredState = 0;
grenadeItem->Animation.Velocity = 32;
grenadeItem->Animation.VerticalVelocity = -32 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->Animation.Velocity.z = 32;
grenadeItem->Animation.Velocity.y = -32 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->HitPoints = 120;
AddActiveItem(grenadeItemNumber);
@ -371,7 +371,7 @@ namespace TEN::Entities::TR4
{
item->Pose.Position.y = item->Floor;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
SoundEffect(SFX_TR4_VEHICLE_JEEP_MOVING, &item->Pose, SoundEnvironment::Land, 1.0f + (float)item->ItemFlags[0] / SECTOR(8)); // TODO: Check actual sound!

View file

@ -291,7 +291,7 @@ namespace TEN::Entities::TR4
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.ActiveState = HARPY_STATE_DEATH_START;
item->Animation.IsAirborne = true;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
}
CreatureTilt(item, 0);
@ -312,7 +312,7 @@ namespace TEN::Entities::TR4
item->Pose.Position.y = item->Floor;
item->Animation.TargetState = HARPY_STATE_DEATH_END;
item->Animation.IsAirborne = false;
item->Animation.VerticalVelocity = 0;
item->Animation.Velocity.y = 0;
}
item->Pose.Orientation.x = 0;

View file

@ -462,7 +462,7 @@ namespace TEN::Entities::TR4
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 20)
{
if (!creature->Enemy->Animation.Velocity)
if (!creature->Enemy->Animation.Velocity.z)
{
angle1 += (GetRandomControl() & 0x1FF) - 256;
angle2 += (GetRandomControl() & 0x1FF) - 256;
@ -593,8 +593,8 @@ namespace TEN::Entities::TR4
grenadeItem->Animation.ActiveState = grenadeItem->Pose.Orientation.x;
grenadeItem->Animation.TargetState = grenadeItem->Pose.Orientation.y;
grenadeItem->Animation.RequiredState = 0;
grenadeItem->Animation.Velocity = 128;
grenadeItem->Animation.VerticalVelocity = -128 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->Animation.Velocity.z = 128;
grenadeItem->Animation.Velocity.y = -128 * phd_sin(grenadeItem->Pose.Orientation.x);
grenadeItem->HitPoints = 120;
grenadeItem->ItemFlags[2] = 1;

View file

@ -130,7 +130,7 @@ namespace TEN::Entities::TR4
fx->fallspeed = -(GetRandomControl() / 1024);
fx->frameNumber = Objects[103].meshIndex;
fx->objectNumber = ID_BODY_PART;
fx->shade = 0x4210;
fx->color = Vector4::One;
fx->flag2 = 0x601;
auto* spark = GetFreeParticle();

View file

@ -31,7 +31,7 @@ namespace TEN::Entities::TR4
item->Data = WraithInfo();
auto* wraith = (WraithInfo*)item->Data;
item->Animation.Velocity = WraithVelocity;
item->Animation.Velocity.z = WraithVelocity;
item->ItemFlags[0] = 0;
item->ItemFlags[6] = 0;
@ -93,7 +93,7 @@ namespace TEN::Entities::TR4
angleV -= item->Pose.Orientation.x;
int velocity = (WraithVelocity / item->Animation.Velocity) * 8;
int velocity = (WraithVelocity / item->Animation.Velocity.z) * 8;
if (abs(angleH) >= item->ItemFlags[2] || angleH > 0 != item->ItemFlags[2] > 0)
{
@ -147,9 +147,9 @@ namespace TEN::Entities::TR4
if (probe.Position.Floor < item->Pose.Position.y || probe.Position.Ceiling > item->Pose.Position.y)
hitWall = true;
item->Pose.Position.x += item->Animation.Velocity * phd_sin(item->Pose.Orientation.y);
item->Pose.Position.y += item->Animation.Velocity * phd_sin(item->Pose.Orientation.x);
item->Pose.Position.z += item->Animation.Velocity * phd_cos(item->Pose.Orientation.y);
item->Pose.Position.x += item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.y);
item->Pose.Position.y += item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.x);
item->Pose.Position.z += item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.y);
auto outsideRoom = IsRoomOutside(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);
if (item->RoomNumber != outsideRoom && outsideRoom != NO_ROOM)
@ -221,8 +221,8 @@ namespace TEN::Entities::TR4
{
if (Wibble & 16)
{
if (item->Animation.Velocity < WraithVelocity)
item->Animation.Velocity++;
if (item->Animation.Velocity.z < WraithVelocity)
item->Animation.Velocity.z++;
if (item->ItemFlags[6])
{
@ -233,8 +233,8 @@ namespace TEN::Entities::TR4
}
else
{
if (item->Animation.Velocity > 32)
item->Animation.Velocity -= 12;
if (item->Animation.Velocity.z > 32)
item->Animation.Velocity.z -= 12;
if (target->IsLara())
{

View file

@ -55,8 +55,8 @@ void ClockworkBeetleControl(short itemNumber)
SoundEffect(SFX_TR4_CLOCKWORK_BEETLE_WINDUP, &beetle->Pose);
beetle->Animation.VerticalVelocity += 12;
beetle->Pose.Position.y += beetle->Animation.VerticalVelocity;
beetle->Animation.Velocity.y += 12;
beetle->Pose.Position.y += beetle->Animation.Velocity.y;
short roomNumber = beetle->RoomNumber;
FloorInfo* floor = GetFloor(beetle->Pose.Position.x, beetle->Pose.Position.y - 20, beetle->Pose.Position.z, &roomNumber);
@ -66,10 +66,10 @@ void ClockworkBeetleControl(short itemNumber)
{
beetle->Pose.Position.y = height;
if (beetle->Animation.VerticalVelocity <= 32)
beetle->Animation.VerticalVelocity = 0;
if (beetle->Animation.Velocity.y <= 32)
beetle->Animation.Velocity.y = 0;
else
beetle->Animation.VerticalVelocity = -beetle->Animation.VerticalVelocity >> 1;
beetle->Animation.Velocity.y = -beetle->Animation.Velocity.y / 2;
flag = 1;
}
@ -139,22 +139,22 @@ void ClockworkBeetleControl(short itemNumber)
if (pow(x, 2) + pow(z, 2) >= 0x19000)
{
if (beetle->Animation.Velocity < 32)
beetle->Animation.Velocity++;
if (beetle->Animation.Velocity.z < 32)
beetle->Animation.Velocity.z++;
}
else
{
if (beetle->Animation.Velocity <= 4)
if (beetle->Animation.Velocity.z <= 4)
{
if (beetle->Animation.Velocity < 4)
beetle->Animation.Velocity++;
if (beetle->Animation.Velocity.z < 4)
beetle->Animation.Velocity.z++;
}
else
beetle->Animation.Velocity = beetle->Animation.Velocity - (beetle->ItemFlags[2] == 4) - 1;
beetle->Animation.Velocity.z = beetle->Animation.Velocity.z - (beetle->ItemFlags[2] == 4) - 1;
}
beetle->Pose.Position.x += beetle->Animation.Velocity * phd_sin(beetle->Pose.Orientation.y);
beetle->Pose.Position.z += beetle->Animation.Velocity * phd_cos(beetle->Pose.Orientation.y);
beetle->Pose.Position.x += beetle->Animation.Velocity.z * phd_sin(beetle->Pose.Orientation.y);
beetle->Pose.Position.z += beetle->Animation.Velocity.z * phd_cos(beetle->Pose.Orientation.y);
}
else
{
@ -232,11 +232,11 @@ void ClockworkBeetleControl(short itemNumber)
case 3:
{
if (beetle->Animation.Velocity < 32)
beetle->Animation.Velocity++;
if (beetle->Animation.Velocity.z < 32)
beetle->Animation.Velocity.z++;
beetle->Pose.Position.x += beetle->Animation.Velocity * phd_sin(beetle->Pose.Orientation.y);
beetle->Pose.Position.z += beetle->Animation.Velocity * phd_cos(beetle->Pose.Orientation.y);
beetle->Pose.Position.x += beetle->Animation.Velocity.z * phd_sin(beetle->Pose.Orientation.y);
beetle->Pose.Position.z += beetle->Animation.Velocity.z * phd_cos(beetle->Pose.Orientation.y);
if (!floor->Flags.MarkBeetle)
beetle->ItemFlags[3] = 1;
@ -274,7 +274,7 @@ void ClockworkBeetleControl(short itemNumber)
if (flag && beetle->ItemFlags[3] > 30 && val)
{
beetle->Animation.VerticalVelocity = -((val >> 1) + GetRandomControl() % val);
beetle->Animation.Velocity.y = -((val >> 1) + GetRandomControl() % val);
return;
}
}
@ -286,7 +286,7 @@ void ClockworkBeetleControl(short itemNumber)
if (flag && val)
{
beetle->Animation.VerticalVelocity = -((val >> 1) + GetRandomControl() % val);
beetle->Animation.Velocity.y = -((val >> 1) + GetRandomControl() % val);
return;
}
@ -332,7 +332,7 @@ void UseClockworkBeetle(short flag)
else
item->ItemFlags[0] = 0;
item->Animation.Velocity = 0;
item->Animation.Velocity.z = 0;
AddActiveItem(itemNumber);
if (item->ItemFlags[0])

View file

@ -270,7 +270,7 @@ namespace TEN::Entities::TR4
if (TestLaraPosition(&ElementPuzzleBounds, puzzleItem, laraItem))
{
laraItem->Animation.AnimNumber = (abs(puzzleItem->Pose.Position.y - laraItem->Pose.Position.y) >> 8) + LA_TORCH_LIGHT_3;
laraItem->Animation.AnimNumber = (abs(puzzleItem->Pose.Position.y- laraItem->Pose.Position.y) >> 8) + LA_TORCH_LIGHT_3;
laraItem->Animation.FrameNumber = g_Level.Anims[puzzleItem->Animation.AnimNumber].frameBase;
laraItem->Animation.ActiveState = LS_MISC_CONTROL;
laraInfo->Flare.ControlLeft = false;

View file

@ -113,7 +113,7 @@ namespace TEN::Entities::TR4
laraItem->Animation.AnimNumber = LA_MINE_DEATH;
laraItem->Animation.FrameNumber = g_Level.Anims[mineItem->Animation.AnimNumber].frameBase;
laraItem->Animation.ActiveState = LS_DEATH;
laraItem->Animation.Velocity = 0;
laraItem->Animation.Velocity.z = 0;
SoundEffect(SFX_TR4_MINE_EXPLOSION_OVERLAY, &mineItem->Pose);
}

View file

@ -128,19 +128,22 @@ namespace TEN::Entities::TR4
int bloodCount = 0;
if ((item->ItemFlags[0] > 1024 ||
LaraItem->Animation.IsAirborne) &&
if ((item->ItemFlags[0] > 1024 || LaraItem->Animation.IsAirborne) &&
(item->TriggerFlags & 7) > 2 &&
(item->TriggerFlags & 7) < 6)
{
if (LaraItem->Animation.VerticalVelocity > 6 ||
if (LaraItem->Animation.Velocity.y > 6 ||
item->ItemFlags[0] > 1024)
{
LaraItem->HitPoints = -1;
bloodCount = 20;
}
}
else if (LaraItem->Animation.Velocity >= 30)
else if (item->ItemFlags[0] == 1024)
{
LaraItem->HitPoints = -1;
}
else if (LaraItem->Animation.Velocity.z >= 30)
{
DoDamage(LaraItem, 8);
bloodCount = (GetRandomControl() & 3) + 2;
@ -215,7 +218,7 @@ namespace TEN::Entities::TR4
{
item->ItemFlags[0] += (item->ItemFlags[0] >> 3) + 32;
item->ItemFlags[1] -= item->ItemFlags[0];
if (item->ItemFlags[1] < 0)
if (item->ItemFlags[1] <= 0)
{
item->ItemFlags[0] = 1024;
item->ItemFlags[1] = 0;
@ -232,9 +235,9 @@ namespace TEN::Entities::TR4
}
else if (!item->Timer)
{
item->ItemFlags[0] += (item->ItemFlags[0] >> 3) + 32;
if (item->ItemFlags[1] > 0)
{
item->ItemFlags[0] += (item->ItemFlags[0] >> 3) + 32;
item->ItemFlags[1] -= item->ItemFlags[0];
if (item->ItemFlags[1] < 0)
item->ItemFlags[1] = 0;
@ -242,10 +245,13 @@ namespace TEN::Entities::TR4
}
// Update bone mutators.
if (item->ItemFlags[1])
for (int i = 0; i < item->Animation.Mutator.size(); i++)
{
for (int i = 0; i < item->Animation.Mutator.size(); i++)
item->Animation.Mutator[i].Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
float scale = (float)item->ItemFlags[1] / 4096.0f;
if (scale > 0.0f)
item->Animation.Mutator[i].Scale = Vector3(1.0f, scale, 1.0f);
else
item->Animation.Mutator[i].Scale = Vector3::Zero;
}
}
}

View file

@ -558,7 +558,7 @@ namespace TEN::Entities::Vehicles
if (rot < -ANGLE(75))
{
jeepItem->Pose.Position.y -= 41;
jeepItem->Animation.VerticalVelocity = -6 - (GetRandomControl() & 3);
jeepItem->Animation.Velocity.y = -6 - (GetRandomControl() & 3);
jeep->TurnRate = 0;
jeep->Velocity -= (jeep->Velocity / 8);
}
@ -573,7 +573,7 @@ namespace TEN::Entities::Vehicles
if (rot > ANGLE(75))
{
jeepItem->Pose.Position.y -= 41;
jeepItem->Animation.VerticalVelocity = -6 - (GetRandomControl() & 3);
jeepItem->Animation.Velocity.y = -6 - (GetRandomControl() & 3);
jeep->TurnRate = 0;
jeep->Velocity -= (jeep->Velocity / 8);
}
@ -593,9 +593,9 @@ namespace TEN::Entities::Vehicles
short speed;
if (jeepItem->Pose.Position.y < height)
speed = jeepItem->Animation.Velocity;
speed = jeepItem->Animation.Velocity.z;
else
speed = jeepItem->Animation.Velocity * phd_cos(jeepItem->Pose.Orientation.x);
speed = jeepItem->Animation.Velocity.z * phd_cos(jeepItem->Pose.Orientation.x);
jeepItem->Pose.Position.x += speed * phd_sin(jeep->MomentumAngle);
jeepItem->Pose.Position.z += speed * phd_cos(jeep->MomentumAngle);
@ -843,7 +843,7 @@ namespace TEN::Entities::Vehicles
else
jeep->Velocity = 0;
jeepItem->Animation.Velocity = jeep->Velocity / VEHICLE_VELOCITY_SCALE;
jeepItem->Animation.Velocity.z = jeep->Velocity / VEHICLE_VELOCITY_SCALE;
if (jeep->EngineRevs > 0xC000)
jeep->EngineRevs = (GetRandomControl() & 0x1FF) + 48896;
@ -1171,7 +1171,7 @@ namespace TEN::Entities::Vehicles
case JS_JUMP:
if (jeepItem->Pose.Position.y == jeepItem->Floor)
laraItem->Animation.TargetState = JS_LAND;
else if (jeepItem->Animation.VerticalVelocity > 300)
else if (jeepItem->Animation.Velocity.y > 300)
jeep->Flags |= JEEP_FLAG_FALLING;
break;
@ -1413,7 +1413,7 @@ namespace TEN::Entities::Vehicles
jeep->BackLeftWheelRotation -= rotAdd;
int oldY = jeepItem->Pose.Position.y;
jeepItem->Animation.VerticalVelocity = DoJeepDynamics(laraItem, floorHeight, jeepItem->Animation.VerticalVelocity, &jeepItem->Pose.Position.y, 0);
jeepItem->Animation.Velocity.y = DoJeepDynamics(laraItem, floorHeight, jeepItem->Animation.Velocity.y, &jeepItem->Pose.Position.y, 0);
jeep->Velocity = DoVehicleWaterMovement(jeepItem, laraItem, jeep->Velocity, JEEP_FRONT, &jeep->TurnRate);
short xRot;
@ -1489,7 +1489,7 @@ namespace TEN::Entities::Vehicles
auto pos = Vector3Int(90, 0, -500);
GetJointAbsPosition(jeepItem, &pos, 11);
if (jeepItem->Animation.Velocity <= 32)
if (jeepItem->Animation.Velocity.z <= 32)
{
if (JeepSmokeStart >= 16)
{
@ -1506,8 +1506,8 @@ namespace TEN::Entities::Vehicles
TriggerJeepExhaustSmoke(pos.x, pos.y, pos.z, jeepItem->Pose.Orientation.y + -32768, speed, 0);
}
else if (jeepItem->Animation.Velocity < 64)
TriggerJeepExhaustSmoke(pos.x, pos.y, pos.z, jeepItem->Pose.Orientation.y - 32768, 64 - jeepItem->Animation.Velocity, 1);
else if (jeepItem->Animation.Velocity.z < 64)
TriggerJeepExhaustSmoke(pos.x, pos.y, pos.z, jeepItem->Pose.Orientation.y - 32768, 64 - jeepItem->Animation.Velocity.z, 1);
}
return JeepCheckGetOff(laraItem);

View file

@ -410,7 +410,7 @@ namespace TEN::Entities::Vehicles
auto pos = Vector3Int(56, -144, -500);
GetJointAbsPosition(motorbikeItem, &pos, 0);
int speed = motorbikeItem->Animation.Velocity;
int speed = motorbikeItem->Animation.Velocity.z;
if (speed > 32 && speed < 64)
{
TriggerMotorbikeExhaustSmoke(pos.x, pos.y, pos.z, motorbikeItem->Pose.Orientation.y - ANGLE(180.0f), 64 - speed, true);
@ -613,9 +613,9 @@ namespace TEN::Entities::Vehicles
floorHeight = GetCollision(motorbikeItem).Position.Floor;
if (motorbikeItem->Pose.Position.y >= floorHeight)
speed = motorbikeItem->Animation.Velocity * phd_cos(motorbikeItem->Pose.Orientation.x);
speed = motorbikeItem->Animation.Velocity.z * phd_cos(motorbikeItem->Pose.Orientation.x);
else
speed = motorbikeItem->Animation.Velocity;
speed = motorbikeItem->Animation.Velocity.z;
TranslateItem(motorbikeItem, motorbike->MomentumAngle, speed);
@ -897,7 +897,7 @@ namespace TEN::Entities::Vehicles
{
laraItem->Animation.TargetState = MOTORBIKE_STATE_LANDING;
int fallSpeedDamage = motorbikeItem->Animation.VerticalVelocity - 140;
int fallSpeedDamage = motorbikeItem->Animation.Velocity.y - 140;
if (fallSpeedDamage > 0)
{
if (fallSpeedDamage <= 100)
@ -906,7 +906,7 @@ namespace TEN::Entities::Vehicles
DoDamage(laraItem, LARA_HEALTH_MAX);
}
}
else if (motorbikeItem->Animation.VerticalVelocity > 220)
else if (motorbikeItem->Animation.Velocity.y > 220)
motorbike->Flags |= MOTORBIKE_FLAG_FALLING;
break;
@ -1128,7 +1128,7 @@ namespace TEN::Entities::Vehicles
}
}
motorbikeItem->Animation.Velocity = motorbike->Velocity / VEHICLE_VELOCITY_SCALE;
motorbikeItem->Animation.Velocity.z = motorbike->Velocity / VEHICLE_VELOCITY_SCALE;
if (motorbike->EngineRevs > MOTORBIKE_ACCEL_MAX)
motorbike->EngineRevs = (GetRandomControl() & 0x1FF) + 0xBF00;
@ -1253,7 +1253,7 @@ namespace TEN::Entities::Vehicles
motorbike->RightWheelsRotation -= rotation;
int newY = motorbikeItem->Pose.Position.y;
motorbikeItem->Animation.VerticalVelocity = DoMotorBikeDynamics(probe.Position.Floor, motorbikeItem->Animation.VerticalVelocity, &motorbikeItem->Pose.Position.y, 0);
motorbikeItem->Animation.Velocity.y = DoMotorBikeDynamics(probe.Position.Floor, motorbikeItem->Animation.Velocity.y, &motorbikeItem->Pose.Position.y, 0);
motorbike->Velocity = DoVehicleWaterMovement(motorbikeItem, laraItem, motorbike->Velocity, MOTORBIKE_RADIUS, &motorbike->TurnRate);
int r1 = (frontRight.y + frontLeft.y) / 2;

View file

@ -120,7 +120,7 @@ void ControlChef(short itemNumber)
AI.distance < pow(SECTOR(1.5f), 2) &&
(item->TouchBits ||
item->HitStatus ||
LaraItem->Animation.Velocity > 15 ||
LaraItem->Animation.Velocity.z > 15 ||
TargetVisible(item, &aiLaraInfo)))
{
item->Animation.TargetState = CHEF_STATE_TURN_180;

View file

@ -333,7 +333,7 @@ void CyborgControl(short itemNumber)
angle = CreatureTurn(item, creature->MaxTurn);
if (laraAI.distance < pow(SECTOR(2), 2) &&
LaraItem->Animation.Velocity> 20 ||
LaraItem->Animation.Velocity.z> 20 ||
item->HitStatus ||
TargetVisible(item, &laraAI))
{

View file

@ -380,7 +380,7 @@ void GuardControl(short itemNumber)
angle = CreatureTurn(item, creature->MaxTurn);
creature->Enemy = LaraItem;
if ((laraAI.distance < pow(SECTOR(2), 2) && LaraItem->Animation.Velocity > 20) ||
if ((laraAI.distance < pow(SECTOR(2), 2) && LaraItem->Animation.Velocity.z > 20) ||
item->HitStatus ||
TargetVisible(item, &laraAI))
{
@ -752,7 +752,7 @@ void GuardControl(short itemNumber)
joint2 = 0;
if (!item->HitStatus &&
LaraItem->Animation.Velocity < 40 &&
LaraItem->Animation.Velocity.z < 40 &&
!Lara.Control.Weapon.HasFired)
{
creature->Alerted = false;
@ -1191,7 +1191,7 @@ void Mafia2Control(short itemNumber)
creature->Enemy = LaraItem;
angle = CreatureTurn(item, creature->MaxTurn);
if ((laraAI.distance < pow(SECTOR(2), 2) && LaraItem->Animation.Velocity > 20) ||
if ((laraAI.distance < pow(SECTOR(2), 2) && LaraItem->Animation.Velocity.z > 20) ||
item->HitStatus ||
TargetVisible(item, &laraAI))
{

View file

@ -107,7 +107,7 @@ static void ImpThrowStones(ItemInfo* item)
fx->fallspeed = 0;
fxNumber = Objects[ID_IMP_ROCK].meshIndex + (GetRandomControl() & 7);
fx->objectNumber = ID_IMP_ROCK;
fx->shade = 16912;
fx->color = Vector4::One;
fx->counter = 0;
fx->frameNumber = fxNumber;
fx->flag1 = 2;

View file

@ -147,7 +147,7 @@ void LarsonControl(short itemNumber)
CreatureMood(item, &info, VIOLENT);
if (info.distance < SQUARE(2048)
&& LaraItem->Animation.Velocity > 20
&& LaraItem->Animation.Velocity.z > 20
|| item->HitStatus
|| TargetVisible(item, &info) != 0)
{

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