mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-06 19:01:06 +03:00
905 lines
23 KiB
C++
905 lines
23 KiB
C++
#include "framework.h"
|
|
#include "lara.h"
|
|
#include "input.h"
|
|
#include "lara_tests.h"
|
|
#include "lara_slide.h"
|
|
#include "lara_collide.h"
|
|
#include "draw.h"
|
|
|
|
/*this file has all the related functions to ducking and crawling*/
|
|
|
|
/*crouch/duck start*/
|
|
void lara_as_duck(ITEM_INFO* item, COLL_INFO* coll)//14688, 14738 (F)
|
|
{
|
|
/*state 71*/
|
|
/*collision: lara_col_duck*/
|
|
short roomNum;
|
|
|
|
coll->enableSpaz = false;
|
|
coll->enableBaddiePush = true;
|
|
|
|
Lara.isDucked = true;
|
|
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
return;
|
|
}
|
|
|
|
roomNum = LaraItem->roomNumber;
|
|
|
|
if (TrInput & IN_LOOK)
|
|
LookUpDown();
|
|
|
|
GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &roomNum);
|
|
|
|
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED-
|
|
// EnableCrouchRoll = true;
|
|
|
|
|
|
if ((TrInput & IN_FORWARD || TrInput & IN_BACK)
|
|
&& (TrInput & IN_DUCK || Lara.keepDucked)
|
|
&& Lara.gunStatus == LG_NO_ARMS
|
|
&& Lara.waterStatus != LW_WADE
|
|
|| Lara.waterSurfaceDist == 256
|
|
&& !(Lara.waterSurfaceDist > 256))
|
|
{
|
|
|
|
if ((item->animNumber == LA_CROUCH_IDLE
|
|
|| item->animNumber == LA_STAND_TO_CROUCH_END)
|
|
&& !(TrInput & IN_FLARE || TrInput & IN_DRAW)
|
|
&& (Lara.gunType != WEAPON_FLARE || Lara.flareAge < 900 && Lara.flareAge != 0))
|
|
{
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
}
|
|
|
|
}
|
|
else if ((TrInput & IN_SPRINT) /*crouch roll*/
|
|
&& (TrInput & IN_DUCK || Lara.keepDucked)
|
|
&& Lara.gunStatus == LG_NO_ARMS
|
|
&& Lara.waterStatus != LW_WADE
|
|
|| Lara.waterSurfaceDist == 256
|
|
&& !(Lara.waterSurfaceDist > 256))
|
|
// && EnableCrouchRoll == true)
|
|
{
|
|
if (LaraFloorFront(item, item->pos.yRot, 1024) >= 384 || //4 clicks away from holes in the floor
|
|
TestWall(item, 1024, 0, -256)) //4 clicks away from walls
|
|
return;
|
|
|
|
if (!(TrInput & IN_FLARE || TrInput & IN_DRAW) //avoids some flare spawning/wep stuff
|
|
&& (Lara.gunType != WEAPON_FLARE || Lara.flareAge < 900 && Lara.flareAge != 0))
|
|
|
|
{
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
item->goalAnimState = LS_CROUCH_ROLL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void lara_col_duck(ITEM_INFO* item, COLL_INFO* coll)//147C4, 148CC (F)
|
|
{
|
|
/*state 71*/
|
|
/*state code: lara_as_duck*/
|
|
item->gravityStatus = false;
|
|
item->fallspeed = 0;
|
|
|
|
Lara.moveAngle = 0;
|
|
|
|
coll->facing = item->pos.yRot;
|
|
coll->badPos = 384;
|
|
coll->badNeg = -STEPUP_HEIGHT;
|
|
coll->badCeiling = 0;
|
|
|
|
coll->slopesAreWalls = true;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
|
|
|
|
if (LaraFallen(item, coll))
|
|
{
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
}
|
|
else if (!TestLaraSlide(item, coll))
|
|
{
|
|
Lara.keepDucked = coll->midCeiling >= -362;
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
if (coll->midFloor != NO_HEIGHT)
|
|
item->pos.yPos += coll->midFloor;
|
|
|
|
if (TrInput & IN_DUCK && Lara.waterStatus != LW_WADE ||
|
|
Lara.keepDucked ||
|
|
item->animNumber != LA_CROUCH_IDLE)
|
|
{
|
|
if (TrInput & IN_LEFT)
|
|
{
|
|
item->goalAnimState = LS_CROUCH_TURN_LEFT;
|
|
}
|
|
else if (TrInput & IN_RIGHT)
|
|
{
|
|
item->goalAnimState = LS_CROUCH_TURN_RIGHT;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = LS_STOP;
|
|
}
|
|
}
|
|
}
|
|
|
|
void lara_as_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
|
|
{
|
|
/*state 72*/
|
|
/*collision: lara_col_crouch_roll*/
|
|
Camera.targetElevation = -ANGLE(20.0f);
|
|
item->goalAnimState = LS_CROUCH_IDLE;
|
|
}
|
|
|
|
void lara_col_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
|
|
{
|
|
/*state 72*/
|
|
/*state code: lara_as_crouch_roll*/
|
|
Lara.isDucked = true;
|
|
item->gravityStatus = false;
|
|
item->fallspeed = 0;
|
|
Lara.moveAngle = 0;
|
|
coll->facing = item->pos.yRot;
|
|
coll->badPos = STEPUP_HEIGHT;
|
|
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);
|
|
|
|
ShiftItem(item, coll);
|
|
if (coll->midFloor != NO_HEIGHT)
|
|
item->pos.yPos += coll->midFloor;
|
|
}
|
|
/*crouch/duck end*/
|
|
/*-*/
|
|
/*crawl start*/
|
|
void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F)
|
|
{
|
|
/*state 80*/
|
|
/*collision: lara_col_all4s*/
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
item->goalAnimState = LS_DEATH;
|
|
return;
|
|
}
|
|
|
|
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED
|
|
// EnableCrawlFlex1clickdown = true;
|
|
// EnableCrawlFlex1clickup = true;
|
|
// EnableCrawlFlex3clickE = true;
|
|
// EnableCrawlFlex2clickE = true;
|
|
// EnableCrawlFlex1clickE = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (TrInput & IN_JUMP)
|
|
{
|
|
GAME_VECTOR s, d;
|
|
MESH_INFO* StaticMesh;
|
|
PHD_VECTOR v;
|
|
|
|
if (LaraFloorFront(item, item->pos.yRot, 512) > 768 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
|
|
{
|
|
|
|
s.x = LaraItem->pos.xPos;
|
|
s.y = LaraItem->pos.yPos - 96;
|
|
s.z = LaraItem->pos.zPos;
|
|
s.roomNumber = LaraItem->roomNumber;
|
|
|
|
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
d.y = s.y + 160;
|
|
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
|
|
if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)
|
|
{
|
|
// TODO: fix ObjectOnLOS2
|
|
/*if (ObjectOnLOS2(&s, &d, &v, (PHD_VECTOR*)&StaticMesh) == 999)
|
|
{*/
|
|
item->animNumber = LA_CRAWL_JUMP_FLIP_DOWN;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
/*}*/
|
|
}
|
|
}
|
|
else if (LaraFloorFront(item, item->pos.yRot, 256) == 768 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
|
|
{
|
|
s.x = LaraItem->pos.xPos;
|
|
s.y = LaraItem->pos.yPos - 96;
|
|
s.z = LaraItem->pos.zPos;
|
|
s.roomNumber = LaraItem->roomNumber;
|
|
|
|
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
d.y = s.y + 160;
|
|
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
|
|
if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex3clickE == true)
|
|
{
|
|
item->animNumber = LA_CRAWL_JUMP_DOWN_23CLICK;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
}
|
|
}
|
|
else if (LaraFloorFront(item, item->pos.yRot, 256) == 512 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
|
|
{
|
|
|
|
s.x = LaraItem->pos.xPos;
|
|
s.y = LaraItem->pos.yPos - 96;
|
|
s.z = LaraItem->pos.zPos;
|
|
s.roomNumber = LaraItem->roomNumber;
|
|
|
|
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
d.y = s.y + 160;
|
|
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
|
|
if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex2clickE == true)
|
|
{
|
|
item->animNumber = LA_CRAWL_JUMP_DOWN_23CLICK;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
}
|
|
}
|
|
else if (LaraFloorFront(item, item->pos.yRot, 256) == 256 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
|
|
{
|
|
s.x = LaraItem->pos.xPos;
|
|
s.y = LaraItem->pos.yPos - 96;
|
|
s.z = LaraItem->pos.zPos;
|
|
s.roomNumber = LaraItem->roomNumber;
|
|
|
|
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
d.y = s.y + 160;
|
|
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
|
|
|
|
if (LOS(&s, &d) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)// && EnableCrawlFlex1clickE == true)
|
|
{
|
|
item->animNumber = LA_CRAWL_JUMP_DOWN_1CLICK;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if ((TrInput & IN_ACTION) && (TrInput & IN_FORWARD) && item->animNumber != LA_CROUCH_TO_CRAWL_START && item->animNumber != LA_CROUCH_TO_CRAWL_CONTINUE)
|
|
{
|
|
if (LaraFloorFront(item, item->pos.yRot, 256) == -256 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 256, 256) <= -512)// &&
|
|
// EnableCrawlFlex1clickup == true)
|
|
{
|
|
item->animNumber = LA_CRAWL_UP_STEP;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
}
|
|
else
|
|
if (LaraFloorFront(item, item->pos.yRot, 256) == 256 &&
|
|
LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT &&
|
|
LaraCeilingFront(item, item->pos.yRot, 256, -256) <= -512)// &&
|
|
// EnableCrawlFlex1clickdown == true)
|
|
{
|
|
item->animNumber = LA_CRAWL_DOWN_STEP;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->goalAnimState = LS_MISC_CONTROL;
|
|
item->currentAnimState = LS_MISC_CONTROL;
|
|
}
|
|
}
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
if (TrInput & IN_LOOK)
|
|
LookUpDown();
|
|
|
|
Lara.torsoXrot = 0;
|
|
Lara.torsoYrot = 0;
|
|
|
|
coll->enableSpaz = false;
|
|
coll->enableBaddiePush = true;
|
|
|
|
if (item->animNumber == LA_CROUCH_TO_CRAWL_START)
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
|
|
Camera.targetElevation = -ANGLE(23.0f);
|
|
|
|
if (g_Level.Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER)
|
|
{
|
|
item->goalAnimState = LS_CROUCH_IDLE;
|
|
item->requiredAnimState = LS_STOP;
|
|
}
|
|
}
|
|
|
|
void lara_col_all4s(ITEM_INFO* item, COLL_INFO* coll)//14B40, 14C74 (F)
|
|
{
|
|
/*state 80*/
|
|
/*state code: lara_as_all4s*/
|
|
item->fallspeed = 0;
|
|
item->gravityStatus = false;
|
|
|
|
if (item->goalAnimState != LS_CRAWL_TO_HANG)
|
|
{
|
|
Lara.moveAngle = 0;
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
coll->radius = 200;
|
|
coll->badPos = 255;
|
|
coll->badNeg = -127;
|
|
coll->badCeiling = 400;
|
|
|
|
coll->slopesAreWalls = true;
|
|
coll->slopesArePits = true;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
|
|
|
|
if (LaraFallen(item, coll))
|
|
{
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
}
|
|
else if (!TestLaraSlide(item, coll))
|
|
{
|
|
int slope = abs(coll->leftFloor2 - coll->rightFloor2);
|
|
|
|
Lara.keepDucked = coll->midCeiling >= -362;
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
|
|
item->pos.yPos += coll->midFloor;
|
|
|
|
if (TrInput & IN_DUCK || Lara.keepDucked &&
|
|
(!(TrInput & IN_FLARE) && !(TrInput & IN_DRAW) || TrInput & IN_FORWARD) &&
|
|
Lara.waterStatus != LW_WADE)
|
|
{
|
|
if (item->animNumber == LA_CRAWL_IDLE ||
|
|
item->animNumber == LA_CROUCH_TO_CRAWL_END ||
|
|
item->animNumber == LA_CRAWL_TO_IDLE_END_RIGHT_POINTLESS ||
|
|
item->animNumber == LA_CRAWL_TO_IDLE_END_LEFT_POINTLESS)
|
|
{
|
|
if (TrInput & IN_FORWARD)
|
|
{
|
|
if (abs(LaraFloorFront(item, item->pos.yRot, 256)) < 127 && HeightType != BIG_SLOPE)
|
|
item->goalAnimState = LS_CRAWL_FORWARD;
|
|
}
|
|
else if (TrInput & IN_BACK)
|
|
{
|
|
short height = LaraCeilingFront(item, item->pos.yRot, -300, 128);
|
|
short heightl = 0;
|
|
short heightr = 0;
|
|
|
|
if (height != NO_HEIGHT && height <= 256)
|
|
{
|
|
if (TrInput & IN_ACTION)
|
|
{
|
|
int x = item->pos.xPos;
|
|
int z = item->pos.zPos;
|
|
|
|
item->pos.xPos += 128 * phd_sin(item->pos.yRot - ANGLE(90.0f)) >> W2V_SHIFT;
|
|
item->pos.zPos += 128 * phd_cos(item->pos.yRot - ANGLE(90.0f)) >> W2V_SHIFT;
|
|
|
|
heightl = LaraFloorFront(item, item->pos.yRot, -300);
|
|
|
|
item->pos.xPos += 256 * phd_sin(item->pos.yRot + ANGLE(90.0f)) >> W2V_SHIFT;
|
|
item->pos.zPos += 256 * phd_cos(item->pos.yRot + ANGLE(90.0f)) >> W2V_SHIFT;
|
|
|
|
heightr = LaraFloorFront(item, item->pos.yRot, -300);
|
|
|
|
item->pos.xPos = x;
|
|
item->pos.zPos = z;
|
|
}
|
|
|
|
height = LaraFloorFront(item, item->pos.yRot, -300);
|
|
|
|
if (abs(height) >= 255 || HeightType == BIG_SLOPE)
|
|
{
|
|
if (TrInput & IN_ACTION)
|
|
{
|
|
if (height > 768 &&
|
|
heightl > 768 &&
|
|
heightr > 768 &&
|
|
slope < 120)
|
|
{
|
|
int tmp;
|
|
ITEM_INFO* tmp1;
|
|
MESH_INFO* tmp2;
|
|
int x = item->pos.xPos;
|
|
int z = item->pos.zPos;
|
|
|
|
item->pos.xPos -= 100 * phd_sin(coll->facing) >> W2V_SHIFT;
|
|
item->pos.zPos -= 100 * phd_cos(coll->facing) >> W2V_SHIFT;
|
|
|
|
tmp = GetCollidedObjects(item, 100, 1, &tmp1, &tmp2, 0);
|
|
|
|
item->pos.xPos = x;
|
|
item->pos.zPos = z;
|
|
|
|
if (!tmp)
|
|
{
|
|
switch (GetQuadrant(item->pos.yRot))
|
|
{
|
|
case 0:
|
|
item->pos.yRot = 0;
|
|
item->pos.zPos = (item->pos.zPos & 0xFFFFFC00) + 225;
|
|
break;
|
|
case 1:
|
|
item->pos.yRot = ANGLE(90.0f);
|
|
item->pos.xPos = (item->pos.xPos & 0xFFFFFC00) + 225;
|
|
break;
|
|
case 2:
|
|
item->pos.yRot = -ANGLE(180.0f);
|
|
item->pos.zPos = (item->pos.zPos | 0x3FF) - 225;
|
|
break;
|
|
case 3:
|
|
item->pos.yRot = -ANGLE(90.0f);
|
|
item->pos.xPos = (item->pos.xPos | 0x3FF) - 225;
|
|
break;
|
|
}
|
|
|
|
item->goalAnimState = LS_CRAWL_TO_HANG;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (!(abs(height) >= 127))
|
|
{
|
|
item->goalAnimState = LS_CRAWL_BACK;
|
|
}
|
|
}
|
|
}
|
|
else if (TrInput & IN_LEFT)
|
|
{
|
|
item->animNumber = LA_CRAWL_TURN_LEFT;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LS_CRAWL_TURN_LEFT;
|
|
item->goalAnimState = LS_CRAWL_TURN_LEFT;
|
|
}
|
|
else if (TrInput & IN_RIGHT)
|
|
{
|
|
item->animNumber = LA_CRAWL_TURN_RIGHT;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LS_CRAWL_TURN_RIGHT;
|
|
item->goalAnimState = LS_CRAWL_TURN_RIGHT;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = LS_CROUCH_IDLE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void lara_as_crawl(ITEM_INFO* item, COLL_INFO* coll)//150F4, 15228 (F)
|
|
{
|
|
/*state 81*/
|
|
/*collision: lara_col_crawl*/
|
|
if (item->hitPoints <= 0 || TrInput & IN_JUMP)
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
return;
|
|
}
|
|
|
|
if (TrInput & IN_LOOK)
|
|
LookUpDown();
|
|
|
|
Lara.torsoXrot = 0;
|
|
Lara.torsoYrot = 0;
|
|
|
|
coll->enableSpaz = false;
|
|
coll->enableBaddiePush = true;
|
|
|
|
Camera.targetElevation = -ANGLE(23.0f);
|
|
|
|
if (TrInput & IN_FORWARD
|
|
&& (TrInput & IN_DUCK || Lara.keepDucked)
|
|
&& Lara.waterStatus != LW_WADE)
|
|
{
|
|
if (TrInput & IN_LEFT)
|
|
{
|
|
Lara.turnRate -= LARA_TURN_RATE;
|
|
|
|
if (Lara.turnRate < -ANGLE(3.0f))
|
|
Lara.turnRate = -ANGLE(3.0f);
|
|
}
|
|
else if (TrInput & IN_RIGHT)
|
|
{
|
|
Lara.turnRate += LARA_TURN_RATE;
|
|
|
|
if (Lara.turnRate > ANGLE(3.0f))
|
|
Lara.turnRate = ANGLE(3.0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
}
|
|
}
|
|
|
|
void lara_col_crawl(ITEM_INFO* item, COLL_INFO* coll)//1523C, 15370 (F)
|
|
{
|
|
/*state 81*/
|
|
/*state code: lara_as_crawl*/
|
|
item->gravityStatus = false;
|
|
item->fallspeed = 0;
|
|
|
|
Lara.moveAngle = 0;
|
|
|
|
coll->radius = 200;
|
|
|
|
coll->badPos = 255;
|
|
coll->badNeg = -127;
|
|
coll->badCeiling = 400;
|
|
|
|
coll->slopesArePits = true;
|
|
coll->slopesAreWalls = true;
|
|
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, -400);
|
|
|
|
if (LaraDeflectEdgeDuck(item, coll))
|
|
{
|
|
item->currentAnimState = LS_CRAWL_IDLE;
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
|
|
if (item->animNumber != LA_CRAWL_IDLE)
|
|
{
|
|
item->animNumber = LA_CRAWL_IDLE;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
}
|
|
}
|
|
else if (LaraFallen(item, coll))
|
|
{
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
}
|
|
else if (!TestLaraSlide(item, coll))
|
|
{
|
|
ShiftItem(item, coll);
|
|
|
|
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
|
|
item->pos.yPos += coll->midFloor;
|
|
}
|
|
}
|
|
|
|
void lara_as_all4turnl(ITEM_INFO* item, COLL_INFO* coll)//15390(<), 154C4(<) (F)
|
|
{
|
|
/*state 84*/
|
|
/*collision: lara_col_all4turnlr*/
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
return;
|
|
}
|
|
|
|
coll->enableSpaz = 0;
|
|
coll->enableBaddiePush = 1;
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
Camera.targetElevation = -ANGLE(23.0f);
|
|
item->pos.yRot -= ANGLE(1.5f);
|
|
|
|
if (!(TrInput & IN_LEFT))
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
}
|
|
|
|
void lara_as_all4turnr(ITEM_INFO* item, COLL_INFO* coll)//15484(<), 155B8(<) (F)
|
|
{
|
|
/*state 85*/
|
|
/*collision: lara_col_all4turnlr*/
|
|
if (item->hitPoints <= 0)
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
return;
|
|
}
|
|
|
|
coll->enableSpaz = 0;
|
|
coll->enableBaddiePush = 1;
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
Camera.targetElevation = -ANGLE(23.0f);
|
|
item->pos.yRot += ANGLE(1.5f);
|
|
|
|
if (!(TrInput & IN_RIGHT))
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
}
|
|
|
|
void lara_col_all4turnlr(ITEM_INFO* item, COLL_INFO* coll)//153FC, 15530 (F)
|
|
{
|
|
/*states 84 and 85*/
|
|
/*state code: lara_as_all4turnl(84) and lara_as_all4turnr(85)*/
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
|
|
|
|
if (!TestLaraSlide(item, coll))
|
|
{
|
|
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
|
|
item->pos.yPos += coll->midFloor;
|
|
}
|
|
}
|
|
|
|
void lara_as_crawlb(ITEM_INFO* item, COLL_INFO* coll)//154F0, 15624 (F)
|
|
{
|
|
/*state 86*/
|
|
/*collision: lara_col_crawlb*/
|
|
if (item->hitPoints <= 0 || Lara.waterStatus == 4)
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
return;
|
|
}
|
|
|
|
if (TrInput & IN_LOOK)
|
|
LookUpDown();
|
|
|
|
coll->enableSpaz = false;
|
|
coll->enableBaddiePush = true;
|
|
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
|
|
Camera.targetElevation = -ANGLE(23.0f);
|
|
|
|
if (TrInput & IN_BACK)
|
|
{
|
|
if (TrInput & IN_RIGHT)
|
|
{
|
|
Lara.turnRate -= LARA_TURN_RATE;
|
|
if (Lara.turnRate < -ANGLE(3.0f))
|
|
Lara.turnRate = -ANGLE(3.0f);
|
|
}
|
|
else if (TrInput & IN_LEFT)
|
|
{
|
|
Lara.turnRate += LARA_TURN_RATE;
|
|
if (Lara.turnRate > ANGLE(3.0f))
|
|
Lara.turnRate = ANGLE(3.0f);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
}
|
|
}
|
|
|
|
void lara_col_crawlb(ITEM_INFO* item, COLL_INFO* coll)//15614, 15748 (F)
|
|
{
|
|
/*state 86*/
|
|
/*state code: lara_as_crawlb*/
|
|
item->gravityStatus = false;
|
|
item->fallspeed = 0;
|
|
|
|
coll->radius = 250;
|
|
coll->badPos = 255;
|
|
coll->badNeg = -127;
|
|
coll->badCeiling = 400;
|
|
coll->slopesArePits = true;
|
|
coll->slopesAreWalls = true;
|
|
|
|
Lara.moveAngle = ANGLE(180);
|
|
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
|
|
|
|
if (LaraDeflectEdgeDuck(item, coll))
|
|
{
|
|
item->currentAnimState = LS_CRAWL_IDLE;
|
|
item->goalAnimState = LS_CRAWL_IDLE;
|
|
|
|
if (item->animNumber != LA_CRAWL_IDLE)
|
|
{
|
|
item->animNumber = LA_CRAWL_IDLE;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
}
|
|
}
|
|
else if (LaraFallen(item, coll))
|
|
{
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
}
|
|
else if (!TestLaraSlide(item, coll))
|
|
{
|
|
ShiftItem(item, coll);
|
|
|
|
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
|
|
item->pos.yPos += coll->midFloor;
|
|
|
|
Lara.moveAngle = 0;
|
|
}
|
|
}
|
|
|
|
void lara_as_duckl(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
|
{
|
|
/*state 105*/
|
|
/*collision: lara_col_ducklr*/
|
|
coll->enableSpaz = false;
|
|
if ((TrInput & (IN_DUCK | IN_LEFT)) != (IN_DUCK | IN_LEFT) || item->hitPoints <= 0)
|
|
item->goalAnimState = LS_CROUCH_IDLE;
|
|
item->pos.yRot -= ANGLE(1.5f);
|
|
}
|
|
|
|
void lara_as_duckr(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
|
{
|
|
/*state 106*/
|
|
/*collision: lara_col_ducklr*/
|
|
coll->enableSpaz = false;
|
|
if ((TrInput & (IN_DUCK | IN_LEFT)) != (IN_DUCK | IN_LEFT) || item->hitPoints <= 0) /* @ORIGINAL_BUG: the condition checks for IN_LEFT instead of IN_RIGHT */
|
|
item->goalAnimState = LS_CROUCH_IDLE;
|
|
item->pos.yRot += ANGLE(1.5f);
|
|
}
|
|
|
|
void lara_col_ducklr(ITEM_INFO* item, COLL_INFO* coll)//14534, 145E4 (F)
|
|
{
|
|
/*state 105 and 106*/
|
|
/*state code: lara_as_duckl(105) and lara_col_ducklr(106)*/
|
|
// FIXED
|
|
Lara.isDucked = true;
|
|
if (TrInput & IN_LOOK)
|
|
LookUpDown();
|
|
|
|
item->gravityStatus = false;
|
|
item->fallspeed = 0;
|
|
|
|
Lara.moveAngle = 0;
|
|
|
|
coll->facing = item->pos.yRot;
|
|
coll->badPos = 384;
|
|
coll->badNeg = -STEPUP_HEIGHT;
|
|
coll->badCeiling = 0;
|
|
coll->slopesAreWalls = true;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
|
|
|
|
if (LaraFallen(item, coll))
|
|
{
|
|
Lara.gunStatus = LG_NO_ARMS;
|
|
}
|
|
else if (!TestLaraSlide(item, coll))
|
|
{
|
|
if (coll->midCeiling < -362)
|
|
Lara.keepDucked = false;
|
|
else
|
|
Lara.keepDucked = true;
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
if (coll->midFloor != NO_HEIGHT)
|
|
item->pos.yPos += coll->midFloor;
|
|
}
|
|
}
|
|
/*crawling end*/
|
|
|
|
void lara_col_crawl2hang(ITEM_INFO* item, COLL_INFO* coll)//15770, 158A4 (F)
|
|
{
|
|
Camera.targetAngle = 0;
|
|
Camera.targetElevation = -ANGLE(45.0f);
|
|
|
|
coll->enableSpaz = false;
|
|
coll->enableBaddiePush = false;
|
|
|
|
if (item->animNumber == LA_CRAWL_TO_HANG_END)
|
|
{
|
|
int edgeCatch;
|
|
int edge;
|
|
|
|
item->fallspeed = 512;
|
|
item->pos.yPos += 255;
|
|
|
|
coll->badPos = NO_BAD_POS;
|
|
coll->badNeg = -STEPUP_HEIGHT;
|
|
coll->badCeiling = BAD_JUMP_CEILING;
|
|
|
|
Lara.moveAngle = 0;
|
|
coll->facing = Lara.moveAngle;
|
|
|
|
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 870);
|
|
edgeCatch = LaraTestEdgeCatch(item, coll, &edge);
|
|
|
|
if (edgeCatch)
|
|
{
|
|
if (edgeCatch >= 0 || LaraTestHangOnClimbWall(item, coll))
|
|
{
|
|
short angle = item->pos.yRot;
|
|
if (SnapToQuadrant(angle, 35))
|
|
{
|
|
BOUNDING_BOX* bounds;
|
|
|
|
if (TestHangSwingIn(item, angle))
|
|
{
|
|
|
|
Lara.headYrot = 0;
|
|
Lara.headXrot = 0;
|
|
Lara.torsoYrot = 0;
|
|
Lara.torsoXrot = 0;
|
|
item->animNumber = LA_JUMP_UP_TO_MONKEYSWING;
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
item->currentAnimState = LS_MONKEYSWING_IDLE;
|
|
item->goalAnimState = LS_MONKEYSWING_IDLE;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
bounds = GetBoundsAccurate(item);
|
|
|
|
if (edgeCatch <= 0)
|
|
{
|
|
item->pos.yPos = edge - bounds->Y1;
|
|
}
|
|
else
|
|
{
|
|
|
|
/* item->pos.xPos += coll->shift.x;
|
|
item->pos.zPos += coll->shift.z;
|
|
@ORIGINAL_BUG: these two caused teleportation when Lara performed crawl2hang on triangulated geometry. replacing with shifts to the edges of blocks solved it*/
|
|
|
|
short angl = (unsigned short)(item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
|
|
switch (angl)
|
|
{
|
|
case NORTH:
|
|
item->pos.zPos = (item->pos.zPos | (WALL_SIZE - 1)) - LARA_RAD;
|
|
break;
|
|
|
|
case EAST:
|
|
item->pos.xPos = (item->pos.xPos | (WALL_SIZE - 1)) - LARA_RAD;
|
|
break;
|
|
|
|
case SOUTH:
|
|
item->pos.zPos = (item->pos.zPos & -WALL_SIZE) + LARA_RAD;
|
|
break;
|
|
|
|
case WEST:
|
|
item->pos.xPos = (item->pos.xPos & -WALL_SIZE) + LARA_RAD;
|
|
break;
|
|
}
|
|
}
|
|
item->pos.yPos += coll->frontFloor - bounds->Y1;
|
|
item->pos.yRot = angle;
|
|
|
|
item->gravityStatus = true;
|
|
item->speed = 2;
|
|
item->fallspeed = 1;
|
|
|
|
Lara.gunStatus = LG_HANDS_BUSY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|