TombEngine/TR5Main/Game/Lara/lara_crawl.cpp

901 lines
19 KiB
C++
Raw Normal View History

#include "framework.h"
#include "lara.h"
#include "input.h"
2021-09-19 18:29:25 +03:00
#include "level.h"
#include "lara_tests.h"
#include "lara_collide.h"
#include "animation.h"
2021-09-19 18:29:25 +03:00
#include "control/los.h"
#include "lara_flare.h"
#include "lara_helpers.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-19 23:41:26 +03:00
#include "control/control.h"
2021-09-19 18:29:25 +03:00
// -----------------------------
// CRAWLING & CROUCHING
// Control & Collision Functions
// -----------------------------
// ----------
// CROUCHING:
// ----------
// State: LS_CROUCH_IDLE (71)
// Collision: lara_col_crouch_idle()
void lara_as_crouch_idle(ITEM_INFO* item, COLL_INFO* coll)
{
// TODO: Deplete air meter if Lara's head is below the water. Original implementation had a weird buffer zone before
// wade depth where Lara couldn't crouch at all, and if the player forced her into the crouched state by
// crouching into the region from a run as late as possible, she wasn't able to turn or begin crawling.
// Since Lara can now crawl at a considerable depth, a region of peril would make sense. @Sezz 2021.13.21
Lara.keepCrouched = TestLaraKeepCrouched(item, coll); // TODO: This MUST be true on the first frame that Lara climbs up into a crawlspace. @Sezz 2021.10.14
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
if (TrInput & IN_LEFT)
Lara.turnRate = -LARA_CRAWL_TURN;
else if (TrInput & IN_RIGHT)
Lara.turnRate = LARA_CRAWL_TURN;
if ((TrInput & IN_DUCK || Lara.keepCrouched) &&
Lara.waterStatus != LW_WADE)
{
// TODO: LUA
Lara.NewAnims.CrouchRoll = true;
if ((TrInput & IN_SPRINT) &&
TestLaraCrouchRoll(item, coll) &&
Lara.gunStatus == LG_NO_ARMS &&
Lara.NewAnims.CrouchRoll)
{
item->goalAnimState = LS_CROUCH_ROLL;
return;
}
// TODO: This will lock Lara if the dispatch can't happen.
// Maybe rejoining that split animation wasn't such a good idea... @Sezz 2021.10.16
if (TrInput & (IN_FORWARD | IN_BACK) &&
TestLaraCrouchToCrawl(item))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_CROUCH_TURN_LEFT;
return;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_CROUCH_TURN_RIGHT;
return;
}
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
item->goalAnimState = LS_STOP;
}
// State: LS_CROUCH_IDLE (71)
// Control: lara_as_crouch_idle()
void lara_col_crouch_idle(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.isDucked = true;
Lara.moveAngle = item->pos.yRot;
item->gravityStatus = false;
item->fallspeed = 0;
coll->Setup.Height = LARA_HEIGHT_CRAWL;
coll->Setup.ForwardAngle = item->pos.yRot;
coll->Setup.BadHeightDown = STEP_SIZE - 1;
coll->Setup.BadHeightUp = -(STEP_SIZE - 1);
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
GetCollisionInfo(coll, item);
if (TestLaraFall(coll))
{
Lara.gunStatus = LG_NO_ARMS;
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
// State: LS_CROUCH_ROLL (72)
// Collision: lara_as_crouch_roll()
void lara_as_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
{
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (TrInput & IN_LEFT)
{
Lara.turnRate = -LARA_CROUCH_ROLL_TURN;
2021-11-09 17:59:36 +11:00
DoLaraLean(item, coll, -LARA_LEAN_MAX, 7);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate = LARA_CROUCH_ROLL_TURN;
2021-11-09 17:59:36 +11:00
DoLaraLean(item, coll, LARA_LEAN_MAX, 7);
}
item->goalAnimState = LS_CROUCH_IDLE;
}
// State: LS_CROUCH_ROLL (72)
// Control: lara_as_crouch_roll()
void lara_col_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.isDucked = true;
Lara.moveAngle = item->pos.yRot;
item->gravityStatus = 0;
item->fallspeed = 0;
coll->Setup.Height = LARA_HEIGHT_CRAWL;
2021-10-18 20:15:53 +11:00
coll->Setup.BadHeightDown = STEP_SIZE - 1;
coll->Setup.BadHeightUp = -(STEP_SIZE - 1);
coll->Setup.ForwardAngle = item->pos.yRot;
coll->Setup.BadCeilingHeight = 0;
coll->Setup.SlopesAreWalls = true;
GetCollisionInfo(coll, item);
// TODO: With sufficient speed, Lara can still roll off ledges. This is particularly a problem when
// she becomes airborne within a crawlspace as collision handling will push her back very rapidly. @Sezz 2021.11.02
if (LaraDeflectEdgeCrawl(item, coll))
{
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
}
if (TestLaraFall(coll))
{
Lara.gunStatus = LG_NO_ARMS;
item->speed /= 3; // Truncate speed to prevent flying off.
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
if (TestLaraHitCeiling(coll))
{
SetLaraHitCeiling(item, coll);
return;
}
if (TestLaraStep(coll))
{
DoLaraStep(item, coll);
return;
}
}
// State: LS_CROUCH_TURN_LEFT (105)
// Collision: lara_col_crouch_turn_left()
void lara_as_crouch_turn_left(ITEM_INFO* item, COLL_INFO* coll)
{
coll->Setup.EnableSpaz = false;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
Lara.turnRate = -LARA_CRAWL_TURN;
if ((TrInput & IN_DUCK || Lara.keepCrouched) &&
Lara.waterStatus != LW_WADE)
{
if ((TrInput & IN_SPRINT) &&
TestLaraCrouchRoll(item, coll) &&
Lara.NewAnims.CrouchRoll)
{
item->goalAnimState = LS_CROUCH_ROLL;
return;
}
if (TrInput & (IN_FORWARD | IN_BACK) &&
TestLaraCrouchToCrawl(item))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_CROUCH_TURN_LEFT;
return;
}
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
item->goalAnimState = LS_STOP;
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_LEFT (105)
// Control: lara_as_crouch_turn_left()
void lara_col_crouch_turn_left(ITEM_INFO* item, COLL_INFO* coll)
2021-10-15 01:37:41 +11:00
{
lara_col_crouch_idle(item, coll);
2021-10-15 01:37:41 +11:00
}
// State: LS_CROUCH_TURN_RIGHT (106)
// Collision: lara_col_crouch_turn_right()
void lara_as_crouch_turn_right(ITEM_INFO* item, COLL_INFO* coll)
{
coll->Setup.EnableSpaz = false;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
Lara.turnRate = LARA_CRAWL_TURN;
if ((TrInput & IN_DUCK || Lara.keepCrouched) &&
Lara.waterStatus != LW_WADE)
{
if ((TrInput & IN_SPRINT) &&
TestLaraCrouchRoll(item, coll) &&
Lara.NewAnims.CrouchRoll)
{
item->goalAnimState = LS_CROUCH_ROLL;
return;
}
if (TrInput & (IN_FORWARD | IN_BACK) &&
TestLaraCrouchToCrawl(item))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_CROUCH_TURN_RIGHT;
return;
}
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
item->goalAnimState = LS_STOP;
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_RIGHT (106)
// Control: lara_as_crouch_turn_right()
void lara_col_crouch_turn_right(ITEM_INFO* item, COLL_INFO* coll)
{
lara_col_crouch_idle(item, coll);
}
// ---------
// CRAWLING:
// ---------
// State: LS_CRAWL_IDLE (80)
// Collision: lara_col_crawl_idle()
void lara_as_crawl_idle(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.gunStatus = LG_HANDS_BUSY;
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
if (TrInput & IN_LEFT)
Lara.turnRate = -LARA_CRAWL_TURN;
else if (TrInput & IN_RIGHT)
Lara.turnRate = LARA_CRAWL_TURN;
// TODO: LUA
2021-11-05 22:42:33 +11:00
Lara.NewAnims.CrawlExtended = true;
if ((TrInput & IN_DUCK || Lara.keepCrouched) &&
Lara.waterStatus != LW_WADE)
{
// TODO: Not all weapons are classified as standing weapons??
// TODO: Allow standing vault up 2 steps when spawning flare while standing. @Sezz 2021.10.16
// TODO: Flare not working.
if ((TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) ||
((TrInput & (IN_DRAW | IN_FLARE) &&
!IsStandingWeapon(Lara.gunType) && // TODO: From here or from crouch, it needs to be consistent.
TestLaraDrawWeaponsFromCrawlIdle(item))))
{
Lara.gunStatus = LG_NO_ARMS;
item->goalAnimState = LS_CROUCH_IDLE;
return;
}
if (TrInput & IN_FORWARD)
{
if (TrInput & (IN_ACTION | IN_JUMP) &&
2021-11-05 22:42:33 +11:00
TestLaraCrawlVault(item, coll) &&
Lara.NewAnims.CrawlExtended)
{
DoLaraCrawlVault(item, coll);
return;
}
else [[likely]]
{
item->goalAnimState = LS_CRAWL_FORWARD;
return;
}
}
else if (TrInput & IN_BACK)
{
if (TrInput & (IN_ACTION | IN_JUMP) &&
2021-10-17 22:10:01 +11:00
TestLaraCrawlToHang(item, coll))
{
DoLaraCrawlToHangSnap(item, coll);
2021-10-17 22:10:01 +11:00
item->goalAnimState = LS_CRAWL_TO_HANG;
return;
2021-10-17 22:10:01 +11:00
}
2021-10-24 20:43:02 +11:00
else if (TestLaraCrawlBack(item, coll)) [[likely]]
{
2021-10-17 22:10:01 +11:00
item->goalAnimState = LS_CRAWL_BACK;
return;
}
}
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_CRAWL_TURN_LEFT;
return;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_CRAWL_TURN_RIGHT;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
Lara.gunStatus = LG_NO_ARMS;
item->goalAnimState = LS_CROUCH_IDLE;
}
// State: LS_CRAWL_IDLE (80)
// Control: lara_as_crawl_idle()
void lara_col_crawl_idle(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.isDucked = true;
Lara.moveAngle = item->pos.yRot;
Lara.torsoXrot = 0; // TODO: More pleasing reset. @Sezz 2021.10.28
Lara.torsoYrot = 0;
item->fallspeed = 0;
item->gravityStatus = false;
coll->Setup.ForwardAngle = Lara.moveAngle;
coll->Setup.Radius = LARA_RAD_CRAWL;
coll->Setup.Height = LARA_HEIGHT_CRAWL;
coll->Setup.BadHeightDown = STEP_SIZE - 1;
2021-10-18 20:15:53 +11:00
coll->Setup.BadHeightUp = -(STEP_SIZE - 1);
coll->Setup.BadCeilingHeight = LARA_HEIGHT_CRAWL;
coll->Setup.SlopesAreWalls = true;
coll->Setup.SlopesArePits = true;
GetCollisionInfo(coll, item);
if (TestLaraFall(coll))
{
Lara.gunStatus = LG_NO_ARMS;
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
if (coll->Middle.Floor != NO_HEIGHT && coll->Middle.Floor > -256)
item->pos.yPos += coll->Middle.Floor;
}
2021-10-04 23:52:23 +11:00
// State: LS_CRAWL_FORWARD (81)
// Collision: lara_col_crawl_forward()
void lara_as_crawl_forward(ITEM_INFO* item, COLL_INFO* coll)
2021-10-04 23:52:23 +11:00
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.gunStatus = LG_HANDS_BUSY;
2021-10-04 23:52:23 +11:00
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
2021-10-04 23:52:23 +11:00
if (item->hitPoints <= 0)
{
2021-10-18 20:15:53 +11:00
item->goalAnimState = LS_DEATH;
2021-10-04 23:52:23 +11:00
return;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_SLOW_TURN)
Lara.turnRate = -LARA_SLOW_TURN;
// TODO: Flexing.
/*Lara.headZrot -= (Lara.headZrot + LARA_CRAWL_FLEX) / 12;
Lara.torsoZrot = Lara.headZrot;*/
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_SLOW_TURN)
Lara.turnRate = LARA_SLOW_TURN;
/*Lara.headZrot += (LARA_CRAWL_FLEX - Lara.headZrot) / 12;
Lara.torsoZrot = Lara.headZrot;*/
}
if ((TrInput & IN_DUCK || Lara.keepCrouched) &&
Lara.waterStatus != LW_WADE)
2021-10-04 23:52:23 +11:00
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
2021-10-04 23:52:23 +11:00
if (TrInput & IN_FORWARD)
{
if (TrInput & (IN_ACTION | IN_JUMP) &&
2021-11-05 22:42:33 +11:00
TestLaraCrawlVault(item, coll) &&
Lara.NewAnims.CrawlExtended)
2021-10-24 20:43:02 +11:00
{
DoLaraCrawlVault(item, coll);
return;
2021-10-24 20:43:02 +11:00
}
else [[likely]]
{
2021-10-24 20:43:02 +11:00
item->goalAnimState = LS_CRAWL_FORWARD;
2021-10-04 23:52:23 +11:00
return;
}
2021-10-04 23:52:23 +11:00
}
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
}
// State: LS_CRAWL_FORWARD (81)
// Control: lara_as_crawl_forward()
void lara_col_crawl_forward(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.isDucked = true;
Lara.moveAngle = item->pos.yRot;
Lara.torsoXrot = 0;
Lara.torsoYrot = 0;
item->gravityStatus = false;
item->fallspeed = 0;
coll->Setup.Radius = LARA_RAD_CRAWL;
coll->Setup.Height = LARA_HEIGHT_CRAWL;
2021-10-18 20:15:53 +11:00
coll->Setup.BadHeightDown = STEP_SIZE - 1; // Offset of 1 is required or Lara will crawl up/down steps.
coll->Setup.BadHeightUp = -(STEP_SIZE - 1); // TODO: Stepping approach is different from walk/run because new anims do not submerge Lara. Resolve this. @Sezz 2021.10.31
coll->Setup.BadCeilingHeight = LARA_HEIGHT_CRAWL;
coll->Setup.SlopesArePits = true;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item, true);
if (LaraDeflectEdgeCrawl(item, coll))
LaraCollideStopCrawl(item, coll);
if (TestLaraFall(coll))
{
Lara.gunStatus = LG_NO_ARMS;
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
if (TestLaraStep(coll))
{
DoLaraStep(item, coll);
return;
}
}
// State: LS_CRAWL_BACK (86)
// Collision: lara_col_crawl_back()
void lara_as_crawl_back(ITEM_INFO* item, COLL_INFO* coll)
{
2021-11-14 19:02:28 +11:00
Lara.look = false;
Lara.gunStatus = LG_HANDS_BUSY;
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
if (TrInput & IN_LEFT)
{
2021-10-05 18:03:37 +11:00
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_SLOW_TURN)
Lara.turnRate = -LARA_SLOW_TURN;
// TODO: Flexing.
/*Lara.headZrot -= (Lara.headZrot + LARA_CRAWL_FLEX) / 12;
Lara.torsoZrot = Lara.headZrot;*/
}
else if (TrInput & IN_RIGHT)
{
2021-10-05 18:03:37 +11:00
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_SLOW_TURN)
Lara.turnRate = LARA_SLOW_TURN;
/*Lara.headZrot += (LARA_CRAWL_FLEX - Lara.headZrot) / 12;
Lara.torsoZrot = Lara.headZrot;*/
}
if ((TrInput & IN_DUCK || Lara.keepCrouched)
&& Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_BACK)
{
// TODO: Not quite working.
/*if (TrInput & (IN_ACTION | IN_JUMP) &&
TestLaraCrawlToHang(item, coll))
{
DoLaraCrawlToHangSnap(item, coll);
item->goalAnimState = LS_CRAWL_TO_HANG;
2021-11-06 19:35:48 +11:00
return;
}
else [[likely]]*/
2021-11-06 19:35:48 +11:00
{
item->goalAnimState = LS_CRAWL_BACK;
2021-11-06 19:35:48 +11:00
return;
}
}
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
}
// State: LS_CRAWL_BACK (86)
// Control: lara_as_crawl_back()
void lara_col_crawl_back(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.keepCrouched = TestLaraKeepCrouched(item, coll);
Lara.isDucked = true;
Lara.moveAngle = item->pos.yRot + ANGLE(180.0f);
item->gravityStatus = false;
item->fallspeed = 0;
coll->Setup.Radius = LARA_RAD_CRAWL;
coll->Setup.Height = LARA_HEIGHT_CRAWL;
2021-10-18 20:15:53 +11:00
coll->Setup.BadHeightDown = STEP_SIZE - 1; // Offset of 1 is required or Lara will crawl up/down steps.
coll->Setup.BadHeightUp = -(STEP_SIZE - 1);
coll->Setup.BadCeilingHeight = LARA_HEIGHT_CRAWL;
coll->Setup.SlopesArePits = true;
coll->Setup.SlopesAreWalls = true;
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item, true);
if (LaraDeflectEdgeCrawl(item, coll))
LaraCollideStopCrawl(item, coll);
if (TestLaraFall(coll))
{
Lara.gunStatus = LG_NO_ARMS;
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
if (TestLaraStep(coll))
{
DoLaraStep(item, coll);
return;
}
}
// State: LS_CRAWL_TURN_LEFT (84)
// Collision: lara_col_crawl_turn_left()
void lara_as_crawl_turn_left(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.gunStatus = LG_HANDS_BUSY;
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
Lara.turnRate = -LARA_CRAWL_TURN;
if ((TrInput & IN_DUCK || Lara.keepCrouched)
&& Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
if (TrInput & IN_FORWARD &&
coll->CollisionType != CT_FRONT &&
coll->CollisionType != CT_TOP_FRONT &&
TestLaraCrawlForward(item, coll))
{
item->goalAnimState = LS_CRAWL_FORWARD;
return;
}
if (TrInput & IN_BACK &&
2021-10-24 20:43:02 +11:00
TestLaraCrawlBack(item, coll))
{
item->goalAnimState = LS_CRAWL_BACK;
return;
}
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_CRAWL_TURN_LEFT;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_LEFT (84)
// Control: lara_as_crawl_turn_left()
void lara_col_crawl_turn_left(ITEM_INFO* item, COLL_INFO* coll)
2021-10-15 01:37:41 +11:00
{
lara_col_crawl_idle(item, coll);
2021-10-15 01:37:41 +11:00
}
// State: LS_CRAWL_TURN_RIGHT (85)
// Collision: lara_col_crawl_turn_right()
void lara_as_crawl_turn_right(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.gunStatus = LG_HANDS_BUSY;
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = true;
Camera.targetElevation = -ANGLE(24.0f);
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}
Lara.turnRate = LARA_CRAWL_TURN;
if ((TrInput & IN_DUCK || Lara.keepCrouched)
&& Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll))
{
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
if (TrInput & IN_FORWARD &&
coll->CollisionType != CT_FRONT &&
coll->CollisionType != CT_TOP_FRONT &&
TestLaraCrawlForward(item, coll))
{
item->goalAnimState = LS_CRAWL_FORWARD;
return;
}
if (TrInput & IN_BACK &&
2021-10-24 20:43:02 +11:00
TestLaraCrawlBack(item, coll))
{
item->goalAnimState = LS_CRAWL_BACK;
return;
}
if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_CRAWL_TURN_RIGHT;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
return;
}
item->goalAnimState = LS_CRAWL_IDLE;
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_RIGHT (85)
// Control: lara_as_crawl_turn_right()
void lara_col_crawl_turn_right(ITEM_INFO* item, COLL_INFO* coll)
{
lara_col_crawl_idle(item, coll);
}
2021-02-03 01:50:59 -03:00
void lara_col_crawl2hang(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
2021-09-10 00:20:59 +03:00
coll->Setup.EnableSpaz = false;
coll->Setup.EnableObjectPush = false;
if (item->animNumber == LA_CRAWL_TO_HANG_END)
{
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 = Lara.moveAngle;
Lara.moveAngle = item->pos.yRot;
2021-10-26 18:05:16 +03:00
MoveItem(item, item->pos.yRot, -STEP_SIZE);
GetCollisionInfo(coll, item);
2021-10-26 18:05:16 +03:00
SnapItemToLedge(item, coll);
2021-10-26 18:05:16 +03:00
if (TestHangSwingIn(item, item->pos.yRot))
{
2021-10-26 18:05:16 +03:00
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2021-11-11 01:02:50 +11:00
SetAnimation(item, LA_JUMP_UP_TO_MONKEYSWING);
2021-10-26 18:05:16 +03:00
}
else
{
2021-11-11 01:02:50 +11:00
SetAnimation(item, LA_REACH_TO_HANG, 12);
2021-11-06 19:35:48 +11:00
2021-10-26 18:05:16 +03:00
if (TestHangFeet(item, item->pos.yRot))
item->goalAnimState = LS_HANG_FEET;
}
2021-10-26 18:05:16 +03:00
GetCollisionInfo(coll, item);
item->pos.yPos += coll->Front.Floor - GetBoundsAccurate(item)->Y1 - 20;
2021-10-26 18:05:16 +03:00
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
2021-10-26 18:05:16 +03:00
Lara.gunStatus = LG_HANDS_BUSY;
}
}