2020-08-14 17:54:25 -05:00
|
|
|
#include "framework.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/Lara/lara_basic.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
|
|
|
|
#include "Game/animation.h"
|
|
|
|
#include "Game/camera.h"
|
|
|
|
#include "Game/collision/collide_room.h"
|
|
|
|
#include "Game/health.h"
|
|
|
|
#include "Game/items.h"
|
|
|
|
#include "Game/Lara/lara.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/Lara/lara_tests.h"
|
|
|
|
#include "Game/Lara/lara_collide.h"
|
|
|
|
#include "Game/Lara/lara_slide.h"
|
|
|
|
#include "Game/Lara/lara_monkey.h"
|
|
|
|
#include "Game/Lara/lara_helpers.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Game/pickup/pickup.h"
|
|
|
|
#include "Sound/sound.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Specific/input.h"
|
|
|
|
#include "Specific/level.h"
|
|
|
|
#include "Specific/setup.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Scripting/GameFlowScript.h"
|
2021-09-25 11:27:47 +02:00
|
|
|
|
2021-10-09 14:39:06 +11:00
|
|
|
// ------------------------------
|
|
|
|
// BASIC MOVEMENT & MISCELLANEOUS
|
2021-10-08 20:08:55 +11:00
|
|
|
// Control & Collision Functions
|
2021-10-09 14:39:06 +11:00
|
|
|
// ------------------------------
|
|
|
|
|
|
|
|
// --------------
|
|
|
|
// MISCELLANEOUS:
|
|
|
|
// --------------
|
2021-10-08 20:08:55 +11:00
|
|
|
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_void_func(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_default_col(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 21:01:50 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsPit = true;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-09-19 06:42:24 +03:00
|
|
|
GetCollisionInfo(coll, item);
|
2021-09-25 13:00:14 +03:00
|
|
|
LaraResetGravityStatus(item, coll);
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_as_special(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
|
|
|
Camera.flags = CF_FOLLOW_CENTER;
|
|
|
|
Camera.targetAngle = ANGLE(170.0f);
|
2020-09-26 05:06:08 +10:00
|
|
|
Camera.targetElevation = -ANGLE(25.0f);
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_as_null(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2021-09-10 00:20:59 +03:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.EnableSpasm = false;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_as_controlled(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-09-10 00:20:59 +03:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.EnableSpasm = false;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->FrameNumber == g_Level.Anims[item->AnimNumber].frameEnd - 1)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.HandStatus = HandStatus::Free;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
2020-08-14 17:54:25 -05:00
|
|
|
if (UseForcedFixedCamera)
|
|
|
|
UseForcedFixedCamera = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-10 22:31:34 +11:00
|
|
|
void lara_as_controlled_no_look(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-09-10 00:20:59 +03:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.EnableSpasm = false;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2022-02-14 17:05:52 +11:00
|
|
|
// State: LS_VAULT, LS_VAULT_2_STEPS, LS_VAULT_3_STEPS,
|
|
|
|
// VAULT_1_STEP_CROUCH, VAULT_2_STEPS_CROUCH, VAULT_3_STEPS_CROUCH (164, 165, 166, 167, 168, 169)
|
2022-02-04 19:06:59 +11:00
|
|
|
// Control: lara_as_null()
|
|
|
|
void lara_col_vault(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2022-02-04 19:06:59 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2022-02-04 19:06:59 +11:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
|
|
|
coll->Setup.EnableSpasm = false;
|
|
|
|
|
2022-02-13 15:58:12 +11:00
|
|
|
// Disable smooth angle adjustment for now.
|
|
|
|
//ApproachLaraTargetAngle(item, coll->NearestLedgeAngle, 2.5f);
|
2022-02-11 19:26:08 +11:00
|
|
|
EaseOutLaraHeight(item, info->ProjectedFloorHeight - item->Position.yPos);
|
2022-02-04 19:06:59 +11:00
|
|
|
}
|
|
|
|
|
2022-02-05 23:13:31 +11:00
|
|
|
// State: LS_AUTO_JUMP (62)
|
|
|
|
// Control: lara_as_null()
|
|
|
|
void lara_col_auto_jump(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2022-02-05 23:13:31 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2022-02-05 23:13:31 +11:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
|
|
|
coll->Setup.EnableSpasm = false;
|
2022-02-07 13:06:02 +11:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Control.CalculatedJumpVelocity = -3 - sqrt(-9600 - 12 * std::max<int>(info->ProjectedFloorHeight - item->Position.yPos, -CLICK(7.5f)));
|
2022-02-12 20:23:45 +11:00
|
|
|
|
2022-02-13 15:58:12 +11:00
|
|
|
// Disable smooth angle adjustment for now.
|
|
|
|
//if (info->Control.ApproachTargetAngle)
|
|
|
|
// ApproachLaraTargetAngle(item, coll->NearestLedgeAngle, 2.5f);
|
2022-02-05 23:13:31 +11:00
|
|
|
}
|
|
|
|
|
2021-10-09 14:39:06 +11:00
|
|
|
// ---------------
|
|
|
|
// BASIC MOVEMENT:
|
|
|
|
// ---------------
|
|
|
|
|
|
|
|
// State: LS_WALK_FORWARD (0)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_walk_forward()
|
|
|
|
void lara_as_walk_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 14:39:06 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Control.Count.RunJump++;
|
2022-02-17 02:00:40 +11:00
|
|
|
if (info->Control.Count.RunJump > LARA_RUN_JUMP_TIME / 2) // TODO: Tune this again.
|
|
|
|
info->Control.Count.RunJump = LARA_RUN_JUMP_TIME / 2;
|
2021-11-19 22:48:47 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-09 14:39:06 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-09 14:39:06 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-19 22:48:47 +11:00
|
|
|
// TODO: Implement item alignment properly someday. @Sezz 2021.11.01
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.IsMoving)
|
2021-11-01 15:07:42 +11:00
|
|
|
return;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_MED_TURN_MAX;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 6);
|
2021-10-09 14:39:06 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_MED_TURN_MAX;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 6);
|
2021-10-09 14:39:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
2022-02-17 02:00:40 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
|
|
|
vaultResult.Success)
|
|
|
|
{
|
|
|
|
item->TargetState = vaultResult.TargetState;
|
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (info->Control.WaterStatus == WaterStatus::Wade)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-11-02 14:22:58 +11:00
|
|
|
else if (TrInput & IN_WALK) [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-09 14:39:06 +11:00
|
|
|
else
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-09 14:39:06 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-09 14:39:06 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// State: LA_WALK_FORWARD (0)
|
|
|
|
// Control: lara_as_walk_forward()
|
2021-11-25 23:38:59 +11:00
|
|
|
void lara_col_walk_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 14:39:06 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
|
|
|
coll->Setup.FloorSlopeIsPit = true;
|
2021-10-17 20:07:30 +11:00
|
|
|
coll->Setup.DeathFlagIsPit = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-09 14:39:06 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-10-09 14:39:06 +11:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-09 16:56:07 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-09 16:56:07 +11:00
|
|
|
|
2022-02-06 00:27:25 +11:00
|
|
|
if (TestAndDoLaraLadderClimb(item, coll))
|
2021-10-17 20:07:30 +11:00
|
|
|
return;
|
|
|
|
|
2022-02-13 23:23:36 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
{
|
|
|
|
item->TargetState = LS_SPLAT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
|
|
|
return;
|
|
|
|
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
}
|
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) && coll->CollisionType != CT_FRONT)
|
2021-10-09 14:39:06 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
2021-10-09 16:56:07 +11:00
|
|
|
return;
|
2021-10-09 14:39:06 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-26 17:51:28 +10:00
|
|
|
// State: LS_RUN_FORWARD (1)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_run_forward()
|
|
|
|
void lara_as_run_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Control.Count.RunJump++;
|
|
|
|
if (info->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
|
|
|
|
info->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
|
2021-11-19 22:48:47 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-09-26 17:51:28 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_FAST_TURN_MAX;
|
2021-09-26 17:51:28 +10:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE);
|
2021-09-26 17:51:28 +10:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_FAST_TURN_MAX;
|
2021-09-26 17:51:28 +10:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE);
|
2021-09-26 17:51:28 +10:00
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if ((TrInput & IN_JUMP || info->Control.RunJumpQueued) &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-11 19:26:08 +11:00
|
|
|
if (info->Control.Count.RunJump >= LARA_RUN_JUMP_TIME &&
|
2022-01-04 01:39:02 +11:00
|
|
|
TestLaraRunJumpForward(item, coll))
|
2021-12-13 16:12:33 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_FORWARD;
|
2021-12-13 16:12:33 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-09-26 17:51:28 +10:00
|
|
|
|
2022-01-22 00:22:24 +11:00
|
|
|
SetLaraRunJumpQueue(item, coll);
|
2021-09-26 17:51:28 +10:00
|
|
|
}
|
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
if (TrInput & IN_SPRINT && info->SprintEnergy &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-09-26 17:51:28 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if ((TrInput & (IN_ROLL | IN_FORWARD & IN_BACK)) && !info->Control.RunJumpQueued &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-09-26 17:51:28 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)) &&
|
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-09-26 17:51:28 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-09-26 17:51:28 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
2022-02-17 02:00:40 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
|
|
|
!TestLaraSplat(item, OFFSET_RADIUS(coll->Setup.Radius), -CLICK(2.5f)) && // HACK: Do not interfere with splat!
|
|
|
|
vaultResult.Success)
|
|
|
|
{
|
|
|
|
item->TargetState = vaultResult.TargetState;
|
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (info->Control.WaterStatus == WaterStatus::Wade)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-09-26 17:51:28 +10:00
|
|
|
else if (TrInput & IN_WALK)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-09-26 17:51:28 +10:00
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-09-26 17:51:28 +10:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-09-26 17:51:28 +10:00
|
|
|
}
|
|
|
|
|
2021-10-09 16:56:07 +11:00
|
|
|
// State: LS_RUN_FORWARD (1)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_run_forward()
|
|
|
|
void lara_col_run_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 16:56:07 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-09 16:56:07 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
LaraResetGravityStatus(item, coll);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-11-23 12:30:04 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-11-23 12:30:04 +11:00
|
|
|
|
2022-02-06 00:27:25 +11:00
|
|
|
if (TestAndDoLaraLadderClimb(item, coll))
|
2021-11-23 12:30:04 +11:00
|
|
|
return;
|
|
|
|
|
2021-10-09 16:56:07 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Position.zRot = 0;
|
2021-10-09 16:56:07 +11:00
|
|
|
|
2022-02-02 21:59:34 +11:00
|
|
|
if (coll->HitTallObject || TestLaraSplat(item, OFFSET_RADIUS(coll->Setup.Radius), -CLICK(2.5f)))
|
2021-10-09 16:56:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPLAT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
2021-10-09 16:56:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ActiveState = LS_SPLAT;
|
2021-10-09 16:56:07 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-16 14:20:26 +11:00
|
|
|
item->TargetState = LS_SPLAT_SOFT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
2022-02-16 18:13:07 +11:00
|
|
|
{
|
|
|
|
item->ActiveState = LS_SPLAT_SOFT;
|
2022-02-16 14:20:26 +11:00
|
|
|
return;
|
2022-02-16 18:13:07 +11:00
|
|
|
}
|
2022-02-16 14:20:26 +11:00
|
|
|
|
2021-10-09 16:56:07 +11:00
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
}
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) && coll->CollisionType != CT_FRONT)
|
2021-10-09 16:56:07 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-16 18:13:07 +11:00
|
|
|
// State: LS_IDLE (2), LS_SPLAT_SOFT (170)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_idle()
|
|
|
|
void lara_as_idle(ITEM_INFO* item, COLL_INFO* coll)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 21:01:50 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.CanLook = ((TestEnvironment(ENV_FLAG_SWAMP, item) && info->Control.WaterStatus == WaterStatus::Wade) || item->AnimNumber == LA_SWANDIVE_ROLL) ? false : true;
|
2021-11-14 17:31:00 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handles waterskin and clockwork beetle.
|
2021-11-25 23:38:59 +11:00
|
|
|
// TODO: Hardcoding.
|
2021-09-28 01:22:47 +10:00
|
|
|
if (UseSpecialItem(item))
|
|
|
|
return;
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (TrInput & IN_LOOK && info->Control.CanLook)
|
2022-02-16 18:13:07 +11:00
|
|
|
LookUpDown(item);
|
2021-09-28 01:22:47 +10:00
|
|
|
|
2021-10-08 15:47:54 +11:00
|
|
|
if (TrInput & IN_LEFT &&
|
2022-01-22 21:08:30 +11:00
|
|
|
!(TrInput & IN_JUMP)) // JUMP locks y rotation.
|
2021-09-28 13:05:29 +10:00
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-09-28 13:05:29 +10:00
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
else if (TrInput & IN_RIGHT &&
|
|
|
|
!(TrInput & IN_JUMP))
|
2021-09-28 13:05:29 +10:00
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-09-28 13:05:29 +10:00
|
|
|
}
|
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-01-25 18:02:22 +11:00
|
|
|
if (TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-12-10 12:30:23 +11:00
|
|
|
PseudoLaraAsSwampIdle(item, coll);
|
2021-11-07 21:55:38 +11:00
|
|
|
else [[likely]]
|
2021-12-10 12:30:23 +11:00
|
|
|
PseudoLaraAsWadeIdle(item, coll);
|
2021-09-28 01:22:47 +10:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-20 00:11:04 +11:00
|
|
|
if (TrInput & IN_JUMP)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2021-12-20 00:11:04 +11:00
|
|
|
SetLaraJumpDirection(item, coll);
|
2022-02-10 16:18:15 +11:00
|
|
|
if (info->Control.JumpDirection != JumpDirection::None)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2021-12-20 00:11:04 +11:00
|
|
|
|
2022-01-13 03:13:18 +11:00
|
|
|
return;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:22:28 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-05 23:13:31 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
2022-02-05 23:13:31 +11:00
|
|
|
vaultResult.Success)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = vaultResult.TargetState;
|
2022-02-05 23:13:31 +11:00
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_WALK)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraWalkForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_SPRINT && TestLaraRunForward(item, coll))
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
2021-10-22 00:07:24 +11:00
|
|
|
else if (TrInput & IN_BACK)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TestLaraWalkBack(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-12 15:35:16 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
2021-12-26 15:30:53 +11:00
|
|
|
else if (TestLaraRunBack(item, coll)) [[likely]]
|
2021-10-06 14:03:12 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_BACK;
|
2021-10-19 21:28:36 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-08 15:47:54 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2021-10-08 20:08:55 +11:00
|
|
|
if (TrInput & IN_SPRINT ||
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate <= -LARA_SLOW_TURN_MAX ||
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::WeaponReady && info->Control.WeaponControl.GunType != WEAPON_TORCH) ||
|
|
|
|
(info->Control.HandStatus == HandStatus::DrawWeapon && info->Control.WeaponControl.GunType != WEAPON_FLARE))
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_FAST;
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-09-28 01:22:47 +10:00
|
|
|
|
2021-10-04 22:02:02 +11:00
|
|
|
return;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
else if (TrInput & IN_RIGHT)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2021-10-08 20:08:55 +11:00
|
|
|
if (TrInput & IN_SPRINT ||
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate >= LARA_SLOW_TURN_MAX ||
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::WeaponReady && info->Control.WeaponControl.GunType != WEAPON_TORCH) ||
|
|
|
|
(info->Control.HandStatus == HandStatus::DrawWeapon && info->Control.WeaponControl.GunType != WEAPON_FLARE))
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_FAST;
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-09-28 01:22:47 +10:00
|
|
|
|
2021-10-04 22:02:02 +11:00
|
|
|
return;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// TODO: Without animation blending, the AFK state's
|
2021-11-04 21:07:47 +11:00
|
|
|
// movement lock will be rather obnoxious.
|
2021-11-25 23:38:59 +11:00
|
|
|
// Adding some idle breathing would also be nice. @Sezz 2021.10.31
|
2022-02-11 19:26:08 +11:00
|
|
|
if (info->Control.Count.Pose >= LARA_POSE_TIME && TestLaraPose(item, coll) &&
|
2021-12-02 12:47:07 +11:00
|
|
|
g_GameFlow->Animations.Pose)
|
2021-11-04 21:07:47 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_POSE;
|
2021-11-04 21:07:47 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// TODO: Future-proof for rising water.
|
|
|
|
// TODO: Make these into true states someday? It may take a bit of work. @Sezz 2021.10.13
|
2021-10-13 19:50:46 +11:00
|
|
|
// Pseudo-state for idling in wade-height water.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PseudoLaraAsWadeIdle(ITEM_INFO* item, COLL_INFO* coll)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-12-28 18:46:25 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.JumpDirection = JumpDirection::Up;
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-05 23:13:31 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-11-07 21:55:38 +11:00
|
|
|
{
|
2022-02-05 23:13:31 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
2022-02-05 23:13:31 +11:00
|
|
|
vaultResult.Success)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = vaultResult.TargetState;
|
2022-02-05 23:13:31 +11:00
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2022-02-05 23:13:31 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-11-07 21:55:38 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_BACK && TestLaraWalkBack(item, coll))
|
2021-11-07 21:55:38 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-07 21:55:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-11-07 21:55:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-11-07 21:55:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-11-07 21:55:38 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-11-07 21:55:38 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-11-07 21:55:38 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-11-07 21:55:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-11-07 21:55:38 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// Pseudo-state for idling in swamps.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PseudoLaraAsSwampIdle(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-07 21:55:38 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2022-02-05 23:13:31 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-05 23:13:31 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
2022-02-05 23:13:31 +11:00
|
|
|
vaultResult.Success)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = vaultResult.TargetState;
|
2022-02-05 23:13:31 +11:00
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraWadeForwardSwamp(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2022-02-05 23:13:31 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
2021-10-04 22:02:02 +11:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_BACK && TestLaraWalkBackSwamp(item, coll))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2021-11-02 14:22:58 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
2021-10-14 21:11:59 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-10-14 21:11:59 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-11-02 14:22:58 +11:00
|
|
|
else if (TrInput & IN_RIGHT)
|
2021-10-14 21:11:59 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-10-14 21:11:59 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeftSwamp(item, coll))
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-05 22:09:07 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRightSwamp(item, coll))
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-05 22:09:07 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2022-02-16 18:13:07 +11:00
|
|
|
// State: LS_IDLE (2), LS_POSE (4), LS_SPLAT_SOFT (170)
|
|
|
|
// Control: lara_as_idle(), lara_as_pose()
|
2021-11-25 23:38:59 +11:00
|
|
|
void lara_col_idle(ITEM_INFO* item, COLL_INFO* coll)
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = (item->Velocity >= 0) ? item->Position.yRot : item->Position.yRot + ANGLE(180.0f);
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = TestEnvironment(ENV_FLAG_SWAMP, item) ? NO_LOWER_BOUND : STEPUP_HEIGHT;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsPit = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
|
|
|
coll->Setup.FloorSlopeIsWall = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-09-28 01:22:47 +10:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-09-28 01:22:47 +10:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-09-28 01:22:47 +10:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
|
2022-02-06 00:27:25 +11:00
|
|
|
if (TestAndDoLaraLadderClimb(item, coll))
|
2022-01-04 22:50:18 +11:00
|
|
|
return;
|
2021-12-25 15:39:34 +11:00
|
|
|
|
2021-10-15 00:46:15 +11:00
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-12-01 02:11:14 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
2021-09-28 01:22:47 +10:00
|
|
|
}
|
|
|
|
|
2021-10-13 19:50:46 +11:00
|
|
|
// State: LS_POSE (4)
|
2021-12-10 22:31:34 +11:00
|
|
|
// Collision: lara_col_idle()
|
2021-10-31 18:33:39 +11:00
|
|
|
void lara_as_pose(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-31 18:33:39 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-31 18:33:39 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LOOK)
|
2022-02-16 18:13:07 +11:00
|
|
|
LookUpDown(item);
|
2021-10-31 18:33:39 +11:00
|
|
|
|
|
|
|
if (TestLaraPose(item, coll))
|
|
|
|
{
|
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-31 18:33:39 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_WAKE)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-31 18:33:39 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_POSE;
|
2021-10-31 18:33:39 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-31 18:33:39 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// State: LS_RUN_BACK (5)
|
|
|
|
// Collision: lara_col_run_back()
|
|
|
|
void lara_as_run_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 20:19:34 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2021-10-09 20:19:34 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_MED_TURN_MAX;
|
2021-10-09 20:19:34 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
|
2021-10-09 20:19:34 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_MED_TURN_MAX;
|
2021-10-09 20:19:34 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
|
2021-10-09 20:19:34 +11:00
|
|
|
}
|
|
|
|
|
2021-10-30 12:24:16 +11:00
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-30 12:24:16 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-09 20:19:34 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// State: LS_RUN_BACK (5)
|
|
|
|
// Control: lara_as_run_back()
|
|
|
|
void lara_col_run_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 20:19:34 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot + ANGLE(180.0f);
|
2022-02-09 13:20:57 +11:00
|
|
|
item->VerticalVelocity = 0;
|
|
|
|
item->Airborne = false;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.FloorSlopeIsPit = true;
|
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-09 20:19:34 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
if (coll->Middle.Floor > (STEPUP_HEIGHT / 2))
|
2021-10-09 20:19:34 +11:00
|
|
|
{
|
2021-10-14 19:58:29 +11:00
|
|
|
SetLaraFallBackState(item);
|
2021-10-09 20:19:34 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-09 20:19:34 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-09 20:19:34 +11:00
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-10-09 20:19:34 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-05 22:09:07 +11:00
|
|
|
// State: LS_TURN_RIGHT_SLOW (6)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_turn_right_slow()
|
|
|
|
void lara_as_turn_right_slow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.CanLook = (TestEnvironment(ENV_FLAG_SWAMP, item) && info->Control.WaterStatus == WaterStatus::Wade) ? false : true;
|
2021-11-14 17:31:00 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-05 22:09:07 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < 0)
|
|
|
|
info->Control.TurnRate = 0;
|
|
|
|
else if (info->Control.TurnRate > LARA_MED_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_MED_FAST_TURN_MAX;
|
2021-10-06 14:03:12 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-01-25 18:02:22 +11:00
|
|
|
if (TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-12-10 12:30:23 +11:00
|
|
|
PsuedoLaraAsSwampTurnRightSlow(item, coll);
|
2021-11-07 23:58:51 +11:00
|
|
|
else [[likely]]
|
2021-12-10 12:30:23 +11:00
|
|
|
PsuedoLaraAsWadeTurnRightSlow(item, coll);
|
2021-10-05 22:09:07 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-02 15:54:43 +11:00
|
|
|
if (TrInput & IN_JUMP)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-01-02 15:54:43 +11:00
|
|
|
SetLaraJumpDirection(item, coll);
|
2022-02-10 16:18:15 +11:00
|
|
|
if (info->Control.JumpDirection != JumpDirection::None)
|
2022-01-02 15:54:43 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-01-02 15:54:43 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-05 22:09:07 +11:00
|
|
|
}
|
|
|
|
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_ROLL)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-05 22:09:07 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)))
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-10-05 22:09:07 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:22:28 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraWalkForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_SPRINT && TestLaraRunForward(item, coll))
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-05 22:09:07 +11:00
|
|
|
}
|
2021-10-22 00:07:24 +11:00
|
|
|
else if (TrInput & IN_BACK)
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TestLaraWalkBack(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-12 15:35:16 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-24 20:43:02 +11:00
|
|
|
}
|
2021-12-26 15:30:53 +11:00
|
|
|
else if (TestLaraRunBack(item, coll)) [[likely]]
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_BACK;
|
2021-10-24 20:43:02 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-05 22:09:07 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-05 22:09:07 +11:00
|
|
|
if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_WALK) // TODO: This hasn't worked since TR1.
|
2021-10-05 22:09:07 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-12-02 18:52:00 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-10-05 22:09:07 +11:00
|
|
|
}
|
2022-02-10 01:38:32 +11:00
|
|
|
else if (info->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_FAST;
|
2021-10-05 22:09:07 +11:00
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-10-05 22:09:07 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-05 22:09:07 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// Pseudo-state for turning right slowly in wade-height water.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PsuedoLaraAsWadeTurnRightSlow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate > LARA_WADE_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_WADE_TURN_MAX;
|
2021-11-25 21:08:51 +11:00
|
|
|
|
2021-12-28 18:46:25 +11:00
|
|
|
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.JumpDirection = JumpDirection::Up;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_FORWARD && TestLaraRunForward(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_BACK && TestLaraWalkBack(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-13 19:50:46 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// Pseudo-state for turning right slowly in swamps.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PsuedoLaraAsSwampTurnRightSlow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate > LARA_SWAMP_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SWAMP_TURN_MAX;
|
2021-11-25 21:08:51 +11:00
|
|
|
|
2021-12-26 15:30:53 +11:00
|
|
|
if (TrInput & IN_FORWARD && TestLaraWadeForwardSwamp(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_BACK && TestLaraWalkBackSwamp(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeftSwamp(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRightSwamp(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2020-08-14 17:54:25 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-10-15 00:46:15 +11:00
|
|
|
// State: LS_TURN_RIGHT_SLOW (6)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_turn_right_slow()
|
|
|
|
void lara_col_turn_right_slow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-15 00:46:15 +11:00
|
|
|
{
|
2021-11-25 23:38:59 +11:00
|
|
|
lara_col_idle(item, coll);
|
2021-10-15 00:46:15 +11:00
|
|
|
}
|
|
|
|
|
2021-10-08 15:47:54 +11:00
|
|
|
// State: LS_TURN_LEFT_SLOW (7)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_turn_left_slow()
|
|
|
|
void lara_as_turn_left_slow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.CanLook = (TestEnvironment(ENV_FLAG_SWAMP, item) && info->Control.WaterStatus == WaterStatus::Wade) ? false : true;
|
2021-11-14 17:31:00 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > 0)
|
|
|
|
info->Control.TurnRate = 0;
|
|
|
|
else if (info->Control.TurnRate < -LARA_MED_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_MED_FAST_TURN_MAX;
|
2021-10-08 15:47:54 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-01-25 18:02:22 +11:00
|
|
|
if (TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-12-10 12:30:23 +11:00
|
|
|
PsuedoLaraAsSwampTurnLeftSlow(item, coll);
|
2021-11-07 23:58:51 +11:00
|
|
|
else [[likely]]
|
2021-12-10 12:30:23 +11:00
|
|
|
PsuedoLaraAsWadeTurnLeftSlow(item, coll);
|
2021-10-08 15:47:54 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-02 15:54:43 +11:00
|
|
|
if (TrInput & IN_JUMP)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-01-02 15:54:43 +11:00
|
|
|
SetLaraJumpDirection(item, coll);
|
2022-02-10 16:18:15 +11:00
|
|
|
if (info->Control.JumpDirection != JumpDirection::None)
|
2022-01-02 15:54:43 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-01-02 15:54:43 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_ROLL)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:22:28 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraWalkForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_SPRINT && TestLaraRunForward(item, coll))
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
2021-10-22 00:07:24 +11:00
|
|
|
else if (TrInput & IN_BACK)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TestLaraWalkBack(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-12 15:35:16 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-24 20:43:02 +11:00
|
|
|
}
|
2021-12-26 15:30:53 +11:00
|
|
|
else if (TestLaraRunBack(item, coll)) [[likely]]
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_BACK;
|
2021-10-24 20:43:02 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2021-10-13 19:50:46 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-12-02 18:52:00 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
2022-02-10 01:38:32 +11:00
|
|
|
else if (info->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_FAST;
|
2021-10-08 15:47:54 +11:00
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_SLOW;
|
2021-10-08 15:47:54 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// Pseudo-state for turning left slowly in wade-height water.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PsuedoLaraAsWadeTurnLeftSlow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate < -LARA_WADE_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_WADE_TURN_MAX;
|
2021-11-25 21:08:51 +11:00
|
|
|
|
2021-12-28 18:46:25 +11:00
|
|
|
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.JumpDirection = JumpDirection::Up;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_FORWARD && TestLaraRunForward(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_BACK && TestLaraWalkBack(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-13 19:50:46 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-10-13 19:50:46 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-13 19:50:46 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// Pseudo-state for turning left slowly in swamps.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PsuedoLaraAsSwampTurnLeftSlow(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.TurnRate < -LARA_SWAMP_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SWAMP_TURN_MAX;
|
2021-11-25 21:08:51 +11:00
|
|
|
|
2021-12-26 15:30:53 +11:00
|
|
|
if (TrInput & IN_FORWARD && TestLaraWadeForwardSwamp(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_BACK && TestLaraWalkBack(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-11-07 23:58:51 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_SLOW;
|
2021-11-07 23:58:51 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-11-07 23:58:51 +11:00
|
|
|
}
|
|
|
|
|
2021-10-15 00:46:15 +11:00
|
|
|
// State: LS_TURN_LEFT_SLOW (7)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_turn_left_slow()
|
|
|
|
void lara_col_turn_left_slow(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2021-11-25 23:38:59 +11:00
|
|
|
lara_col_turn_right_slow(item, coll);
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_DEATH (8)
|
|
|
|
// Collision: lara_col_death()
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_as_death(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-09-10 00:20:59 +03:00
|
|
|
coll->Setup.EnableObjectPush = false;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.EnableSpasm = false;
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2020-08-14 17:54:25 -05:00
|
|
|
if (BinocularRange)
|
|
|
|
{
|
|
|
|
BinocularRange = 0;
|
2021-11-08 19:35:17 +03:00
|
|
|
LaserSight = false;
|
2020-09-26 05:06:08 +10:00
|
|
|
AlterFOV(ANGLE(80.0f));
|
2022-02-09 16:55:46 +11:00
|
|
|
item->MeshBits = -1;
|
2022-02-15 21:25:24 +11:00
|
|
|
info->IsBusy = false;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_DEATH (8)
|
|
|
|
// Control: lara_as_death()
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_col_death(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
2021-09-10 01:19:15 +03:00
|
|
|
coll->Setup.Radius = LARA_RAD_DEATH;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-09-19 06:42:24 +03:00
|
|
|
GetCollisionInfo(coll, item);
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
StopSoundEffect(SFX_TR4_LARA_FALL);
|
2022-02-09 16:55:46 +11:00
|
|
|
item->HitPoints = -1;
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Air = -1;
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-12-02 18:52:00 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_SPLAT (12)
|
|
|
|
// Collision: lara_col_splat()
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_as_splat(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_SPLAT (12)
|
|
|
|
// Control: lara_as_splat()
|
2021-02-03 01:50:59 -03:00
|
|
|
void lara_col_splat(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 17:54:25 -05:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
|
|
|
coll->Setup.FloorSlopeIsPit = true;
|
|
|
|
coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-09-19 06:42:24 +03:00
|
|
|
GetCollisionInfo(coll, item);
|
2021-12-02 18:52:00 +11:00
|
|
|
|
2020-08-14 17:54:25 -05:00
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
2021-12-23 23:37:40 +11:00
|
|
|
if (abs(coll->Middle.Floor) <= CLICK(1))
|
|
|
|
LaraSnapToHeight(item, coll);
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
|
|
|
|
2021-10-09 23:00:26 +11:00
|
|
|
// State: LS_WALK_BACK (16)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_walk_back()
|
|
|
|
void lara_as_walk_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.CanLook = (TestEnvironment(ENV_FLAG_SWAMP, item) && info->Control.WaterStatus == WaterStatus::Wade) ? false : true;
|
2021-11-14 17:31:00 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-09 23:00:26 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.IsMoving)
|
2021-11-01 15:07:42 +11:00
|
|
|
return;
|
2021-10-09 23:00:26 +11:00
|
|
|
|
2022-01-25 18:02:22 +11:00
|
|
|
if (TestEnvironment(ENV_FLAG_SWAMP, item) &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus == WaterStatus::Wade)
|
2021-11-17 16:49:21 +11:00
|
|
|
{
|
2021-12-10 12:30:23 +11:00
|
|
|
PseudoLaraAsSwampWalkBack(item, coll);
|
2021-11-17 16:49:21 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-09 23:00:26 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-10-09 23:00:26 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
|
2021-10-22 01:50:43 +11:00
|
|
|
|
2021-10-09 23:00:26 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-10-09 23:00:26 +11:00
|
|
|
|
2021-11-23 13:53:35 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
|
2021-10-09 23:00:26 +11:00
|
|
|
}
|
|
|
|
|
2021-10-14 01:17:21 +11:00
|
|
|
if (TrInput & IN_BACK &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(TrInput & IN_WALK || info->Control.WaterStatus == WaterStatus::Wade))
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-10-09 23:00:26 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-09 23:00:26 +11:00
|
|
|
}
|
|
|
|
|
2021-11-17 16:49:21 +11:00
|
|
|
// Pseudo-state for walking back in swamps.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PseudoLaraAsSwampWalkBack(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-17 16:49:21 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-17 16:49:21 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX / 3)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX / 3;
|
2021-11-17 16:49:21 +11:00
|
|
|
|
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 3);
|
|
|
|
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX / 3)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX / 3;
|
2021-11-17 16:49:21 +11:00
|
|
|
|
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_BACK)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-17 16:49:21 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-11-17 16:49:21 +11:00
|
|
|
}
|
|
|
|
|
2021-10-09 23:00:26 +11:00
|
|
|
// State: LS_WALK_BACK (16)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_walk_back()
|
|
|
|
void lara_col_walk_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot + ANGLE(180.0f);
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-02-11 01:31:54 +11:00
|
|
|
coll->Setup.LowerFloorBound = (info->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : STEPUP_HEIGHT;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsPit = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
|
|
|
coll->Setup.FloorSlopeIsWall = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
2021-11-30 23:17:51 +11:00
|
|
|
coll->Setup.DeathFlagIsPit = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-09 23:00:26 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-09 23:00:26 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-09 23:00:26 +11:00
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-10-09 23:00:26 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-08 20:08:55 +11:00
|
|
|
// State: LS_TURN_RIGHT_FAST (20)
|
|
|
|
// Collision: lara_col_turn_right_fast()
|
|
|
|
void lara_as_turn_right_fast(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_MED_TURN_MAX;
|
|
|
|
else if (info->Control.TurnRate > LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_FAST_TURN_MAX;
|
2021-10-08 15:47:54 +11:00
|
|
|
|
2022-01-02 15:54:43 +11:00
|
|
|
if (TrInput & IN_JUMP)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-01-02 15:54:43 +11:00
|
|
|
SetLaraJumpDirection(item, coll);
|
2022-02-10 16:18:15 +11:00
|
|
|
if (info->Control.JumpDirection != JumpDirection::None)
|
2022-01-02 15:54:43 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-01-02 15:54:43 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_ROLL &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)) &&
|
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:22:28 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade) // Should not be possible, but here for security.
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraRunForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
else if (TrInput & IN_WALK)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraWalkForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_SPRINT && TestLaraRunForward(item, coll))
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
2021-10-22 00:07:24 +11:00
|
|
|
else if (TrInput & IN_BACK)
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TestLaraWalkBack(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-12 15:35:16 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-24 20:43:02 +11:00
|
|
|
}
|
2021-12-26 15:30:53 +11:00
|
|
|
else if (TestLaraRunBack(item, coll)) [[likely]]
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_BACK;
|
2021-10-24 20:43:02 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-08 15:47:54 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Hold WALK to slow down again.
|
|
|
|
if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_RIGHT_FAST;
|
2021-10-08 15:47:54 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-08 15:47:54 +11:00
|
|
|
}
|
|
|
|
|
2021-10-08 20:08:55 +11:00
|
|
|
// State: LS_TURN_RIGHT_FAST (20)
|
|
|
|
// Control: lara_as_turn_right_fast()
|
|
|
|
void lara_col_turn_right_fast(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2021-11-25 23:38:59 +11:00
|
|
|
lara_col_idle(item, coll);
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// State: LS_TURN_LEFT_FAST (152)
|
|
|
|
// Collision: lara_col_turn_left_fast()
|
|
|
|
void lara_as_turn_left_fast(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > -LARA_MED_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_MED_TURN_MAX;
|
|
|
|
else if (info->Control.TurnRate < -LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_FAST_TURN_MAX;
|
2021-11-25 21:08:51 +11:00
|
|
|
|
2022-01-02 15:54:43 +11:00
|
|
|
if (TrInput & IN_JUMP)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-01-02 15:54:43 +11:00
|
|
|
SetLaraJumpDirection(item, coll);
|
2022-02-10 16:18:15 +11:00
|
|
|
if (info->Control.JumpDirection != JumpDirection::None)
|
2022-01-02 15:54:43 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_JUMP_PREPARE;
|
2022-01-02 15:54:43 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_ROLL &&
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)) &&
|
|
|
|
info->Control.WaterStatus != WaterStatus::Wade)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-10-28 23:22:28 +11:00
|
|
|
if (TrInput & IN_FORWARD)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-17 02:00:40 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraRunForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-10-08 20:08:55 +11:00
|
|
|
else if (TrInput & IN_WALK)
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
|
|
|
if (TestLaraWalkForward(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_SPRINT && TestLaraRunForward(item, coll))
|
2021-10-28 23:22:28 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (TestLaraRunForward(item, coll)) [[likely]]
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-28 23:22:28 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
2021-10-22 00:07:24 +11:00
|
|
|
else if (TrInput & IN_BACK)
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TrInput & IN_WALK)
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2021-11-12 15:35:16 +11:00
|
|
|
if (TestLaraWalkBack(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_BACK;
|
2021-11-12 15:35:16 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-24 20:43:02 +11:00
|
|
|
}
|
2021-12-26 15:30:53 +11:00
|
|
|
else if (TestLaraRunBack(item, coll)) [[likely]]
|
2021-10-24 20:43:02 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_BACK;
|
2021-10-24 20:43:02 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TrInput & IN_LSTEP && TestLaraStepLeft(item, coll))
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-12-02 18:52:00 +11:00
|
|
|
else if (TrInput & IN_RSTEP && TestLaraStepRight(item, coll))
|
2021-10-08 20:08:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_TURN_LEFT_FAST;
|
2021-10-08 20:08:55 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// State: LS_TURN_LEFT_FAST (152)
|
|
|
|
// Control: lara_as_turn_left_fast()
|
|
|
|
void lara_col_turn_left_fast(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
2021-11-25 23:38:59 +11:00
|
|
|
lara_col_idle(item, coll);
|
2021-10-08 20:08:55 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// State: LS_STEP_RIGHT (21)
|
|
|
|
// Collision: lara_col_step_right()
|
|
|
|
void lara_as_step_right(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 17:19:38 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-10-14 17:19:38 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-14 17:19:38 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-14 17:19:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.IsMoving)
|
2021-11-01 15:07:42 +11:00
|
|
|
return;
|
2021-10-14 17:19:38 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-10-14 17:19:38 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-10-14 17:19:38 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_RSTEP)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_RIGHT;
|
2021-10-14 17:19:38 +11:00
|
|
|
return;
|
|
|
|
}
|
2021-11-25 23:38:59 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-14 17:19:38 +11:00
|
|
|
}
|
|
|
|
|
2021-10-10 14:03:38 +11:00
|
|
|
// State: LS_STEP_RIGHT (21)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_step_right()
|
|
|
|
void lara_col_step_right(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot + ANGLE(90.0f);
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-02-11 01:31:54 +11:00
|
|
|
coll->Setup.LowerFloorBound = (info->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : CLICK(0.8f);
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.UpperFloorBound = -CLICK(0.8f);
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsPit = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
|
|
|
coll->Setup.FloorSlopeIsWall = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
2021-11-30 23:17:51 +11:00
|
|
|
coll->Setup.DeathFlagIsPit = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-10 14:03:38 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-10 14:03:38 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-10 14:03:38 +11:00
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) || TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// State: LS_STEP_LEFT (22)
|
|
|
|
// Collision: lara_col_step_left()
|
|
|
|
void lara_as_step_left(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 17:19:38 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-10-14 17:19:38 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-14 17:19:38 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-10-14 17:19:38 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
if (info->Control.IsMoving)
|
2021-11-01 15:07:42 +11:00
|
|
|
return;
|
2021-10-14 17:19:38 +11:00
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-10-14 17:19:38 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-10-14 17:19:38 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LSTEP)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_STEP_LEFT;
|
2021-11-13 22:23:38 +11:00
|
|
|
return;
|
2020-09-26 03:28:30 +10:00
|
|
|
}
|
2021-11-13 22:23:38 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2020-09-26 05:06:08 +10:00
|
|
|
}
|
2020-09-26 03:28:30 +10:00
|
|
|
|
2021-10-10 14:03:38 +11:00
|
|
|
// State: LS_STEP_LEFT (22)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_step_left()
|
|
|
|
void lara_col_step_left(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot - ANGLE(90.0f);
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-02-11 01:31:54 +11:00
|
|
|
coll->Setup.LowerFloorBound = (info->Control.WaterStatus == WaterStatus::Wade) ? NO_LOWER_BOUND : CLICK(0.8f);
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.UpperFloorBound = -CLICK(0.8f);
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsPit = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
|
|
|
coll->Setup.FloorSlopeIsWall = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
2021-11-30 23:17:51 +11:00
|
|
|
coll->Setup.DeathFlagIsPit = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-10 14:03:38 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-10 14:03:38 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-10 14:03:38 +11:00
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) || TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-10-10 14:03:38 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// State: LS_ROLL_BACK (23)
|
|
|
|
// Collision: lara_col_roll_back()
|
|
|
|
void lara_as_roll_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-07 12:57:34 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-11-14 19:02:28 +11:00
|
|
|
|
2021-11-13 17:34:24 +11:00
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_BACK;
|
2021-11-13 17:34:24 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-11-07 12:57:34 +11:00
|
|
|
}
|
|
|
|
|
2021-11-13 17:34:24 +11:00
|
|
|
// State: LS_ROLL_BACK (23)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_roll_back()
|
|
|
|
void lara_col_roll_back(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 19:58:29 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot + ANGLE(180.0f);
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-12-02 18:52:00 +11:00
|
|
|
Camera.laraNode = 0;
|
2021-10-14 19:58:29 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-14 19:58:29 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-14 19:58:29 +11:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (coll->Middle.Floor > (STEPUP_HEIGHT / 2)) // Was 200.
|
2021-10-14 19:58:29 +11:00
|
|
|
{
|
|
|
|
SetLaraFallBackState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-10-14 19:58:29 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-15 18:26:03 +11:00
|
|
|
// State: LS_ROLL_FORWARD (45)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_roll_forward()
|
|
|
|
void lara_as_roll_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-11-07 12:57:34 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.CanLook = false;
|
2021-11-14 19:02:28 +11:00
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// TODO: Change swandive roll anim state to something sensible.
|
2021-11-07 12:57:34 +11:00
|
|
|
if (TrInput & IN_FORWARD &&
|
2022-02-09 16:55:46 +11:00
|
|
|
item->AnimNumber == LA_SWANDIVE_ROLL) // Hack.
|
2021-11-07 12:57:34 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-11-07 12:57:34 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-13 17:34:24 +11:00
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_ROLL_FORWARD;
|
2021-11-13 17:34:24 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-11-07 12:57:34 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// State: LS_ROLL_FORWARD (45)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_roll_forward()
|
|
|
|
void lara_col_roll_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-15 18:26:03 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-15 18:26:03 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-20 12:25:51 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2021-10-15 18:26:03 +11:00
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-05 21:29:00 +11:00
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-15 18:26:03 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-15 18:26:03 +11:00
|
|
|
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-10-15 18:26:03 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-14 17:40:22 +11:00
|
|
|
// State: LS_WADE_FORWARD (65)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_wade_forward()
|
|
|
|
void lara_as_wade_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 17:40:22 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 17:31:00 +11:00
|
|
|
|
2022-02-11 01:31:54 +11:00
|
|
|
info->Control.CanLook = (TestEnvironment(ENV_FLAG_SWAMP, item) && info->Control.WaterStatus == WaterStatus::Wade) ? false : true;
|
2021-10-14 17:40:22 +11:00
|
|
|
Camera.targetElevation = -ANGLE(22.0f);
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-10-14 17:40:22 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-14 17:40:22 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-01-25 18:02:22 +11:00
|
|
|
if (TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-10-14 17:40:22 +11:00
|
|
|
{
|
2021-12-10 12:30:23 +11:00
|
|
|
PseudoLaraAsSwampWadeForward(item, coll);
|
2021-10-14 17:40:22 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_FAST_TURN_MAX;
|
2021-10-14 17:40:22 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_FAST_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_FAST_TURN_MAX;
|
2021-10-14 17:40:22 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Dry)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-10-14 17:40:22 +11:00
|
|
|
else [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
2021-10-14 17:40:22 +11:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
|
2021-11-25 23:38:59 +11:00
|
|
|
// Pseudo-state for wading in swamps.
|
2021-12-10 12:30:23 +11:00
|
|
|
void PseudoLaraAsSwampWadeForward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 17:40:22 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2021-10-14 17:40:22 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SWAMP_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SWAMP_TURN_MAX;
|
2021-10-14 17:40:22 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX / 5 * 3, LARA_LEAN_RATE / 3);
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SWAMP_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SWAMP_TURN_MAX;
|
2021-10-14 17:40:22 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX / 5 * 3, LARA_LEAN_RATE / 3);
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
2022-02-17 02:00:40 +11:00
|
|
|
auto vaultResult = TestLaraVault(item, coll);
|
|
|
|
|
|
|
|
if (TrInput & IN_ACTION && info->Control.HandStatus == HandStatus::Free &&
|
|
|
|
vaultResult.Success)
|
|
|
|
{
|
|
|
|
item->TargetState = vaultResult.TargetState;
|
|
|
|
SetLaraVault(item, coll, vaultResult);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
else [[likely]]
|
|
|
|
item->TargetState = LS_WADE_FORWARD;
|
|
|
|
|
2021-10-14 17:40:22 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-10-14 17:40:22 +11:00
|
|
|
}
|
|
|
|
|
2021-10-24 22:18:22 +11:00
|
|
|
// State: LS_WADE_FORWARD (65)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_wade_forward()
|
|
|
|
void lara_col_wade_forward(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-24 22:18:22 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = TestEnvironment(ENV_FLAG_SWAMP, item) ? false : true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-24 22:18:22 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-06 00:27:25 +11:00
|
|
|
if (TestAndDoLaraLadderClimb(item, coll))
|
2021-11-23 12:30:04 +11:00
|
|
|
return;
|
|
|
|
|
2021-10-24 22:18:22 +11:00
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Position.zRot = 0;
|
2021-10-24 22:18:22 +11:00
|
|
|
|
2022-02-16 23:57:18 +11:00
|
|
|
if (!TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-10-24 22:18:22 +11:00
|
|
|
{
|
2022-02-16 23:57:18 +11:00
|
|
|
item->TargetState = LS_SPLAT_SOFT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
|
|
|
{
|
|
|
|
item->ActiveState = LS_SPLAT_SOFT;
|
|
|
|
return;
|
|
|
|
}
|
2021-10-24 22:18:22 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
}
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) || TestEnvironment(ENV_FLAG_SWAMP, item))
|
2021-10-24 22:18:22 +11:00
|
|
|
{
|
2021-10-25 18:41:53 +11:00
|
|
|
DoLaraStep(item, coll);
|
2021-10-24 22:18:22 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-29 18:35:21 +10:00
|
|
|
// State: LS_SPRINT (73)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Collision: lara_col_sprint()
|
|
|
|
void lara_as_sprint(ITEM_INFO* item, COLL_INFO* coll)
|
2021-09-29 18:35:21 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->SprintEnergy--;
|
2021-09-29 18:35:21 +10:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Control.Count.RunJump++;
|
|
|
|
if (info->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
|
|
|
|
info->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
|
2021-12-12 21:11:27 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0)
|
2021-09-29 18:35:21 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_DEATH;
|
2021-09-29 18:35:21 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-09-29 18:35:21 +10:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE);
|
2021-09-29 18:35:21 +10:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-09-29 18:35:21 +10:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE);
|
2021-09-29 18:35:21 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT_DIVE;
|
2021-09-29 18:35:21 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-02 18:32:52 +11:00
|
|
|
if (TrInput & IN_CROUCH &&
|
2022-02-11 01:31:54 +11:00
|
|
|
(info->Control.HandStatus == HandStatus::Free || !IsStandingWeapon(info->Control.WeaponControl.GunType)))
|
2021-09-29 18:35:21 +10:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_CROUCH_IDLE;
|
2021-09-29 18:35:21 +10:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Supposedly there is a bug wherein sprinting into the boundary between shallow and deep water
|
2021-11-25 23:38:59 +11:00
|
|
|
// while meeting some condition allows Lara to run around in the water room. Investigate. @Sezz 2021.09.29
|
2021-09-29 18:35:21 +10:00
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
2022-02-11 01:31:54 +11:00
|
|
|
if (info->Control.WaterStatus == WaterStatus::Wade)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD; // TODO: Dispatch to wade forward state directly. @Sezz 2021.09.29
|
2021-09-29 18:35:21 +10:00
|
|
|
else if (TrInput & IN_WALK)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_WALK_FORWARD;
|
2022-02-11 19:26:08 +11:00
|
|
|
else if (TrInput & IN_SPRINT && info->SprintEnergy > 0) [[likely]]
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPRINT;
|
2021-09-29 18:35:21 +10:00
|
|
|
else
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2021-09-29 18:35:21 +10:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-09-29 18:35:21 +10:00
|
|
|
}
|
|
|
|
|
2021-10-09 23:53:39 +11:00
|
|
|
// State: LS_SPRINT (73)
|
2021-11-25 23:38:59 +11:00
|
|
|
// Control: lara_as_sprint()
|
|
|
|
void lara_col_sprint(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-09 23:53:39 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot;
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = 0;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-10-09 23:53:39 +11:00
|
|
|
GetCollisionInfo(coll, item);
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-11-23 12:30:04 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
|
|
|
{
|
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraSlide(item, coll))
|
2021-12-18 20:42:15 +11:00
|
|
|
{
|
|
|
|
SetLaraSlideState(item, coll);
|
2021-10-09 23:53:39 +11:00
|
|
|
return;
|
2021-12-18 20:42:15 +11:00
|
|
|
}
|
2021-10-09 23:53:39 +11:00
|
|
|
|
|
|
|
if (LaraDeflectEdge(item, coll))
|
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Position.zRot = 0;
|
2021-10-09 23:53:39 +11:00
|
|
|
|
2022-02-02 21:59:34 +11:00
|
|
|
if (coll->HitTallObject || TestLaraSplat(item, OFFSET_RADIUS(coll->Setup.Radius), -CLICK(2.5f)))
|
2021-10-09 23:53:39 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_SPLAT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
2021-10-09 23:53:39 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->ActiveState = LS_SPLAT;
|
2021-10-09 23:53:39 +11:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-16 14:20:26 +11:00
|
|
|
item->TargetState = LS_SPLAT_SOFT;
|
|
|
|
if (GetChange(item, &g_Level.Anims[item->AnimNumber]))
|
2022-02-16 18:13:07 +11:00
|
|
|
{
|
|
|
|
item->ActiveState = LS_SPLAT_SOFT;
|
2022-02-16 14:20:26 +11:00
|
|
|
return;
|
2022-02-16 18:13:07 +11:00
|
|
|
}
|
2022-02-16 14:20:26 +11:00
|
|
|
|
2021-10-09 23:53:39 +11:00
|
|
|
LaraCollideStop(item, coll);
|
|
|
|
}
|
|
|
|
|
2022-02-06 00:27:25 +11:00
|
|
|
if (TestAndDoLaraLadderClimb(item, coll))
|
2021-10-09 23:53:39 +11:00
|
|
|
return;
|
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll) && coll->CollisionType != CT_FRONT)
|
2021-10-09 23:53:39 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_SPRINT_DIVE (74)
|
|
|
|
// Collision: lara_col_sprint_dive()
|
|
|
|
void lara_as_sprint_dive(ITEM_INFO* item, COLL_INFO* coll)
|
2021-10-14 19:58:29 +11:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-11 19:26:08 +11:00
|
|
|
info->Control.Count.RunJump++;
|
|
|
|
if (info->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
|
|
|
|
info->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
|
2021-12-08 16:07:34 +11:00
|
|
|
|
2021-10-14 19:58:29 +11:00
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate -= LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate < -LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = -LARA_SLOW_TURN_MAX;
|
2021-10-14 19:58:29 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, -(LARA_LEAN_MAX * 3) / 5, LARA_LEAN_RATE);
|
2021-10-14 19:58:29 +11:00
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.TurnRate += LARA_TURN_RATE;
|
|
|
|
if (info->Control.TurnRate > LARA_SLOW_TURN_MAX)
|
|
|
|
info->Control.TurnRate = LARA_SLOW_TURN_MAX;
|
2021-10-14 19:58:29 +11:00
|
|
|
|
2021-11-17 15:59:51 +11:00
|
|
|
DoLaraLean(item, coll, (LARA_LEAN_MAX * 3) / 5, LARA_LEAN_RATE);
|
2021-10-14 19:58:29 +11:00
|
|
|
}
|
|
|
|
|
2021-12-22 16:00:13 +11:00
|
|
|
// TODO: Make this state a true jump?
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->TargetState != LS_DEATH &&
|
|
|
|
item->TargetState != LS_IDLE &&
|
|
|
|
item->TargetState != LS_RUN_FORWARD &&
|
2022-02-09 13:20:57 +11:00
|
|
|
item->VerticalVelocity >= LARA_FREEFALL_SPEED)
|
2021-10-30 13:42:55 +11:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_FREEFALL;
|
2021-10-30 13:42:55 +11:00
|
|
|
}
|
2021-10-14 19:58:29 +11:00
|
|
|
}
|
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
// State: LS_SPRINT_DIVE (74)
|
|
|
|
// Control: lara_col_sprint_dive()
|
|
|
|
void lara_col_sprint_dive(ITEM_INFO* item, COLL_INFO* coll)
|
2020-09-26 05:06:08 +10:00
|
|
|
{
|
2022-02-14 17:05:52 +11:00
|
|
|
auto* info = GetLaraInfo(item);
|
2021-11-14 22:51:43 +11:00
|
|
|
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = (item->Velocity >= 0) ? item->Position.yRot : item->Position.yRot + ANGLE(180.0f);
|
2022-01-30 14:43:33 +11:00
|
|
|
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
|
|
|
coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
|
|
|
|
coll->Setup.LowerCeilingBound = BAD_JUMP_CEILING;
|
|
|
|
coll->Setup.FloorSlopeIsWall = true;
|
2022-02-10 01:38:32 +11:00
|
|
|
coll->Setup.ForwardAngle = info->Control.MoveAngle;
|
2021-09-19 06:42:24 +03:00
|
|
|
GetCollisionInfo(coll, item);
|
2021-12-02 18:52:00 +11:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
LaraDeflectEdgeJump(item, coll);
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
if (TestLaraFall(item, coll))
|
2020-09-26 05:06:08 +10:00
|
|
|
{
|
2021-12-02 18:52:00 +11:00
|
|
|
SetLaraFallState(item);
|
|
|
|
return;
|
|
|
|
}
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2022-02-09 13:20:57 +11:00
|
|
|
if (item->Velocity < 0)
|
2022-02-10 01:38:32 +11:00
|
|
|
info->Control.MoveAngle = item->Position.yRot; // ???
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2022-02-09 13:20:57 +11:00
|
|
|
if (coll->Middle.Floor <= 0 && item->VerticalVelocity > 0)
|
2021-12-02 18:52:00 +11:00
|
|
|
{
|
2022-01-22 22:36:29 +11:00
|
|
|
DoLaraFallDamage(item);
|
2022-01-22 21:08:30 +11:00
|
|
|
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->HitPoints <= 0) // TODO: It seems Core wanted to make the sprint dive a true jump.
|
|
|
|
item->TargetState = LS_DEATH;
|
2022-02-11 01:31:54 +11:00
|
|
|
else if (!(TrInput & IN_FORWARD) || TrInput & IN_WALK || info->Control.WaterStatus == WaterStatus::Wade)
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_IDLE;
|
2021-12-02 18:52:00 +11:00
|
|
|
else
|
2022-02-09 16:55:46 +11:00
|
|
|
item->TargetState = LS_RUN_FORWARD;
|
2020-09-26 05:06:08 +10:00
|
|
|
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Airborne = false;
|
|
|
|
item->VerticalVelocity = 0;
|
2022-02-09 16:55:46 +11:00
|
|
|
item->Position.yPos += coll->Middle.Floor;
|
2022-02-09 13:20:57 +11:00
|
|
|
item->Velocity = 0;
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2021-12-02 18:52:00 +11:00
|
|
|
AnimateLara(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
ShiftItem(item, coll);
|
2020-08-14 17:54:25 -05:00
|
|
|
|
2022-01-27 20:56:05 +11:00
|
|
|
if (TestLaraStep(item, coll))
|
2021-12-02 18:52:00 +11:00
|
|
|
{
|
|
|
|
DoLaraStep(item, coll);
|
|
|
|
return;
|
2020-08-14 17:54:25 -05:00
|
|
|
}
|
2022-02-17 02:00:40 +11:00
|
|
|
}
|