2020-08-14 04:08:10 -05:00
|
|
|
#include "framework.h"
|
|
|
|
#include "lara.h"
|
|
|
|
#include "lara_collide.h"
|
2020-09-26 03:28:30 +10:00
|
|
|
#include "lara_tests.h"
|
2020-08-14 04:08:10 -05:00
|
|
|
#include "input.h"
|
|
|
|
#include "sound.h"
|
2020-09-26 03:28:30 +10:00
|
|
|
//#include "lara_slide.h"
|
2020-08-14 04:08:10 -05:00
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
int OldAngle = 1; // Don't care. To be deleted.
|
2020-08-14 04:08:10 -05:00
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
// For later.
|
|
|
|
bool EnableAugmentedSlide; // Adds steep sliding, slope hugging, 180 turn.
|
|
|
|
bool EnableNonCardinalSlide; // Slides Lara in true slope direction.
|
|
|
|
bool EnableSlideInterpolation; // Adapts Lara angles to slope.
|
|
|
|
bool EnableSlideSteering; // Allows player influence on slide trajectory.
|
2020-08-14 04:08:10 -05:00
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
// SLOPE SLIDING
|
|
|
|
|
|
|
|
// ------------------------------
|
|
|
|
// Auxiliary functions
|
|
|
|
// ------------------------------
|
|
|
|
|
|
|
|
bool TestLaraSlide(COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
short GetLaraSlideDirection(COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
short laraAngle = ANGLE(0.0f);
|
|
|
|
|
|
|
|
//if (EnableNonCardinalSlide)
|
|
|
|
//{
|
|
|
|
// // TODO: Get true slope direction.
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
if (coll->tiltX > 2)
|
|
|
|
{
|
|
|
|
laraAngle = -ANGLE(90.0f);
|
|
|
|
}
|
|
|
|
else if (coll->tiltX < -2)
|
|
|
|
{
|
|
|
|
laraAngle = ANGLE(90.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX))
|
|
|
|
{
|
|
|
|
laraAngle = ANGLE(180.0f);
|
|
|
|
}
|
|
|
|
else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX))
|
|
|
|
{
|
|
|
|
laraAngle = ANGLE(0.0f);
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
|
|
|
|
return laraAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetSlopeAngle(COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetLaraSlide(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
short dir = GetLaraSlideDirection(coll);
|
|
|
|
short polarity = dir - item->pos.yRot;
|
|
|
|
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
|
|
|
// Slide back.
|
|
|
|
if (polarity < ANGLE(-90.0f) || polarity > ANGLE(90.0f))
|
|
|
|
{
|
|
|
|
if (GetSlopeAngle(coll) < ANGLE(60.0f))//SLOPE_ANGLE_STEEP)
|
|
|
|
{
|
|
|
|
Lara.moveAngle = ANGLE(180);
|
|
|
|
item->goalAnimState = LS_SLIDE_BACK;
|
|
|
|
item->pos.yRot = dir + ANGLE(180.0f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SLIDE_STEEP_BACK;
|
|
|
|
item->pos.yRot = dir + ANGLE(180.0f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Slide forward.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (GetSlopeAngle(coll) < ANGLE(60.0f))//SLOPE_ANGLE_STEEP)
|
|
|
|
{
|
|
|
|
Lara.moveAngle = 0;
|
|
|
|
item->goalAnimState = LS_SLIDE_FORWARD;
|
|
|
|
item->pos.yRot = dir;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SLIDE_STEEP_FORWARD;
|
|
|
|
item->pos.yRot = dir;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// LEGACY. Staying until everything is done.
|
|
|
|
int Old_TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
|
|
|
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
short angle = ANGLE(0.0f);
|
|
|
|
if (coll->tiltX > 2)
|
|
|
|
angle = -ANGLE(90.0f);
|
|
|
|
else if (coll->tiltX < -2)
|
|
|
|
angle = ANGLE(90.0f);
|
|
|
|
|
|
|
|
if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX))
|
|
|
|
angle = ANGLE(180.0f);
|
|
|
|
else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX))
|
|
|
|
angle = ANGLE(0.0f);
|
|
|
|
|
|
|
|
short delta = angle - item->pos.yRot;
|
|
|
|
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
|
|
|
if (delta < -ANGLE(90.0f) || delta > ANGLE(90.0f))
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == LS_SLIDE_BACK && OldAngle == angle)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
item->animNumber = LA_SLIDE_BACK_START;
|
|
|
|
item->goalAnimState = LS_SLIDE_BACK;
|
|
|
|
item->currentAnimState = LS_SLIDE_BACK;
|
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
|
|
item->pos.yRot = angle + ANGLE(180.0f);
|
|
|
|
Lara.moveAngle = ANGLE(180);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == LS_SLIDE_FORWARD && OldAngle == angle)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
item->animNumber = LA_SLIDE_FORWARD;
|
|
|
|
item->goalAnimState = LS_SLIDE_FORWARD;
|
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
|
|
item->currentAnimState = LS_SLIDE_FORWARD;
|
|
|
|
item->pos.yRot = angle;
|
|
|
|
Lara.moveAngle = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
OldAngle = angle;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
void PerformLaraSlide(ITEM_INFO* item, COLL_INFO* coll)//127BC, 1286C (F)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
void PerformLaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
|
|
|
switch (coll->collType)
|
|
|
|
{
|
|
|
|
case CT_LEFT:
|
|
|
|
item->pos.yRot += ANGLE(5.0f);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CT_RIGHT:
|
|
|
|
item->pos.yRot -= ANGLE(5.0f);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CT_TOP:
|
|
|
|
case CT_TOP_FRONT:
|
|
|
|
if (item->fallspeed <= 0)
|
|
|
|
item->fallspeed = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CT_CLAMP:
|
|
|
|
item->pos.zPos -= (400 * phd_cos(coll->facing)) >> W2V_SHIFT;
|
|
|
|
item->pos.xPos -= (400 * phd_sin(coll->facing)) >> W2V_SHIFT;
|
|
|
|
|
|
|
|
item->speed = 0;
|
|
|
|
|
|
|
|
coll->midFloor = 0;
|
|
|
|
|
|
|
|
if (item->fallspeed <= 0)
|
|
|
|
item->fallspeed = 16;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-09-26 03:28:30 +10:00
|
|
|
|
|
|
|
// ------------------------------
|
|
|
|
// SLOPE SLIDING
|
|
|
|
// Control & Collision Functions
|
|
|
|
// ------------------------------
|
|
|
|
|
|
|
|
// State: 24
|
|
|
|
// Collision: lara_col_Slide()
|
|
|
|
void lara_as_slide(ITEM_INFO* player, COLL_INFO* coll)//1A824(<), 1A958(<) (F)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
2020-09-26 03:28:30 +10:00
|
|
|
Camera.targetElevation = player->pos.xRot - ANGLE(45.0f);
|
|
|
|
|
|
|
|
/*if (TrInput & IN_LEFT)
|
|
|
|
{
|
|
|
|
player->pos.yRot -= ANGLE(2.0f);
|
|
|
|
|
|
|
|
Lara.turnRate -= LARA_TURN_RATE;
|
|
|
|
if (Lara.turnRate < -LARA_FAST_TURN)
|
|
|
|
{
|
|
|
|
Lara.turnRate = -LARA_FAST_TURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraLean(coll) & EnableSlideSteering)
|
|
|
|
{
|
|
|
|
player->pos.zRot -= LARA_LEAN_RATE;
|
|
|
|
if (player->pos.zRot < -LARA_LEAN_MAX)
|
|
|
|
{
|
|
|
|
player->pos.zRot = -LARA_LEAN_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
|
|
|
player->pos.yRot += ANGLE(2.0f);
|
|
|
|
|
|
|
|
Lara.turnRate += LARA_TURN_RATE;
|
|
|
|
if (Lara.turnRate > LARA_FAST_TURN)
|
|
|
|
{
|
|
|
|
Lara.turnRate = LARA_FAST_TURN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TestLaraLean(coll) && EnableSlideSteering)
|
|
|
|
{
|
|
|
|
player->pos.zRot += LARA_LEAN_RATE;
|
|
|
|
if (player->pos.zRot > LARA_LEAN_MAX)
|
|
|
|
{
|
|
|
|
player->pos.zRot = LARA_LEAN_MAX;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
|
|
|
|
|
|
|
if ((TrInput & IN_BACK) || (TrInput & IN_DUCK))
|
|
|
|
{
|
|
|
|
player->goalAnimState = LS_SLIDE_STEEP_FORWARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
|
|
|
{
|
|
|
|
player->goalAnimState = LS_JUMP_FORWARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_ROLL)
|
|
|
|
{
|
|
|
|
player->goalAnimState = LS_SLIDE_TURN_180;
|
|
|
|
//SetLaraSlide(item, coll); // Temp: Lara slides up the slope otherwise.
|
|
|
|
}
|
2020-08-14 04:08:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void lara_col_slide(ITEM_INFO* item, COLL_INFO* coll)//1C108(<), 1C23C(<) (F)
|
|
|
|
{
|
2020-09-26 03:28:30 +10:00
|
|
|
Lara.moveAngle = ANGLE(0.0f);
|
|
|
|
|
|
|
|
coll->badPos = NO_BAD_POS;
|
|
|
|
coll->badNeg = -512;
|
|
|
|
coll->badCeiling = 0;
|
|
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
|
|
|
|
|
|
|
|
LaraDeflectEdge(item, coll);
|
|
|
|
|
|
|
|
if (coll->midFloor <= 200)
|
|
|
|
{
|
|
|
|
item->pos.yPos += coll->midFloor;
|
|
|
|
|
|
|
|
if (!TestLaraSlide(coll))
|
|
|
|
{
|
|
|
|
item->goalAnimState = (TrInput & IN_FORWARD) ? LS_RUN_FORWARD : LS_STOP;
|
|
|
|
|
|
|
|
StopSoundEffect(SFX_LARA_SLIPPING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (TrInput & IN_ACTION && coll->midFloor >= 1024 && EnableSafetyDrop)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SAFE_DROP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_FALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->gravityStatus = true;
|
|
|
|
item->fallspeed = 0;
|
|
|
|
|
|
|
|
StopSoundEffect(SFX_LARA_SLIPPING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// State: 32
|
|
|
|
// Collision: lara_col_SlideBack()
|
|
|
|
void lara_as_slide_back(ITEM_INFO* item, COLL_INFO* coll)//1A9E0(<), 1AB14(<) (F)
|
|
|
|
{
|
|
|
|
Camera.targetElevation = item->pos.xRot;
|
|
|
|
|
|
|
|
//if (TrInput & IN_FORWARD)
|
|
|
|
// item->goalAnimState = LS_SLIDE_STEEP_BACK;
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_JUMP_BACK;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*if (TrInput & IN_ROLL)
|
|
|
|
{
|
|
|
|
item->pos.yRot += ANGLE(180.0f);
|
|
|
|
item->goalAnimState = LS_SLIDE_FORWARD;
|
|
|
|
SetLaraSlide(item, coll);
|
|
|
|
}*/
|
|
|
|
}
|
|
|
|
|
|
|
|
void lara_col_slide_back(ITEM_INFO* item, COLL_INFO* coll)//1C284(<), 1C3B8(<) (F)
|
|
|
|
{
|
|
|
|
Lara.moveAngle = ANGLE(180.0f);
|
|
|
|
|
|
|
|
coll->badPos = NO_BAD_POS;
|
|
|
|
coll->badNeg = -512;
|
|
|
|
coll->badCeiling = 0;
|
|
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
|
|
|
|
if (TestLaraHitCeiling(coll))
|
|
|
|
{
|
|
|
|
SetLaraHitCeiling(item, coll);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
|
|
|
|
|
|
|
|
LaraDeflectEdge(item, coll);
|
|
|
|
|
|
|
|
if (coll->midFloor <= 200)
|
|
|
|
{
|
|
|
|
item->pos.yPos += coll->midFloor;
|
|
|
|
|
|
|
|
if (!TestLaraSlide(coll))
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_STOP;
|
|
|
|
StopSoundEffect(SFX_LARA_SLIPPING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (TrInput & IN_ACTION && coll->midFloor >= 1024 && EnableSafetyDrop)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SAFE_DROP;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_FALL_BACK;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->gravityStatus = true;
|
|
|
|
item->fallspeed = 0;
|
|
|
|
|
|
|
|
StopSoundEffect(SFX_LARA_SLIPPING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: Unique handling for steep slopes. Anims on the way.
|
|
|
|
void lara_as_steep_slide(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
if (item->pos.xRot >= ANGLE(60))
|
|
|
|
{
|
|
|
|
Camera.targetElevation = ANGLE(-60.0f);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Camera.targetElevation = ANGLE(-45.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_FORWARD)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SLIDE_FORWARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_JUMP_FORWARD;
|
|
|
|
}
|
2020-08-14 04:08:10 -05:00
|
|
|
}
|
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
void lara_col_steep_slide(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
2020-09-26 03:28:30 +10:00
|
|
|
Lara.moveAngle = ANGLE(0.0f);
|
|
|
|
PerformLaraSlide(item, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lara_as_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
Camera.targetElevation = ANGLE(-60.0f);
|
|
|
|
|
|
|
|
if (TrInput & IN_BACK)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_SLIDE_BACK;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
|
|
|
item->goalAnimState = LS_JUMP_BACK;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-26 03:28:30 +10:00
|
|
|
void lara_col_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
Lara.moveAngle = ANGLE(180.0f);
|
|
|
|
PerformLaraSlide(item, coll);
|
|
|
|
}
|
|
|
|
|
|
|
|
void lara_as_slide_turn_180(ITEM_INFO* item, COLL_INFO* coll)
|
2020-08-14 04:08:10 -05:00
|
|
|
{
|
2020-09-26 03:28:30 +10:00
|
|
|
Lara.moveAngle = ANGLE(0.0f);
|
2020-08-14 04:08:10 -05:00
|
|
|
}
|
2020-09-26 03:28:30 +10:00
|
|
|
|
|
|
|
// TODO: Straddling illegal slopes.
|
|
|
|
// TODO: Grabbing edge of plateau leading to steep slope.
|