TombEngine/TR5Main/Game/Lara/lara_basic.cpp

2269 lines
52 KiB
C++
Raw Normal View History

#include "framework.h"
#include "lara.h"
#include "lara_basic.h"
#include "lara_tests.h"
#include "lara_collide.h"
#include "lara_slide.h"
#include "lara_monkey.h"
#include "input.h"
2021-09-19 18:29:25 +03:00
#include "level.h"
#include "health.h"
2021-09-19 18:29:25 +03:00
#include "Sound/sound.h"
#include "animation.h"
#include "pickup.h"
2021-08-28 13:27:58 +02:00
#include "collide.h"
2021-09-19 23:41:26 +03:00
#include "items.h"
2021-08-28 13:27:58 +02:00
#include "camera.h"
2021-09-25 11:27:47 +02:00
/*generic functions*/
2021-02-03 01:50:59 -03:00
void lara_void_func(ITEM_INFO* item, COLL_INFO* coll)
{
return;
}
2021-02-03 01:50:59 -03:00
void lara_default_col(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesArePits = true;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
2021-09-25 13:00:14 +03:00
LaraResetGravityStatus(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_special(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.flags = CF_FOLLOW_CENTER;
Camera.targetAngle = ANGLE(170.0f);
Camera.targetElevation = -ANGLE(25.0f);
}
2021-02-03 01:50:59 -03:00
void lara_as_null(ITEM_INFO* item, COLL_INFO* coll)
{
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
}
2021-02-03 01:50:59 -03:00
void lara_as_controlled(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.look = false;
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd - 1)
{
Lara.gunStatus = LG_NO_ARMS;
if (UseForcedFixedCamera)
UseForcedFixedCamera = 0;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_controlledl(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.look = false;
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
}
/*end generic functions*/
/*-*/
/*basic movement*/
2021-02-03 01:50:59 -03:00
void lara_as_walk(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 0*/
/*collision: lara_col_walk*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (!Lara.isMoving)
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
}
if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = LS_WALK_FORWARD;
}
else
{
item->goalAnimState = LS_RUN_FORWARD;
}
}
else
{
item->goalAnimState = LS_STOP;
}
}
}
2021-02-03 01:50:59 -03:00
void lara_col_walk(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 0*/
/*state code: lara_as_walk*/
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
coll->Setup.SlopesArePits = true;
coll->Setup.DeathFlagIsPit = 1;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
item->goalAnimState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
return;
LaraCollideStop(item, coll);
}
if (!LaraFallen(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
if (coll->Front.Floor == NO_HEIGHT || coll->Front.Floor <= STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
coll->Middle.Floor = 0;
}
else
{
item->goalAnimState = LS_STEP_DOWN;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
}
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= -STEPUP_HEIGHT && coll->Middle.Floor < -STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
if (coll->Front.Floor == NO_HEIGHT ||
coll->Front.Floor < -STEPUP_HEIGHT ||
coll->Front.Floor >= -STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
coll->Middle.Floor = 0;
}
else
{
item->goalAnimState = LS_STEP_UP;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
}
2021-09-10 00:18:47 +03:00
if (!TestLaraSlide(item, coll) && coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
}
2021-02-03 01:50:59 -03:00
void lara_as_run(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 1*/
/*collision: lara_col_run*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_ROLL)
{
item->animNumber = LA_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 2;
item->currentAnimState = LS_ROLL_FORWARD;
item->goalAnimState = LS_STOP;
return;
}
if (TrInput & IN_SPRINT && DashTimer)
{
item->goalAnimState = LS_SPRINT;
return;
}
if (TrInput & IN_DUCK &&
Lara.waterStatus != LW_WADE &&
(Lara.gunStatus == LG_NO_ARMS ||
Lara.gunType == WEAPON_NONE ||
Lara.gunType == WEAPON_PISTOLS ||
Lara.gunType == WEAPON_REVOLVER ||
Lara.gunType == WEAPON_UZI ||
Lara.gunType == WEAPON_FLARE))
{
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_FAST_TURN)
Lara.turnRate = -LARA_FAST_TURN;
if (TestLaraLean(item, coll))
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX)
item->pos.zRot = -LARA_LEAN_MAX;
2020-08-25 19:39:50 -03:00
}
2021-07-09 19:41:56 -05:00
else
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX * 3 / 5)//gives best results
item->pos.zRot = -LARA_LEAN_MAX * 3 / 5;
}
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_FAST_TURN)
Lara.turnRate = LARA_FAST_TURN;
if (TestLaraLean(item, coll))
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX)
item->pos.zRot = LARA_LEAN_MAX;
2020-08-25 19:39:50 -03:00
}
2021-07-09 19:41:56 -05:00
else
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX * 3 / 5)//gives best results
item->pos.zRot = LARA_LEAN_MAX * 3 / 5;
}
}
2021-09-14 00:35:10 +03:00
static bool doJump = false;
2021-09-13 09:19:35 +03:00
if (item->animNumber == LA_STAND_TO_RUN)
{
2021-09-13 09:19:35 +03:00
doJump = false;
}
else if (item->animNumber == LA_RUN)
{
if (item->frameNumber == 4)
2021-09-13 09:19:35 +03:00
doJump = true;
}
else
{
2021-09-13 09:19:35 +03:00
doJump = true;
}
2021-09-13 09:19:35 +03:00
if (TrInput & IN_JUMP && doJump && !item->gravityStatus)
{
item->goalAnimState = LS_JUMP_FORWARD;
}
else if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_WADE_FORWARD;
}
else
{
if (TrInput & IN_WALK)
item->goalAnimState = LS_WALK_FORWARD;
else
item->goalAnimState = LS_RUN_FORWARD;
}
}
else
{
item->goalAnimState = LS_STOP;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_run(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 1*/
/*state code: lara_col_run*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
2021-09-25 13:00:14 +03:00
LaraResetGravityStatus(item, coll);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
2021-09-14 00:41:11 +03:00
if (coll->HitTallBounds || TestLaraWall(item, 256, 0, -640))
{
item->goalAnimState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
{
item->currentAnimState = LS_SPLAT;
return;
}
}
LaraCollideStop(item, coll);
}
if (!LaraFallen(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= -STEPUP_HEIGHT && coll->Middle.Floor < -STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
if (coll->Front.Floor == NO_HEIGHT || coll->Front.Floor < -STEPUP_HEIGHT || coll->Front.Floor >= -STEP_SIZE / 2)
{
2021-09-10 00:18:47 +03:00
coll->Middle.Floor = 0;
}
else
{
item->goalAnimState = LS_STEP_UP;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
}
if (!TestLaraSlide(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor < 50)
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
else
{
item->goalAnimState = LS_STEP_DOWN; // for theoretical running stepdown anims, not in default anims
if (GetChange(item, &g_Level.Anims[item->animNumber]))
2021-09-10 00:18:47 +03:00
item->pos.yPos += coll->Middle.Floor; // move Lara to middle.Floor
else
item->pos.yPos += 50; // do the default aligment
}
}
}
}
}
void lara_as_stop(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 2*/
/*collision: lara_col_stop*/
2021-09-10 00:43:26 +03:00
COLL_RESULT fheight = {}; fheight.Position.Floor = NO_HEIGHT;
COLL_RESULT rheight = {}; rheight.Position.Floor = NO_HEIGHT;
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (item->animNumber != LA_SPRINT_TO_STAND_RIGHT && item->animNumber != LA_SPRINT_TO_STAND_LEFT)
StopSoundEffect(SFX_TR4_LARA_SLIPPING);
// Handles waterskin and clockwork beetle
if (UseSpecialItem(item))
return;
if (TrInput & IN_ROLL && Lara.waterStatus != LW_WADE)
{
item->animNumber = LA_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 2;
item->currentAnimState = LS_ROLL_FORWARD;
item->goalAnimState = LS_STOP;
return;
}
if (TrInput & IN_DUCK
&& Lara.waterStatus != LW_WADE
&& item->currentAnimState == LS_STOP
&& (Lara.gunStatus == LG_NO_ARMS
|| Lara.gunType == WEAPON_NONE
|| Lara.gunType == WEAPON_PISTOLS
|| (Lara.gunType == WEAPON_REVOLVER && !LaserSight)
|| Lara.gunType == WEAPON_UZI
|| Lara.gunType == WEAPON_FLARE))
{
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
item->goalAnimState = LS_STOP;
if (TrInput & IN_LOOK)
LookUpDown();
2021-09-18 00:36:28 +03:00
if (TrInput & IN_LSTEP)
{
2021-09-18 00:36:28 +03:00
auto collFloorResult = LaraCollisionFront(item, item->pos.yRot - ANGLE(90.0f), LARA_RAD + 48);
auto collCeilingResult = LaraCeilingCollisionFront(item, item->pos.yRot - ANGLE(90.0f), LARA_RAD + 48, LARA_HEIGHT);
if ((collFloorResult.Position.Floor < 128 && collFloorResult.Position.Floor > -128) && !collFloorResult.Position.Slope&& collCeilingResult.Position.Ceiling <= 0)
item->goalAnimState = LS_STEP_LEFT;
}
2021-09-18 00:36:28 +03:00
else if (TrInput & IN_RSTEP)
{
2021-09-18 00:36:28 +03:00
auto collFloorResult = LaraCollisionFront(item, item->pos.yRot + ANGLE(90.0f), LARA_RAD + 48);
auto collCeilingResult = LaraCeilingCollisionFront(item, item->pos.yRot + ANGLE(90.0f), LARA_RAD + 48, LARA_HEIGHT);
2021-09-18 00:36:28 +03:00
if ((collFloorResult.Position.Floor < 128 && collFloorResult.Position.Floor > -128) && !collFloorResult.Position.Slope&& collCeilingResult.Position.Ceiling <= 0)
item->goalAnimState = LS_STEP_RIGHT;
}
else if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_TURN_LEFT_SLOW;
}
2021-09-18 00:36:28 +03:00
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_TURN_RIGHT_SLOW;
}
if (TrInput & IN_FORWARD)
fheight = LaraCollisionFront(item, item->pos.yRot, LARA_RAD + 4);
else if (TrInput & IN_BACK)
rheight = LaraCollisionFront(item, item->pos.yRot - ANGLE(180.0f), LARA_RAD + 4); // TR3: item->pos.yRot + ANGLE(180)?
if (Lara.waterStatus == LW_WADE)
{
if (TrInput & IN_JUMP && !(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
item->goalAnimState = LS_JUMP_PREPARE;
if (TrInput & IN_FORWARD)
{
bool wade = false;
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
2021-09-10 00:43:26 +03:00
if (fheight.Position.Floor > -(STEPUP_HEIGHT - 1))
{
lara_as_wade(item, coll);
wade = true;
}
}
else
{
2021-09-10 00:43:26 +03:00
if ((fheight.Position.Floor < (STEPUP_HEIGHT - 1)) && (fheight.Position.Floor > -(STEPUP_HEIGHT - 1)))
{
lara_as_wade(item, coll);
wade = true;
}
}
if (!wade)
{
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
coll->Setup.Radius = LARA_RAD + 2;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (TestLaraVault(item, coll))
return;
2021-09-10 00:20:59 +03:00
coll->Setup.Radius = LARA_RAD;
}
}
else if (TrInput & IN_BACK)
{
2021-09-10 00:43:26 +03:00
if ((rheight.Position.Floor < (STEPUP_HEIGHT - 1)) && (rheight.Position.Floor > -(STEPUP_HEIGHT - 1)))
lara_as_back(item, coll);
}
}
else
{
if (TrInput & IN_JUMP)
{
2021-09-18 03:06:21 +03:00
if (coll->Middle.Ceiling <= -LARA_HEADROOM)
2021-09-18 00:36:28 +03:00
item->goalAnimState = LS_JUMP_PREPARE;
}
else if (TrInput & IN_FORWARD)
{
2021-09-18 00:36:28 +03:00
auto cheight = LaraCeilingCollisionFront(item, item->pos.yRot, LARA_RAD + 4, LARA_HEIGHT);
// Don't try to move if there is slope in front
2021-09-18 00:36:28 +03:00
if (fheight.Position.Slope && (fheight.Position.Floor < 0 || cheight.Position.Ceiling > 0))
return; // item->goalAnimState = LS_STOP was removed here because it prevented Lara from rotating while still holding forward. -- Lwmte, 17.09.2021
// Don't try to move if there is no headroom in front
if (coll->CollisionType == CT_FRONT)
return;
2021-09-18 03:06:21 +03:00
if (TrInput & IN_WALK)
lara_as_walk(item, coll);
else
2021-09-18 03:06:21 +03:00
lara_as_run(item, coll);
}
else if (TrInput & IN_BACK)
{
if (TrInput & IN_WALK)
{
if ((rheight.Position.Floor < (STEPUP_HEIGHT - 1)) && (rheight.Position.Floor > -(STEPUP_HEIGHT - 1)) && !rheight.Position.Slope)
lara_as_back(item, coll);
}
2021-09-10 00:43:26 +03:00
else if (rheight.Position.Floor > -(STEPUP_HEIGHT - 1))
{
item->goalAnimState = LS_HOP_BACK;
}
}
}
}
2021-02-03 01:50:59 -03:00
void lara_col_stop(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 2*/
/*state code: lara_as_stop*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
item->gravityStatus = false;
item->fallspeed = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesArePits = true;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (LaraHitCeiling(item, coll))
return;
if (LaraFallen(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
#if 1
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
#else
2021-09-10 00:18:47 +03:00
if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->Middle.Floor < 0)
item->pos.yPos += coll->Middle.Floor;
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->Middle.Floor)
item->pos.yPos += SWAMP_GRAVITY;
#endif
}
2021-02-03 01:50:59 -03:00
void lara_as_forwardjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 3*/
/*collision: */
if (item->goalAnimState == LS_SWANDIVE_START ||
item->goalAnimState == LS_REACH)
item->goalAnimState = LS_JUMP_FORWARD;
if (item->goalAnimState != LS_DEATH &&
item->goalAnimState != LS_STOP &&
item->goalAnimState != LS_RUN_FORWARD)
{
if (Lara.gunStatus == LG_NO_ARMS && TrInput & IN_ACTION)
item->goalAnimState = LS_REACH;
if (TrInput & IN_BACK || TrInput & IN_ROLL)
item->goalAnimState = LS_JUMP_ROLL_180;
if (Lara.gunStatus == LG_NO_ARMS && TrInput & IN_WALK)
item->goalAnimState = LS_SWANDIVE_START;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(3.0f))
Lara.turnRate = -ANGLE(3.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(3.0f))
Lara.turnRate = ANGLE(3.0f);
}
}
2021-02-03 01:50:59 -03:00
void lara_col_forwardjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 3*/
/*state code: lara_as_forwardjump*/
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot + ANGLE(180);
else
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = LS_DEATH;
}
else
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_STOP;
}
else
{
if (TrInput & IN_FORWARD && !(TrInput & IN_STEPSHIFT))
item->goalAnimState = LS_RUN_FORWARD;
else
item->goalAnimState = LS_STOP;
}
}
item->gravityStatus = false;
item->fallspeed = 0;
item->speed = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_pose(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 4*/
/*state code: lara_void_func*/
lara_col_stop(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_fastback(ITEM_INFO* item, COLL_INFO* coll)
{
/*state: 5*/
/*collision: lara_col_fastback*/
item->goalAnimState = LS_STOP;
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(6.0f))
Lara.turnRate = -ANGLE(6.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(6.0f))
Lara.turnRate = ANGLE(6.0f);
}
}
2021-02-03 01:50:59 -03:00
void lara_col_fastback(ITEM_INFO* item, COLL_INFO* coll)
{
/*state: 5*/
/*state code: lara_as_fastback*/
item->fallspeed = 0;
item->gravityStatus = false;
Lara.moveAngle = item->pos.yRot + ANGLE(180);
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = false;
coll->Setup.SlopesArePits = true;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (!LaraHitCeiling(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 200)
{
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
2021-09-10 00:18:47 +03:00
if (!TestLaraSlide(item, coll) && coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
else
{
item->fallspeed = 0;
item->animNumber = LA_FALL_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_FALL_BACK;
item->goalAnimState = LS_FALL_BACK;
item->gravityStatus = true;
}
}
}
2021-02-03 01:50:59 -03:00
void lara_as_turn_r(ITEM_INFO* item, COLL_INFO* coll)
{
/*state: 6*/
/*collision: */
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
Lara.turnRate += LARA_TURN_RATE;
if (Lara.gunStatus != LG_READY || Lara.waterStatus == LW_WADE)
{
if (Lara.turnRate > ANGLE(4.0f))
{
2021-09-18 00:36:28 +03:00
if (TrInput & IN_WALK || Lara.waterStatus == LW_WADE)
Lara.turnRate = ANGLE(4.0f);
else
item->goalAnimState = LS_TURN_FAST;
}
}
else
{
item->goalAnimState = LS_TURN_FAST;
}
// Don't try to move forward if button isn't pressed or there's no headroom in front
if (!(TrInput & IN_FORWARD) || coll->CollisionType == CT_FRONT)
{
if (!(TrInput & IN_RIGHT))
item->goalAnimState = LS_STOP;
return;
}
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = LS_WALK_FORWARD;
}
else
{
item->goalAnimState = LS_RUN_FORWARD;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_turn_r(ITEM_INFO* item, COLL_INFO* coll)
{
/*state: 6*/
/*state code: lara_as_turn_r*/
item->fallspeed = 0;
item->gravityStatus = false;
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
coll->Setup.SlopesArePits = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
#if 1
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > 100)
#else
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > 100 && !(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
#endif
{
item->fallspeed = 0;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_JUMP_FORWARD;
item->goalAnimState = LS_JUMP_FORWARD;
item->gravityStatus = true;
return;
}
if (TestLaraSlide(item, coll))
return;
#if 1
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
#else
2021-09-10 00:18:47 +03:00
if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->Middle.Floor < 0)
item->pos.yPos += coll->Middle.Floor;
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->Middle.Floor)
item->pos.yPos += SWAMP_GRAVITY;
#endif
}
2021-02-03 01:50:59 -03:00
void lara_as_turn_l(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 7*/
/*collision: lara_col_turn_l*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.gunStatus != LG_READY || Lara.waterStatus == LW_WADE)
{
if (Lara.turnRate < -ANGLE(4.0f))
{
2021-09-18 00:36:28 +03:00
if (TrInput & IN_WALK || Lara.waterStatus == LW_WADE)
Lara.turnRate = -ANGLE(4.0f);
else
item->goalAnimState = LS_TURN_FAST;
}
}
else
{
item->goalAnimState = LS_TURN_FAST;
}
// Don't try to move forward if button isn't pressed or there's no headroom in front
if (!(TrInput & IN_FORWARD) || coll->CollisionType == CT_FRONT)
{
if (!(TrInput & IN_LEFT))
item->goalAnimState = LS_STOP;
return;
}
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = LS_WALK_FORWARD;
}
else
{
item->goalAnimState = LS_RUN_FORWARD;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_turn_l(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 7*/
/*state code: lara_as_turn_l*/
lara_col_turn_r(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_death(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 8*/
/*collision: lara_col_death*/
Lara.look = false;
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
if (BinocularRange)
{
BinocularRange = 0;
LaserSight = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->meshBits = -1;
Lara.busy = false;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_death(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 8*/
/*state code: lara_as_death*/
StopSoundEffect(SFX_TR4_LARA_FALL);
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 01:19:15 +03:00
coll->Setup.Radius = LARA_RAD_DEATH;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
ShiftItem(item, coll);
item->hitPoints = -1;
Lara.air = -1;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
2021-02-03 01:50:59 -03:00
void lara_as_fastfall(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 9*/
/*collision: lara_col_fastfall*/
item->speed = (item->speed * 95) / 100;
if (item->fallspeed == 154)
SoundEffect(SFX_TR4_LARA_FALL, &item->pos, 0);
}
2021-02-03 01:50:59 -03:00
void lara_col_fastfall(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 9*/
/*state code: lara_as_fastfall*/
item->gravityStatus = true;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraSlideEdgeJump(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = LS_DEATH;
}
else
{
item->goalAnimState = LS_STOP;
item->currentAnimState = LS_STOP;
item->animNumber = LA_FREEFALL_LAND;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
StopSoundEffect(SFX_TR4_LARA_FALL);
item->fallspeed = 0;
item->gravityStatus = false;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_reach(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 11*/
/*collision: lara_col_reach*/
Camera.targetAngle = ANGLE(85.0f);
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
2021-02-03 01:50:59 -03:00
void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 11*/
/*state code: lara_as_reach*/
if (Lara.ropePtr == -1)
item->gravityStatus = true;
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
short angle;
bool result = false;
int edge = 0;
int edgeCatch = 0;
2021-09-10 00:18:47 +03:00
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && !coll->HitStatic)
{
2021-09-10 00:18:47 +03:00
if (Lara.canMonkeySwing && coll->CollisionType == CT_TOP)
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.gunStatus = LG_HANDS_BUSY;
item->animNumber = LA_REACH_TO_MONKEYSWING;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_MONKEYSWING_IDLE;
item->currentAnimState = LS_MONKEYSWING_IDLE;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
return;
}
2021-09-10 00:18:47 +03:00
if (coll->Middle.Ceiling <= -384 &&
coll->Middle.Floor >= 200 &&
coll->CollisionType == CT_FRONT)
{
2021-09-14 00:30:44 +03:00
edgeCatch = TestLaraEdgeCatch(item, coll, &edge);
2021-09-14 00:30:44 +03:00
if (!(!edgeCatch || edgeCatch < 0 && !TestLaraHangOnClimbWall(item, coll)))
{
angle = item->pos.yRot;
result = SnapToQuadrant(angle, 35);
}
}
}
if (!result)
{
LaraSlideEdgeJump(item, coll);
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = LS_DEATH;
}
else
{
item->goalAnimState = LS_STOP;
item->fallspeed = 0;
item->gravityStatus = false;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
}
else
{
if (TestHangSwingIn(item, angle))
{
2021-07-09 19:41:56 -05:00
if (Lara.NewAnims.OscillateHanging)
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
item->animNumber = LA_REACH_TO_HANG_OSCILLATE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_HANG;
item->goalAnimState = LS_HANG;
}
else
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
item->animNumber = LA_REACH_TO_MONKEYSWING;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_MONKEYSWING_IDLE;
item->goalAnimState = LS_MONKEYSWING_IDLE;
}
}
else
{
2021-07-09 19:41:56 -05:00
if (TestHangFeet(item, angle))
{
item->animNumber = LA_REACH_TO_HANG;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_HANG;
item->goalAnimState = LS_HANG_FEET;
}
2021-07-09 19:41:56 -05:00
else
{
item->animNumber = LA_REACH_TO_HANG;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_HANG;
item->goalAnimState = LS_HANG;
}
}
BOUNDING_BOX* bounds = GetBoundsAccurate(item);
if (edgeCatch <= 0)
{
item->pos.yPos = edge - bounds->Y1 - 22;
}
else
{
2021-09-10 00:18:47 +03:00
item->pos.yPos += coll->Front.Floor - bounds->Y1;
Vector2 v = GetOrthogonalIntersect(item->pos.xPos, item->pos.zPos, LARA_RAD, angle);
item->pos.xPos = v.x;
item->pos.zPos = v.y;
}
item->pos.yRot = angle;
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
Lara.gunStatus = LG_HANDS_BUSY;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_splat(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.look = false;
}
2021-02-03 01:50:59 -03:00
void lara_col_splat(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.moveAngle = item->pos.yRot;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
coll->Setup.SlopesArePits = true;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= -256 && coll->Middle.Floor <= 256)
item->pos.yPos += coll->Middle.Floor;
}
2021-02-03 01:50:59 -03:00
void lara_col_land(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 14*/
/*state code: lara_void_func*/
lara_col_stop(item, coll);
}
void lara_as_compress(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 15*/
/*collision: lara_col_compress*/
if (Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_FORWARD && !LaraFacingCorner(item, item->pos.yRot, 256) && LaraFloorFront(item, item->pos.yRot, 256) >= -384)
{
item->goalAnimState = LS_JUMP_FORWARD;
Lara.moveAngle = item->pos.yRot;
}
else if (TrInput & IN_LEFT && !LaraFacingCorner(item, item->pos.yRot - ANGLE(90.0f), 256) && LaraFloorFront(item, item->pos.yRot - ANGLE(90.0f), 256) >= -384)
{
2020-09-02 15:59:57 -05:00
item->goalAnimState = LS_JUMP_LEFT;
Lara.moveAngle = item->pos.yRot - ANGLE(90);
}
else if (TrInput & IN_RIGHT && !LaraFacingCorner(item, item->pos.yRot + ANGLE(90.0f), 256) && LaraFloorFront(item, item->pos.yRot + ANGLE(90.0f), 256) >= -384)
{
2020-09-02 15:59:57 -05:00
item->goalAnimState = LS_JUMP_RIGHT;
Lara.moveAngle = item->pos.yRot + ANGLE(90);
}
else if (TrInput & IN_BACK && !LaraFacingCorner(item, item->pos.yRot - ANGLE(180.0f), 256) && LaraFloorFront(item, item->pos.yRot - ANGLE(180.0f), 256) >= -384)
{
item->goalAnimState = LS_JUMP_BACK;
Lara.moveAngle = item->pos.yRot + ANGLE(180);
}
}
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
2021-02-03 01:50:59 -03:00
void lara_col_compress(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 15*/
/*state code: lara_as_compress*/
item->fallspeed = 0;
item->gravityStatus = false;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = NO_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (!LaraFallen(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Ceiling > -100)
{
item->animNumber = LA_STAND_SOLID;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_STOP;
item->currentAnimState = LS_STOP;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
2021-09-10 00:20:59 +03:00
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
}
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > -256 && coll->Middle.Floor < 256)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_back(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 16*/
/*collision: lara_col_back*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (!Lara.isMoving)
{
if ((TrInput & IN_BACK) && ((TrInput & IN_WALK) || Lara.waterStatus == LW_WADE))
item->goalAnimState = LS_WALK_BACK;
else
item->goalAnimState = LS_STOP;
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
}
}
}
2021-02-03 01:50:59 -03:00
void lara_col_back(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 16*/
/*state code: lara_as_back*/
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot + ANGLE(180);
if (Lara.waterStatus == LW_WADE)
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
else
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = STEPUP_HEIGHT;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesArePits = true;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (LaraHitCeiling(item, coll))
return;
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
if (LaraFallen(item, coll))
return;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > STEP_SIZE / 2 && coll->Middle.Floor < STEPUP_HEIGHT)
{
item->goalAnimState = LS_STEP_BACK_DOWN;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
if (TestLaraSlide(item, coll))
return;
#if 0
2021-09-10 00:18:47 +03:00
if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->Middle.Floor < 0)
item->pos.yPos += coll->Middle.Floor;
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->Middle.Floor)
item->pos.yPos += SWAMP_GRAVITY;
#else
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
#endif
}
2021-02-03 01:50:59 -03:00
void lara_as_fastturn(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 20*/
/*collision: lara_col_fastturn*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (Lara.turnRate < 0)
{
Lara.turnRate = -LARA_FAST_TURN;
if (!(TrInput & IN_LEFT))
item->goalAnimState = LS_STOP;
}
else
{
Lara.turnRate = LARA_FAST_TURN;
if (!(TrInput & IN_RIGHT))
item->goalAnimState = LS_STOP;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_fastturn(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 20*/
/*state code: lara_as_fastturn*/
lara_col_stop(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_stepright(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 21*/
/*collision: lara_col_stepright*/
Lara.look = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (!Lara.isMoving)
{
if (!(TrInput & IN_RSTEP))
{
item->goalAnimState = LS_STOP;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
}
}
}
2021-02-03 01:50:59 -03:00
void lara_col_stepright(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 21*/
/*state code: lara_as_stepright*/
if (item->currentAnimState == LS_STEP_RIGHT)
Lara.moveAngle = item->pos.yRot + ANGLE(90);
else
Lara.moveAngle = item->pos.yRot - ANGLE(90);
item->gravityStatus = false;
item->fallspeed = 0;
if (Lara.waterStatus == LW_WADE)
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
else
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = 128;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
coll->Setup.SlopesArePits = true;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightUp = -128;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (!LaraHitCeiling(item, coll))
{
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
2021-09-10 00:18:47 +03:00
if (!LaraFallen(item, coll) && !TestLaraSlide(item, coll) && coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_stepleft(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 22*/
/*collision: lara_col_stepleft*/
Lara.look = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (!Lara.isMoving)
{
if (!(TrInput & IN_LSTEP))
{
item->goalAnimState = LS_STOP;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_SLOW_TURN)
Lara.turnRate = -LARA_SLOW_TURN;
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_SLOW_TURN)
Lara.turnRate = LARA_SLOW_TURN;
}
}
}
2021-02-03 01:50:59 -03:00
void lara_col_stepleft(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 22*/
/*state code: lara_as_stepleft*/
lara_col_stepright(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_col_roll2(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 23*/
/*state code: lara_void_func*/
Camera.laraNode = 0;
Lara.moveAngle = item->pos.yRot + ANGLE(180);
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
item->gravityStatus = false;
item->fallspeed = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (LaraHitCeiling(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor > 200)
{
item->animNumber = LA_FALL_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_FALL_BACK;
item->goalAnimState = LS_FALL_BACK;
item->fallspeed = 0;
item->gravityStatus = true;
return;
}
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
2021-02-03 01:50:59 -03:00
void lara_as_backjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 25*/
/*collision: lara_col_backjump*/
Camera.targetAngle = ANGLE(135.0f);
if (item->fallspeed <= LARA_FREEFALL_SPEED)
{
if (item->goalAnimState == LS_RUN_FORWARD)
{
item->goalAnimState = LS_STOP;
}
else if ((TrInput & IN_FORWARD || TrInput & IN_ROLL) && item->goalAnimState != LS_STOP)
{
item->goalAnimState = LS_JUMP_ROLL_180;
}
}
else
{
item->goalAnimState = LS_FREEFALL;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_backjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 25*/
/*state code: lara_as_backjump*/
Lara.moveAngle = item->pos.yRot + ANGLE(180);
lara_col_jumper(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_rightjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 26*/
/*collision: lara_col_rightjump*/
Lara.look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
else if (TrInput & IN_LEFT && item->goalAnimState != LS_STOP)
item->goalAnimState = LS_JUMP_ROLL_180;
}
2021-02-03 01:50:59 -03:00
void lara_col_rightjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 26*/
/*state code: lara_as_rightjump*/
Lara.moveAngle = item->pos.yRot + ANGLE(90);
lara_col_jumper(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_as_leftjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 27*/
/*collision: lara_col_leftjump*/
Lara.look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
else if (TrInput & IN_RIGHT && item->goalAnimState != LS_STOP)
item->goalAnimState = LS_JUMP_ROLL_180;
}
2021-02-03 01:50:59 -03:00
void lara_col_leftjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 27*/
/*state code: lara_as_leftjump*/
Lara.moveAngle = item->pos.yRot - ANGLE(90);
lara_col_jumper(item, coll);
}
void lara_col_jumper(ITEM_INFO* item, COLL_INFO* coll)
{
/*states 25, 26, 27*/
/*state code: none, but is called in lara_col_backjump, lara_col_rightjump and lara_col_leftjump*/
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
2021-09-10 00:18:47 +03:00
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
item->goalAnimState = LS_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_upjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 28*/
/*collision: lara_col_upjump*/
if (item->fallspeed > LARA_FREEFALL_SPEED)
{
item->goalAnimState = LS_FREEFALL;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_upjump(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 28*/
/*state code: lara_as_upjump*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
Lara.moveAngle = item->pos.yRot;
coll->Setup.Height = LARA_HEIGHT_STRETCH;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = item->speed < 0 ? Lara.moveAngle + ANGLE(180.0f) : Lara.moveAngle;
GetCollisionInfo(coll, item);
2021-09-10 00:18:47 +03:00
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && !coll->HitStatic)
{
2021-09-10 00:18:47 +03:00
if (Lara.canMonkeySwing && coll->CollisionType == CT_TOP)
{
item->goalAnimState = LS_MONKEYSWING_IDLE;
item->currentAnimState = LS_MONKEYSWING_IDLE;
item->animNumber = LA_JUMP_UP_TO_MONKEYSWING;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.gunStatus = LG_HANDS_BUSY;
MonkeySwingSnap(item, coll);
return;
}
2021-09-10 00:18:47 +03:00
if (coll->CollisionType == CT_FRONT && coll->Middle.Ceiling <= -STEPUP_HEIGHT)
{
int edge;
2021-09-14 00:30:44 +03:00
int edgeCatch = TestLaraEdgeCatch(item, coll, &edge);
if (edgeCatch)
{
2021-09-14 00:30:44 +03:00
if (edgeCatch >= 0 || TestLaraHangOnClimbWall(item, coll))
{
short angle = item->pos.yRot;
bool result = SnapToQuadrant(angle, 35);
if (result)
{
BOUNDING_BOX* bounds;
if (TestHangSwingIn(item, angle))
{
item->animNumber = LA_JUMP_UP_TO_MONKEYSWING;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_MONKEYSWING_IDLE;
item->currentAnimState = LS_MONKEYSWING_IDLE;
}
else
{
2021-07-09 19:41:56 -05:00
if (TestHangFeet(item, angle))
{
item->animNumber = LA_REACH_TO_HANG;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 12;
item->currentAnimState = LS_HANG;
item->goalAnimState = LS_HANG_FEET;
}
2021-07-09 19:41:56 -05:00
else
{
item->animNumber = LA_REACH_TO_HANG;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase + 12;
item->currentAnimState = LS_HANG;
item->goalAnimState = LS_HANG;
}
}
bounds = GetBoundsAccurate(item);
if (edgeCatch <= 0)
item->pos.yPos = edge - bounds->Y1 + 4;
else
2021-09-10 00:18:47 +03:00
item->pos.yPos += coll->Front.Floor - bounds->Y1;
Vector2 v = GetOrthogonalIntersect(item->pos.xPos, item->pos.zPos, LARA_RAD, item->pos.yRot);
item->pos.xPos = v.x;
item->pos.zPos = v.y;
item->pos.yRot = angle;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.gunStatus = LG_HANDS_BUSY;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
return;
}
}
}
}
}
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->CollisionType == CT_CLAMP ||
coll->CollisionType == CT_TOP ||
coll->CollisionType == CT_TOP_FRONT)
item->fallspeed = 1;
2021-09-10 00:18:47 +03:00
if (coll->CollisionType == CT_NONE)
{
if (item->fallspeed < -70)
{
if (TrInput & IN_FORWARD && item->speed < 5)
{
item->speed++;
}
else if (TrInput & IN_BACK && item->speed > -5)
{
item->speed -= 2;
}
}
}
else
{
item->speed = item->speed <= 0 ? -2 : 2;
}
2021-09-10 00:18:47 +03:00
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
item->goalAnimState = LaraLandedBad(item, coll) ? LS_DEATH : LS_STOP;
item->gravityStatus = false;
item->fallspeed = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_fallback(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 29*/
/*collision: lara_col_fallback*/
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
if (TrInput & IN_ACTION)
if (Lara.gunStatus == LG_NO_ARMS)
item->goalAnimState = LS_REACH;
}
2021-02-03 01:50:59 -03:00
void lara_col_fallback(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 29*/
/*state code: lara_as_fallback*/
Lara.moveAngle = item->pos.yRot + ANGLE(180);
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
2021-09-10 00:18:47 +03:00
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
item->goalAnimState = LS_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_roll(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 45*/
/*state code: lara_void_func*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesArePits = false;
coll->Setup.SlopesAreWalls = true;
item->gravityStatus = false;
item->fallspeed = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (LaraHitCeiling(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
if (LaraFallen(item, coll))
return;
2021-07-09 19:41:56 -05:00
//##LUA debug etc.
Lara.NewAnims.SwandiveRollRun = 1;
if (TrInput & IN_FORWARD && item->animNumber == LA_SWANDIVE_ROLL && Lara.NewAnims.SwandiveRollRun)
{
item->goalAnimState = LS_RUN_FORWARD;
}
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
2021-02-03 01:50:59 -03:00
void lara_as_swandive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 52*/
/*collision: lara_col_swandive*/
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpaz = false;
if (item->fallspeed > LARA_FREEFALL_SPEED && item->goalAnimState != LS_DIVE)
item->goalAnimState = LS_SWANDIVE_END;
}
2021-02-03 01:50:59 -03:00
void lara_col_swandive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 52*/
/*state code: lara_as_swandive*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
item->goalAnimState = LS_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_fastdive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 53*/
/*collision: lara_col_fastdive*/
if (TrInput & IN_ROLL && item->goalAnimState == LS_SWANDIVE_END)
item->goalAnimState = LS_JUMP_ROLL_180;
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpaz = false;
item->speed = (item->speed * 95) / 100;
}
2021-02-03 01:50:59 -03:00
void lara_col_fastdive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 53*/
/*state code: lara_as_fastdive*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
if (item->fallspeed <= 133)
item->goalAnimState = LS_STOP;
else
item->goalAnimState = LS_DEATH;
item->fallspeed = 0;
item->gravityStatus = 0;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
2021-02-03 01:50:59 -03:00
void lara_as_gymnast(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 54*/
/*collision: lara_default_col*/
2021-09-10 00:20:59 +03:00
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
}
2021-02-03 01:50:59 -03:00
void lara_as_wade(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 65*/
/*collision: lara_col_wade*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
Camera.targetElevation = -ANGLE(22.0f);
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -(LARA_FAST_TURN >> 1))
Lara.turnRate = -(LARA_FAST_TURN >> 1);
if (TestLaraLean(item, coll))
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -(LARA_LEAN_MAX >> 1))
item->pos.zRot = -(LARA_LEAN_MAX >> 1);
2021-07-09 19:41:56 -05:00
}
else
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX * 3 / 5)
item->pos.zRot = -LARA_LEAN_MAX * 3 / 5;
}
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-10-06 11:15:37 -05:00
if (Lara.turnRate > (LARA_FAST_TURN / 2))
Lara.turnRate = (LARA_FAST_TURN / 2);
if (TestLaraLean(item, coll))
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > (LARA_LEAN_MAX >> 1))
item->pos.zRot = (LARA_LEAN_MAX >> 1);
2021-07-09 19:41:56 -05:00
}
else
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX * 3 / 5)
item->pos.zRot = LARA_LEAN_MAX * 3 / 5;
}
}
if (TrInput & IN_FORWARD)
item->goalAnimState = LS_WADE_FORWARD;
else
item->goalAnimState = LS_STOP;
}
else
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_FAST_TURN)
Lara.turnRate = -LARA_FAST_TURN;
if (TestLaraLean(item, coll))
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX)
item->pos.zRot = -LARA_LEAN_MAX;
}
2021-07-09 19:41:56 -05:00
else
{
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX * 3 / 5)
item->pos.zRot = -LARA_LEAN_MAX * 3 / 5;
}
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_FAST_TURN)
Lara.turnRate = LARA_FAST_TURN;
if (TestLaraLean(item, coll))
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX)
item->pos.zRot = LARA_LEAN_MAX;
}
2021-07-09 19:41:56 -05:00
else
{
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX * 3 / 5)
item->pos.zRot = LARA_LEAN_MAX * 3 / 5;
}
}
if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_ABOVE_WATER)
item->goalAnimState = LS_RUN_FORWARD;
else
item->goalAnimState = LS_WADE_FORWARD;
}
else
{
item->goalAnimState = LS_STOP;
}
}
}
void lara_col_wade(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 65*/
/*state code: lara_as_wade*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (LaraHitCeiling(item, coll))
return;
if (TestLaraVault(item, coll))
return;
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
if (!coll->Front.Slope && coll->Front.Floor < -((STEP_SIZE * 5) / 2) && !(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
item->goalAnimState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
return;
}
LaraCollideStop(item, coll);
}
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= -STEPUP_HEIGHT && coll->Middle.Floor < -STEP_SIZE / 2 && !(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
item->goalAnimState = LS_STEP_UP;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= 50 && !(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
item->pos.yPos += 50;
return;
}
2021-09-10 00:18:47 +03:00
if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->Middle.Floor < 0)
item->pos.yPos += coll->Middle.Floor; // Enforce to floor height.. if not a swamp room.
else if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->Middle.Floor)
item->pos.yPos += SWAMP_GRAVITY;
}
2021-02-03 01:50:59 -03:00
void lara_as_dash(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 73*/
/*collision: lara_col_dash*/
if (item->hitPoints <= 0 || !DashTimer || !(TrInput & IN_SPRINT) || Lara.waterStatus == LW_WADE)
{
item->goalAnimState = LS_RUN_FORWARD;
return;
}
DashTimer--;
if (TrInput & IN_DUCK
&& (Lara.gunStatus == LG_NO_ARMS
|| Lara.gunType == WEAPON_NONE
|| Lara.gunType == WEAPON_PISTOLS
|| Lara.gunType == WEAPON_REVOLVER
|| Lara.gunType == WEAPON_UZI
|| Lara.gunType == WEAPON_FLARE))
{
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
item->pos.zRot -= ANGLE(1.5f);
if (item->pos.zRot < -ANGLE(16.0f))
item->pos.zRot = -ANGLE(16.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
item->pos.zRot += ANGLE(1.5f);
if (item->pos.zRot > ANGLE(16.0f))
item->pos.zRot = ANGLE(16.0f);
}
if (!(TrInput & IN_JUMP) || item->gravityStatus)
{
if (TrInput & IN_FORWARD)
{
if (TrInput & IN_WALK)
item->goalAnimState = LS_WALK_FORWARD;
else
item->goalAnimState = LS_SPRINT;
}
else if (!(TrInput & IN_LEFT) && !(TrInput & IN_RIGHT))
{
item->goalAnimState = LS_STOP;
}
}
else
{
item->goalAnimState = LS_SPRINT_ROLL;
}
}
2021-02-03 01:50:59 -03:00
void lara_col_dash(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 73*/
/*state code: lara_as_dash*/
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = 0;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
2021-09-14 00:41:11 +03:00
if (coll->HitTallBounds || TestLaraWall(item, 256, 0, -640))
{
item->goalAnimState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
{
item->currentAnimState = LS_SPLAT;
return;
}
}
LaraCollideStop(item, coll);
}
if (!LaraFallen(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor >= -STEPUP_HEIGHT && coll->Middle.Floor < -STEP_SIZE / 2)
{
item->goalAnimState = LS_STEP_UP;
GetChange(item, &g_Level.Anims[item->animNumber]);
}
if (!TestLaraSlide(item, coll))
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor < 50)
{
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
else
{
item->goalAnimState = LS_STEP_DOWN; // for theoretical sprint stepdown anims, not in default anims
if (GetChange(item, &g_Level.Anims[item->animNumber]))
2021-09-10 00:18:47 +03:00
item->pos.yPos += coll->Middle.Floor; // move Lara to middle.Floor
else
item->pos.yPos += 50; // do the default aligment
}
}
}
}
}
2021-02-03 01:50:59 -03:00
void lara_as_dashdive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 74*/
/*collision: lara_col_dashdive*/
if (item->goalAnimState != LS_DEATH &&
item->goalAnimState != LS_STOP &&
item->goalAnimState != LS_RUN_FORWARD &&
item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
2021-02-03 01:50:59 -03:00
void lara_col_dashdive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 74*/
/*state code: lara_as_dashdive*/
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot + ANGLE(180);
else
Lara.moveAngle = item->pos.yRot;
2021-09-19 17:48:32 +03:00
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
2021-09-10 00:20:59 +03:00
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
2021-09-10 00:20:59 +03:00
coll->Setup.SlopesAreWalls = true;
2021-09-10 00:20:59 +03:00
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (!LaraFallen(item, coll))
{
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot;
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = LS_DEATH;
}
else if (Lara.waterStatus == LW_WADE || !(TrInput & IN_FORWARD) || TrInput & IN_WALK)
{
item->goalAnimState = LS_STOP;
}
else
{
item->goalAnimState = LS_RUN_FORWARD;
}
item->gravityStatus = false;
item->fallspeed = 0;
2021-09-10 00:18:47 +03:00
item->pos.yPos += coll->Middle.Floor;
item->speed = 0;
AnimateLara(item);
}
ShiftItem(item, coll);
2021-09-10 00:18:47 +03:00
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}