2020-08-14 17:54:25 -05:00
# 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"
# include "health.h"
# include "sound.h"
# include "draw.h"
# include "pickup.h"
2020-09-26 03:28:30 +10:00
bool EnableBackKeyTurn = false ;
bool EnableJump = false ;
// BASIC MOVEMENT
// ------------------------------
// Auxiliary Functions
// ------------------------------
bool TestLaraStepDown ( COLL_INFO * coll )
{
if ( coll - > midFloor < = STEPUP_HEIGHT & &
coll - > midFloor > STEP_SIZE / 2 )
{
return true ;
}
return false ;
}
bool TestLaraStepUp ( COLL_INFO * coll )
{
if ( coll - > frontFloor > = - STEPUP_HEIGHT & &
coll - > frontFloor < - STEP_SIZE / 2 )
{
return true ;
}
return false ;
}
// TODO: Some states can't use this function yet due to missing step up/down anims.
void DoLaraStep ( ITEM_INFO * item , COLL_INFO * coll )
{
if ( TestLaraStepDown ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_DOWN ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else if ( TestLaraStepUp ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_UP ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
item - > pos . yPos + = coll - > midFloor ;
}
}
// ------------------------------
// GENERAL
// Control & Collision Functions
// ------------------------------
2020-08-14 17:54:25 -05:00
void lara_void_func ( ITEM_INFO * item , COLL_INFO * coll ) //19928(<), 19A5C(<) (F)
{
return ;
}
void lara_default_col ( ITEM_INFO * item , COLL_INFO * coll ) //1C80C(<), 1C940(<) (F)
{
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > badPos = 384 ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesArePits = true ;
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
}
void lara_as_special ( ITEM_INFO * item , COLL_INFO * coll ) //1ADDC(<), 1AF10(<) (F)
{
Camera . flags = CF_FOLLOW_CENTER ;
Camera . targetAngle = ANGLE ( 170.0f ) ;
2020-09-26 03:28:30 +10:00
Camera . targetElevation = ANGLE ( - 25.0f ) ;
2020-08-14 17:54:25 -05:00
}
void lara_as_null ( ITEM_INFO * item , COLL_INFO * coll ) //1A5DC(<), 1A710(<) (F)
{
coll - > enableBaddiePush = false ;
coll - > enableSpaz = false ;
}
void lara_as_controlled ( ITEM_INFO * item , COLL_INFO * coll ) //1B0FC(<), 1B230(<) (F)
{
Lara . look = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > enableBaddiePush = false ;
coll - > enableSpaz = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
if ( item - > frameNumber = = g_Level . Anims [ item - > animNumber ] . frameEnd - 1 )
{
Lara . gunStatus = LG_NO_ARMS ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
if ( UseForcedFixedCamera )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
UseForcedFixedCamera = 0 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
void lara_as_controlledl ( ITEM_INFO * item , COLL_INFO * coll ) //1B180(<), 1B2B4(<) (F)
{
Lara . look = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > enableBaddiePush = false ;
coll - > enableSpaz = false ;
}
2020-09-26 03:28:30 +10:00
// ------------------------------
// BASIC MOVEMENT
// Control & Collision Functions
// ------------------------------
// State: 0
// Collision: lara_col_walk_forward()
void lara_as_walk_forward ( ITEM_INFO * item , COLL_INFO * coll ) //191B8(<), 192EC(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
// TODO: Looking while walking.
// BUG: When looking while running Lara transitions into a walk, look mode locks.
2020-08-14 17:54:25 -05:00
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
if ( Lara . isMoving )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
return ;
}
// TODO: Lara refuses to turn when performing walk-to-stand anims.
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( - 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
{
if ( Lara . waterStatus = = LW_WADE )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_WADE_FORWARD ;
}
else if ( TrInput & IN_WALK )
{
item - > goalAnimState = LS_WALK_FORWARD ;
2020-08-14 17:54:25 -05:00
}
else
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_RUN_FORWARD ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 0
// State code: lara_as_walk_forward()
void lara_col_walk_forward ( ITEM_INFO * item , COLL_INFO * coll ) //1B3E8, 1B51C (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = 0 ;
2020-08-14 17:54:25 -05:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
coll - > badPos = 384 ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
coll - > slopesArePits = true ;
coll - > lavaIsPit = 1 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( TestLaraLean ( coll ) & & item - > pos . zRot < = 0 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot - = LARA_LEAN_RATE ;
if ( item - > pos . zRot < - LARA_LEAN_MAX / 2 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = - LARA_LEAN_MAX / 2 ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
}
else if ( TrInput & IN_RIGHT )
{
if ( TestLaraLean ( coll ) & & item - > pos . zRot > = 0 )
{
item - > pos . zRot + = LARA_LEAN_RATE ;
if ( item - > pos . zRot > LARA_LEAN_MAX / 2 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = LARA_LEAN_MAX / 2 ;
2020-08-14 17:54:25 -05:00
}
}
}
2020-09-26 03:28:30 +10:00
if ( TestLaraVault ( item , coll ) )
2020-08-14 17:54:25 -05:00
{
return ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraHitCeiling ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraHitCeiling ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraWallDeflect ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraWallDeflect ( item , coll ) ;
item - > goalAnimState = LS_SPLAT ;
if ( GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) )
{
return ;
}
LaraCollideStop ( item , coll ) ;
}
if ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = STEPUP_HEIGHT ) )
{
DoLaraStep ( item , coll ) ;
}
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraSlide ( item , coll ) ;
return ;
}
}
// State: 1
// Collision: lara_col_run()
void lara_as_run ( ITEM_INFO * item , COLL_INFO * coll ) //192EC, 19420 (F)
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_DEATH ;
2020-08-14 17:54:25 -05:00
return ;
}
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < - LARA_FAST_TURN )
2020-08-25 19:39:50 -03:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = - LARA_FAST_TURN ;
2020-08-25 19:39:50 -03:00
}
2020-08-14 17:54:25 -05:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > LARA_FAST_TURN )
2020-08-25 19:39:50 -03:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = LARA_FAST_TURN ;
2020-08-25 19:39:50 -03:00
}
2020-08-14 17:54:25 -05:00
}
if ( item - > animNumber = = LA_STAND_TO_RUN )
{
2020-09-26 03:28:30 +10:00
EnableJump = false ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
else if ( item - > animNumber = = LA_RUN & & item - > frameNumber = = 4 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
EnableJump = true ;
2020-08-14 17:54:25 -05:00
}
else
{
2020-09-26 03:28:30 +10:00
EnableJump = true ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_JUMP & & EnableJump & & ! item - > gravityStatus )
2020-08-14 17:54:25 -05:00
{
item - > goalAnimState = LS_JUMP_FORWARD ;
2020-09-26 03:28:30 +10:00
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_ROLL | |
( TrInput & IN_BACK & & EnableBackKeyTurn ) )
& & ! ( TrInput & IN_JUMP ) ) // A slightly hacky fix to prevent unintentional rolling when JUMP and ROLL are pressed and EnableJump isn't true yet.
{
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
2020-08-14 17:54:25 -05:00
{
if ( Lara . waterStatus = = LW_WADE )
{
item - > goalAnimState = LS_WADE_FORWARD ;
}
2020-09-26 03:28:30 +10:00
else if ( TrInput & IN_WALK )
{
item - > goalAnimState = LS_WALK_FORWARD ;
}
2020-08-14 17:54:25 -05:00
else
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_RUN_FORWARD ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 1
// State code: lara_col_run()
2020-08-14 17:54:25 -05:00
void lara_col_run ( ITEM_INFO * item , COLL_INFO * coll ) //1B64C, 1B780 (F)
{
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( TestLaraLean ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot - = LARA_LEAN_RATE ;
if ( item - > pos . zRot < - LARA_LEAN_MAX )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = - LARA_LEAN_MAX ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
if ( TestLaraLean ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot + = LARA_LEAN_RATE ;
if ( item - > pos . zRot > LARA_LEAN_MAX )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = LARA_LEAN_MAX ;
2020-08-14 17:54:25 -05:00
}
}
}
2020-09-26 03:28:30 +10:00
if ( TestLaraVault ( item , coll ) )
{
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraHitCeiling ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraHitCeiling ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( LaraDeflectEdge ( item , coll ) )
{
item - > pos . zRot = 0 ;
if ( TestWall ( 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 ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = STEPUP_HEIGHT ) )
{
//DoLaraStep(item, coll); // Uncomment this line and remove everything below when a step down anim is created.
/*if (TestLaraStepDown(coll))
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_DOWN ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else */ if ( TestLaraStepUp ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_UP ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
item - > pos . yPos + = coll - > midFloor ;
}
}
if ( TestLaraFall ( coll ) )
{
//if (TrInput & IN_ACTION &&
// EnableSafetyDrop &&
// coll->midFloor >= 1024 &&
// Lara.gunStatus == LG_NO_ARMS) // TODO: Also test for floor behind and static below.
//{
// item->goalAnimState = LS_SAFE_DROP;
//}
//else
//{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
//}
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
// LEGACY step code. Has NO_HEIGHT checks unaccounted for above; not sure what they do exactly. -Sezz
//if (coll->midFloor >= -STEPUP_HEIGHT && coll->midFloor < -STEP_SIZE / 2)
//{
// if (coll->frontFloor == NO_HEIGHT || coll->frontFloor < -STEPUP_HEIGHT || coll->frontFloor >= -STEP_SIZE / 2)
// {
// coll->midFloor = 0;
// }
// else
// {
// item->goalAnimState = LS_STEP_UP;
// GetChange(item, &g_Level.Anims[item->animNumber]);
// }
//}
//else
//{
// if (coll->midFloor < 50)
// {
// if (coll->midFloor != NO_HEIGHT)
// {
// item->pos.yPos += coll->midFloor / 2;
// }
// else
// {
// item->goalAnimState = LS_STEP_DOWN; // for theoretical running stepdown anims, not in default anims
// if (GetChange(item, &g_Level.Anims[item->animNumber]))
// {
// item->pos.yPos += coll->midFloor; // move Lara to midFloor
// }
// else
// {
// item->pos.yPos += 50; // do the default aligment
// }
// }
// }
//}
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
return ;
}
}
// State: 2
// Collision: lara_col_stop()
void lara_as_stop ( ITEM_INFO * item , COLL_INFO * coll )
{
int fHeight = NO_HEIGHT ;
int rHeight = NO_HEIGHT ;
if ( item - > animNumber ! = LA_SPRINT_TO_STAND_RIGHT & & item - > animNumber ! = LA_SPRINT_TO_STAND_LEFT )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
StopSoundEffect ( SFX_LARA_SLIPPING ) ;
}
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_DEATH ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
// Handles waterskin and clockwork beetle.
if ( UseSpecialItem ( item ) )
2020-08-14 17:54:25 -05:00
{
return ;
}
2020-09-26 03:28:30 +10:00
// TODO: This prevents locks and looping actions, but those should be caught by each state.
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_STOP ;
if ( TrInput & IN_LOOK )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
LookUpDown ( ) ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( TrInput & IN_FORWARD )
{
2020-09-26 03:28:30 +10:00
fHeight = LaraFloorFront ( item , item - > pos . yRot , LARA_RAD + 4 ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
else if ( TrInput & IN_BACK )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
rHeight = LaraFloorFront ( item , item - > pos . yRot - ANGLE ( 180.0f ) , LARA_RAD + 4 ) ; // TR3: item->pos.yRot + ANGLE(180) ?
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
int height , ceiling ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
{
item - > goalAnimState = LS_TURN_LEFT_SLOW ;
}
else if ( TrInput & IN_RIGHT )
{
item - > goalAnimState = LS_TURN_RIGHT_SLOW ;
}
else if ( TrInput & IN_LSTEP )
{
height = LaraFloorFront ( item , item - > pos . yRot - ANGLE ( 90.0f ) , LARA_RAD + 48 ) ;
ceiling = LaraCeilingFront ( item , item - > pos . yRot - ANGLE ( 90.0f ) , LARA_RAD + 48 , LARA_HITE ) ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( ( height < 128 & & height > - 128 ) & & HeightType ! = BIG_SLOPE & & ceiling < = 0 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STEP_LEFT ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RSTEP )
{
height = LaraFloorFront ( item , item - > pos . yRot + ANGLE ( 90.0f ) , LARA_RAD + 48 ) ;
ceiling = LaraCeilingFront ( item , item - > pos . yRot + ANGLE ( 90.0f ) , LARA_RAD + 48 , LARA_HITE ) ;
if ( ( height < 128 & & height > - 128 ) & & HeightType ! = BIG_SLOPE & & ceiling < = 0 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STEP_RIGHT ;
2020-08-14 17:54:25 -05:00
}
}
if ( Lara . waterStatus = = LW_WADE )
{
if ( TrInput & IN_JUMP & & ! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_JUMP_PREPARE ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( TrInput & IN_FORWARD )
{
2020-09-26 03:28:30 +10:00
if ( ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP & &
fHeight > - ( STEPUP_HEIGHT - 1 ) ) | |
( fHeight < ( STEPUP_HEIGHT - 1 ) & &
fHeight > - ( STEPUP_HEIGHT - 1 ) ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_WADE_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
coll - > radius = LARA_RAD + 2 ;
coll - > facing = Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( TestLaraVault ( item , coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
coll - > radius = LARA_RAD ;
return ;
}
if ( TrInput & IN_BACK )
{
if ( ( rHeight < ( STEPUP_HEIGHT - 1 ) ) & & ( rHeight > - ( STEPUP_HEIGHT - 1 ) ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_WALK_BACK ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
}
// TODO: Add failsafe which automatically crouches Lara if she unexpectedly embeds into a crawlspace.
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 ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ROLL & & Lara . waterStatus ! = LW_WADE )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
else [[likely]]
2020-08-14 17:54:25 -05:00
{
if ( TrInput & IN_JUMP )
{
item - > goalAnimState = LS_JUMP_PREPARE ;
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
{
int height = LaraFloorFront ( item , item - > pos . yRot , LARA_RAD + 4 ) ;
int ceiling = LaraCeilingFront ( item , item - > pos . yRot , LARA_RAD + 4 , LARA_HITE ) ;
2020-08-14 17:54:25 -05:00
if ( ( HeightType = = BIG_SLOPE | | HeightType = = DIAGONAL ) & & ( height < 0 | | ceiling > 0 ) )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
/*if (TrInput & IN_ACTION &&
EnableSafetyDrop & &
LaraFloorFront ( item , - item - > pos . yRot , 100 ) < = 1024 )
{
item - > goalAnimState = LS_SAFE_DROP ;
}
else */ if ( TrInput & IN_WALK )
{
item - > goalAnimState = LS_WALK_FORWARD ;
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
item - > goalAnimState = LS_RUN_FORWARD ;
}
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_BACK )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
/*if (TrInput & IN_ACTION && LaraFloorFront(item, -item->pos.yRot, 100) < 1024 && EnableSafetyDrop)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_SAFE_DROP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
else */ if ( TrInput & IN_WALK )
{
if ( ( rHeight < ( STEPUP_HEIGHT - 1 ) ) & & ( rHeight > - ( STEPUP_HEIGHT - 1 ) ) & & HeightType ! = BIG_SLOPE )
{
item - > goalAnimState = LS_WALK_BACK ;
}
}
else if ( rHeight > - ( STEPUP_HEIGHT - 1 ) )
2020-08-14 17:54:25 -05:00
{
item - > goalAnimState = LS_HOP_BACK ;
}
2020-09-26 03:28:30 +10:00
return ;
}
//if (TrInput & IN_SPRINT)
//{
// 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_ROLL & & Lara . waterStatus ! = LW_WADE )
{
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
}
}
2020-09-26 03:28:30 +10:00
// State: 2
// State code: lara_as_stop()
2020-08-14 17:54:25 -05:00
void lara_col_stop ( ITEM_INFO * item , COLL_INFO * coll ) // (F) (D)
{
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
2020-08-14 17:54:25 -05:00
coll - > badPos = STEPUP_HEIGHT ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesArePits = true ;
2020-09-26 03:28:30 +10:00
coll - > slopesAreWalls = true ;
2020-08-14 17:54:25 -05:00
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TestLaraVault ( item , coll ) )
{
return ;
}
if ( TestLaraHitCeiling ( coll ) )
{
SetLaraHitCeiling ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
ShiftItem ( item , coll ) ;
# if 1
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
# else
if ( ! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) | | coll - > midFloor < 0 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else if ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP & & coll - > midFloor )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = SWAMP_GRAVITY ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
# endif
}
2020-09-26 03:28:30 +10:00
// State: 3
// Collision: lara_col_forward_jump()
void lara_as_jump_forward ( ITEM_INFO * item , COLL_INFO * coll ) //18A34, 18B68 (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
//if (item->hitPoints <= 0)
//{
// item->goalAnimState = LS_DEATH;
// return;
//}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FREEFALL ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// Petition to ban banana jumps.
2020-08-14 17:54:25 -05:00
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
2020-09-26 03:28:30 +10:00
if ( Lara . turnRate < ANGLE ( - 3.0f ) )
{
Lara . turnRate = ANGLE ( - 3.0f ) ;
}
2020-08-14 17:54:25 -05:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 3.0f ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
Lara . turnRate = ANGLE ( 3.0f ) ;
2020-09-26 03:28:30 +10:00
}
}
if ( TrInput & IN_ACTION & &
Lara . gunStatus = = LG_NO_ARMS )
{
item - > goalAnimState = LS_REACH ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_WALK & &
Lara . gunStatus = = LG_NO_ARMS )
{
item - > goalAnimState = LS_SWANDIVE_START ;
return ;
}
if ( TrInput & IN_ROLL | |
( TrInput & IN_BACK & & EnableBackKeyTurn ) )
{
item - > goalAnimState = LS_JUMP_ROLL_180 ;
return ;
}
//item->goalAnimState = LS_JUMP_FORWARD;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 3
// State code: lara_as_forward_jump()
void lara_col_jump_forward ( ITEM_INFO * item , COLL_INFO * coll ) //18B88, 18CBC (F)
2020-08-14 17:54:25 -05:00
{
if ( item - > speed < 0 )
2020-09-26 03:28:30 +10:00
{
Lara . moveAngle = ANGLE ( 180.0f ) ;
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
LaraDeflectEdgeJump ( item , coll ) ;
2020-09-26 03:28:30 +10:00
if ( item - > speed < 0 ) // ??
{
2020-08-14 17:54:25 -05:00
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( coll - > midFloor < = 0 & & item - > fallspeed > 0 )
{
2020-09-26 03:28:30 +10:00
if ( LaraLandedBad ( item , coll ) ) // ?
2020-08-14 17:54:25 -05:00
{
item - > goalAnimState = LS_DEATH ;
}
else
{
if ( Lara . waterStatus = = LW_WADE )
{
item - > goalAnimState = LS_STOP ;
}
else
{
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD & & ! ( TrInput & IN_STEPSHIFT ) ) // ???
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_RUN_FORWARD ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_STOP ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
item - > speed = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
AnimateLara ( item ) ;
}
}
2020-09-26 03:28:30 +10:00
// State: 4
// Collision: lara_void_func()
2020-08-14 17:54:25 -05:00
void lara_col_pose ( ITEM_INFO * item , COLL_INFO * coll ) //1B87C(<), 1B9B0(<) (F)
{
lara_col_stop ( item , coll ) ;
}
2020-09-26 03:28:30 +10:00
// State: 5
// Collision: lara_col_hop_back()
void lara_as_hop_back ( ITEM_INFO * item , COLL_INFO * coll ) //1959C(<), 196D0(<) (F)
2020-08-14 17:54:25 -05:00
{
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
2020-09-26 03:28:30 +10:00
if ( Lara . turnRate < ANGLE ( - 6.0f ) )
{
Lara . turnRate = ANGLE ( - 6.0f ) ;
}
2020-08-14 17:54:25 -05:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 6.0f ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
Lara . turnRate = ANGLE ( 6.0f ) ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 5
// State code: lara_as_hop_back()
void lara_col_hop_back ( ITEM_INFO * item , COLL_INFO * coll ) //1B89C, 1B9D0 (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
coll - > slopesAreWalls = 0 ;
coll - > slopesArePits = true ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TestLaraHitCeiling ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraHitCeiling ( item , coll ) ;
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraWallDeflect ( coll ) )
{
SetLaraWallDeflect ( item , coll ) ;
LaraCollideStop ( item , coll ) ;
}
// TODO: Hop back step height check is unique among the land traversal states. Appropriate to make test functions have extra parameters to account for this one case?
if ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = 200 ) )
{
if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
2020-08-14 17:54:25 -05:00
}
else
{
2020-09-26 03:28:30 +10:00
item - > pos . yPos + = coll - > midFloor ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( coll - > midFloor > = 200 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FALL_BACK ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraSlide ( item , coll ) ;
return ;
}
item - > goalAnimState = LS_STOP ;
}
// State: 6
// Collision: lara_col_turn_right()
void lara_as_turn_right ( ITEM_INFO * item , COLL_INFO * coll ) //19628(<), 1975C(<) (F)
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . waterStatus = = LW_WADE | |
Lara . gunStatus ! = LG_READY )
{
if ( Lara . turnRate > ANGLE ( 4.0f ) )
{
item - > goalAnimState = LS_TURN_RIGHT_FAST ; // TODO: Investigate why a 1 frame WALK input causes an early dispatch to FAST_TURN instead of SIDESTEP.
2020-08-14 17:54:25 -05:00
}
}
else
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_TURN_RIGHT_FAST ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_JUMP )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_PREPARE ;
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
//if (TrInput & IN_SPRINT)
//{
// 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 ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ROLL & & Lara . waterStatus ! = LW_WADE )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
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 ;
}
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( ! ( TrInput & IN_RIGHT ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
return ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 6
// State code: lara_as_turn_r()
void lara_col_turn_right ( ITEM_INFO * item , COLL_INFO * coll ) // (F) (D)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = 0 ;
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > badPos = STEPUP_HEIGHT ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = 1 ;
coll - > slopesArePits = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
# if 1
if ( coll - > midFloor > 100 )
# else
if ( coll - > midFloor > 100 & & ! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) )
# endif
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FALL ;
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
//return; ??
2020-08-14 17:54:25 -05:00
# if 1
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
# else
if ( ! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) | | coll - > midFloor < 0 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else if ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP & & coll - > midFloor )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = SWAMP_GRAVITY ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
# endif
}
2020-09-26 03:28:30 +10:00
// TODO: TURN_RIGHT_FAST is dispatched instead?!
// State: 7
// Collision: lara_col_turn()
void lara_as_turn_left ( ITEM_INFO * item , COLL_INFO * coll ) //1972C(<), 19860(<) (F)
2020-08-14 17:54:25 -05:00
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
Lara . turnRate - = LARA_TURN_RATE ;
2020-09-26 03:28:30 +10:00
if ( Lara . waterStatus = = LW_WADE | |
Lara . gunStatus ! = LG_READY )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_TURN_LEFT_FAST ;
2020-08-14 17:54:25 -05:00
}
}
else
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_TURN_LEFT_FAST ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_JUMP )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_PREPARE ;
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
//if (TrInput & IN_SPRINT)
//{
// 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 ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ROLL & & Lara . waterStatus ! = LW_WADE )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
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 ;
}
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( ! ( TrInput & IN_LEFT ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
return ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 6
// State code: lara_as_turn_left()
void lara_col_turn_left ( ITEM_INFO * item , COLL_INFO * coll ) // (F) (D)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
lara_col_turn_right ( item , coll ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 8
// Collision: lara_col_death()
2020-08-14 17:54:25 -05:00
void lara_as_death ( ITEM_INFO * item , COLL_INFO * coll ) //19830(<), 19964(<) (F)
{
Lara . look = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > enableBaddiePush = false ;
coll - > enableSpaz = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
if ( BinocularRange )
{
BinocularRange = 0 ;
LaserSight = 0 ;
LaraItem - > meshBits = - 1 ;
Lara . busy = false ;
2020-09-26 03:28:30 +10:00
AlterFOV ( ANGLE ( 80.0f ) ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 8
// State code: lara_as_death()
2020-08-14 17:54:25 -05:00
void lara_col_death ( ITEM_INFO * item , COLL_INFO * coll ) //1BADC(<), 1BC10(<) (F)
{
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
coll - > badPos = 384 ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > radius = 400 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
StopSoundEffect ( SFX_LARA_FALL ) ;
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
ShiftItem ( item , coll ) ;
item - > hitPoints = - 1 ;
Lara . air = - 1 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 9
// Collision: lara_col_freefall()
void lara_as_freefall ( ITEM_INFO * item , COLL_INFO * coll ) //198BC(<), 199F0(<) (F)
2020-08-14 17:54:25 -05:00
{
item - > speed = ( item - > speed * 95 ) / 100 ;
if ( item - > fallspeed = = 154 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
SoundEffect ( SFX_LARA_FALL , & item - > pos , 0 ) ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 9
// State code: lara_as_freefall()
void lara_col_freefall ( ITEM_INFO * item , COLL_INFO * coll ) //1BB88, 1BCBC (F)
2020-08-14 17:54:25 -05:00
{
item - > gravityStatus = true ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
StopSoundEffect ( SFX_LARA_FALL ) ;
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
PerformLaraSlideEdgeJump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
if ( coll - > midFloor < = 0 )
{
if ( LaraLandedBad ( item , coll ) )
{
item - > goalAnimState = LS_DEATH ;
}
else
{
item - > goalAnimState = LS_STOP ;
}
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 11
// Collision: lara_col_reach()
2020-08-14 17:54:25 -05:00
void lara_as_reach ( ITEM_INFO * item , COLL_INFO * coll ) //18CE0(<), 18E14(<) (F)
{
Camera . targetAngle = ANGLE ( 85.0f ) ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FREEFALL ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 11
// State code: lara_as_reach()
2020-08-14 17:54:25 -05:00
void lara_col_reach ( ITEM_INFO * item , COLL_INFO * coll ) //18D0C, 18E40 (F)
{
if ( Lara . ropePtr = = - 1 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > gravityStatus = true ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = 0 ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
short angle ;
bool result = false ;
int edge = 0 ;
int edgeCatch = 0 ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ACTION & &
Lara . gunStatus = = LG_NO_ARMS & &
! coll - > hitStatic )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( coll - > collType = = CT_TOP & & Lara . canMonkeySwing )
2020-08-14 17:54:25 -05:00
{
Lara . headYrot = 0 ;
Lara . headXrot = 0 ;
Lara . torsoYrot = 0 ;
Lara . torsoXrot = 0 ;
Lara . gunStatus = LG_HANDS_BUSY ;
2020-09-26 03:28:30 +10:00
// TODO: State dispatch. Doing it the obvious way results in a delay before the catch.
2020-08-14 17:54:25 -05:00
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 ;
}
if ( coll - > midCeiling < = - 384 & &
coll - > midFloor > = 200 & &
coll - > collType = = CT_FRONT )
{
edgeCatch = LaraTestEdgeCatch ( item , coll , & edge ) ;
if ( ! ( ! edgeCatch | | edgeCatch < 0 & & ! LaraTestHangOnClimbWall ( item , coll ) ) )
{
angle = item - > pos . yRot ;
if ( coll - > midSplitFloor & & coll - > frontSplitFloor = = coll - > midSplitFloor )
{
result = SnapToDiagonal ( angle , 35 ) ;
}
else
{
result = SnapToQuadrant ( angle , 35 ) ;
}
}
}
}
if ( ! result )
{
2020-09-26 03:28:30 +10:00
PerformLaraSlideEdgeJump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
coll - > facing = Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
ShiftItem ( item , coll ) ;
if ( item - > fallspeed > 0 & & coll - > midFloor < = 0 )
{
if ( LaraLandedBad ( item , coll ) )
{
item - > goalAnimState = LS_DEATH ;
}
else
{
item - > goalAnimState = LS_STOP ;
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
}
else
{
if ( TestHangSwingIn ( item , angle ) )
{
Lara . headYrot = 0 ;
Lara . headXrot = 0 ;
Lara . torsoYrot = 0 ;
Lara . torsoXrot = 0 ;
2020-09-26 03:28:30 +10:00
item - > animNumber = LA_REACH_TO_HANG_OSCILLATE ;
2020-08-14 17:54:25 -05:00
item - > frameNumber = g_Level . Anims [ item - > animNumber ] . frameBase ;
2020-09-26 03:28:30 +10:00
item - > currentAnimState = LS_HANG ;
item - > goalAnimState = LS_HANG ;
item - > gravityStatus = false ;
item - > speed = 0 ;
item - > fallspeed = 0 ;
2020-08-14 17:54:25 -05:00
}
else
{
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 ;
}
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
{
item - > pos . yPos + = coll - > frontFloor - bounds - > Y1 ;
if ( coll - > midSplitFloor )
{
Vector2 v = GetDiagonalIntersect ( item - > pos . xPos , item - > pos . zPos , coll - > midSplitFloor , LARA_RAD , angle ) ;
item - > pos . xPos = v . x ;
item - > pos . zPos = v . y ;
}
else
{
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 ;
}
}
void lara_as_splat ( ITEM_INFO * item , COLL_INFO * coll ) //1A340(<), 1A474(<) (F)
{
Lara . look = false ;
}
void lara_col_splat ( ITEM_INFO * item , COLL_INFO * coll ) //1BC74(<), 1BDA8(<) (F)
{
Lara . moveAngle = 0 ;
coll - > slopesAreWalls = true ;
coll - > slopesArePits = true ;
coll - > badPos = 384 ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
ShiftItem ( item , coll ) ;
if ( coll - > midFloor > = - 256 & & coll - > midFloor < = 256 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 15
// Collision: lara_col_jump_prepare()
void lara_as_jump_prepare ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
if ( Lara . waterStatus ! = LW_WADE )
{
2020-09-26 03:28:30 +10:00
// TODO: Check ceilings as well.
2020-08-14 17:54:25 -05:00
if ( TrInput & IN_FORWARD & & LaraFloorFront ( item , item - > pos . yRot , 256 ) > = - 384 )
{
item - > goalAnimState = LS_JUMP_FORWARD ;
Lara . moveAngle = 0 ;
}
2020-09-26 03:28:30 +10:00
else if ( TrInput & IN_BACK & & LaraFloorFront ( item , item - > pos . yRot - ANGLE ( 180.0f ) , 256 ) > = - 384 )
{
item - > goalAnimState = LS_JUMP_BACK ;
Lara . moveAngle = ANGLE ( 180.0f ) ;
}
2020-08-14 17:54:25 -05:00
else if ( TrInput & IN_LEFT & & LaraFloorFront ( item , item - > pos . yRot - ANGLE ( 90.0f ) , 256 ) > = - 384 )
{
2020-09-02 15:59:57 -05:00
item - > goalAnimState = LS_JUMP_LEFT ;
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( - 90.0f ) ;
2020-08-14 17:54:25 -05:00
}
else if ( TrInput & IN_RIGHT & & LaraFloorFront ( item , item - > pos . yRot + ANGLE ( 90.0f ) , 256 ) > = - 384 )
{
2020-09-02 15:59:57 -05:00
item - > goalAnimState = LS_JUMP_RIGHT ;
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 90.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
else if ( TrInput & IN_ROLL )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_ROLL_180 ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
//else
//{
// // Cancel jump preparation if the ceiling in a chosen direction is too low.
//}
2020-08-14 17:54:25 -05:00
}
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FREEFALL ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 15
// State code: lara_as_jump_prepare()
void lara_col_jump_prepare ( ITEM_INFO * item , COLL_INFO * coll ) //1BD30, 1BE64 (F)
2020-08-14 17:54:25 -05:00
{
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = NO_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TestLaraFall ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
// G A R B A G E.
// TODO: Dispatch crouch if ceiling lowers.
if ( coll - > midCeiling > - 100 )
{
item - > animNumber = LA_STAND_SOLID ; // <- This anim needs to go!!
item - > frameNumber = g_Level . Anims [ item - > animNumber ] . frameBase ;
item - > goalAnimState = LS_STOP ;
item - > currentAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
item - > speed = 0 ;
item - > fallspeed = 0 ;
item - > gravityStatus = false ;
item - > pos . xPos = coll - > old . x ;
item - > pos . yPos = coll - > old . y ;
item - > pos . zPos = coll - > old . z ;
}
if ( coll - > midFloor > - 256 & & coll - > midFloor < 256 )
{
item - > pos . yPos + = coll - > midFloor ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 16
// Collision: lara_col_walk_back()
void lara_as_walk_back ( ITEM_INFO * item , COLL_INFO * coll ) //1A4F0(<), 1A624(<) (F)
2020-08-14 17:54:25 -05:00
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
if ( Lara . isMoving )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( - 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_JUMP )
{
item - > goalAnimState = LS_JUMP_PREPARE ; // TODO
return ;
}
if ( TrInput & IN_BACK & &
( TrInput & IN_WALK | | Lara . waterStatus = = LW_WADE ) )
{
item - > goalAnimState = LS_WALK_BACK ;
return ;
}
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 16
// State code: lara_as_walk_back()
void lara_col_walk_back ( ITEM_INFO * item , COLL_INFO * coll ) // (F) (D)
2020-08-14 17:54:25 -05:00
{
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
2020-08-14 17:54:25 -05:00
if ( Lara . waterStatus = = LW_WADE )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
coll - > badPos = NO_BAD_POS ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
coll - > badPos = STEPUP_HEIGHT ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesArePits = true ;
coll - > slopesAreWalls = 1 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( LaraHitCeiling ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( LaraDeflectEdge ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
LaraCollideStop ( item , coll ) ;
2020-09-26 03:28:30 +10:00
}
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = STEPUP_HEIGHT ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
// Like the hop back, step back is also unique. TODO: Make step test/set functions take extra parameters.
if ( TestLaraStepDown ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_BACK_DOWN ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
/*else if (TestLaraStepUp(coll))
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_BACK_UP ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
} */
else if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
item - > pos . yPos + = coll - > midFloor ;
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
#if 0
if ( ! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) | | coll - > midFloor < 0 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else if ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP & & coll - > midFloor )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = SWAMP_GRAVITY ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
# else
2020-09-26 03:28:30 +10:00
//if (coll->midFloor != NO_HEIGHT)
//{
// item->pos.yPos += coll->midFloor;
//}
2020-08-14 17:54:25 -05:00
# endif
}
2020-09-26 03:28:30 +10:00
// State: 20
// Collision: lara_col_fast_turn_right()
void lara_as_turn_right_fast ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
Lara . turnRate = LARA_FAST_TURN ;
if ( TrInput & IN_JUMP )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_PREPARE ;
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ROLL & & Lara . waterStatus ! = LW_WADE )
{
item - > goalAnimState = LS_ROLL_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
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 ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_CROUCH_IDLE ;
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD )
{
if ( Lara . waterStatus = = LW_WADE ) // Failsafe.
{
item - > goalAnimState = LS_WADE_FORWARD ;
}
else if ( TrInput & IN_WALK )
{
item - > goalAnimState = LS_WALK_FORWARD ;
}
else
{
item - > goalAnimState = LS_RUN_FORWARD ;
}
return ;
}
if ( ! ( TrInput & IN_RIGHT ) )
{
item - > goalAnimState = LS_STOP ;
return ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 20
// State code: lara_as_turn_right_fast()
void lara_col_turn_right_fast ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
lara_col_stop ( item , coll ) ; // TODO: Investigate why collision is different to regular turn.
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 157
// State code: lara_as_turn_left_fast()
void lara_as_turn_left_fast ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
Lara . turnRate = - LARA_FAST_TURN ;
if ( TrInput & IN_JUMP )
{
item - > goalAnimState = LS_JUMP_PREPARE ;
return ;
}
if ( TrInput & IN_ROLL & & Lara . waterStatus ! = LW_WADE )
{
item - > goalAnimState = LS_ROLL_FORWARD ;
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_FORWARD )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( Lara . waterStatus = = LW_WADE ) // Failsafe.
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_WADE_FORWARD ;
}
else if ( TrInput & IN_WALK )
{
item - > goalAnimState = LS_WALK_FORWARD ;
}
else
{
item - > goalAnimState = LS_RUN_FORWARD ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
}
if ( ! ( TrInput & IN_LEFT ) )
{
item - > goalAnimState = LS_STOP ;
return ;
}
}
// State: 157
// State code: lara_as_turn_left_fast()
void lara_col_turn_left_fast ( ITEM_INFO * item , COLL_INFO * coll )
{
lara_col_turn_right_fast ( item , coll ) ;
}
// State: 21
// Collision: lara_col_sidestep()
void lara_as_step_right ( ITEM_INFO * item , COLL_INFO * coll ) //1A67C(<), 1A7B0(<) (F)
{
Lara . look = false ;
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
if ( Lara . isMoving )
{
return ;
}
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( - 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_RSTEP )
{
item - > goalAnimState = LS_STEP_RIGHT ;
return ;
}
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 21
// State code: lara_as_step_right()
void lara_col_step_right ( ITEM_INFO * item , COLL_INFO * coll ) //1BFB0, 1C0E4 (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 90.0f ) ;
2020-08-14 17:54:25 -05:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
if ( Lara . waterStatus = = LW_WADE )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
coll - > badPos = NO_BAD_POS ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
coll - > badPos = 128 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
coll - > slopesAreWalls = true ;
coll - > slopesArePits = true ;
coll - > badNeg = - 128 ;
coll - > badCeiling = 0 ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TestLaraHitCeiling ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraHitCeiling ( item , coll ) ;
return ;
}
if ( TestLaraWallDeflect ( coll ) )
{
SetLaraWallDeflect ( item , coll ) ;
LaraCollideStop ( item , coll ) ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
return ;
}
if ( abs ( coll - > midFloor ) > 0 & & coll - > midFloor ! = NO_HEIGHT )
{
if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
}
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
return ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 22
// Collision: lara_col_sidestep()
void lara_as_step_left ( ITEM_INFO * item , COLL_INFO * coll ) //1A750(<), 1A884(<) (F)
2020-08-14 17:54:25 -05:00
{
Lara . look = false ;
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
2020-09-26 03:28:30 +10:00
if ( Lara . isMoving )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < - LARA_SLOW_TURN )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = - LARA_SLOW_TURN ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > LARA_SLOW_TURN )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = LARA_SLOW_TURN ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LSTEP )
{
item - > goalAnimState = LS_STEP_LEFT ;
return ;
}
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 22
// State code: lara_as_step_left()
void lara_col_step_left ( ITEM_INFO * item , COLL_INFO * coll ) //1BFB0, 1C0E4 (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( - 90.0f ) ;
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
if ( Lara . waterStatus = = LW_WADE )
{
coll - > badPos = NO_BAD_POS ;
}
else
{
coll - > badPos = 128 ;
}
coll - > slopesAreWalls = true ;
coll - > slopesArePits = true ;
coll - > badNeg = - 128 ;
coll - > badCeiling = 0 ;
coll - > facing = Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( TestLaraHitCeiling ( coll ) )
{
SetLaraHitCeiling ( item , coll ) ;
return ;
}
if ( TestLaraWallDeflect ( coll ) )
{
SetLaraWallDeflect ( item , coll ) ;
LaraCollideStop ( item , coll ) ;
}
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
return ;
}
if ( abs ( coll - > midFloor ) > 0 & & coll - > midFloor ! = NO_HEIGHT )
{
if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
item - > pos . yPos + = coll - > midFloor ;
}
}
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
return ;
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 23
// State code: lara_void_func()
2020-08-14 17:54:25 -05:00
void lara_col_roll2 ( ITEM_INFO * item , COLL_INFO * coll ) //1C384, 1C4B8 (F)
{
Camera . laraNode = 0 ;
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
2020-08-14 17:54:25 -05:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
2020-09-26 03:28:30 +10:00
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
2020-08-14 17:54:25 -05:00
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( LaraHitCeiling ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( coll - > midFloor > 200 )
{
2020-09-26 03:28:30 +10:00
// TODO: not working?
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FALL_BACK ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
return ;
}
ShiftItem ( item , coll ) ;
if ( coll - > midFloor ! = NO_HEIGHT )
item - > pos . yPos + = coll - > midFloor ;
}
2020-09-26 03:28:30 +10:00
// State: 25
// Cllision: lara_col_jump_back()
void lara_as_jump_back ( ITEM_INFO * item , COLL_INFO * coll ) //1A854(<), 1A988(<) (F)
2020-08-14 17:54:25 -05:00
{
Camera . targetAngle = ANGLE ( 135.0f ) ;
2020-09-26 03:28:30 +10:00
Lara . look = false ;
//if (item->hitPoints <= 0)
//{
// item->goalAnimState = LS_DEATH;
// return;
//}
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FREEFALL ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( ( TrInput & IN_ROLL | |
TrInput & IN_FORWARD & & EnableBackKeyTurn ) & &
item - > goalAnimState ! = LS_STOP )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_ROLL_180 ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
//item->goalAnimState = LS_JUMP_BACK;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 25
// State code: lara_as_jump_back()
void lara_col_jump_back ( ITEM_INFO * item , COLL_INFO * coll ) //1C130(<), 1C264(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
lara_col_jump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 26
// Collision: lara_col_jump_right()
//
void lara_as_jump_right ( ITEM_INFO * item , COLL_INFO * coll ) //1A8C4(<), 1A9F8(<) (F)
2020-08-14 17:54:25 -05:00
{
Lara . look = false ;
2020-09-26 03:28:30 +10:00
//if (item->hitPoints <= 0)
//{
// item->goalAnimState = LS_DEATH;
// return;
//}
2020-08-14 17:54:25 -05:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FREEFALL ;
2020-09-26 03:28:30 +10:00
return ;
}
//if (TrInput & IN_ACTION)
//{
// item->goalAnimState = LS_REACH;
// return;
//}
if ( ( TrInput & IN_ROLL | |
TrInput & IN_LEFT & & EnableBackKeyTurn ) & &
item - > goalAnimState ! = LS_STOP )
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_JUMP_ROLL_180 ;
2020-09-26 03:28:30 +10:00
return ;
}
//item->goalAnimState = LS_JUMP_RIGHT;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 26
// State code: lara_as_jump_right()
void lara_col_jump_right ( ITEM_INFO * item , COLL_INFO * coll ) //1C15C(<), 1C290(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 90.0f ) ;
lara_col_jump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 27
// Collision: lara_col_jump_left()
void lara_as_jump_left ( ITEM_INFO * item , COLL_INFO * coll ) //1A92C(<), 1AA60(<) (F)
2020-08-14 17:54:25 -05:00
{
Lara . look = false ;
2020-09-26 03:28:30 +10:00
//if (item->hitPoints <= 0)
//{
// item->goalAnimState = LS_DEATH;
// return;
//}
2020-08-14 17:54:25 -05:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FREEFALL ;
2020-09-26 03:28:30 +10:00
return ;
}
//if (TrInput & IN_ACTION)
//{
// item->goalAnimState = LS_REACH;
// return;
//}
if ( ( TrInput & IN_ROLL | |
TrInput & IN_RIGHT & & EnableBackKeyTurn ) & &
item - > goalAnimState ! = LS_STOP )
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_JUMP_ROLL_180 ;
2020-09-26 03:28:30 +10:00
return ;
}
//item->goalAnimState = LS_JUMP_LEFT;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 27
// State code: lara_as_jump_left()
void lara_col_jump_left ( ITEM_INFO * item , COLL_INFO * coll ) //1C188(<), 1C2BC(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( - 90.0f ) ;
lara_col_jump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// States: 25, 26, 27
// State code: none; called in lara_col_jump_back(), lara_col_jump_right(), lara_col_jump_left()
void lara_col_jump ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
LaraDeflectEdgeJump ( item , coll ) ;
if ( item - > fallspeed > 0 & & coll - > midFloor < = 0 )
{
if ( LaraLandedBad ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_DEATH ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_STOP ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 28
// Collision: lara_col_jump_up()
void lara_as_jump_up ( ITEM_INFO * item , COLL_INFO * coll )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( item - > hitPoints < = 0 )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FREEFALL ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_JUMP_UP ;
}
// State: 28
// State code: lara_as_jump_up()
void lara_col_jump_up ( ITEM_INFO * item , COLL_INFO * coll )
{
2020-08-14 17:54:25 -05:00
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > hitCeiling = false ;
coll - > facing = item - > speed < 0 ? Lara . moveAngle + ANGLE ( 180.0f ) : Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , 870 ) ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ACTION & &
Lara . gunStatus = = LG_NO_ARMS & &
! coll - > hitStatic )
2020-08-14 17:54:25 -05:00
{
if ( Lara . canMonkeySwing & & coll - > collType = = CT_TOP )
{
2020-09-26 03:28:30 +10:00
Lara . gunStatus = LG_HANDS_BUSY ;
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_MONKEYSWING_IDLE ;
item - > gravityStatus = false ;
item - > speed = 0 ;
item - > fallspeed = 0 ;
MonkeySwingSnap ( item , coll ) ;
return ;
}
2020-09-26 03:28:30 +10:00
if ( coll - > collType = = CT_FRONT & &
coll - > midCeiling < = - STEPUP_HEIGHT )
2020-08-14 17:54:25 -05:00
{
int edge ;
int edgeCatch = LaraTestEdgeCatch ( item , coll , & edge ) ;
if ( edgeCatch )
{
if ( edgeCatch > = 0 | | LaraTestHangOnClimbWall ( item , coll ) )
{
short angle = item - > pos . yRot ;
bool result ;
if ( coll - > midSplitFloor & & coll - > frontSplitFloor = = coll - > midSplitFloor )
{
result = SnapToDiagonal ( angle , 35 ) ;
}
else
{
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
{
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 ;
}
else
{
item - > goalAnimState = LS_HANG ;
}
}
bounds = GetBoundsAccurate ( item ) ;
if ( edgeCatch < = 0 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos = edge - bounds - > Y1 + 4 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > frontFloor - bounds - > Y1 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( coll - > midSplitFloor )
{
Vector2 v = GetDiagonalIntersect ( item - > pos . xPos , item - > pos . zPos , coll - > midSplitFloor , LARA_RAD , item - > pos . yRot ) ;
item - > pos . xPos = v . x ;
item - > pos . zPos = v . y ;
}
else
{
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 ) ;
if ( coll - > collType = = CT_CLAMP | |
coll - > collType = = CT_TOP | |
coll - > collType = = CT_TOP_FRONT | |
coll - > hitCeiling )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > fallspeed = 1 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( coll - > collType = = 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 ;
}
if ( item - > fallspeed > 0 & & coll - > midFloor < = 0 )
{
item - > goalAnimState = LaraLandedBad ( item , coll ) ? LS_DEATH : LS_STOP ;
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 29
// Collision: lara_col_fall_back()
void lara_as_fall_back ( ITEM_INFO * item , COLL_INFO * coll ) //1959C(<), 196D0(<) (F)
2020-08-14 17:54:25 -05:00
{
if ( item - > fallspeed > LARA_FREEFALL_SPEED )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_FREEFALL ;
2020-09-26 03:28:30 +10:00
return ;
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ACTION & &
Lara . gunStatus = = LG_NO_ARMS )
{
item - > goalAnimState = LS_REACH ;
return ;
}
item - > goalAnimState = LS_FALL_BACK ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 29
// State code: lara_as_fall_back()
void lara_col_fall_back ( ITEM_INFO * item , COLL_INFO * coll ) //1C1B4(<), 1C2E8(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
2020-08-14 17:54:25 -05:00
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
LaraDeflectEdgeJump ( item , coll ) ;
if ( item - > fallspeed > 0 & & coll - > midFloor < = 0 )
{
if ( LaraLandedBad ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_DEATH ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_STOP ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 45
// State code: lara_void_func()
2020-08-14 17:54:25 -05:00
void lara_col_roll ( ITEM_INFO * item , COLL_INFO * coll ) //1C2B0, 1C3E4 (F)
{
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
2020-08-14 17:54:25 -05:00
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesArePits = false ;
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( LaraHitCeiling ( item , coll ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
if ( TestLaraSlide ( coll ) )
{
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD & &
item - > animNumber = = LA_SWANDIVE_ROLL )
2020-08-14 17:54:25 -05:00
{
item - > goalAnimState = LS_RUN_FORWARD ;
}
ShiftItem ( item , coll ) ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 52
// Collision: lara_col_swandive_start()
void lara_as_swandive_start ( ITEM_INFO * item , COLL_INFO * coll ) //1AE08(<), 1AF3C(<) (F)
2020-08-14 17:54:25 -05:00
{
coll - > enableBaddiePush = true ;
coll - > enableSpaz = false ;
2020-09-26 03:28:30 +10:00
if ( item - > fallspeed > LARA_FREEFALL_SPEED
& & item - > goalAnimState ! = LS_DIVE )
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_SWANDIVE_END ;
2020-09-26 03:28:30 +10:00
return ;
}
item - > goalAnimState = LS_SWANDIVE_START ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 52
// State code: lara_as_swandive_start()
void lara_col_swandive_start ( ITEM_INFO * item , COLL_INFO * coll ) //1C4A0(<), 1C5D4(<) (F)
2020-08-14 17:54:25 -05:00
{
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
LaraDeflectEdgeJump ( item , coll ) ;
if ( coll - > midFloor < = 0 & & item - > fallspeed > 0 )
{
item - > goalAnimState = LS_STOP ;
item - > fallspeed = 0 ;
item - > gravityStatus = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 53
// Collision: lara_col_swandive_freefall()
void lara_as_swandive_freefall ( ITEM_INFO * item , COLL_INFO * coll ) //1AE4C(<), 1AF80(<) (F)
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > speed = ( item - > speed * 95 ) / 100 ;
2020-08-14 17:54:25 -05:00
coll - > enableBaddiePush = true ;
coll - > enableSpaz = false ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_ROLL | |
( TrInput & IN_BACK & & EnableBackKeyTurn ) )
{
item - > goalAnimState = LS_JUMP_ROLL_180 ;
return ;
}
item - > goalAnimState = LS_SWANDIVE_END ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 53
// State code: lara_as_swandive_freefall()
void lara_col_swandive_freefall ( ITEM_INFO * item , COLL_INFO * coll ) //1C558(<), 1C68C(<) (F)
2020-08-14 17:54:25 -05:00
{
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = BAD_JUMP_CEILING ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
LaraDeflectEdgeJump ( item , coll ) ;
if ( coll - > midFloor < = 0 & & item - > fallspeed > 0 )
{
if ( item - > fallspeed < = 133 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_STOP ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
else
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > goalAnimState = LS_DEATH ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
item - > fallspeed = 0 ;
item - > gravityStatus = 0 ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
item - > pos . yPos + = coll - > midFloor ;
}
}
}
// State: 54
// Collision: lara_default_col()
void lara_as_gymnast ( ITEM_INFO * item , COLL_INFO * coll ) //1AEC8(<), 1AFFC(<) (F)
{
coll - > enableBaddiePush = false ;
coll - > enableSpaz = false ;
}
// State: 65
// Collision: lara_col_wade()
void lara_as_wade ( ITEM_INFO * item , COLL_INFO * coll ) //1AF10, 1B044 (F)
{
Camera . targetElevation = ANGLE ( - 22.0f ) ;
if ( item - > hitPoints < = 0 )
{
item - > goalAnimState = LS_STOP ;
return ;
}
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 / 2 ) )
{
Lara . turnRate = - ( LARA_FAST_TURN / 2 ) ;
}
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ( LARA_FAST_TURN / 2 ) )
{
Lara . turnRate = ( LARA_FAST_TURN / 2 ) ;
}
}
if ( TrInput & IN_FORWARD )
{
item - > goalAnimState = LS_WADE_FORWARD ;
return ;
}
}
else
{
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < - LARA_FAST_TURN )
{
Lara . turnRate = - LARA_FAST_TURN ;
}
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > LARA_FAST_TURN )
{
Lara . turnRate = LARA_FAST_TURN ;
}
}
if ( TrInput & IN_FORWARD )
{
if ( Lara . waterStatus = = LW_ABOVE_WATER )
{
item - > goalAnimState = LS_RUN_FORWARD ;
}
else
{
item - > goalAnimState = LS_WADE_FORWARD ;
}
return ;
}
}
item - > goalAnimState = LS_STOP ;
}
// State: 65
// State code: lara_as_wade()
void lara_col_wade ( ITEM_INFO * item , COLL_INFO * coll )
{
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
if ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP )
{
if ( TrInput & IN_LEFT )
{
if ( TestLaraLean ( coll ) )
{
item - > pos . zRot - = LARA_LEAN_RATE ;
if ( item - > pos . zRot < - ( LARA_LEAN_MAX / 2 ) )
{
item - > pos . zRot = - ( LARA_LEAN_MAX / 2 ) ;
}
}
}
else if ( TrInput & IN_RIGHT )
{
if ( TestLaraLean ( coll ) )
{
item - > pos . zRot + = LARA_LEAN_RATE ;
if ( item - > pos . zRot > ( LARA_LEAN_MAX / 2 ) )
{
item - > pos . zRot = ( LARA_LEAN_MAX / 2 ) ;
}
}
}
}
else
{
if ( TrInput & IN_LEFT )
{
if ( TestLaraLean ( coll ) )
{
item - > pos . zRot - = LARA_LEAN_RATE ;
if ( item - > pos . zRot < - LARA_LEAN_MAX )
{
item - > pos . zRot = - LARA_LEAN_MAX ;
}
}
}
else if ( TrInput & IN_RIGHT )
{
if ( TestLaraLean ( coll ) )
{
item - > pos . zRot + = LARA_LEAN_RATE ;
if ( item - > pos . zRot > LARA_LEAN_MAX )
{
item - > pos . zRot = LARA_LEAN_MAX ;
}
}
}
}
if ( TestLaraVault ( item , coll ) )
{
return ;
}
if ( LaraHitCeiling ( item , coll ) )
{
return ;
}
if ( LaraDeflectEdge ( item , coll ) )
{
item - > pos . zRot = 0 ;
if ( ( coll - > frontType = = WALL | | coll - > frontType = = SPLIT_TRI ) & &
coll - > frontFloor < - ( ( 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 ) ;
}
if ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = STEPUP_HEIGHT ) & &
! ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP ) )
{
//DoLaraStep(item, coll); // Uncomment this line and remove everything below when a step down anim is created.
/*if (TestLaraStepDown(coll))
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_DOWN ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else */ if ( TestLaraStepUp ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_UP ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
}
/*if (!(g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->midFloor < 0)
{
item - > pos . yPos + = coll - > midFloor ; // Enforce to floor height.. if not a swamp room.
}
else */ if ( g_Level . Rooms [ item - > roomNumber ] . flags & ENV_FLAG_SWAMP & & coll - > midFloor )
{
item - > pos . yPos + = SWAMP_GRAVITY ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
// State: 73
// Collision: lara_col_sprint()
void lara_as_sprint ( ITEM_INFO * item , COLL_INFO * coll ) //15A28, 15B5C (F)
2020-08-14 17:54:25 -05:00
{
if ( item - > hitPoints < = 0 )
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_RUN_FORWARD ; // item->goalAnimState = LS_DEATH;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate - = LARA_TURN_RATE ;
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( - 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 4.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . turnRate = ANGLE ( 4.0f ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_JUMP | | item - > gravityStatus )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( LaraFloorFront ( item , item - > pos . yRot , 1600 ) > = 384 ) // Something fun. However, the range should be probed rather than the final location.
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_SWANDIVE_START ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
else
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_SPRINT_ROLL ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
}
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_SPRINT ) | | ! DashTimer | |
Lara . waterStatus = = LW_WADE )
{
item - > goalAnimState = LS_RUN_FORWARD ;
return ;
}
DashTimer - - ;
if ( TrInput & IN_FORWARD )
{
if ( TrInput & IN_WALK )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_WALK_FORWARD ;
2020-08-14 17:54:25 -05:00
}
else
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_SPRINT ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// Legacy doesn't require FORWARD to be held when sprinting. Keep original behaviour?
//if (TrInput & IN_LEFT || TrInput & IN_RIGHT)
//{
// item->goalAnimState = LS_SPRINT;
// return;
//}
item - > goalAnimState = LS_STOP ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
// State: 73
// State code: lara_as_sprint()
void lara_col_sprint ( ITEM_INFO * item , COLL_INFO * coll ) //15C50, 15D84 (F)
2020-08-14 17:54:25 -05:00
{
Lara . moveAngle = 0 ;
coll - > badPos = NO_BAD_POS ;
coll - > badNeg = - STEPUP_HEIGHT ;
coll - > badCeiling = 0 ;
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
{
if ( TestLaraLean ( coll ) )
{
item - > pos . zRot - = ANGLE ( 1.5f ) ;
if ( item - > pos . zRot < ANGLE ( - 16.0f ) )
{
item - > pos . zRot = ANGLE ( - 16.0f ) ;
}
}
}
else if ( TrInput & IN_RIGHT )
{
item - > pos . zRot + = ANGLE ( 1.5f ) ;
if ( item - > pos . zRot > ANGLE ( 16.0f ) )
{
item - > pos . zRot = ANGLE ( 16.0f ) ;
}
}
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
if ( TestLaraVault ( item , coll ) )
{
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraHitCeiling ( coll ) )
{
SetLaraHitCeiling ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( LaraDeflectEdge ( item , coll ) )
{
item - > pos . zRot = 0 ;
2020-09-26 03:28:30 +10:00
if ( TestWall ( item , 256 , 0 , - 640 ) )
2020-08-14 17:54:25 -05:00
{
item - > goalAnimState = LS_SPLAT ;
if ( GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) )
2020-09-26 03:28:30 +10:00
{
item - > currentAnimState = LS_SPLAT ;
2020-08-14 17:54:25 -05:00
return ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
LaraCollideStop ( item , coll ) ;
}
2020-09-26 03:28:30 +10:00
if ( TestLaraFall ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
// TODO: Step dispatches are the normal run step up anims. This is why Lara sprints up stairs like a dolt.
if ( abs ( coll - > midFloor ) > 0 & & abs ( coll - > midFloor < = STEPUP_HEIGHT ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
/*if (TestLaraStepDown(coll))
{
item - > pos . yPos + = coll - > midFloor ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STEP_DOWN ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else */ if ( TestLaraStepUp ( coll ) )
{
item - > pos . yPos + = coll - > midFloor ;
item - > goalAnimState = LS_STEP_UP ;
GetChange ( item , & g_Level . Anims [ item - > animNumber ] ) ;
}
else if ( abs ( coll - > midFloor ) > = 50 )
{
item - > pos . yPos + = 50 * GetSign ( coll - > midFloor ) ;
}
else
{
item - > pos . yPos + = coll - > midFloor ;
}
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TestLaraSlide ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
SetLaraSlide ( item , coll ) ;
2020-08-14 17:54:25 -05:00
return ;
}
2020-09-26 03:28:30 +10:00
}
// State: 74
// Collision: lara_col_sprint_roll()
void lara_as_sprint_roll ( ITEM_INFO * item , COLL_INFO * coll ) //15E1C(<), 15F50(<) (F)
{
//if (item->hitPoints <= 0)
//{
// item->goalAnimState = LS_DEATH;
// return;
//}
2020-08-14 17:54:25 -05:00
if ( TrInput & IN_LEFT )
{
Lara . turnRate - = LARA_TURN_RATE ;
2020-09-26 03:28:30 +10:00
if ( Lara . turnRate < ANGLE ( - 4.0f ) )
{
Lara . turnRate = ANGLE ( - 4.0f ) ;
}
2020-08-14 17:54:25 -05:00
}
else if ( TrInput & IN_RIGHT )
{
Lara . turnRate + = LARA_TURN_RATE ;
if ( Lara . turnRate > ANGLE ( 4.0f ) )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
Lara . turnRate = ANGLE ( 4.0f ) ;
2020-09-26 03:28:30 +10:00
}
}
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_FORWARD ) // Not necessary...
{
item - > goalAnimState = LS_RUN_FORWARD ;
return ;
2020-08-14 17:54:25 -05:00
}
2020-09-26 03:28:30 +10:00
item - > goalAnimState = LS_STOP ;
//LEGACY.
//if (item->goalAnimState != LS_DEATH &&
// item->goalAnimState != LS_STOP &&
// item->goalAnimState != LS_RUN_FORWARD &&
// item->fallspeed > LARA_FREEFALL_SPEED)
//{
// item->goalAnimState = LS_FREEFALL; // Hmm? It's not possible to go into a freefall from this state.
//}
}
// State: 74
// State code: lara_as_sprint_dive()
void lara_col_sprint_roll ( ITEM_INFO * item , COLL_INFO * coll ) //15E5C, 15F90 (F)
{
if ( item - > speed < 0 ) // Is this necessary??
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = ANGLE ( 180.0f ) ;
2020-08-14 17:54:25 -05:00
}
else
{
2020-09-26 03:28:30 +10:00
Lara . moveAngle = 0 ;
2020-08-14 17:54:25 -05:00
}
coll - > badPos = NO_BAD_POS ;
2020-09-26 03:28:30 +10:00
coll - > badNeg = - 256 ;
coll - > badCeiling = BAD_JUMP_CEILING ;
2020-08-14 17:54:25 -05:00
coll - > slopesAreWalls = true ;
coll - > facing = Lara . moveAngle ;
2020-09-26 03:28:30 +10:00
2020-08-14 17:54:25 -05:00
GetCollisionInfo ( coll , item - > pos . xPos , item - > pos . yPos , item - > pos . zPos , item - > roomNumber , LARA_HITE ) ;
2020-09-26 03:28:30 +10:00
LaraDeflectEdgeJump ( item , coll ) ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
if ( TrInput & IN_LEFT )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
if ( TestLaraLean ( coll ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot - = ANGLE ( 1.5f ) ;
if ( item - > pos . zRot < ANGLE ( - 16.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = ANGLE ( - 16.0f ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
}
else if ( TrInput & IN_RIGHT )
{
item - > pos . zRot + = ANGLE ( 1.5f ) ;
if ( item - > pos . zRot > ANGLE ( 16.0f ) )
2020-08-14 17:54:25 -05:00
{
2020-09-26 03:28:30 +10:00
item - > pos . zRot = ANGLE ( 16.0f ) ;
2020-08-14 17:54:25 -05:00
}
}
2020-09-26 03:28:30 +10:00
if ( TestLaraFall ( coll ) )
{
item - > goalAnimState = LS_FALL ;
item - > fallspeed = 0 ;
item - > gravityStatus = true ;
2020-08-14 17:54:25 -05:00
2020-09-26 03:28:30 +10:00
return ;
2020-08-14 17:54:25 -05:00
if ( item - > speed < 0 )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
Lara . moveAngle = 0 ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
if ( coll - > midFloor < = 0 & & item - > fallspeed > 0 )
{
2020-09-26 03:28:30 +10:00
item - > gravityStatus = false ;
item - > fallspeed = 0 ;
item - > pos . yPos + = coll - > midFloor ;
item - > speed = 0 ;
2020-08-14 17:54:25 -05:00
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 ;
}
AnimateLara ( item ) ;
}
ShiftItem ( item , coll ) ;
if ( coll - > midFloor ! = NO_HEIGHT )
2020-09-26 03:28:30 +10:00
{
2020-08-14 17:54:25 -05:00
item - > pos . yPos + = coll - > midFloor ;
2020-09-26 03:28:30 +10:00
}
2020-08-14 17:54:25 -05:00
}
}