2020-08-08 16:35:05 -05:00
|
|
|
#include "framework.h"
|
|
|
|
#include "lara.h"
|
|
|
|
#include "input.h"
|
2020-08-16 16:01:58 -05:00
|
|
|
#include "draw.h"
|
|
|
|
#include "effect2.h"
|
2020-08-08 16:35:05 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
/*this file has all the generic **collision** test functions called in lara's state code*/
|
2020-08-14 04:08:10 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
2020-08-08 16:35:05 -05:00
|
|
|
{
|
|
|
|
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
|
|
|
item->goalAnimState = LS_STOP;
|
|
|
|
item->speed = 0;
|
|
|
|
item->gravityStatus = false;
|
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
return 1;
|
2020-08-08 16:35:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (coll->collType == CT_LEFT)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
item->pos.yRot += ANGLE(5.0f);
|
|
|
|
}
|
|
|
|
else if (coll->collType == CT_RIGHT)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
item->pos.yRot -= ANGLE(5.0f);
|
|
|
|
}
|
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
return 0;
|
2020-08-08 16:35:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
|
|
|
|
switch (coll->collType)
|
|
|
|
{
|
|
|
|
case CT_FRONT:
|
|
|
|
case CT_TOP_FRONT:
|
|
|
|
if (!Lara.climbStatus || item->speed != 2)
|
|
|
|
{
|
|
|
|
if (coll->midFloor <= 512)
|
|
|
|
{
|
|
|
|
if (coll->midFloor <= 128)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_GRAB_TO_FALL;
|
|
|
|
item->currentAnimState = LS_GRAB_TO_FALL;
|
2020-09-26 05:06:08 +10:00
|
|
|
|
2020-08-08 16:35:05 -05:00
|
|
|
item->animNumber = LA_JUMP_UP_LAND;
|
|
|
|
item->frameNumber = g_Level.Anims[LA_JUMP_UP_LAND].frameBase;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_FREEFALL;
|
|
|
|
item->currentAnimState = LS_FREEFALL;
|
2020-09-26 05:06:08 +10:00
|
|
|
|
2020-08-08 16:35:05 -05:00
|
|
|
item->animNumber = LA_JUMP_WALL_SMASH_START;
|
|
|
|
item->frameNumber = g_Level.Anims[LA_JUMP_WALL_SMASH_START].frameBase + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->speed /= 4;
|
|
|
|
Lara.moveAngle += ANGLE(180);
|
|
|
|
|
|
|
|
if (item->fallspeed <= 0)
|
|
|
|
item->fallspeed = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case CT_TOP:
|
|
|
|
if (item->fallspeed <= 0)
|
|
|
|
item->fallspeed = 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
case CT_LEFT:
|
|
|
|
item->pos.yRot += ANGLE(5.0f);
|
|
|
|
break;
|
|
|
|
case CT_RIGHT:
|
|
|
|
item->pos.yRot -= ANGLE(5.0f);
|
|
|
|
break;
|
|
|
|
case CT_CLAMP:
|
|
|
|
item->pos.xPos -= (100 * 4 * phd_sin(coll->facing)) >> W2V_SHIFT;
|
|
|
|
item->pos.zPos -= (100 * 4 * phd_cos(coll->facing)) >> W2V_SHIFT;
|
|
|
|
|
|
|
|
item->speed = 0;
|
|
|
|
coll->midFloor = 0;
|
|
|
|
|
|
|
|
if (item->fallspeed <= 0)
|
|
|
|
item->fallspeed = 16;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
2020-08-08 16:35:05 -05:00
|
|
|
{
|
2020-09-26 05:06:08 +10:00
|
|
|
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
|
2020-08-08 16:35:05 -05:00
|
|
|
{
|
2020-09-26 05:06:08 +10:00
|
|
|
ShiftItem(item, coll);
|
2020-08-08 16:35:05 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
item->gravityStatus = false;
|
|
|
|
item->speed = 0;
|
2020-08-08 16:35:05 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
return 1;
|
|
|
|
}
|
2020-08-08 16:35:05 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
if (coll->collType == CT_LEFT)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
item->pos.yRot += ANGLE(2.0f);
|
|
|
|
}
|
|
|
|
else if (coll->collType == CT_RIGHT)
|
|
|
|
{
|
|
|
|
ShiftItem(item, coll);
|
|
|
|
item->pos.yRot -= ANGLE(2.0f);
|
|
|
|
}
|
2020-08-08 16:35:05 -05:00
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
return 0;
|
2020-08-08 16:35:05 -05:00
|
|
|
}
|
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
|
2020-08-08 16:35:05 -05:00
|
|
|
{
|
|
|
|
if (coll->collType == CT_TOP || coll->collType == CT_CLAMP)
|
|
|
|
{
|
|
|
|
item->pos.xPos = coll->old.x;
|
|
|
|
item->pos.yPos = coll->old.y;
|
|
|
|
item->pos.zPos = coll->old.z;
|
|
|
|
|
|
|
|
item->goalAnimState = LS_STOP;
|
|
|
|
item->currentAnimState = LS_STOP;
|
|
|
|
|
|
|
|
item->animNumber = LA_STAND_SOLID;
|
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
item->speed = 0;
|
|
|
|
item->fallspeed = 0;
|
|
|
|
item->gravityStatus = false;
|
|
|
|
|
2020-09-26 05:06:08 +10:00
|
|
|
return 1;
|
2020-08-08 16:35:05 -05:00
|
|
|
}
|
2020-09-26 05:06:08 +10:00
|
|
|
return 0;
|
2020-08-08 16:35:05 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)//126F0(<), 127A0(<) (F)
|
|
|
|
{
|
|
|
|
switch (coll->oldAnimState)
|
|
|
|
{
|
|
|
|
case LS_STOP:
|
|
|
|
case LS_TURN_RIGHT_SLOW:
|
|
|
|
case LS_TURN_LEFT_SLOW:
|
2020-09-26 05:06:08 +10:00
|
|
|
case LS_TURN_FAST:
|
2020-08-08 16:35:05 -05:00
|
|
|
item->currentAnimState = coll->oldAnimState;
|
|
|
|
item->animNumber = coll->oldAnimNumber;
|
|
|
|
item->frameNumber = coll->oldFrameNumber;
|
|
|
|
if (TrInput & IN_LEFT)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_TURN_LEFT_SLOW;
|
|
|
|
}
|
|
|
|
else if (TrInput & IN_RIGHT)
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_TURN_RIGHT_SLOW;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->goalAnimState = LS_STOP;
|
|
|
|
}
|
|
|
|
AnimateLara(item);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
item->animNumber = LA_STAND_SOLID;
|
|
|
|
item->frameNumber = g_Level.Anims[LA_STAND_SOLID].frameBase;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-08-09 00:54:57 -05:00
|
|
|
|
|
|
|
void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle) // (F) (D)
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == LS_SHIMMY_RIGHT)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case NORTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x390;
|
|
|
|
return;
|
|
|
|
case EAST:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0x70;
|
|
|
|
return;
|
|
|
|
case SOUTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0x70;
|
|
|
|
return;
|
|
|
|
case WEST:
|
|
|
|
default:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x390;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState == LS_SHIMMY_LEFT)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case NORTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0x70;
|
|
|
|
return;
|
|
|
|
case EAST:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x390;
|
|
|
|
return;
|
|
|
|
case SOUTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x390;
|
|
|
|
return;
|
|
|
|
case WEST:
|
|
|
|
default:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0x70;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState == LS_SHIMMY_FEET_RIGHT)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case NORTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x720;
|
|
|
|
return;
|
|
|
|
case EAST:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0xE0;
|
|
|
|
return;
|
|
|
|
case SOUTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0xE0;
|
|
|
|
return;
|
|
|
|
case WEST:
|
|
|
|
default:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x720;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState == LS_SHIMMY_FEET_LEFT)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case NORTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0xE0;
|
|
|
|
return;
|
|
|
|
case EAST:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x720;
|
|
|
|
return;
|
|
|
|
case SOUTH:
|
|
|
|
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x720;
|
|
|
|
return;
|
|
|
|
case WEST:
|
|
|
|
default:
|
|
|
|
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0xE0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
short GetDirOctant(int rot)//160B4(<), 161E8(<) (F)
|
|
|
|
{
|
|
|
|
return abs(rot) >= ANGLE(45) && abs(rot) <= ANGLE(135.0f);
|
|
|
|
}
|
2020-08-16 16:01:58 -05:00
|
|
|
|
|
|
|
void GetLaraDeadlyBounds() // (F) (D)
|
|
|
|
{
|
|
|
|
BOUNDING_BOX* bounds;
|
|
|
|
BOUNDING_BOX tbounds;
|
|
|
|
|
|
|
|
bounds = GetBoundsAccurate(LaraItem);
|
|
|
|
phd_RotBoundingBoxNoPersp(&LaraItem->pos, bounds, &tbounds);
|
|
|
|
|
|
|
|
DeadlyBounds[0] = LaraItem->pos.xPos + tbounds.X1;
|
|
|
|
DeadlyBounds[1] = LaraItem->pos.xPos + tbounds.X2;
|
|
|
|
DeadlyBounds[2] = LaraItem->pos.yPos + tbounds.Y1;
|
|
|
|
DeadlyBounds[3] = LaraItem->pos.yPos + tbounds.Y2;
|
|
|
|
DeadlyBounds[4] = LaraItem->pos.zPos + tbounds.Z1;
|
|
|
|
DeadlyBounds[5] = LaraItem->pos.zPos + tbounds.Z2;
|
|
|
|
}
|