2020-08-10 00:21:45 -05:00
# include "framework.h"
# include "lara.h"
# include "input.h"
2021-09-19 18:29:25 +03:00
# include "level.h"
2020-08-10 00:21:45 -05:00
# include "lara_tests.h"
# include "lara_collide.h"
2021-09-16 05:06:03 +03:00
# include "animation.h"
2021-09-19 18:29:25 +03:00
# include "control/los.h"
2021-09-27 18:18:03 +10:00
# 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
2021-09-27 18:18:03 +10:00
// -----------------------------
2021-09-26 20:59:16 +10:00
// CRAWLING & CROUCHING
// Control & Collision Functions
2021-09-27 18:18:03 +10:00
// -----------------------------
2021-09-26 20:59:16 +10:00
2021-10-04 22:46:39 +11:00
// ----------
// CROUCHING:
// ----------
2021-09-26 20:59:16 +10:00
// State: LS_CROUCH_IDLE (71)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crouch_idle()
void lara_as_crouch_idle ( ITEM_INFO * item , COLL_INFO * coll )
2021-09-26 20:59:16 +10:00
{
2021-10-14 01:17:21 +11:00
// TODO: Deplete air meter if Lara's head is below the water. Original implementation had a weird buffer zone before
2021-10-15 18:26:03 +11:00
// wade depth where Lara couldn't crouch at all, and if the player forced her into the crouched state by
2021-10-14 01:17:21 +11:00
// 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
2021-11-13 18:10:22 +11:00
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
2021-09-26 20:59:16 +10:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-09-26 20:59:16 +10:00
if ( item - > hitPoints < = 0 )
{
2021-10-13 19:50:46 +11:00
item - > goalAnimState = LS_DEATH ;
2021-09-26 20:59:16 +10:00
return ;
}
if ( TrInput & IN_LOOK )
LookUpDown ( ) ;
2021-10-30 13:42:55 +11:00
if ( TrInput & IN_LEFT )
2021-11-01 17:57:43 +11:00
Lara . turnRate = - LARA_CRAWL_TURN ;
2021-10-30 13:42:55 +11:00
else if ( TrInput & IN_RIGHT )
2021-11-01 17:57:43 +11:00
Lara . turnRate = LARA_CRAWL_TURN ;
2021-10-14 01:59:55 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched ) & &
2021-10-13 19:50:46 +11:00
Lara . waterStatus ! = LW_WADE )
2021-09-26 20:59:16 +10:00
{
2021-11-01 17:57:43 +11:00
// TODO: LUA
2021-09-26 20:59:16 +10:00
Lara . NewAnims . CrouchRoll = true ;
2021-10-13 19:50:46 +11:00
if ( ( TrInput & IN_SPRINT ) & &
2021-10-16 22:53:29 +11:00
TestLaraCrouchRoll ( item , coll ) & &
2021-11-11 23:31:04 +11:00
Lara . gunStatus = = LG_NO_ARMS & &
2021-10-13 19:50:46 +11:00
Lara . NewAnims . CrouchRoll )
2021-09-26 20:59:16 +10:00
{
item - > goalAnimState = LS_CROUCH_ROLL ;
return ;
}
2021-10-16 20:50:16 +11:00
// 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
2021-11-13 19:41:07 +11:00
if ( TrInput & ( IN_FORWARD | IN_BACK ) & &
2021-10-22 00:07:24 +11:00
TestLaraCrouchToCrawl ( item ) )
2021-09-26 20:59:16 +10:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
2021-10-13 19:50:46 +11:00
if ( TrInput & IN_LEFT )
2021-09-26 20:59:16 +10:00
{
item - > goalAnimState = LS_CROUCH_TURN_LEFT ;
return ;
}
2021-10-13 19:50:46 +11:00
else if ( TrInput & IN_RIGHT )
2021-09-26 20:59:16 +10:00
{
item - > goalAnimState = LS_CROUCH_TURN_RIGHT ;
return ;
}
2021-10-04 22:46:39 +11:00
item - > goalAnimState = LS_CROUCH_IDLE ;
2021-09-26 20:59:16 +10:00
return ;
}
item - > goalAnimState = LS_STOP ;
}
// State: LS_CROUCH_IDLE (71)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crouch_idle()
void lara_col_crouch_idle ( ITEM_INFO * item , COLL_INFO * coll )
2021-09-26 20:59:16 +10:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-11 23:16:02 +11:00
Lara . isDucked = true ;
2021-11-05 17:50:53 +11:00
Lara . moveAngle = item - > pos . yRot ;
2021-09-26 20:59:16 +10:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
coll - > Setup . Height = LARA_HEIGHT_CRAWL ;
coll - > Setup . ForwardAngle = item - > pos . yRot ;
2021-11-12 15:35:16 +11:00
coll - > Setup . BadHeightDown = STEP_SIZE - 1 ;
coll - > Setup . BadHeightUp = - ( STEP_SIZE - 1 ) ;
2021-09-26 20:59:16 +10:00
coll - > Setup . BadCeilingHeight = 0 ;
coll - > Setup . SlopesAreWalls = true ;
GetCollisionInfo ( coll , item ) ;
if ( TestLaraFall ( coll ) )
{
Lara . gunStatus = LG_NO_ARMS ;
SetLaraFallState ( item ) ;
return ;
}
2021-11-05 21:29:00 +11:00
if ( TestLaraSlide ( item , coll ) )
2021-09-26 20:59:16 +10:00
return ;
ShiftItem ( item , coll ) ;
if ( coll - > Middle . Floor ! = NO_HEIGHT )
item - > pos . yPos + = coll - > Middle . Floor ;
}
2021-09-27 18:18:03 +10:00
// State: LS_CROUCH_ROLL (72)
// Collision: lara_as_crouch_roll()
2021-09-26 20:59:16 +10:00
void lara_as_crouch_roll ( ITEM_INFO * item , COLL_INFO * coll )
2021-09-27 18:18:03 +10:00
{
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-09-27 18:18:03 +10:00
2021-10-28 16:13:56 +11:00
if ( TrInput & IN_LEFT )
2021-09-27 18:18:03 +10:00
{
2021-10-13 19:50:46 +11:00
Lara . turnRate = - LARA_CROUCH_ROLL_TURN ;
2021-09-27 18:18:03 +10:00
2021-11-09 17:59:36 +11:00
DoLaraLean ( item , coll , - LARA_LEAN_MAX , 7 ) ;
2021-09-27 18:18:03 +10:00
}
2021-10-28 16:13:56 +11:00
else if ( TrInput & IN_RIGHT )
2021-09-27 18:18:03 +10:00
{
2021-10-13 19:50:46 +11:00
Lara . turnRate = LARA_CROUCH_ROLL_TURN ;
2021-09-27 18:18:03 +10:00
2021-11-09 17:59:36 +11:00
DoLaraLean ( item , coll , LARA_LEAN_MAX , 7 ) ;
2021-09-27 18:18:03 +10:00
}
item - > goalAnimState = LS_CROUCH_IDLE ;
}
// State: LS_CROUCH_ROLL (72)
// Control: lara_as_crouch_roll()
2021-09-26 20:59:16 +10:00
void lara_col_crouch_roll ( ITEM_INFO * item , COLL_INFO * coll )
2021-09-27 18:18:03 +10:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-11 23:16:02 +11:00
Lara . isDucked = true ;
2021-11-05 17:50:53 +11:00
Lara . moveAngle = item - > pos . yRot ;
2021-09-27 18:18:03 +10:00
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 ) ;
2021-09-27 18:18:03 +10:00
coll - > Setup . ForwardAngle = item - > pos . yRot ;
coll - > Setup . BadCeilingHeight = 0 ;
coll - > Setup . SlopesAreWalls = true ;
GetCollisionInfo ( coll , item ) ;
2021-11-02 14:22:58 +11:00
// TODO: With sufficient speed, Lara can still roll off ledges. This is particularly a problem when
2021-11-12 15:35:16 +11:00
// she becomes airborne within a crawlspace as collision handling will push her back very rapidly. @Sezz 2021.11.02
2021-11-12 00:17:29 +11:00
if ( LaraDeflectEdgeCrawl ( item , coll ) )
2021-10-14 01:17:21 +11:00
{
item - > pos . xPos = coll - > Setup . OldPosition . x ;
item - > pos . yPos = coll - > Setup . OldPosition . y ;
item - > pos . zPos = coll - > Setup . OldPosition . z ;
}
2021-09-27 18:18:03 +10:00
if ( TestLaraFall ( coll ) )
{
Lara . gunStatus = LG_NO_ARMS ;
2021-11-12 15:35:16 +11:00
item - > speed / = 3 ; // Truncate speed to prevent flying off.
2021-09-27 18:18:03 +10:00
SetLaraFallState ( item ) ;
return ;
}
2021-11-05 21:29:00 +11:00
if ( TestLaraSlide ( item , coll ) )
2021-09-27 18:18:03 +10:00
return ;
2021-10-14 01:17:21 +11:00
ShiftItem ( item , coll ) ;
if ( TestLaraHitCeiling ( coll ) )
2021-09-27 18:18:03 +10:00
{
2021-10-14 01:17:21 +11:00
SetLaraHitCeiling ( item , coll ) ;
2021-09-27 18:18:03 +10:00
return ;
}
2021-10-14 01:17:21 +11:00
if ( TestLaraStep ( coll ) )
2021-09-27 18:18:03 +10:00
{
2021-10-14 01:17:21 +11:00
DoLaraStep ( item , coll ) ;
2021-09-27 18:18:03 +10:00
return ;
}
2020-08-10 00:21:45 -05:00
}
2021-10-04 22:46:39 +11:00
// State: LS_CROUCH_TURN_LEFT (105)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crouch_turn_left()
void lara_as_crouch_turn_left ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-04 22:46:39 +11:00
{
coll - > Setup . EnableSpaz = false ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-04 22:46:39 +11:00
if ( item - > hitPoints < = 0 )
{
2021-10-13 19:50:46 +11:00
item - > goalAnimState = LS_DEATH ;
2021-10-04 22:46:39 +11:00
return ;
}
if ( TrInput & IN_LOOK )
LookUpDown ( ) ;
2021-11-01 17:57:43 +11:00
Lara . turnRate = - LARA_CRAWL_TURN ;
2021-10-04 22:46:39 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched ) & &
2021-10-13 19:50:46 +11:00
Lara . waterStatus ! = LW_WADE )
2021-10-04 22:46:39 +11:00
{
2021-10-14 01:17:21 +11:00
if ( ( TrInput & IN_SPRINT ) & &
TestLaraCrouchRoll ( item , coll ) & &
Lara . NewAnims . CrouchRoll )
2021-10-04 22:46:39 +11:00
{
item - > goalAnimState = LS_CROUCH_ROLL ;
return ;
}
2021-10-14 01:17:21 +11:00
if ( TrInput & ( IN_FORWARD | IN_BACK ) & &
2021-10-22 00:07:24 +11:00
TestLaraCrouchToCrawl ( item ) )
2021-10-04 22:46:39 +11:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
if ( TrInput & IN_LEFT )
{
item - > goalAnimState = LS_CROUCH_TURN_LEFT ;
return ;
}
item - > goalAnimState = LS_CROUCH_IDLE ;
return ;
}
2021-10-14 17:47:49 +11:00
item - > goalAnimState = LS_STOP ;
2021-10-04 22:46:39 +11:00
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_LEFT (105)
2021-10-30 12:45:52 +11:00
// 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
{
2021-10-30 12:45:52 +11:00
lara_col_crouch_idle ( item , coll ) ;
2021-10-15 01:37:41 +11:00
}
2021-10-04 22:46:39 +11:00
// State: LS_CROUCH_TURN_RIGHT (106)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crouch_turn_right()
void lara_as_crouch_turn_right ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-04 22:46:39 +11:00
{
coll - > Setup . EnableSpaz = false ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-04 22:46:39 +11:00
if ( item - > hitPoints < = 0 )
{
2021-11-12 15:35:16 +11:00
item - > goalAnimState = LS_DEATH ;
2021-10-04 22:46:39 +11:00
return ;
}
if ( TrInput & IN_LOOK )
LookUpDown ( ) ;
2021-11-01 17:57:43 +11:00
Lara . turnRate = LARA_CRAWL_TURN ;
2021-10-04 22:46:39 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched ) & &
2021-10-13 19:50:46 +11:00
Lara . waterStatus ! = LW_WADE )
2021-10-04 22:46:39 +11:00
{
2021-10-14 01:17:21 +11:00
if ( ( TrInput & IN_SPRINT ) & &
TestLaraCrouchRoll ( item , coll ) & &
Lara . NewAnims . CrouchRoll )
2021-10-04 22:46:39 +11:00
{
item - > goalAnimState = LS_CROUCH_ROLL ;
return ;
}
2021-10-14 01:17:21 +11:00
if ( TrInput & ( IN_FORWARD | IN_BACK ) & &
2021-10-22 00:07:24 +11:00
TestLaraCrouchToCrawl ( item ) )
2021-10-04 22:46:39 +11:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
if ( TrInput & IN_RIGHT )
{
item - > goalAnimState = LS_CROUCH_TURN_RIGHT ;
return ;
}
item - > goalAnimState = LS_CROUCH_IDLE ;
return ;
}
2021-10-14 17:47:49 +11:00
item - > goalAnimState = LS_STOP ;
2021-10-04 22:46:39 +11:00
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_RIGHT (106)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crouch_turn_right()
void lara_col_crouch_turn_right ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-04 22:46:39 +11:00
{
2021-10-30 12:45:52 +11:00
lara_col_crouch_idle ( item , coll ) ;
2021-10-04 22:46:39 +11:00
}
// ---------
// CRAWLING:
// ---------
2021-10-16 20:50:16 +11:00
// State: LS_CRAWL_IDLE (80)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crawl_idle()
void lara_as_crawl_idle ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-16 20:50:16 +11:00
{
2021-10-24 13:27:46 +11:00
Lara . gunStatus = LG_HANDS_BUSY ;
2021-10-16 20:50:16 +11:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-16 20:50:16 +11:00
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_DEATH ;
return ;
}
if ( TrInput & IN_LOOK )
LookUpDown ( ) ;
2021-11-01 17:57:43 +11:00
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 ;
2021-10-16 20:50:16 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched ) & &
2021-10-16 20:50:16 +11:00
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.
2021-11-11 23:31:04 +11:00
if ( ( TrInput & IN_SPRINT & & TestLaraCrouchRoll ( item , coll ) ) | |
( ( TrInput & ( IN_DRAW | IN_FLARE ) & &
2021-10-16 20:50:16 +11:00
! IsStandingWeapon ( Lara . gunType ) & & // TODO: From here or from crouch, it needs to be consistent.
2021-11-11 23:31:04 +11:00
TestLaraDrawWeaponsFromCrawlIdle ( item ) ) ) )
2021-10-16 20:50:16 +11:00
{
Lara . gunStatus = LG_NO_ARMS ;
item - > goalAnimState = LS_CROUCH_IDLE ;
return ;
}
2021-10-28 23:22:28 +11:00
if ( TrInput & IN_FORWARD )
2021-10-16 20:50:16 +11:00
{
2021-10-28 15:25:25 +11:00
if ( TrInput & ( IN_ACTION | IN_JUMP ) & &
2021-11-05 22:42:33 +11:00
TestLaraCrawlVault ( item , coll ) & &
Lara . NewAnims . CrawlExtended )
2021-10-16 20:50:16 +11:00
{
DoLaraCrawlVault ( item , coll ) ;
2021-10-22 00:07:24 +11:00
return ;
2021-10-16 20:50:16 +11:00
}
2021-11-08 22:24:49 +11:00
else [[likely]]
2021-10-22 00:07:24 +11:00
{
2021-10-16 20:50:16 +11:00
item - > goalAnimState = LS_CRAWL_FORWARD ;
2021-10-22 00:07:24 +11:00
return ;
}
2021-10-16 20:50:16 +11:00
}
else if ( TrInput & IN_BACK )
{
2021-10-28 15:25:25 +11:00
if ( TrInput & ( IN_ACTION | IN_JUMP ) & &
2021-10-17 22:10:01 +11:00
TestLaraCrawlToHang ( item , coll ) )
{
2021-10-18 15:22:38 +11:00
DoLaraCrawlToHangSnap ( item , coll ) ;
2021-10-17 22:10:01 +11:00
item - > goalAnimState = LS_CRAWL_TO_HANG ;
2021-10-22 00:07:24 +11:00
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-22 00:07:24 +11:00
{
2021-10-17 22:10:01 +11:00
item - > goalAnimState = LS_CRAWL_BACK ;
2021-10-16 20:50:16 +11:00
2021-10-22 00:07:24 +11:00
return ;
}
2021-10-16 20:50:16 +11:00
}
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)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crawl_idle()
void lara_col_crawl_idle ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-16 20:50:16 +11:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-16 20:50:16 +11:00
Lara . isDucked = true ;
2021-11-05 17:50:53 +11:00
Lara . moveAngle = item - > pos . yRot ;
2021-10-28 23:57:49 +11:00
Lara . torsoXrot = 0 ; // TODO: More pleasing reset. @Sezz 2021.10.28
Lara . torsoYrot = 0 ;
2021-10-16 20:50:16 +11:00
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 ) ;
2021-10-16 20:50:16 +11:00
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)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crawl_forward()
void lara_as_crawl_forward ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-04 23:52:23 +11:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-24 13:27:46 +11:00
Lara . gunStatus = LG_HANDS_BUSY ;
2021-10-04 23:52:23 +11:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
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 ; */
}
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched ) & &
2021-10-13 19:50:46 +11:00
Lara . waterStatus ! = LW_WADE )
2021-10-04 23:52:23 +11:00
{
2021-11-11 23:31:04 +11:00
if ( TrInput & IN_SPRINT & & TestLaraCrouchRoll ( item , coll ) )
2021-10-28 15:25:25 +11:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
2021-10-04 23:52:23 +11:00
if ( TrInput & IN_FORWARD )
{
2021-10-28 15:25:25 +11:00
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 ) ;
2021-10-28 23:22:28 +11:00
return ;
2021-10-24 20:43:02 +11:00
}
2021-11-08 22:24:49 +11:00
else [[likely]]
2021-10-28 23:22:28 +11:00
{
2021-10-24 20:43:02 +11:00
item - > goalAnimState = LS_CRAWL_FORWARD ;
2021-10-04 23:52:23 +11:00
2021-10-28 23:22:28 +11:00
return ;
}
2021-10-04 23:52:23 +11:00
}
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
item - > goalAnimState = LS_CRAWL_IDLE ;
}
2021-10-11 23:16:02 +11:00
// State: LS_CRAWL_FORWARD (81)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crawl_forward()
void lara_col_crawl_forward ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-11 23:16:02 +11:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-11 23:16:02 +11:00
Lara . isDucked = true ;
2021-11-05 17:50:53 +11:00
Lara . moveAngle = item - > pos . yRot ;
2021-10-28 23:57:49 +11:00
Lara . torsoXrot = 0 ;
Lara . torsoYrot = 0 ;
2021-10-11 23:16:02 +11:00
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.
2021-11-01 00:18:29 +11:00
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
2021-10-11 23:16:02 +11:00
coll - > Setup . BadCeilingHeight = LARA_HEIGHT_CRAWL ;
coll - > Setup . SlopesArePits = true ;
coll - > Setup . SlopesAreWalls = true ;
coll - > Setup . ForwardAngle = Lara . moveAngle ;
GetCollisionInfo ( coll , item , true ) ;
2021-11-12 00:17:29 +11:00
if ( LaraDeflectEdgeCrawl ( item , coll ) )
2021-11-08 22:24:49 +11:00
LaraCollideStopCrawl ( item , coll ) ;
2021-10-11 23:16:02 +11:00
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 ;
}
2020-09-26 03:28:30 +10:00
}
2020-08-10 00:21:45 -05:00
2021-10-11 23:16:02 +11:00
// State: LS_CRAWL_BACK (86)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crawl_back()
void lara_as_crawl_back ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-05 00:12:22 +11:00
{
2021-10-24 13:27:46 +11:00
Lara . gunStatus = LG_HANDS_BUSY ;
2021-10-05 00:12:22 +11:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-05 00:12:22 +11:00
if ( item - > hitPoints < = 0 )
{
2021-10-06 14:03:12 +11:00
item - > goalAnimState = LS_DEATH ;
2021-10-05 00:12:22 +11:00
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 ;
2021-10-05 00:12:22 +11:00
// 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 ;
2021-10-05 00:12:22 +11:00
/*Lara.headZrot += (LARA_CRAWL_FLEX - Lara.headZrot) / 12;
Lara . torsoZrot = Lara . headZrot ; */
}
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched )
2021-10-05 00:12:22 +11:00
& & Lara . waterStatus ! = LW_WADE )
{
if ( TrInput & IN_BACK )
{
2021-10-18 15:22:38 +11:00
// TODO: Not quite working.
2021-11-13 17:34:24 +11:00
/*if (TrInput & (IN_ACTION | IN_JUMP) &&
2021-10-18 15:22:38 +11:00
TestLaraCrawlToHang ( item , coll ) )
{
DoLaraCrawlToHangSnap ( item , coll ) ;
item - > goalAnimState = LS_CRAWL_TO_HANG ;
2021-11-06 19:35:48 +11:00
return ;
2021-10-18 15:22:38 +11:00
}
2021-11-13 17:34:24 +11:00
else [[likely]] */
2021-11-06 19:35:48 +11:00
{
2021-10-18 15:22:38 +11:00
item - > goalAnimState = LS_CRAWL_BACK ;
2021-10-05 00:12:22 +11:00
2021-11-06 19:35:48 +11:00
return ;
}
2021-10-05 00:12:22 +11:00
}
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
item - > goalAnimState = LS_CRAWL_IDLE ;
}
2021-10-11 23:16:02 +11:00
// State: LS_CRAWL_BACK (86)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crawl_back()
void lara_col_crawl_back ( ITEM_INFO * item , COLL_INFO * coll )
2020-09-26 05:06:08 +10:00
{
2021-11-13 18:10:22 +11:00
Lara . keepCrouched = TestLaraKeepCrouched ( item , coll ) ;
2021-10-11 23:16:02 +11:00
Lara . isDucked = true ;
2021-11-05 17:50:53 +11:00
Lara . moveAngle = item - > pos . yRot + ANGLE ( 180.0f ) ;
2021-10-11 23:16:02 +11:00
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.
2021-10-11 23:16:02 +11:00
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 ) ;
2021-11-12 00:17:29 +11:00
if ( LaraDeflectEdgeCrawl ( item , coll ) )
2021-11-08 22:24:49 +11:00
LaraCollideStopCrawl ( item , coll ) ;
2020-08-10 00:21:45 -05:00
2021-10-11 23:16:02 +11:00
if ( TestLaraFall ( coll ) )
{
Lara . gunStatus = LG_NO_ARMS ;
SetLaraFallState ( item ) ;
2020-08-10 00:21:45 -05:00
2021-10-11 23:16:02 +11:00
return ;
}
2020-08-10 00:21:45 -05:00
2021-10-11 23:16:02 +11:00
if ( TestLaraSlide ( item , coll ) )
return ;
ShiftItem ( item , coll ) ;
if ( TestLaraStep ( coll ) )
2020-08-10 00:21:45 -05:00
{
2021-10-11 23:16:02 +11:00
DoLaraStep ( item , coll ) ;
return ;
2020-08-10 00:21:45 -05:00
}
}
2021-10-05 15:53:21 +11:00
2021-10-05 17:33:32 +11:00
// State: LS_CRAWL_TURN_LEFT (84)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crawl_turn_left()
void lara_as_crawl_turn_left ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-05 17:33:32 +11:00
{
2021-10-24 13:27:46 +11:00
Lara . gunStatus = LG_HANDS_BUSY ;
2021-10-05 17:33:32 +11:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-05 17:33:32 +11:00
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_DEATH ;
return ;
}
2021-11-01 17:57:43 +11:00
Lara . turnRate = - LARA_CRAWL_TURN ;
2021-10-05 17:33:32 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched )
2021-10-05 17:33:32 +11:00
& & Lara . waterStatus ! = LW_WADE )
{
2021-11-11 23:31:04 +11:00
if ( TrInput & IN_SPRINT & & TestLaraCrouchRoll ( item , coll ) )
2021-10-28 15:25:25 +11:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
2021-10-22 00:07:24 +11:00
if ( TrInput & IN_FORWARD & &
coll - > CollisionType ! = CT_FRONT & &
2021-10-28 15:25:25 +11:00
coll - > CollisionType ! = CT_TOP_FRONT & &
TestLaraCrawlForward ( item , coll ) )
2021-10-05 17:33:32 +11:00
{
2021-10-28 15:25:25 +11:00
item - > goalAnimState = LS_CRAWL_FORWARD ;
2021-10-05 17:33:32 +11:00
2021-10-28 15:25:25 +11:00
return ;
2021-10-05 17:33:32 +11:00
}
2021-10-22 00:07:24 +11:00
if ( TrInput & IN_BACK & &
2021-10-24 20:43:02 +11:00
TestLaraCrawlBack ( item , coll ) )
2021-10-05 17:33:32 +11:00
{
item - > goalAnimState = LS_CRAWL_BACK ;
return ;
}
if ( TrInput & IN_LEFT )
{
item - > goalAnimState = LS_CRAWL_TURN_LEFT ;
return ;
}
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
2021-11-01 17:57:43 +11:00
item - > goalAnimState = LS_CRAWL_IDLE ;
2021-10-05 17:33:32 +11:00
}
2021-10-15 01:37:41 +11:00
// State: LS_CRAWL_TURN_LEFT (84)
2021-10-30 12:45:52 +11:00
// 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
{
2021-10-30 12:45:52 +11:00
lara_col_crawl_idle ( item , coll ) ;
2021-10-15 01:37:41 +11:00
}
2021-10-05 17:33:32 +11:00
// State: LS_CRAWL_TURN_RIGHT (85)
2021-10-30 12:45:52 +11:00
// Collision: lara_col_crawl_turn_right()
void lara_as_crawl_turn_right ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-05 17:33:32 +11:00
{
2021-10-24 13:27:46 +11:00
Lara . gunStatus = LG_HANDS_BUSY ;
2021-10-05 17:33:32 +11:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = true ;
2021-11-08 22:24:49 +11:00
Camera . targetElevation = - ANGLE ( 24.0f ) ;
2021-10-05 17:33:32 +11:00
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_DEATH ;
return ;
}
2021-11-01 17:57:43 +11:00
Lara . turnRate = LARA_CRAWL_TURN ;
2021-10-05 17:33:32 +11:00
2021-11-13 18:10:22 +11:00
if ( ( TrInput & IN_DUCK | | Lara . keepCrouched )
2021-10-05 17:33:32 +11:00
& & Lara . waterStatus ! = LW_WADE )
{
2021-11-11 23:31:04 +11:00
if ( TrInput & IN_SPRINT & & TestLaraCrouchRoll ( item , coll ) )
2021-10-28 15:25:25 +11:00
{
item - > goalAnimState = LS_CRAWL_IDLE ;
return ;
}
2021-10-22 00:07:24 +11:00
if ( TrInput & IN_FORWARD & &
coll - > CollisionType ! = CT_FRONT & &
2021-10-28 15:25:25 +11:00
coll - > CollisionType ! = CT_TOP_FRONT & &
TestLaraCrawlForward ( item , coll ) )
2021-10-05 17:33:32 +11:00
{
2021-10-28 15:25:25 +11:00
item - > goalAnimState = LS_CRAWL_FORWARD ;
2021-10-05 17:33:32 +11:00
2021-10-28 15:25:25 +11:00
return ;
2021-10-05 17:33:32 +11:00
}
2021-10-22 00:07:24 +11:00
if ( TrInput & IN_BACK & &
2021-10-24 20:43:02 +11:00
TestLaraCrawlBack ( item , coll ) )
2021-10-05 17:33:32 +11:00
{
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)
2021-10-30 12:45:52 +11:00
// Control: lara_as_crawl_turn_right()
void lara_col_crawl_turn_right ( ITEM_INFO * item , COLL_INFO * coll )
2021-10-11 23:16:02 +11:00
{
2021-10-30 12:45:52 +11:00
lara_col_crawl_idle ( item , coll ) ;
2021-10-11 23:16:02 +11:00
}
2021-02-03 01:50:59 -03:00
void lara_col_crawl2hang ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-11 03:55:34 -05:00
{
Camera . targetAngle = 0 ;
Camera . targetElevation = - ANGLE ( 45.0f ) ;
2021-09-10 00:20:59 +03:00
coll - > Setup . EnableSpaz = false ;
coll - > Setup . EnableObjectPush = false ;
2020-08-11 03:55:34 -05:00
if ( item - > animNumber = = LA_CRAWL_TO_HANG_END )
{
2021-09-19 06:42:24 +03:00
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 ;
2021-09-19 06:42:24 +03:00
coll - > Setup . ForwardAngle = Lara . moveAngle ;
2020-09-26 05:06:08 +10:00
2020-12-19 23:34:52 -03:00
Lara . moveAngle = item - > pos . yRot ;
2020-08-11 03:55:34 -05:00
2021-10-26 18:05:16 +03:00
MoveItem ( item , item - > pos . yRot , - STEP_SIZE ) ;
2021-09-19 06:42:24 +03:00
GetCollisionInfo ( coll , item ) ;
2021-10-26 18:05:16 +03:00
SnapItemToLedge ( item , coll ) ;
2020-09-26 05:06:08 +10:00
2021-10-26 18:05:16 +03:00
if ( TestHangSwingIn ( item , item - > pos . yRot ) )
2020-08-11 03:55:34 -05:00
{
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 ;
}
2020-08-11 03:55:34 -05:00
2021-10-26 18:05:16 +03:00
GetCollisionInfo ( coll , item ) ;
item - > pos . yPos + = coll - > Front . Floor - GetBoundsAccurate ( item ) - > Y1 - 20 ;
2020-08-11 03:55:34 -05:00
2021-10-26 18:05:16 +03:00
item - > gravityStatus = true ;
item - > speed = 2 ;
item - > fallspeed = 1 ;
2020-08-11 03:55:34 -05:00
2021-10-26 18:05:16 +03:00
Lara . gunStatus = LG_HANDS_BUSY ;
2020-08-11 03:55:34 -05:00
}
}