TombEngine/TR5Main/Game/larasurf.cpp

484 lines
10 KiB
C++

#include "larasurf.h"
#include "..\Global\global.h"
#include "control.h"
#include "camera.h"
#include "collide.h"
#include "items.h"
#include "box.h"
#include "Lara.h"
#include "laraswim.h"
#include "larafire.h"
#include "laramisc.h"
extern void(*lara_control_routines[NUM_LARA_STATES + 1])(ITEM_INFO* item, COLL_INFO* coll);
extern void(*lara_collision_routines[NUM_LARA_STATES + 1])(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_surftread(ITEM_INFO* item, COLL_INFO* coll)
{
if (item->goalAnimState == STATE_LARA_UNDERWATER_FORWARD)
{
item->currentAnimState = STATE_LARA_UNDERWATER_DIVING;
item->animNumber = ANIMATION_LARA_FREE_FALL_TO_UNDERWATER_ALTERNATE;
item->pos.xRot = -8190;
item->frameNumber = Anims[item->animNumber].frameBase;
item->fallspeed = 80;
Lara.waterStatus = LW_UNDERWATER;
}
Lara.moveAngle = item->pos.yRot;
LaraSurfaceCollision(item, coll);
}
void lara_col_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DD90(<), 4E1F4(<) (F)
{
Lara.moveAngle = item->pos.yRot + ANGLE(90);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DD64(<), 4E1C8(<) (F)
{
Lara.moveAngle = item->pos.yRot - ANGLE(90);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfback(ITEM_INFO* item, COLL_INFO* coll)//4DD38(<), 4E19C(<) (F)
{
Lara.moveAngle = item->pos.yRot - ANGLE(180);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4DCE8(<), 4E14C(<) (F)
{
coll->badNeg = -384;
Lara.moveAngle = item->pos.yRot;
LaraSurfaceCollision(item, coll);
LaraTestWaterClimbOut(item, coll);
}
void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
{
item->fallspeed -= 4;
if (item->fallspeed < 0)
item->fallspeed = 0;
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
return;
}
if (TrInput & IN_LOOK)
{
LookUpDown();
return;
}
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(4);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(4);
}
if (TrInput & IN_FORWARD)
{
item->goalAnimState = STATE_LARA_ONWATER_FORWARD;
}
else if (TrInput & IN_BACK)
{
item->goalAnimState = STATE_LARA_ONWATER_BACK;
}
if (TrInput & IN_LSTEP)
{
item->goalAnimState = STATE_LARA_ONWATER_LEFT;
}
else if (TrInput & IN_RSTEP)
{
item->goalAnimState = STATE_LARA_ONWATER_RIGHT;
}
if (TrInput & IN_JUMP)
{
Lara.diveCount++;
if (Lara.diveCount == 10)
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
}
else
{
Lara.diveCount = 0;
}
}
void lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DAF8, 4DF5C (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
return;
}
Lara.diveCount = 0;
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
}
if (!(TrInput & IN_RSTEP))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
}
item->fallspeed += 8;
if (item->fallspeed > 60)
item->fallspeed = 60;
}
void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
return;
}
Lara.diveCount = 0;
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
}
if (!(TrInput & IN_LSTEP))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
}
item->fallspeed += 8;
if (item->fallspeed > 60)
item->fallspeed = 60;
}
void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
return;
}
Lara.diveCount = 0;
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
}
if (!(TrInput & IN_BACK))
{
item->goalAnimState = STATE_LARA_ONWATER_STOP;
}
item->fallspeed += 8;
if (item->fallspeed > 60)
item->fallspeed = 60;
}
void lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4D8E4(<), 4DD48(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_WATER_DEATH;
return;
}
Lara.diveCount = 0;
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(4);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(4);
}
if (!(TrInput & IN_FORWARD))
item->goalAnimState = STATE_LARA_ONWATER_STOP;
if (TrInput & IN_JUMP)
item->goalAnimState = STATE_LARA_ONWATER_STOP;
item->fallspeed += 8;
if (item->fallspeed > 60)
item->fallspeed = 60;
}
void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)//4D684, 4DAE8 (F)
{
Camera.targetElevation = -ANGLE(22);
coll->badPos = 32512;
coll->badNeg = -128;
coll->badCeiling = 100;
coll->old.x = item->pos.xPos;
coll->old.y = item->pos.yPos;
coll->old.z = item->pos.zPos;
coll->slopesAreWalls = 0;
coll->slopesArePits = 0;
coll->lavaIsPit = 0;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
coll->radius = 100;
coll->trigger = NULL;
if (TrInput & IN_LOOK && Lara.look)
LookLeftRight();
else
ResetLook();
Lara.look = true;
lara_control_routines[item->currentAnimState](item, coll);
if (item->pos.zRot >= -ANGLE(2) && item->pos.zRot <= ANGLE(2))
item->pos.zRot = 0;
else if (item->pos.zRot < 0)
item->pos.zRot += ANGLE(2);
else
item->pos.zRot -= ANGLE(2);
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
LaraWaterCurrent(coll);
AnimateLara(item);
item->pos.xPos += item->fallspeed * SIN(Lara.moveAngle) >> (W2V_SHIFT + 2);
item->pos.zPos += item->fallspeed * COS(Lara.moveAngle) >> (W2V_SHIFT + 2);
LaraBaddieCollision(item, coll);
lara_collision_routines[item->currentAnimState](item, coll);
UpdateLaraRoom(item, 100);
LaraGun();
TestTriggers(coll->trigger, 0, 0);
}
void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)//4D4F0(<), 4D954(<) (F)
{
coll->facing = Lara.moveAngle;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos + 700, item->pos.zPos, item->roomNumber, 800);
ShiftItem(item, coll);
if (coll->collType & (CT_FRONT | CT_TOP | CT_TOP_FRONT | CT_CLAMP) ||
coll->midFloor < 0 && (coll->midType == BIG_SLOPE || coll->midType == DIAGONAL))
{
item->fallspeed = 0;
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
}
else if (coll->collType == CT_LEFT)
{
item->pos.yRot += ANGLE(5);
}
else if (coll->collType == CT_RIGHT)
{
item->pos.yRot -= ANGLE(5);
}
if (GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber) - item->pos.yPos > -100)
{
LaraTestWaterStepOut(item, coll);
}
else
{
item->goalAnimState = STATE_LARA_UNDERWATER_FORWARD;
item->currentAnimState = STATE_LARA_UNDERWATER_DIVING;
item->animNumber = ANIMATION_LARA_FREE_FALL_TO_UNDERWATER_ALTERNATE;
item->pos.xRot = -8190;
item->frameNumber = Anims[item->animNumber].frameBase;
item->fallspeed = 80;
Lara.waterStatus = LW_UNDERWATER;
}
}
int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
{
if (coll->collType != CT_FRONT || !(TrInput & IN_ACTION))
return 0;
if (abs(coll->rightFloor2 - coll->leftFloor2) >= 60
|| Lara.gunStatus
&& (Lara.gunStatus != LG_READY
|| Lara.gunType != WEAPON_FLARE))
return 0;
if (coll->frontCeiling > 0)
return 0;
if (coll->midCeiling > -384)
return 0;
int frontFloor = coll->frontFloor + 700;
if (frontFloor <= -512 || frontFloor > 316)
return 0;
short rot = item->pos.yRot;
if (item->pos.yRot < -ANGLE(35) || item->pos.yRot > ANGLE(35))
{
if (item->pos.yRot < 10014 || item->pos.yRot > 22754)
{
if (item->pos.yRot >= 26397 || item->pos.yRot <= -26397)
{
rot = ANGLE(180);
}
else if (item->pos.yRot >= -22754 && item->pos.yRot <= -10014)
{
rot = -ANGLE(90);
}
}
else
{
rot = ANGLE(90);
}
}
else
{
rot = 0;
}
if (rot & 0x3FFF)
return 0;
item->pos.yPos += coll->frontFloor + 695;
UpdateLaraRoom(item, -381);
if (rot > 0)
{
if (rot == ANGLE(90))
{
item->pos.xPos = (item->pos.xPos & 0xFFFFFC00) + 1124;
}
}
else if (rot)
{
if (rot == ANGLE(180))
{
item->pos.zPos = (item->pos.zPos & 0xFFFFFC00) - 100;
}
else if (rot == -ANGLE(90))
{
item->pos.xPos = (item->pos.xPos & 0xFFFFFC00) - 100;
}
}
else
{
item->pos.zPos = (item->pos.zPos & 0xFFFFFC00) + 1124;
}
if (frontFloor >= -128)
{
if (frontFloor >= 128)
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_WADE;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_LAND_LOW;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
else
{
item->animNumber = ANIMATION_LARA_CLIMB_OUT_OF_WATER;
item->frameNumber = Anims[item->animNumber].frameBase;
}
item->currentAnimState = STATE_LARA_ONWATER_EXIT;
item->goalAnimState = STATE_LARA_STOP;
item->pos.yRot = rot;
Lara.gunStatus = LG_HANDS_BUSY;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.waterStatus = LW_ABOVE_WATER;
return 1;
}
int LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll)//4D100, 4D564 (F)
{
if (coll->collType == CT_FRONT
|| coll->midType == BIG_SLOPE
|| coll->midType == DIAGONAL
|| coll->midFloor >= 0)
{
return 0;
}
if (coll->midFloor >= -128)
{
if (item->goalAnimState == STATE_LARA_ONWATER_LEFT)
{
item->goalAnimState = STATE_LARA_WALK_LEFT;
}
else if (item->goalAnimState == STATE_LARA_ONWATER_RIGHT)
{
item->goalAnimState = STATE_LARA_WALK_RIGHT;
}
else
{
item->animNumber = ANIMATION_LARA_WADE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_WADE_FORWARD;
item->currentAnimState = STATE_LARA_WADE_FORWARD;
}
}
else
{
item->animNumber = ANIMATION_LARA_ONWATER_TO_WADE_DEEP;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_ONWATER_EXIT;
item->goalAnimState = STATE_LARA_STOP;
}
item->pos.yPos += coll->frontFloor + 695;
UpdateLaraRoom(item, -381);
item->pos.zRot = 0;
item->pos.xRot = 0;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.waterStatus = LW_WADE;
return true;
}