TombEngine/TR5Main/Game/Lara/lara.cpp

1143 lines
26 KiB
C++
Raw Normal View History

#include "framework.h"
2019-11-21 07:43:34 +01:00
#include "Lara.h"
#include "lara_basic.h"
#include "lara_tests.h"
#include "lara_monkey.h"
#include "lara_crawl.h"
#include "lara_objects.h"
#include "lara_hang.h"
#include "lara_slide.h"
#include "inventory.h"
2020-08-09 22:09:14 -03:00
#include "lara_fire.h"
#include "lara_surface.h"
#include "lara_swim.h"
#include "lara_one_gun.h"
#include "lara_two_guns.h"
2019-11-21 07:43:34 +01:00
#include "laramisc.h"
2020-08-09 22:09:14 -03:00
#include "lara_climb.h"
2018-08-19 09:46:58 +02:00
#include "motorbike.h"
#include "cannon.h"
#include "quad.h"
#include "snowmobile.h"
#include "jeep.h"
#include "boat.h"
#include "upv.h"
#include "kayak.h"
#include "minecart.h"
#include "GameFlowScript.h"
#include "health.h"
#include "effect2.h"
#include "sound.h"
#include "savegame.h"
using std::function;
2019-11-21 07:43:34 +01:00
extern Inventory g_Inventory;
2019-12-02 09:11:21 +01:00
short elevation = 57346;
LaraInfo Lara;
2020-04-23 19:22:01 +02:00
ITEM_INFO* LaraItem;
byte LaraNodeUnderwater[NUM_LARA_MESHES];
2019-12-02 06:39:51 +01:00
function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
2019-12-02 06:39:51 +01:00
lara_as_walk,
lara_as_run,
lara_as_stop,
lara_as_forwardjump,
lara_void_func,//4
lara_as_fastback,//5
lara_as_turn_r,//6
lara_as_turn_l,//7
lara_as_death,//8
2019-12-02 06:39:51 +01:00
lara_as_fastfall,
lara_as_hang,
lara_as_reach,
lara_as_splat,
lara_as_tread,
lara_void_func,
lara_as_compress,//15
lara_as_back,//16
lara_as_swim,//17
lara_as_glide,//18
lara_as_null,//19
lara_as_fastturn,//20
lara_as_stepright,//21
lara_as_stepleft,//22
2019-12-02 06:39:51 +01:00
lara_void_func,
lara_as_slide,//24
lara_as_backjump,//25
lara_as_rightjump,//26
lara_as_leftjump,//27
lara_as_upjump,//28
lara_as_fallback,//29
lara_as_hangleft,//30
lara_as_hangright,//31
lara_as_slideback,//32
2019-12-02 06:39:51 +01:00
lara_as_surftread,
lara_as_surfswim,
lara_as_dive,
lara_as_pushblock,//36
lara_as_pullblock,//37
lara_as_ppready,//38
lara_as_pickup,//39
lara_as_switchon,//40
lara_as_switchoff,//41
lara_as_usekey,//42
lara_as_usepuzzle,//43
lara_as_uwdeath,//44
lara_void_func,//45
lara_as_special,//46
lara_as_surfback,//47
lara_as_surfleft,//48
lara_as_surfright,//49
lara_void_func,//50
lara_void_func,//51
lara_as_swandive,//52
lara_as_fastdive,//53
lara_as_gymnast,//54
2019-12-02 06:39:51 +01:00
lara_as_waterout,
lara_as_climbstnc,
lara_as_climbing,
lara_as_climbleft,
lara_as_climbend,
lara_as_climbright,
lara_as_climbdown,//
2019-12-02 06:39:51 +01:00
lara_void_func,
lara_void_func,
lara_void_func,
lara_as_wade,//65
lara_as_waterroll,//66
lara_as_pickupflare,//67
lara_void_func,//68
lara_void_func,//69
lara_as_deathslide,//70
lara_as_duck,//71
lara_as_crouch_roll,//72
2019-12-02 06:39:51 +01:00
lara_as_dash,
lara_as_dashdive,
lara_as_hang2,
lara_as_monkeyswing,
lara_as_monkeyl,
lara_as_monkeyr,
lara_as_monkey180,
lara_as_all4s,//80
lara_as_crawl,//81
2019-12-02 06:39:51 +01:00
lara_as_hangturnl,
lara_as_hangturnr,
lara_as_all4turnl,//84
lara_as_all4turnr,//85
lara_as_crawlb,//86
2019-12-02 06:39:51 +01:00
lara_as_null,
lara_as_null,
lara_as_controlled,
lara_as_ropel,
lara_as_roper,
lara_as_controlled,
lara_as_controlled,
lara_as_controlled,
lara_as_controlledl,
lara_as_controlledl,
lara_as_controlled,
lara_as_pickup,//98
lara_as_null,//99
lara_as_null,//100
lara_as_null,//101
lara_as_poleleft,//102
lara_as_poleright,//103
lara_as_pulley,//104
lara_as_duckl,//105
lara_as_duckr,//106
lara_as_extcornerl,//107
lara_as_extcornerr,//108
lara_as_intcornerl,//109
lara_as_intcornerr,//110
lara_as_rope,//111
lara_as_climbrope,//112
lara_as_climbroped,//113
lara_as_rope,//114
lara_as_rope,//115
2019-12-02 06:39:51 +01:00
lara_void_func,
lara_as_controlled,
lara_as_swimcheat,
lara_as_trpose,//119
lara_as_null,//120
lara_as_trwalk,//121
lara_as_trfall,//122
lara_as_trfall,//123
lara_as_null,//124
lara_as_null,//125
lara_as_switchon,//126
lara_as_null,//127
lara_as_parallelbars,//128
lara_as_pbleapoff,//129
lara_as_null,//130
lara_as_null,//131
lara_as_null,//132
lara_as_null,//133
lara_as_null,//134
lara_as_null,//135
lara_as_null,//136
lara_as_null,//137
lara_as_null,//138
lara_as_hang_feet,//139
lara_as_hang_feet_shimmyr,//140
lara_as_hang_feet_shimmyl,//141
lara_as_hang_feet_inRcorner,//142
lara_as_hang_feet_inLcorner,//143
lara_as_hang_feet_outRcorner,//144
lara_as_hang_feet_outLcorner,//145
2020-06-13 14:51:13 -05:00
lara_as_controlledl,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_stepoff_left,
lara_as_stepoff_right
2019-12-02 06:39:51 +01:00
};
function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
2019-12-02 06:39:51 +01:00
lara_col_walk,
lara_col_run,
lara_col_stop,
lara_col_forwardjump,
lara_col_pose,
lara_col_fastback,
lara_col_turn_r,
lara_col_turn_l,
lara_col_death,
lara_col_fastfall,
lara_col_hang,
lara_col_reach,
lara_col_splat,
lara_col_tread,
lara_col_land,
lara_col_compress,
lara_col_back,
lara_col_swim,
lara_col_glide,
lara_default_col,
lara_col_fastturn,
lara_col_stepright,
lara_col_stepleft,
lara_col_roll2,
lara_col_slide,
lara_col_backjump,
lara_col_rightjump,
lara_col_leftjump,
lara_col_upjump,
lara_col_fallback,
lara_col_hangleft,
lara_col_hangright,
lara_col_slideback,
lara_col_surftread,
lara_col_surfswim,
lara_col_dive,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_uwdeath,
lara_col_roll,
lara_void_func,
lara_col_surfback,
lara_col_surfleft,
lara_col_surfright,
lara_void_func,
lara_void_func,
lara_col_swandive,
lara_col_fastdive,
lara_default_col,
lara_default_col,
lara_col_climbstnc,
lara_col_climbing,
lara_col_climbleft,
lara_col_climbend,
lara_col_climbright,
lara_col_climbdown,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_wade,
lara_col_waterroll,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_duck,
lara_col_crouch_roll,
2019-12-02 06:39:51 +01:00
lara_col_dash,
lara_col_dashdive,
lara_col_hang2,
lara_col_monkeyswing,
lara_col_monkeyl,
lara_col_monkeyr,
lara_col_monkey180,
lara_col_all4s,
lara_col_crawl,
lara_col_hangturnlr,
lara_col_hangturnlr,
lara_col_all4turnlr,
lara_col_all4turnlr,
lara_col_crawlb,
lara_void_func,
lara_col_crawl2hang,
lara_default_col,
lara_void_func,
lara_void_func,
lara_default_col,
lara_void_func,
lara_void_func,
lara_col_turnswitch,
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_polestat,
lara_col_poleup,
lara_col_poledown,
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_ducklr,
lara_col_ducklr,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_rope,
lara_void_func,
lara_void_func,
lara_col_ropefwd,
lara_col_ropefwd,
lara_void_func,
lara_void_func,
lara_col_swim,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
2020-05-23 15:59:18 -05:00
lara_void_func,
lara_col_hang_feet,
lara_col_hang_feet_shimmyr,
lara_col_hang_feet_shimmyl,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
2020-06-13 14:51:13 -05:00
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_default_col,
lara_default_col
2019-12-02 06:39:51 +01:00
};
void LaraControl(short itemNumber) // (AF) (D)
{
ITEM_INFO* item = LaraItem;
LaraCheatyBits();
if (Lara.isMoving)
{
if (Lara.moveCount > 90)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
}
++Lara.moveCount;
}
if (!DisableLaraControl)
Lara.locationPad = 128;
int oldX = LaraItem->pos.xPos;
int oldY = LaraItem->pos.yPos;
int oldZ = LaraItem->pos.zPos;
if (Lara.gunStatus == LG_HANDS_BUSY &&
LaraItem->currentAnimState == LS_STOP &&
LaraItem->goalAnimState == LS_STOP &&
LaraItem->animNumber == LA_STAND_IDLE &&
!LaraItem->gravityStatus)
{
Lara.gunStatus = LG_NO_ARMS;
}
if (item->currentAnimState != LS_SPRINT && DashTimer < 120)
DashTimer++;
Lara.isDucked = false;
#if 1
bool isWater = g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER;
#else
bool isWater = g_Level.Rooms[item->roomNumber].flags & (ENV_FLAG_WATER | ENV_FLAG_SWAMP);
#endif
int wd = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
int wh = GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
int hfw;
if (wh != NO_HEIGHT)
hfw = item->pos.yPos - wh;
else
hfw = NO_HEIGHT;
Lara.waterSurfaceDist = -hfw;
#if 0
if (Lara.Vehicle == NO_ITEM)
#endif
WadeSplash(item, wh, wd);
short roomNumber;
#if 0
if (Lara.Vehicle == NO_ITEM && Lara.ExtraAnim == 0)
{
#endif
switch (Lara.waterStatus)
{
case LW_ABOVE_WATER:
if (hfw != NO_HEIGHT && hfw >= STEP_SIZE)
{
if (wd <= 474)
{
if (hfw > 256)
{
Lara.waterStatus = LW_WADE;
if (!(item->gravityStatus))
{
item->goalAnimState = LS_STOP;
}
#if 0
else if (isWater & ENV_FLAG_SWAMP)
{
if (item->currentAnimState == LS_SWANDIVE_BEGIN || item->currentAnimState == LS_SWANDIVE_END) // Is Lara swan-diving?
item->pos.yPos = wh + 1000;
item->goalAnimState = LS_WADE_FORWARD;
item->currentAnimState = LS_WADE_FORWARD;
item->animNumber = LA_WADE;
item->frameNumber = GF(LA_WADE, 0);
}
#endif
}
}
#if 1
else if (isWater)
#else
else if (!(isWater & ENV_FLAG_SWAMP))
#endif
{
Lara.air = 1800;
Lara.waterStatus = LW_UNDERWATER;
item->gravityStatus = false;
item->pos.yPos += 100;
UpdateLaraRoom(LaraItem, 0);
StopSoundEffect(SFX_LARA_FALL);
if (item->currentAnimState == LS_SWANDIVE_START)
{
item->pos.xRot = -ANGLE(45);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else if (item->currentAnimState == LS_SWANDIVE_END)
{
item->pos.xRot = -ANGLE(85);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else
{
item->pos.xRot = -ANGLE(45);
item->animNumber = LA_FREEFALL_DIVE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_DIVE;
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed = 3 * item->fallspeed / 2;
}
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
Splash(LaraItem);
}
Camera.targetElevation = -ANGLE(22);
if (hfw >= 256) /* @ORIGINAL_BUG: checking hfw for equality with 256 results in the wade bug */
{
if (hfw > 730)
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos += 1 - hfw;
switch (item->currentAnimState)
{
case LS_WALK_BACK:
item->animNumber = LA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_BACK;
item->currentAnimState = LS_ONWATER_BACK;
break;
case LS_STEP_RIGHT:
item->animNumber = LA_ONWATER_SWIM_RIGHT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_RIGHT;
item->currentAnimState = LS_ONWATER_RIGHT;
break;
case LS_STEP_LEFT:
item->animNumber = LA_ONWATER_SWIM_LEFT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_LEFT;
item->currentAnimState = LS_ONWATER_LEFT;
break;
default:
item->animNumber = LA_ONWATER_SWIM;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_FORWARD;
item->currentAnimState = LS_ONWATER_FORWARD;
break;
}
item->gravityStatus = false;
item->fallspeed = 0;
Lara.diveCount = 0;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
UpdateLaraRoom(item, 0);
}
}
else
{
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == LS_WADE_FORWARD)
item->goalAnimState = LS_RUN_FORWARD;
}
}
break;
case LW_UNDERWATER:
roomNumber = item->roomNumber;
GetFloor(item->pos.xPos, item->pos.yPos - 256, item->pos.zPos, &roomNumber);
if (wd == NO_HEIGHT
|| abs(hfw) >= 256
|| g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER
|| item->animNumber == LA_UNDERWATER_RESURFACE
|| item->animNumber == LA_ONWATER_DIVE)
{
if (!isWater)
{
if (wd == NO_HEIGHT || abs(hfw) >= 256)
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->speed = item->fallspeed / 4;
item->gravityStatus = true;
item->fallspeed = 0;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
}
else
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos = wh;
item->animNumber = LA_UNDERWATER_RESURFACE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_STOP;
item->currentAnimState = LS_ONWATER_STOP;
item->fallspeed = 0;
Lara.diveCount = 11;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
UpdateLaraRoom(item, -381);
SoundEffect(SFX_LARA_BREATH, &LaraItem->pos, 2);
}
}
}
else
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos = wh + 1;
item->animNumber = LA_UNDERWATER_RESURFACE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_STOP;
item->currentAnimState = LS_ONWATER_STOP;
item->fallspeed = 0;
Lara.diveCount = 11;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
UpdateLaraRoom(item, 0);
SoundEffect(SFX_LARA_BREATH, &LaraItem->pos, 2);
}
break;
case LW_SURFACE:
if (!isWater)
{
if (hfw <= 256)
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->speed = item->fallspeed / 4;
item->gravityStatus = true;
}
else
{
Lara.waterStatus = LW_WADE; /* @DEAD_CODE: Lara has to reach a room without water while in the surface but then GetWaterHeight() return value never will make hfw > 256 */
item->animNumber = LA_STAND_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_WADE_FORWARD;
item->currentAnimState = LS_STOP;
AnimateItem(item);
}
item->fallspeed = 0;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
}
break;
case LW_WADE:
Camera.targetElevation = -ANGLE(22);
if (hfw >= 256) /* @ORIGINAL_BUG: checking hfw for equality with 256 results in the wade bug */
{
#if 1
if (hfw > 730)
#else
if (hfw > 730 && !(isWater & ENV_FLAG_SWAMP))
#endif
{
Lara.waterStatus = LW_SURFACE;
item->pos.yPos += 1 - hfw;
switch (item->currentAnimState)
{
case LS_WALK_BACK:
item->animNumber = LA_ONWATER_IDLE_TO_SWIM_BACK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_BACK;
item->currentAnimState = LS_ONWATER_BACK;
break;
case LS_STEP_RIGHT:
item->animNumber = LA_ONWATER_SWIM_RIGHT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_RIGHT;
item->currentAnimState = LS_ONWATER_RIGHT;
break;
case LS_STEP_LEFT:
item->animNumber = LA_ONWATER_SWIM_LEFT;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_LEFT;
item->currentAnimState = LS_ONWATER_LEFT;
break;
default:
item->animNumber = LA_ONWATER_SWIM;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_ONWATER_FORWARD;
item->currentAnimState = LS_ONWATER_FORWARD;
break;
}
item->gravityStatus = false;
item->fallspeed = 0;
Lara.diveCount = 0;
LaraItem->pos.zRot = 0;
LaraItem->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
UpdateLaraRoom(item, 0);
}
}
else
{
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == LS_WADE_FORWARD)
item->goalAnimState = LS_RUN_FORWARD;
}
break;
}
#if 0
}
#endif
if (item->hitPoints <= 0)
{
item->hitPoints = -1;
if (Lara.deathCount == 0)
S_CDStop();
Lara.deathCount++;
if ((LaraItem->flags & 0x100))
{
Lara.deathCount++;
return;
}
}
switch (Lara.waterStatus)
{
case LW_ABOVE_WATER:
case LW_WADE:
#if 0
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -775)
{
if (item->hitPoints >= 0)
{
Lara.air -= 6;
if (Lara.air < 0)
{
Lara.air = -1;
item->hitPoints -= 10;
}
}
}
else if (Lara.gassed)
#else
if (Lara.gassed)
#endif
{
if (item->hitPoints >= 0 && --Lara.air < 0)
{
Lara.air = -1;
item->hitPoints -= 5;
}
}
else if (Lara.air < 1800 && item->hitPoints >= 0)
{
#if 0
/* lara is not equipped with any vehicle */
if (Lara.Vehicle == NO_ITEM) // only for the upv !!
{
#endif
Lara.air += 10;
if (Lara.air > 1800)
Lara.air = 1800;
#if 0
}
#endif
}
LaraAboveWater(item, &lara_coll);
break;
case LW_UNDERWATER:
if (item->hitPoints >= 0)
{
if (LaraDrawType == LARA_DIVESUIT)
{
/* Hardcoded code */
}
else
{
Lara.air--;
}
if (Lara.air < 0)
{
if (LaraDrawType == LARA_DIVESUIT && Lara.anxiety < 251)
Lara.anxiety += 4;
Lara.air = -1;
item->hitPoints -= 5;
}
}
LaraUnderWater(item, &lara_coll);
break;
case LW_SURFACE:
if (item->hitPoints >= 0)
{
Lara.air += 10;
if (Lara.air > 1800)
Lara.air = 1800;
}
LaraSurface(item, &lara_coll);
break;
case LW_FLYCHEAT:
LaraCheat(item, &lara_coll);
break;
}
Savegame.Game.Distance += sqrt(
SQUARE(item->pos.xPos - oldX) +
SQUARE(item->pos.yPos - oldY) +
SQUARE(item->pos.zPos - oldZ));
}
void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll) //hmmmm
2018-09-16 15:05:16 +02:00
{
coll->old.x = item->pos.xPos;
coll->old.y = item->pos.yPos;
coll->old.z = item->pos.zPos;
coll->oldAnimState = item->currentAnimState;
coll->enableBaddiePush = true;
coll->enableSpaz = true;
coll->slopesAreWalls = false;
coll->slopesArePits = false;
coll->lavaIsPit = false;
coll->oldAnimNumber = item->animNumber;
coll->oldFrameNumber = item->frameNumber;
coll->radius = LARA_RAD;
coll->trigger = NULL;
2018-09-16 15:05:16 +02:00
if ((TrInput & IN_LOOK) && Lara.ExtraAnim == NO_ITEM && Lara.look)
LookLeftRight();
2018-09-16 15:05:16 +02:00
else
ResetLook();
Lara.look = true;
// Process Vehicles
if (Lara.Vehicle != NO_ITEM)
2018-09-16 15:05:16 +02:00
{
switch (g_Level.Items[Lara.Vehicle].objectNumber)
2018-09-16 15:05:16 +02:00
{
2020-06-07 22:24:22 +02:00
case ID_QUAD:
if (QuadBikeControl())
return;
break;
2020-06-07 22:24:22 +02:00
case ID_JEEP:
if (JeepControl())
return;
break;
2020-06-07 22:24:22 +02:00
case ID_MOTORBIKE:
if (MotorbikeControl())
return;
break;
2020-06-07 22:24:22 +02:00
case ID_KAYAK:
if (KayakControl())
return;
break;
2020-06-07 22:24:22 +02:00
case ID_SNOWMOBILE:
if (SkidooControl())
return;
break;
//case ID_SPEEDBOAT:
// if (BoatControl())
// return;
// break;
//case ID_RUBBERBOAT:
// if (RubberBoatControl())
// return;
// break;
//case ID_UPV:
// if (SubControl())
// return;
// break;
//case ID_MINECART:
// if (MineCartControl())
// return;
// break;
2020-06-07 22:24:22 +02:00
default:
break;
2018-09-16 15:05:16 +02:00
}
}
// Handle current Lara status
lara_control_routines[item->currentAnimState](item, coll);
2018-09-16 15:05:16 +02:00
if (item->pos.zRot >= -ANGLE(1.0f) && item->pos.zRot <= ANGLE(1.0f))
2020-06-07 22:24:22 +02:00
item->pos.zRot = 0;
else if (item->pos.zRot < -ANGLE(1.0f))
item->pos.zRot += ANGLE(1.0f);
2018-09-16 15:05:16 +02:00
else
item->pos.zRot -= ANGLE(1.0f);
2018-09-16 15:05:16 +02:00
if (Lara.turnRate >= -ANGLE(2.0f) && Lara.turnRate <= ANGLE(2.0f))
2020-06-07 22:24:22 +02:00
Lara.turnRate = 0;
else if (Lara.turnRate < -ANGLE(2.0f))
Lara.turnRate += ANGLE(2.0f);
2018-09-16 15:05:16 +02:00
else
Lara.turnRate -= ANGLE(2.0f);
2018-09-16 15:05:16 +02:00
item->pos.yRot += Lara.turnRate;
// Animate Lara
AnimateLara(item);
if (Lara.ExtraAnim == NO_ITEM)
{
// Check for collision with items
LaraBaddieCollision(item, coll);
2018-09-16 15:05:16 +02:00
// Handle Lara collision
if (Lara.Vehicle == NO_ITEM)
lara_collision_routines[item->currentAnimState](item, coll);
}
2018-09-16 15:05:16 +02:00
2020-06-07 22:24:22 +02:00
UpdateLaraRoom(item, -LARA_HITE / 2);
2018-09-16 15:05:16 +02:00
//if (Lara.gunType == WEAPON_CROSSBOW && !LaserSight)
// TrInput &= ~IN_ACTION;
2018-09-16 15:05:16 +02:00
// Handle weapons
LaraGun();
// Test if there's a trigger
TestTriggers(coll->trigger, FALSE, 0);
2018-09-16 15:05:16 +02:00
}
void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
{
coll->badPos = 32512;
coll->badNeg = -400;
coll->badCeiling = 400;
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 = true;
coll->enableSpaz = false;
coll->radius = 300;
coll->trigger = NULL;
if (TrInput & IN_LOOK && Lara.look)
LookLeftRight();
else
ResetLook();
Lara.look = true;
lara_control_routines[item->currentAnimState](item, coll);
if (LaraDrawType == LARA_DIVESUIT)
{
if (Lara.turnRate < -ANGLE(0.5))
{
Lara.turnRate += ANGLE(0.5);
}
else if (Lara.turnRate > ANGLE(0.5))
{
Lara.turnRate -= ANGLE(0.5);
}
else
{
Lara.turnRate = 0;
}
}
else if (Lara.turnRate < -ANGLE(2))
{
Lara.turnRate += ANGLE(2);
}
else if (Lara.turnRate > ANGLE(2))
{
Lara.turnRate -= ANGLE(2);
}
else
{
Lara.turnRate = 0;
}
item->pos.yRot += Lara.turnRate;
if (LaraDrawType == LARA_DIVESUIT)
UpdateSubsuitAngles();
if (item->pos.zRot < -ANGLE(2))
item->pos.zRot += ANGLE(2);
else if (item->pos.zRot > ANGLE(2))
item->pos.zRot -= ANGLE(2);
else
item->pos.zRot = 0;
if (item->pos.xRot < -ANGLE(85))
item->pos.xRot = -ANGLE(85);
else if (item->pos.xRot > ANGLE(85))
item->pos.xRot = ANGLE(85);
if (LaraDrawType == LARA_DIVESUIT)
{
if (item->pos.zRot > ANGLE(44))
item->pos.zRot = ANGLE(44);
else if (item->pos.zRot < -ANGLE(44))
item->pos.zRot = -ANGLE(44);
}
else
{
if (item->pos.zRot > ANGLE(22))
item->pos.zRot = ANGLE(22);
else if (item->pos.zRot < -ANGLE(22))
item->pos.zRot = -ANGLE(22);
}
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
LaraWaterCurrent(coll);
AnimateLara(item);
item->pos.xPos += phd_cos(item->pos.xRot) * (item->fallspeed * phd_sin(item->pos.yRot) >> (W2V_SHIFT + 2)) >> W2V_SHIFT;
item->pos.yPos -= item->fallspeed * phd_sin(item->pos.xRot) >> (W2V_SHIFT + 2);
item->pos.zPos += phd_cos(item->pos.xRot) * (item->fallspeed * phd_cos(item->pos.yRot) >> (W2V_SHIFT + 2)) >> W2V_SHIFT;
LaraBaddieCollision(item, coll);
lara_collision_routines[item->currentAnimState](item, coll);
UpdateLaraRoom(item, 0);
LaraGun();
TestTriggers(coll->trigger, 0, 0);
}
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 * phd_sin(item->pos.yRot + Lara.moveAngle) >> (W2V_SHIFT + 2);
item->pos.zPos += item->fallspeed * phd_cos(item->pos.yRot + 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 LaraCheat(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
LaraItem->hitPoints = 1000;
LaraUnderWater(item, coll);
if (TrInput & IN_WALK && !(TrInput & IN_LOOK))
{
Lara.waterStatus = LW_ABOVE_WATER;
item->animNumber = LA_STAND_SOLID;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.gunStatus = LG_NO_ARMS;
LaraInitialiseMeshes();
Lara.meshEffects = 0;
LaraItem->hitPoints = 1000;
}
}