Merge pull request #377 from MontyTRC89/lara_state_cleaning_etc

Lara state cleaning etc
This commit is contained in:
Lwmte 2021-12-17 15:25:43 +03:00 committed by GitHub
commit b8b1f9c47e
92 changed files with 5598 additions and 3685 deletions

View file

@ -16,10 +16,11 @@ settings.errorMode = ErrorMode.WARN;
SetSettings(settings);
local anims = Animations.new();
anims.crawlExtra = true;
anims.crawlExtended = true;
anims.crouchRoll = true;
anims.monkeyRoll = true;
anims.monkeyVault = true;
anims.oscillateHanging = true;
anims.swandiveRollRun = true;
anims.crawlspaceSwandive = true;
anims.monkeyTurn180 = true;
anims.monkeyAutoJump = false;
anims.oscillateHang = true;
anims.pose = false;
SetAnimations(anims);

View file

@ -1,7 +1,9 @@
#include "framework.h"
#include "Lara.h"
#include "lara.h"
#include "lara_basic.h"
#include "lara_helpers.h"
#include "lara_jump.h"
#include "lara_tests.h"
#include "lara_monkey.h"
#include "lara_crawl.h"
@ -54,14 +56,14 @@ byte LaraNodeUnderwater[NUM_LARA_MESHES];
function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
{
lara_as_walk,
lara_as_run,
lara_as_stop,
lara_as_walk_forward,
lara_as_run_forward,
lara_as_idle,
lara_as_forwardjump,
lara_void_func,//4
lara_as_fastback,//5
lara_as_turn_r,//6
lara_as_turn_l,//7
lara_as_pose,//4
lara_as_run_back,//5
lara_as_turn_right_slow,//6
lara_as_turn_left_slow,//7
lara_as_death,//8
lara_as_fastfall,
lara_as_hang,
@ -70,14 +72,14 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_tread,
lara_void_func,
lara_as_compress,//15
lara_as_back,//16
lara_as_walk_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
lara_void_func,
lara_as_controlled_no_look,//19
lara_as_turn_right_fast,//20
lara_as_step_right,//21
lara_as_step_left,//22
lara_as_roll_back,
lara_as_slide,//24
lara_as_backjump,//25
lara_as_rightjump,//26
@ -99,7 +101,7 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_usekey,//42
lara_as_usepuzzle,//43
lara_as_uwdeath,//44
lara_void_func,//45
lara_as_roll_forward,//45
lara_as_special,//46
lara_as_surfback,//47
lara_as_surfleft,//48
@ -119,38 +121,38 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_void_func,
lara_void_func,
lara_void_func,
lara_as_wade,//65
lara_as_wade_forward,//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_idle,//71
lara_as_crouch_roll,//72
lara_as_dash,
lara_as_dashdive,
lara_as_sprint,
lara_as_sprint_dive,
lara_as_monkey_idle,
lara_as_monkeyswing,
lara_as_monkeyl,
lara_as_monkeyr,
lara_as_monkey180,
lara_as_all4s,//80
lara_as_crawl,//81
lara_as_crawl_idle,//80
lara_as_crawl_forward,//81
lara_as_hangturnl,
lara_as_hangturnr,
lara_as_all4turnl,//84
lara_as_all4turnr,//85
lara_as_crawlb,//86
lara_as_null,
lara_as_null,
lara_as_crawl_turn_left,//84
lara_as_crawl_turn_right,//85
lara_as_crawl_back,//86
lara_as_controlled_no_look,
lara_as_controlled_no_look,
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_no_look,
lara_as_controlled_no_look,
lara_as_controlled,
lara_as_pickup,//98
lara_as_pole_idle,//99
@ -159,8 +161,8 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_pole_turn_clockwise,//102
lara_as_pole_turn_counter_clockwise,//103
lara_as_pulley,//104
lara_as_duckl,//105
lara_as_duckr,//106
lara_as_crouch_turn_left,//105
lara_as_crouch_turn_right,//106
lara_as_corner,//107
lara_as_corner,//108
lara_as_corner,//109
@ -174,7 +176,7 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_controlled,
lara_as_swimcheat,
lara_as_trpose,//119
lara_as_null,//120
lara_as_controlled_no_look,//120
lara_as_trwalk,//121
lara_as_trfall,//122
lara_as_trfall,//123
@ -189,8 +191,8 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_parallelbars,//128
lara_as_pbleapoff,//129
lara_as_null,//130
lara_as_null,//131
lara_as_null,//132
lara_as_controlled_no_look,//131
lara_as_controlled_no_look,//132
lara_as_null,//133
lara_as_null,//134
lara_as_null,//135
@ -204,23 +206,27 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] =
lara_as_null,// 143 - Unused
lara_as_null,// 144 - Unused
lara_as_null,// 145 - Unused
lara_as_controlledl,
lara_as_controlled_no_look,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_stepoff_left,
lara_as_stepoff_right
lara_as_stepoff_right,
lara_as_turn_left_fast,
lara_as_controlled,
lara_as_controlled,
lara_as_controlled
};
function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_walk,
lara_col_run,
lara_col_stop,
lara_col_walk_forward,
lara_col_run_forward,
lara_col_idle,
lara_col_forwardjump,
lara_col_pose,
lara_col_fastback,
lara_col_turn_r,
lara_col_turn_l,
lara_col_idle,//4
lara_col_run_back,
lara_col_turn_right_slow,
lara_col_turn_left_slow,
lara_col_death,
lara_col_fastfall,
lara_col_hang,
@ -229,14 +235,14 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_tread,
lara_col_land,
lara_col_compress,
lara_col_back,
lara_col_walk_back,
lara_col_swim,
lara_col_glide,
lara_default_col,
lara_col_fastturn,
lara_col_stepright,
lara_col_stepleft,
lara_col_roll2,
lara_col_turn_right_fast,
lara_col_step_right,
lara_col_step_left,
lara_col_roll_back,
lara_col_slide,
lara_col_backjump,
lara_col_rightjump,
@ -258,7 +264,7 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_default_col,
lara_default_col,
lara_col_uwdeath,
lara_col_roll,
lara_col_roll_forward,
lara_void_func,
lara_col_surfback,
lara_col_surfleft,
@ -278,30 +284,30 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_wade,
lara_col_wade_forward,
lara_col_waterroll,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_duck,
lara_col_crouch_idle,
lara_col_crouch_roll,
lara_col_dash,
lara_col_dashdive,
lara_col_sprint,
lara_col_sprint_dive,
lara_col_monkey_idle,
lara_col_monkeyswing,
lara_col_monkeyl,
lara_col_monkeyr,
lara_col_monkey180,
lara_col_all4s,
lara_col_crawl,
lara_col_crawl_idle,
lara_col_crawl_forward,
lara_col_hangturnlr,
lara_col_hangturnlr,
lara_col_all4turnlr,
lara_col_all4turnlr,
lara_col_crawlb,
lara_col_crawl_turn_left,
lara_col_crawl_turn_right,
lara_col_crawl_back,
lara_void_func,
lara_col_crawl2hang,
lara_col_crawl_to_hang,
lara_default_col,
lara_void_func,
lara_void_func,
@ -318,8 +324,8 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_pole_turn_clockwise,
lara_col_pole_turn_counter_clockwise,
lara_default_col,
lara_col_ducklr,
lara_col_ducklr,
lara_col_crouch_turn_left,
lara_col_crouch_turn_right,
lara_default_col,
lara_default_col,
lara_default_col,
@ -364,59 +370,63 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_default_col,
lara_default_col,
lara_col_turn_left_fast,
lara_default_col,
lara_default_col,
lara_default_col
};
void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
{
LaraCheatyBits();
LaraInfo*& info = item->data;
if (Lara.hasFired)
if (info->hasFired)
{
AlertNearbyGuards(item);
Lara.hasFired = false;
info->hasFired = false;
}
if (Lara.poisoned)
if (info->poisoned)
{
if (Lara.poisoned > 4096)
Lara.poisoned = 4096;
if (info->poisoned > 4096)
info->poisoned = 4096;
if (Lara.poisoned >= 256 && !(Wibble & 0xFF))
item->hitPoints -= Lara.poisoned >> 8;
if (info->poisoned >= 256 && !(Wibble & 0xFF))
item->hitPoints -= info->poisoned >> 8;
}
if (Lara.isMoving)
if (info->isMoving)
{
if (Lara.moveCount > 90)
if (info->moveCount > 90)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
info->isMoving = false;
info->gunStatus = LG_HANDS_FREE;
}
++Lara.moveCount;
++info->moveCount;
}
if (!Lara.uncontrollable)
Lara.locationPad = 128;
if (!info->uncontrollable)
info->locationPad = 128;
int oldX = item->pos.xPos;
int oldY = item->pos.yPos;
int oldZ = item->pos.zPos;
if (Lara.gunStatus == LG_HANDS_BUSY &&
item->currentAnimState == LS_STOP &&
item->goalAnimState == LS_STOP &&
if (info->gunStatus == LG_HANDS_BUSY &&
item->currentAnimState == LS_IDLE &&
item->goalAnimState == LS_IDLE &&
item->animNumber == LA_STAND_IDLE &&
!item->gravityStatus)
{
Lara.gunStatus = LG_NO_ARMS;
info->gunStatus = LG_HANDS_FREE;
}
if (item->currentAnimState != LS_SPRINT && Lara.sprintTimer < LARA_SPRINT_MAX)
Lara.sprintTimer++;
if (item->currentAnimState != LS_SPRINT && info->sprintTimer < LARA_SPRINT_MAX)
info->sprintTimer++;
Lara.isDucked = false;
info->isDucked = false;
bool isWater = TestLaraWater(item);
bool isSwamp = TestLaraSwamp(item);
@ -429,18 +439,14 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
heightFromWater = item->pos.yPos - waterHeight;
else
heightFromWater = NO_HEIGHT;
Lara.waterSurfaceDist = -heightFromWater;
info->waterSurfaceDist = -heightFromWater;
if (Lara.Vehicle == NO_ITEM)
if (info->Vehicle == NO_ITEM)
WadeSplash(item, waterHeight, waterDepth);
TriggerLaraDrips(item);
short roomNumber;
if (Lara.Vehicle == NO_ITEM && Lara.ExtraAnim == -1)
if (info->Vehicle == NO_ITEM && info->ExtraAnim == -1)
{
switch (Lara.waterStatus)
switch (info->waterStatus)
{
case LW_ABOVE_WATER:
if (heightFromWater == NO_HEIGHT || heightFromWater < WADE_DEPTH)
@ -448,17 +454,14 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
Camera.targetElevation = -ANGLE(22.0f);
if (waterDepth > (SWIM_DEPTH - STEP_SIZE) &&
!isSwamp &&
item->currentAnimState != LS_RUN_FORWARD && // Prevent ridiculous entrances when stepping down into wade-height water. @Sezz 2021.11.17
item->currentAnimState != LS_WALK_FORWARD &&
item->currentAnimState != LS_WALK_BACK)
// Water is deep enough to swim; dispatch dive.
if (waterDepth >= SWIM_DEPTH &&
!isSwamp)
{
if (isWater)
{
Lara.air = 1800;
Lara.waterStatus = LW_UNDERWATER;
info->air = LARA_AIR_MAX;
info->waterStatus = LW_UNDERWATER;
item->gravityStatus = false;
item->pos.yPos += 100;
@ -467,6 +470,7 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
if (item->currentAnimState == LS_SWANDIVE_START)
{
info->gunStatus = LG_HANDS_FREE;
item->pos.xRot = -ANGLE(45.0f);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
@ -474,6 +478,7 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
}
else if (item->currentAnimState == LS_SWANDIVE_END)
{
info->gunStatus = LG_HANDS_FREE;
item->pos.xRot = -ANGLE(85.0f);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
@ -486,34 +491,41 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 3 * item->fallspeed / 2;
}
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
ResetLaraFlex(item);
Splash(item);
}
}
else if (heightFromWater > WADE_DEPTH)
// Water is at wade depth; update water status and do special handling.
else if (heightFromWater >= WADE_DEPTH)
{
Lara.waterStatus = LW_WADE;
info->waterStatus = LW_WADE;
if (!item->gravityStatus)
item->goalAnimState = LS_STOP;
// Make splash ONLY within this particular threshold before swim depth while airborne (WadeSplash() above interferes otherwise).
if (waterDepth > (SWIM_DEPTH - STEP_SIZE) &&
!isSwamp &&
item->gravityStatus)
{
Splash(item);
item->goalAnimState = LS_IDLE;
}
// Lara is grounded; block land-to-run.
else if (!item->gravityStatus)
item->goalAnimState = LS_IDLE;
else if (isSwamp)
{
if (item->currentAnimState == LS_SWANDIVE_START || item->currentAnimState == LS_SWANDIVE_END)
if (item->currentAnimState == LS_SWANDIVE_START ||
item->currentAnimState == LS_SWANDIVE_END)
{
item->pos.yPos = waterHeight + (WALL_SIZE - 24);
}
SetAnimation(item, LA_WADE);
}
}
break;
case LW_UNDERWATER:
roomNumber = item->roomNumber;
GetFloor(item->pos.xPos, item->pos.yPos - STEP_SIZE, item->pos.zPos, &roomNumber);
if (isWater ||
waterDepth == DEEP_WATER ||
abs(heightFromWater) >= STEP_SIZE ||
@ -530,11 +542,8 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 0;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.waterStatus = LW_ABOVE_WATER;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
info->waterStatus = LW_ABOVE_WATER;
ResetLaraFlex(item);
}
else
{
@ -543,12 +552,9 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 0;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.waterStatus = LW_SURFACE;
Lara.diveCount = 11;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
info->waterStatus = LW_SURFACE;
info->diveCount = 11;
ResetLaraFlex(item);
UpdateItemRoom(item, -(STEPUP_HEIGHT - 3));
SoundEffect(SFX_TR4_LARA_BREATH, &item->pos, 2);
@ -562,12 +568,9 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 0;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.waterStatus = LW_SURFACE;
Lara.diveCount = 11;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
info->waterStatus = LW_SURFACE;
info->diveCount = 11;
ResetLaraFlex(item);
UpdateItemRoom(item, 0);
SoundEffect(SFX_TR4_LARA_BREATH, &item->pos, 2);
@ -582,13 +585,13 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
SetAnimation(item, LA_FALL_START);
item->speed = item->fallspeed / 4;
item->gravityStatus = true;
Lara.waterStatus = LW_ABOVE_WATER;
info->waterStatus = LW_ABOVE_WATER;
}
else
{
SetAnimation(item, LA_STAND_IDLE);
item->goalAnimState = LS_WADE_FORWARD; // TODO: Check if really needed? -- Lwmte, 10.11.21
Lara.waterStatus = LW_WADE;
info->waterStatus = LW_WADE;
AnimateItem(item);
}
@ -596,10 +599,7 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 0;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
ResetLaraFlex(item);
}
break;
@ -613,24 +613,21 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
{
SetAnimation(item, LA_ONWATER_IDLE);
Lara.waterStatus = LW_SURFACE;
info->waterStatus = LW_SURFACE;
item->pos.yPos += 1 - heightFromWater;
item->gravityStatus = false;
item->fallspeed = 0;
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.diveCount = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
info->diveCount = 0;
ResetLaraFlex(item);
UpdateItemRoom(item, 0);
}
}
else
{
Lara.waterStatus = LW_ABOVE_WATER;
info->waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == LS_WADE_FORWARD)
item->goalAnimState = LS_RUN_FORWARD;
@ -644,41 +641,41 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
{
item->hitPoints = -1;
if (Lara.deathCount == 0)
if (info->deathCount == 0)
StopSoundTracks();
Lara.deathCount++;
info->deathCount++;
if ((item->flags & 0x100))
{
Lara.deathCount++;
info->deathCount++;
return;
}
}
switch (Lara.waterStatus)
switch (info->waterStatus)
{
case LW_ABOVE_WATER:
case LW_WADE:
if (isSwamp && Lara.waterSurfaceDist < -(LARA_HEIGHT + 8)) // TODO: Find best height. @Sezz 2021.11.10
if (isSwamp && info->waterSurfaceDist < -(LARA_HEIGHT + 8)) // TODO: Find best height. @Sezz 2021.11.10
{
if (item->hitPoints >= 0)
{
Lara.air -= 6;
if (Lara.air < 0)
info->air -= 6;
if (info->air < 0)
{
Lara.air = -1;
info->air = -1;
item->hitPoints -= 10;
}
}
}
else if (Lara.air < LARA_AIR_MAX && item->hitPoints >= 0)
else if (info->air < LARA_AIR_MAX && item->hitPoints >= 0)
{
if (Lara.Vehicle == NO_ITEM) // only for the upv !!
if (info->Vehicle == NO_ITEM) // only for the upv !!
{
Lara.air += 10;
if (Lara.air > LARA_AIR_MAX)
Lara.air = LARA_AIR_MAX;
info->air += 10;
if (info->air > LARA_AIR_MAX)
info->air = LARA_AIR_MAX;
}
}
@ -691,13 +688,13 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
{
auto level = g_GameFlow->GetLevel(CurrentLevel);
if (level->LaraType != LaraType::Divesuit)
Lara.air--;
info->air--;
if (Lara.air < 0)
if (info->air < 0)
{
// if (LaraDrawType == LARA_TYPE::DIVESUIT && Lara.anxiety < 251)
// Lara.anxiety += 4;
Lara.air = -1;
// if (LaraDrawType == LARA_TYPE::DIVESUIT && info->anxiety < 251)
// info->anxiety += 4;
info->air = -1;
item->hitPoints -= 5;
}
}
@ -709,9 +706,9 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
case LW_SURFACE:
if (item->hitPoints >= 0)
{
Lara.air += 10;
if (Lara.air > LARA_AIR_MAX)
Lara.air = LARA_AIR_MAX;
info->air += 10;
if (info->air > LARA_AIR_MAX)
info->air = LARA_AIR_MAX;
}
LaraSurface(item, coll);
@ -732,6 +729,8 @@ void LaraControl(ITEM_INFO* item, COLL_INFO* coll)
void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
coll->Setup.OldPosition.x = item->pos.xPos;
coll->Setup.OldPosition.y = item->pos.yPos;
coll->Setup.OldPosition.z = item->pos.zPos;
@ -746,25 +745,25 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.DeathFlagIsPit = false;
coll->Setup.Mode = COLL_PROBE_MODE::QUADRANTS;
coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT;
if (TrInput & IN_LOOK && Lara.look &&
Lara.ExtraAnim == NO_ITEM)
if (TrInput & IN_LOOK && info->look &&
info->ExtraAnim == NO_ITEM)
{
LookLeftRight();
}
else
ResetLook();
else if (coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM) // TEMP HACK: Look feature will need a dedicated refactor; ResetLook() interferes with crawl flexing. @Sezz 2021.12.10
ResetLook(item);
Lara.look = true;
// TODO: Move radius and height default resets above look checks when
coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT;
info->look = true;
UpdateItemRoom(item, -LARA_HEIGHT / 2);
// Process Vehicles
if (Lara.Vehicle != NO_ITEM)
// Process vehicles.
if (info->Vehicle != NO_ITEM)
{
switch (g_Level.Items[Lara.Vehicle].objectNumber)
switch (g_Level.Items[info->Vehicle].objectNumber)
{
case ID_QUAD:
if (QuadBikeControl(item, coll))
@ -807,53 +806,40 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
break;
default:
// Boats are processed like normal items in loop
// Boats are processed like normal items in loop.
LaraGun(item);
return;
}
}
// Handle current Lara status
// Handle current Lara status.
lara_control_routines[item->currentAnimState](item, coll);
if (item->pos.zRot >= -ANGLE(1.0f) && item->pos.zRot <= ANGLE(1.0f))
item->pos.zRot = 0;
else if (item->pos.zRot < -ANGLE(1.0f))
item->pos.zRot += ANGLE(1.0f);
else
item->pos.zRot -= ANGLE(1.0f);
HandleLaraMovementParameters(item, coll);
if (Lara.turnRate >= -ANGLE(2.0f) && Lara.turnRate <= ANGLE(2.0f))
Lara.turnRate = 0;
else if (Lara.turnRate < -ANGLE(2.0f))
Lara.turnRate += ANGLE(2.0f);
else
Lara.turnRate -= ANGLE(2.0f);
item->pos.yRot += Lara.turnRate;
// Animate Lara
// Animate Lara.
AnimateLara(item);
if (Lara.ExtraAnim == -1)
if (info->ExtraAnim == -1)
{
// Check for collision with items
// Check for collision with items.
DoObjectCollision(item, coll);
// Handle Lara collision
if (Lara.Vehicle == NO_ITEM)
// Handle Lara collision.
if (info->Vehicle == NO_ITEM)
lara_collision_routines[item->currentAnimState](item, coll);
}
//if (Lara.gunType == WEAPON_CROSSBOW && !LaserSight)
//if (info->gunType == WEAPON_CROSSBOW && !LaserSight)
// TrInput &= ~IN_ACTION;
// Handle weapons
// Handle weapons.
LaraGun(item);
// Handle breath
// Handle breath.
LaraBreath(item);
// Test for flags & triggers
// Test for flags and triggers.
ProcessSectorFlags(item);
TestTriggers(item, false);
TestVolumes(item);
@ -861,6 +847,8 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
coll->Setup.BadHeightDown = 32512;
coll->Setup.BadHeightUp = -400;
coll->Setup.BadCeilingHeight = 400;
@ -879,12 +867,13 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.Radius = LARA_RAD_UNDERWATER;
coll->Setup.Height = LARA_HEIGHT;
if (TrInput & IN_LOOK && Lara.look)
if (TrInput & IN_LOOK && info->look)
LookLeftRight();
else
ResetLook();
ResetLook(item);
Lara.look = true;
info->look = true;
info->poseCount = 0;
lara_control_routines[item->currentAnimState](item, coll);
@ -892,31 +881,30 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
if (level->LaraType == LaraType::Divesuit)
{
if (Lara.turnRate < -ANGLE(0.5f))
Lara.turnRate += ANGLE(0.5f);
else if (Lara.turnRate > ANGLE(0.5f))
Lara.turnRate -= ANGLE(0.5f);
if (info->turnRate < -ANGLE(0.5f))
info->turnRate += ANGLE(0.5f);
else if (info->turnRate > ANGLE(0.5f))
info->turnRate -= ANGLE(0.5f);
else
Lara.turnRate = 0;
info->turnRate = 0;
}
else if (Lara.turnRate < -ANGLE(2.0f))
Lara.turnRate += ANGLE(2.0f);
else if (Lara.turnRate > ANGLE(2.0f))
Lara.turnRate -= ANGLE(2.0f);
else if (info->turnRate < -ANGLE(2.0f))
info->turnRate += ANGLE(2.0f);
else if (info->turnRate > ANGLE(2.0f))
info->turnRate -= ANGLE(2.0f);
else
Lara.turnRate = 0;
info->turnRate = 0;
item->pos.yRot += Lara.turnRate;
item->pos.yRot += info->turnRate;
if (level->LaraType == LaraType::Divesuit)
UpdateSubsuitAngles();
if (item->pos.zRot < -ANGLE(2.0f))
item->pos.zRot += ANGLE(2.0f);
else if (item->pos.zRot > ANGLE(2.0f))
item->pos.zRot -= ANGLE(2.0f);
else
item->pos.zRot = 0;
if (!info->isMoving && !(TrInput & (IN_LEFT | IN_RIGHT)))
{
if (abs(item->pos.zRot) > ANGLE(0.0f))
item->pos.zRot += item->pos.zRot / -8;
}
if (item->pos.xRot < -ANGLE(85.0f))
item->pos.xRot = -ANGLE(85.0f);
@ -938,7 +926,7 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
item->pos.zRot = -ANGLE(22.0f);
}
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
if (info->currentActive && info->waterStatus != LW_FLYCHEAT)
LaraWaterCurrent(coll);
AnimateLara(item);
@ -949,7 +937,7 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
DoObjectCollision(item, coll);
if (/*Lara.ExtraAnim == -1 &&*/ Lara.Vehicle == NO_ITEM)
if (/*info->ExtraAnim == -1 &&*/ info->Vehicle == NO_ITEM)
lara_collision_routines[item->currentAnimState](item, coll);
UpdateItemRoom(item, 0);
@ -963,6 +951,8 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)
void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
Camera.targetElevation = -ANGLE(22.0f);
coll->Setup.BadHeightDown = 32512;
@ -983,33 +973,33 @@ void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.Radius = LARA_RAD;
coll->Setup.Height = LARA_HEIGHT_SURFACE;
if (TrInput & IN_LOOK && Lara.look)
if (TrInput & IN_LOOK && info->look)
LookLeftRight();
else
ResetLook();
ResetLook(item);
Lara.look = true;
info->look = true;
info->poseCount = 0;
lara_control_routines[item->currentAnimState](item, coll);
if (item->pos.zRot >= -ANGLE(2) && item->pos.zRot <= ANGLE(2.0f))
item->pos.zRot = 0;
else if (item->pos.zRot < 0)
item->pos.zRot += ANGLE(2.0f);
else
item->pos.zRot -= ANGLE(2.0f);
if (!info->isMoving && !(TrInput & (IN_LEFT | IN_RIGHT)))
{
if (abs(item->pos.zRot) > ANGLE(0.0f))
item->pos.zRot += item->pos.zRot / -8;
}
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
if (info->currentActive && info->waterStatus != LW_FLYCHEAT)
LaraWaterCurrent(coll);
AnimateLara(item);
item->pos.xPos += item->fallspeed * phd_sin(Lara.moveAngle) / 4;
item->pos.zPos += item->fallspeed * phd_cos(Lara.moveAngle) / 4;
item->pos.xPos += item->fallspeed * phd_sin(info->moveAngle) / 4;
item->pos.zPos += item->fallspeed * phd_cos(info->moveAngle) / 4;
DoObjectCollision(item, coll);
if (Lara.Vehicle == NO_ITEM)
if (info->Vehicle == NO_ITEM)
lara_collision_routines[item->currentAnimState](item, coll);
UpdateItemRoom(item, 100);
@ -1023,38 +1013,38 @@ void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)
void LaraCheat(ITEM_INFO* item, COLL_INFO* coll)
{
LaraItem->hitPoints = 1000;
LaraInfo*& info = item->data;
item->hitPoints = LARA_HEALTH_MAX;
LaraUnderWater(item, coll);
if (TrInput & IN_WALK && !(TrInput & IN_LOOK))
{
if (TestLaraWater(item) || (Lara.waterSurfaceDist > 0 && Lara.waterSurfaceDist != NO_HEIGHT))
if (TestLaraWater(item) || (info->waterSurfaceDist > 0 && info->waterSurfaceDist != NO_HEIGHT))
{
Lara.waterStatus = LW_UNDERWATER;
info->waterStatus = LW_UNDERWATER;
SetAnimation(item, LA_UNDERWATER_IDLE);
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
ResetLaraFlex(item);
}
else
{
Lara.waterStatus = LW_ABOVE_WATER;
info->waterStatus = LW_ABOVE_WATER;
SetAnimation(item, LA_STAND_SOLID);
item->pos.zRot = 0;
item->pos.xRot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
ResetLaraFlex(item);
}
Lara.gunStatus = LG_NO_ARMS;
info->gunStatus = LG_HANDS_FREE;
LaraInitialiseMeshes();
LaraItem->hitPoints = 1000;
item->hitPoints = LARA_HEALTH_MAX;
}
}
void AnimateLara(ITEM_INFO* item)
{
LaraInfo*& info = item->data;
item->frameNumber++;
ANIM_STRUCT* anim = &g_Level.Anims[item->animNumber];
@ -1083,16 +1073,16 @@ void AnimateLara(ITEM_INFO* item)
item->fallspeed = *(cmd++);
item->speed = *(cmd++);
item->gravityStatus = true;
if (Lara.calcFallSpeed)
if (info->calcFallSpeed)
{
item->fallspeed = Lara.calcFallSpeed;
Lara.calcFallSpeed = 0;
item->fallspeed = info->calcFallSpeed;
info->calcFallSpeed = 0;
}
break;
case COMMAND_ATTACK_READY:
if (Lara.gunStatus != LG_SPECIAL)
Lara.gunStatus = LG_NO_ARMS;
if (info->gunStatus != LG_SPECIAL)
info->gunStatus = LG_HANDS_FREE;
break;
case COMMAND_SOUND_FX:
@ -1140,8 +1130,8 @@ void AnimateLara(ITEM_INFO* item)
flags = cmd[1] & 0xC000;
if ( flags == (int)SOUND_PLAYCONDITION::LandAndWater ||
(flags == (int)SOUND_PLAYCONDITION::Land && (Lara.waterSurfaceDist >= 0 || Lara.waterSurfaceDist == NO_HEIGHT)) ||
(flags == (int)SOUND_PLAYCONDITION::Water && Lara.waterSurfaceDist < 0 && Lara.waterSurfaceDist != NO_HEIGHT && !TestLaraSwamp(item)))
(flags == (int)SOUND_PLAYCONDITION::Land && (info->waterSurfaceDist >= 0 || info->waterSurfaceDist == NO_HEIGHT)) ||
(flags == (int)SOUND_PLAYCONDITION::Water && info->waterSurfaceDist < 0 && info->waterSurfaceDist != NO_HEIGHT && !TestLaraSwamp(item)))
{
SoundEffect(cmd[1] & 0x3FFF, &item->pos, 2);
}
@ -1204,7 +1194,7 @@ void AnimateLara(ITEM_INFO* item)
{
int velocity;
if (Lara.waterStatus == LW_WADE && TestLaraSwamp(item))
if (info->waterStatus == LW_WADE && TestLaraSwamp(item))
{
velocity = (anim->velocity >> 1);
if (anim->acceleration)
@ -1220,11 +1210,11 @@ void AnimateLara(ITEM_INFO* item)
item->speed = velocity >> 16;
}
if (Lara.ropePtr != -1)
if (info->ropePtr != -1)
DelAlignLaraToRope(item);
if (!Lara.isMoving)
MoveItem(item, Lara.moveAngle, item->speed, lateral);
if (!info->isMoving)
MoveItem(item, info->moveAngle, item->speed, lateral);
// Update matrices
g_Renderer.updateLaraAnimations(true);

View file

@ -4,25 +4,44 @@
struct ITEM_INFO;
struct COLL_INFO;
#define FRONT_ARC ANGLE(90.0f)
#define LARA_GRAB_THRESHOLD ANGLE(35.0f)
#define FRONT_ARC ANGLE(90.0f) // TODO: Check use.
// Lean rates
#define LARA_LEAN_RATE ANGLE(1.5f)
#define LARA_LEAN_MAX ANGLE(11.0f)
#define LARA_LEAN_DASH_MAX ANGLE(16.0f)
#define LARA_TURN_RATE ANGLE(2.25f)
#define SUB_SUIT_TURN_RATE ANGLE(0.75f)
#define LARA_JUMP_TURN ANGLE(3.0f)
#define LARA_SLOW_TURN ANGLE(4.0f)
#define LARA_MED_TURN ANGLE(6.0f)
#define LARA_FAST_TURN ANGLE(8.0f)
#define LARA_GRAB_THRESHOLD ANGLE(30.0f)
constexpr auto LARA_HEIGHT = CLICK(3) - 1; // The size of Lara (from the floor to the top of the head)
constexpr auto LARA_HEIGHT_CRAWL = 400; // Size of Lara in crawl state
constexpr auto LARA_HEIGHT_MONKEY = 600; // Size of Lara in monkey state
constexpr auto LARA_HEIGHT_SURFSWIM = 700; // Size of Lara in surface swim state
constexpr auto LARA_HEIGHT_STRETCH = 870; // Size of Lara in jump-up or ledge hanging state
constexpr auto LARA_HEIGHT_SURFACE = 800; // Size of Lara when surfacing water
constexpr auto LARA_HEADROOM = 160; // Amount of reasonable space above Lara's head
// Turn rates
#define LARA_TURN_RATE ANGLE(2.25f)
#define LARA_CRAWL_MOVE_TURN_RATE ANGLE(2.15f)
#define LARA_POLE_TURN_RATE ANGLE(2.25f)
#define LARA_SUBSUIT_TURN_RATE ANGLE(0.75f)
// Turn rate maxes
#define LARA_SLOW_TURN_MAX ANGLE(4.0f)
#define LARA_SLOW_MED_TURN_MAX ANGLE(5.0f)
#define LARA_MED_TURN_MAX ANGLE(6.0f)
#define LARA_MED_FAST_TURN_MAX ANGLE(7.0f)
#define LARA_FAST_TURN_MAX ANGLE(8.0f)
#define LARA_WADE_TURN_MAX ANGLE(5.5f)
#define LARA_SWAMP_TURN_MAX ANGLE(2.0f)
#define LARA_JUMP_TURN_MAX ANGLE(3.0f)
#define LARA_CRAWL_TURN_MAX ANGLE(2.0f)
#define LARA_CRAWL_MOVE_TURN_MAX ANGLE(3.75f)
#define LARA_CROUCH_ROLL_TURN_MAX ANGLE(2.75f)
#define LARA_POLE_TURN_MAX ANGLE(4.5f)
// Flex rates
#define LARA_CRAWL_FLEX_RATE ANGLE(2.25f)
#define LARA_CRAWL_FLEX_MAX ANGLE(50.0f) / 2 // 2 = hardcoded number of bones to flex (head and torso).
constexpr auto LARA_HEIGHT = CLICK(3) - 1; // Lara height in standard states.
constexpr auto LARA_HEIGHT_CRAWL = 350; // Lara height in crawl states.
constexpr auto LARA_HEIGHT_MONKEY = 600; // Lara height in monkey swing states.
constexpr auto LARA_HEIGHT_SURFSWIM = 700; // Lara height in water treading states.
constexpr auto LARA_HEIGHT_STRETCH = 870; // Lara height in jump-up and ledge hanging states.
constexpr auto LARA_HEIGHT_SURFACE = 800; // Lara height when surfacing water.
constexpr auto LARA_HEADROOM = 160; // Amount of reasonable space above Lara's head.
constexpr auto LARA_RAD = 100;
constexpr auto LARA_RAD_CRAWL = 200;
constexpr auto LARA_RAD_UNDERWATER = 300;
@ -30,6 +49,9 @@ constexpr auto LARA_RAD_DEATH = 400;
constexpr auto LARA_FREEFALL_SPEED = 131;
constexpr auto LARA_VELOCITY = 12;
constexpr auto LARA_JUMP_TIME = 22; // Frames to count before running jump is possible.
constexpr auto LARA_POSE_TIME = 30 * 30; // 30 frames * 30 = 30 seconds to AFK pose.
constexpr auto LARA_HEALTH_MAX = 1000.0f;
constexpr auto LARA_AIR_MAX = 1800.0f;
constexpr auto LARA_SPRINT_MAX = 120.0f;

File diff suppressed because it is too large Load diff

View file

@ -1,71 +1,71 @@
#pragma once
struct ITEM_INFO;
struct COLL_INFO;
/*generic functions*/
struct COLL_RESULT;
// ------------------------------
// BASIC MOVEMENT & MISCELLANEOUS
// Control & Collision Functions
// ------------------------------
// --------------
// MISCELLANEOUS:
// --------------
void lara_void_func(ITEM_INFO* item, COLL_INFO* coll);
void lara_default_col(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_special(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_null(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_controlled(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_controlledl(ITEM_INFO* item, COLL_INFO* coll);
/*end generic functions*/
/*-*/
/*basic movement*/
void lara_as_walk(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_walk(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_run(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_run(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_forwardjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_forwardjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_pose(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastback(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastback(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_r(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_r(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_l(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_l(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_controlled_no_look(ITEM_INFO* item, COLL_INFO* coll);
// ---------------
// BASIC MOVEMENT:
// ---------------
void lara_as_walk_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_walk_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_run_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_run_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_idle(ITEM_INFO* item, COLL_INFO* coll);
void PseudoLaraAsWadeIdle(ITEM_INFO* item, COLL_INFO* coll);
void PseudoLaraAsSwampIdle(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_idle(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pose(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_run_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_run_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_right_slow(ITEM_INFO* item, COLL_INFO* coll);
void PsuedoLaraAsSwampTurnRightSlow(ITEM_INFO* item, COLL_INFO* coll);
void PsuedoLaraAsWadeTurnRightSlow(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_right_slow(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_left_slow(ITEM_INFO* item, COLL_INFO* coll);
void PsuedoLaraAsWadeTurnLeftSlow(ITEM_INFO* item, COLL_INFO* coll);
void PsuedoLaraAsSwampTurnLeftSlow(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_left_slow(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_death(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_death(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastfall(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastfall(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_reach(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_splat(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_splat(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_land(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_compress(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_compress(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastturn(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastturn(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_stepright(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_stepright(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_stepleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_stepleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_roll2(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_backjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_backjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rightjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_rightjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_leftjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_leftjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jumper(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_upjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_upjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fallback(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fallback(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_roll(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swandive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_swandive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastdive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastdive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_gymnast(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_wade(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_wade(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_dash(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_dash(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_dashdive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_dashdive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_walk_back(ITEM_INFO* item, COLL_INFO* coll);
void PseudoLaraAsSwampWalkBack(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_walk_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_right_fast(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_right_fast(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_left_fast(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_left_fast(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_step_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_step_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_step_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_step_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_roll_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_roll_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_roll_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_roll_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_wade_forward(ITEM_INFO* item, COLL_INFO* coll);
void PseudoLaraAsSwampWadeForward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_wade_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_sprint(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_sprint(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_sprint_dive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_sprint_dive(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -385,7 +385,7 @@ void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll)
if (item->animNumber == LA_LADDER_IDLE)
{
item->goalAnimState = LS_JUMP_BACK;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.moveAngle = item->pos.yRot + ANGLE(180);
}
}
@ -958,7 +958,7 @@ int LaraCheckForLetGo(ITEM_INFO* item, COLL_INFO* coll)
item->gravityStatus = true;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
return 1;
}

View file

@ -14,7 +14,10 @@
#include "GameFlowScript.h"
#include "GameScriptLevel.h"
/*this file has all the generic **collision** test functions called in lara's state code*/
// -----------------------------
// COLLISION TEST FUNCTIONS
// For State Control & Collision
// -----------------------------
bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll)
{
@ -22,7 +25,7 @@ bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll)
{
ShiftItem(item, coll);
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
item->speed = 0;
item->gravityStatus = false;
@ -43,46 +46,40 @@ bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll)
return false;
}
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)
bool LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)
{
ShiftItem(item, coll);
switch (coll->CollisionType)
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT)
{
case CT_FRONT:
case CT_TOP_FRONT:
if (!Lara.climbStatus || item->speed != 2)
{
if (coll->Middle.Floor <= 512)
{
if (coll->Middle.Floor <= 128)
SetAnimation(item, LA_JUMP_UP_LAND);
}
if (coll->Middle.Floor <= STEP_SIZE)
SetAnimation(item, LA_LAND);
else
{
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
}
item->speed /= 4;
Lara.moveAngle += ANGLE(180);
Lara.moveAngle += ANGLE(180.0f);
if (item->fallspeed <= 0)
item->fallspeed = 1;
}
break;
case CT_TOP:
return true;
}
if (coll->CollisionType == CT_TOP)
{
if (item->fallspeed <= 0)
item->fallspeed = 1;
break;
case CT_LEFT:
}
else if (coll->CollisionType == CT_LEFT)
item->pos.yRot += ANGLE(5.0f);
break;
case CT_RIGHT:
else if (coll->CollisionType == CT_RIGHT)
item->pos.yRot -= ANGLE(5.0f);
break;
case CT_CLAMP:
else if (coll->CollisionType == CT_CLAMP)
{
item->pos.xPos -= 400 * phd_sin(coll->Setup.ForwardAngle);
item->pos.zPos -= 400 * phd_cos(coll->Setup.ForwardAngle);
@ -91,13 +88,14 @@ void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)
if (item->fallspeed <= 0)
item->fallspeed = 16;
break;
}
return false;
}
bool LaraDeflectEdgeCrawl(ITEM_INFO* item, COLL_INFO* coll)
{
// Useless in the best case; Lara does not have to embed in order to perform climbing actions in crawl states. Keeping for security. @Sezz 2021.11.26
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT)
{
ShiftItem(item, coll);
@ -111,17 +109,43 @@ bool LaraDeflectEdgeCrawl(ITEM_INFO* item, COLL_INFO* coll)
if (coll->CollisionType == CT_LEFT)
{
ShiftItem(item, coll);
item->pos.yRot += ANGLE(2.0f);
item->pos.yRot += ANGLE(coll->DiagonalStepAtLeft() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL);
}
else if (coll->CollisionType == CT_RIGHT)
{
ShiftItem(item, coll);
item->pos.yRot -= ANGLE(2.0f);
item->pos.yRot -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE_CRAWL : DEFLECT_STRAIGHT_ANGLE_CRAWL);
}
return false;
}
// TODO: Move the following two functions to lara_tests.cpp and lara_helpers.cpp?
// @Sezz 2021.09.26
bool TestLaraHitCeiling(COLL_INFO* coll)
{
if (coll->CollisionType == CT_TOP ||
coll->CollisionType == CT_CLAMP)
{
return true;
}
return false;
}
void SetLaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll)
{
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
}
// LEGACY
// TODO: Gradually replace usage with TestLaraHitCeiling() and SetLaraHitCeiling(). @Sezz 2021.09.27
bool LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll)
{
if (coll->CollisionType == CT_TOP || coll->CollisionType == CT_CLAMP)
@ -146,33 +170,84 @@ void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)
{
switch (coll->Setup.OldAnimState)
{
case LS_STOP:
case LS_IDLE:
case LS_TURN_RIGHT_SLOW:
case LS_TURN_LEFT_SLOW:
case LS_TURN_FAST:
case LS_TURN_RIGHT_FAST:
case LS_TURN_LEFT_FAST:
item->currentAnimState = coll->Setup.OldAnimState;
item->animNumber = coll->Setup.OldAnimNumber;
item->frameNumber = coll->Setup.OldFrameNumber;
if (TrInput & IN_LEFT)
{
item->goalAnimState = LS_TURN_LEFT_SLOW;
// Prevent turn lock against walls.
if (item->currentAnimState == LS_TURN_RIGHT_SLOW ||
item->currentAnimState == LS_TURN_RIGHT_FAST)
{
item->goalAnimState = LS_IDLE;
}
else
item->goalAnimState = LS_TURN_LEFT_SLOW;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = LS_TURN_RIGHT_SLOW;
if (item->currentAnimState == LS_TURN_LEFT_SLOW ||
item->currentAnimState == LS_TURN_LEFT_FAST)
{
item->goalAnimState = LS_IDLE;
}
else
item->goalAnimState = LS_TURN_RIGHT_SLOW;
}
else
{
item->goalAnimState = LS_STOP;
}
item->goalAnimState = LS_IDLE;
AnimateLara(item);
break;
default:
item->goalAnimState = LS_IDLE;
if (item->animNumber != LA_STAND_SOLID)
SetAnimation(item, LA_STAND_SOLID);
break;
}
}
void LaraCollideStopCrawl(ITEM_INFO* item, COLL_INFO* coll)
{
switch (coll->Setup.OldAnimState)
{
case LS_CRAWL_IDLE:
case LS_CRAWL_TURN_LEFT:
case LS_CRAWL_TURN_RIGHT:
item->currentAnimState = coll->Setup.OldAnimState;
item->animNumber = coll->Setup.OldAnimNumber;
item->frameNumber = coll->Setup.OldFrameNumber;
if (TrInput & IN_LEFT)
item->goalAnimState = LS_CRAWL_TURN_LEFT;
else if (TrInput & IN_RIGHT)
item->goalAnimState = LS_CRAWL_TURN_RIGHT;
else
item->goalAnimState = LS_CRAWL_IDLE;
AnimateLara(item);
break;
default:
item->goalAnimState = LS_STOP;
if (item->animNumber != LA_STAND_SOLID)
item->currentAnimState = LS_CRAWL_IDLE;
item->goalAnimState = LS_CRAWL_IDLE;
if (item->animNumber != LA_CRAWL_IDLE)
{
SetAnimation(item, LA_STAND_SOLID);
item->animNumber = LA_CRAWL_IDLE;
item->frameNumber = GetFrameNumber(item, 0);
}
break;
}
}
@ -261,6 +336,35 @@ void GetLaraDeadlyBounds()
DeadlyBounds[5] = LaraItem->pos.zPos + tbounds.Z2;
}
void LaraJumpCollision(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*states 25, 26, 27*/
/*state code: none, but is called in lara_col_backjump, lara_col_rightjump and lara_col_leftjump*/
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
item->goalAnimState = LS_IDLE;
item->fallspeed = 0;
item->gravityStatus = 0;
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)
{
coll->Setup.ForwardAngle = Lara.moveAngle;
@ -440,3 +544,18 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)
if (Lara.waterStatus != LW_FLYCHEAT && Lara.ExtraAnim == NO_ITEM)
TestLaraWaterDepth(item, coll);
}
bool TestLaraObjectCollision(ITEM_INFO* item, short angle, int dist, int height)
{
auto oldPos = item->pos;
item->pos.xPos += dist * phd_sin(item->pos.yRot + angle);
item->pos.yPos += height;
item->pos.zPos += dist * phd_cos(item->pos.yRot + angle);
auto result = GetCollidedObjects(item, LARA_RAD, 1, CollidedItems, CollidedMeshes, 0);
item->pos = oldPos;
return result;
}

View file

@ -4,17 +4,27 @@ struct COLL_INFO;
constexpr auto DEFLECT_STRAIGHT_ANGLE = 5.0f;
constexpr auto DEFLECT_DIAGONAL_ANGLE = 12.0f;
constexpr auto DEFLECT_STRAIGHT_ANGLE_CRAWL = 2.0f;
constexpr auto DEFLECT_DIAGONAL_ANGLE_CRAWL = 5.0f;
bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll);
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll);
bool LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll);
bool LaraDeflectEdgeCrawl(ITEM_INFO* item, COLL_INFO* coll);
bool LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll);
void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll);
void LaraCollideStopCrawl(ITEM_INFO* item, COLL_INFO* coll);
void LaraSnapToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle);
void LaraResetGravityStatus(ITEM_INFO* item, COLL_INFO* coll);
void LaraSnapToHeight(ITEM_INFO* item, COLL_INFO* coll);
short GetDirOctant(int rot);
void GetLaraDeadlyBounds();
void LaraJumpCollision(ITEM_INFO* item, COLL_INFO* coll);
void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll);
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll);
// TODO: Temporary placement.
bool TestLaraHitCeiling(COLL_INFO* coll);
void SetLaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraObjectCollision(ITEM_INFO* item, short angle, int dist, int height);

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,36 @@
#pragma once
#include "lara_struct.h"
/*crouch/duck start*/
void lara_as_duck(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_duck(ITEM_INFO* item, COLL_INFO* coll);
// -----------------------------
// CRAWL & CROUCH
// Control & Collision Functions
// -----------------------------
// -------
// CROUCH:
// -------
void lara_as_crouch_idle(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crouch_idle(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crouch_roll(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crouch_roll(ITEM_INFO* item, COLL_INFO* coll);
/*crouch/duck end*/
/*-*/
/*crawl start*/
void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_all4s(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawl(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_all4turnl(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_all4turnr(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_all4turnlr(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawlb(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawlb(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_duckl(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_duckr(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_ducklr(ITEM_INFO* item, COLL_INFO* coll);
/*crawl end*/
void lara_col_crawl2hang(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crouch_turn_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crouch_turn_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crouch_turn_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crouch_turn_right(ITEM_INFO* item, COLL_INFO* coll);
// ------
// CRAWL:
// ------
void lara_as_crawl_idle(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_idle(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawl_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawl_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawl_turn_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_turn_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_crawl_turn_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_turn_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_to_hang(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -235,15 +235,17 @@ WEAPON_INFO Weapons[NUM_WEAPONS] =
}
};
// States in which Lara will hold the flare out in front.
short HoldStates[] = {
LS_WALK_FORWARD,
LS_RUN_FORWARD,
LS_STOP,
LS_IDLE,
LS_POSE,
LS_TURN_RIGHT_SLOW,
LS_TURN_LEFT_SLOW,
LS_WALK_BACK,
LS_TURN_FAST,
LS_TURN_RIGHT_FAST,
LS_TURN_LEFT_FAST,
LS_STEP_RIGHT,
LS_STEP_LEFT,
LS_PICKUP,
@ -355,8 +357,8 @@ void LaraGun(ITEM_INFO* laraItem)
}
if (laraItem->hitPoints <= 0)
laraInfo->gunStatus = LG_NO_ARMS;
else if (laraInfo->gunStatus == LG_NO_ARMS)
laraInfo->gunStatus = LG_HANDS_FREE;
else if (laraInfo->gunStatus == LG_HANDS_FREE)
{
// Draw weapon.
if (TrInput & IN_DRAW)
@ -365,12 +367,6 @@ void LaraGun(ITEM_INFO* laraItem)
else if (TrInput & IN_FLARE &&
(g_GameFlow->GetLevel(CurrentLevel)->LaraType != LaraType::Young))
{
if (laraItem->currentAnimState == LS_CROUCH_IDLE &&
laraItem->animNumber != LA_CROUCH_IDLE)
{
return;
}
if (laraInfo->gunType == WEAPON_FLARE)
{
// if (!laraInfo->leftArm.frameNumber) //NO
@ -496,7 +492,7 @@ void LaraGun(ITEM_INFO* laraItem)
break;
default:
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
break;
}
@ -587,7 +583,7 @@ void LaraGun(ITEM_INFO* laraItem)
break;
case LG_NO_ARMS:
case LG_HANDS_FREE:
if (laraInfo->gunType == WEAPON_FLARE)
{
if (laraInfo->Vehicle != NO_ITEM ||
@ -661,7 +657,7 @@ void InitialiseNewWeapon(ITEM_INFO* lara)
case WEAPON_UZI:
laraInfo->rightArm.frameBase = Objects[ID_PISTOLS_ANIM].frameBase;
laraInfo->leftArm.frameBase = Objects[ID_PISTOLS_ANIM].frameBase;
if (laraInfo->gunStatus != LG_NO_ARMS)
if (laraInfo->gunStatus != LG_HANDS_FREE)
draw_pistol_meshes(laraInfo->gunType);
break;
@ -673,14 +669,14 @@ void InitialiseNewWeapon(ITEM_INFO* lara)
case WEAPON_ROCKET_LAUNCHER:
laraInfo->rightArm.frameBase = Objects[WeaponObject(laraInfo->gunType)].frameBase;
laraInfo->leftArm.frameBase = Objects[WeaponObject(laraInfo->gunType)].frameBase;
if (laraInfo->gunStatus != LG_NO_ARMS)
if (laraInfo->gunStatus != LG_HANDS_FREE)
draw_shotgun_meshes(laraInfo->gunType);
break;
case WEAPON_FLARE:
laraInfo->rightArm.frameBase = Objects[ID_LARA_FLARE_ANIM].frameBase;
laraInfo->leftArm.frameBase = Objects[ID_LARA_FLARE_ANIM].frameBase;
if (laraInfo->gunStatus != LG_NO_ARMS)
if (laraInfo->gunStatus != LG_HANDS_FREE)
DrawFlareMeshes(lara);
break;
@ -1113,7 +1109,7 @@ void LaraGetNewTarget(ITEM_INFO* lara, WEAPON_INFO* weaponInfo)
if (TargetList[slot] == laraInfo->target)
break;
}
if (laraInfo->gunStatus != LG_NO_ARMS || TrInput & IN_LOOKSWITCH)
if (laraInfo->gunStatus != LG_HANDS_FREE || TrInput & IN_LOOKSWITCH)
{
if (!laraInfo->target)
{

View file

@ -84,7 +84,7 @@ void ReadyFlare(ITEM_INFO* laraItem)
{
LaraInfo*& laraInfo = laraItem->data;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
laraInfo->leftArm.xRot = 0;
laraInfo->leftArm.yRot = 0;
laraInfo->leftArm.zRot = 0;
@ -118,7 +118,7 @@ void UndrawFlare(ITEM_INFO* laraItem)
laraInfo->flareControlLeft = true;
if (laraItem->goalAnimState == LS_STOP &&
if (laraItem->goalAnimState == LS_IDLE &&
laraInfo->Vehicle == NO_ITEM)
{
if (laraItem->animNumber == LA_STAND_IDLE)
@ -137,7 +137,7 @@ void UndrawFlare(ITEM_INFO* laraItem)
{
laraInfo->requestGunType = laraInfo->lastGunType;
laraInfo->gunType = laraInfo->lastGunType;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
InitialiseNewWeapon(laraItem);
@ -190,7 +190,7 @@ void UndrawFlare(ITEM_INFO* laraItem)
armFrame = 0;
laraInfo->requestGunType = laraInfo->lastGunType;
laraInfo->gunType = laraInfo->lastGunType;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
InitialiseNewWeapon(laraItem);
@ -376,7 +376,7 @@ void DoFlareInHand(ITEM_INFO* laraItem, int flareAge)
if (ItemInfo->flareAge >= FLARE_AGE)
{
if (ItemInfo->gunStatus == LG_NO_ARMS)
if (ItemInfo->gunStatus == LG_HANDS_FREE)
ItemInfo->gunStatus = LG_UNDRAW_GUNS;
}
else if (ItemInfo->flareAge != 0)

View file

@ -20,7 +20,7 @@ void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, bool flip)
item->pos.yPos += STEP_SIZE;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
item->pos.yRot += Lara.nextCornerPos.yRot / 2;
return;
@ -53,7 +53,7 @@ void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
return;
}
@ -278,6 +278,14 @@ void lara_col_hangright(ITEM_INFO* item, COLL_INFO* coll)
Lara.moveAngle = item->pos.yRot + ANGLE(90);
}
void lara_as_gymnast(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 54*/
/*collision: lara_default_col*/
coll->Setup.EnableObjectPush = false;
coll->Setup.EnableSpaz = false;
}
/*go around corners*/
void lara_as_corner(ITEM_INFO* item, COLL_INFO* coll)

View file

@ -8,6 +8,7 @@ void lara_as_hangleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hangleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hangright(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hangright(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_gymnast(ITEM_INFO* item, COLL_INFO* coll);
// Go around corners
void lara_as_corner(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -0,0 +1,253 @@
#include "framework.h"
#include "collide.h"
#include "control/control.h"
#include "input.h"
#include "items.h"
#include "level.h"
#include "lara.h"
#include "lara_helpers.h"
#include "lara_tests.h"
#include "lara_collide.h"
#include "setup.h"
#include "GameFlowScript.h"
// -----------------------------
// HELPER FUNCTIONS
// For State Control & Collision
// -----------------------------
// TODO: Some states can't make the most of this function due to missing step up/down animations.
// Try implementing leg IK as a substitute to make step animations obsolete. @Sezz 2021.10.09
void DoLaraStep(ITEM_INFO* item, COLL_INFO* coll)
{
if (!TestLaraSwamp(item))
{
if (TestLaraStepUp(item, coll))
{
item->goalAnimState = LS_STEP_UP;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
{
item->pos.yPos += coll->Middle.Floor;
return;
}
}
else if (TestLaraStepDown(item, coll))
{
item->goalAnimState = LS_STEP_DOWN;
if (GetChange(item, &g_Level.Anims[item->animNumber]))
{
item->pos.yPos += coll->Middle.Floor;
return;
}
}
}
// Height difference is below threshold for step dispatch OR step animation doesn't exist; translate Lara to new floor height.
// TODO: This approach might cause underirable artefacts where an object pushes Lara rapidly up/down a slope or a platform rapidly ascends/descends.
constexpr int rate = 50;
int threshold = std::max(abs(item->speed) / 3 * 2, STEP_SIZE / 16);
int sign = std::copysign(1, coll->Middle.Floor);
if (TestLaraSwamp(item) && coll->Middle.Floor > 0)
item->pos.yPos += SWAMP_GRAVITY;
else if (abs(coll->Middle.Floor) > (STEPUP_HEIGHT / 2)) // Outer range.
item->pos.yPos += rate * sign;
else if (abs(coll->Middle.Floor) <= (STEPUP_HEIGHT / 2) && // Inner range.
abs(coll->Middle.Floor) >= threshold)
{
item->pos.yPos += std::max((int)abs(coll->Middle.Floor / 2.75), threshold) * sign;
}
else
item->pos.yPos += coll->Middle.Floor;
}
void DoLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
ResetLaraFlex(item);
if (TestLaraCrawlExitDownStep(item, coll))
{
if (TrInput & IN_DUCK && TestLaraCrawlDownStep(item, coll))
item->goalAnimState = LS_STEP_DOWN;
else [[likely]]
item->goalAnimState = LS_CRAWL_EXIT_DOWN_STEP;
return;
}
if (TestLaraCrawlExitJump(item, coll))
{
if (TrInput & IN_WALK)
item->goalAnimState = LS_CRAWL_EXIT_FLIP;
else [[likely]]
item->goalAnimState = LS_CRAWL_EXIT_JUMP;
return;
}
if (TestLaraCrawlUpStep(item, coll))
{
item->goalAnimState = LS_STEP_UP;
return;
}
if (TestLaraCrawlDownStep(item, coll))
{
item->goalAnimState = LS_STEP_DOWN;
return;
}
}
void DoLaraCrawlToHangSnap(ITEM_INFO* item, COLL_INFO* coll)
{
coll->Setup.ForwardAngle = item->pos.yRot + ANGLE(180.0f);
GetCollisionInfo(coll, item);
SnapItemToLedge(item, coll);
MoveItem(item, item->pos.yRot, -LARA_RAD_CRAWL);
item->pos.yRot += ANGLE(180.0f);
LaraResetGravityStatus(item, coll);
}
// TODO: Make lean rate proportional to the turn rate, allowing for nicer aesthetics with future analog stick input.
void DoLaraLean(ITEM_INFO* item, COLL_INFO* coll, int maxAngle, short rate)
{
if (!item->speed)
return;
int sign = copysign(1, maxAngle);
if (coll->CollisionType == CT_LEFT || coll->CollisionType == CT_RIGHT)
item->pos.zRot += std::min(rate, (short)(abs((maxAngle * 3) / 5 - item->pos.zRot) / 3)) * sign;
else
item->pos.zRot += std::min(rate, (short)(abs(maxAngle - item->pos.zRot) / 3)) * sign;
}
void DoLaraCrawlFlex(ITEM_INFO* item, COLL_INFO* coll, short maxAngle, short rate)
{
LaraInfo*& info = item->data;
if (!item->speed)
return;
int sign = copysign(1, maxAngle);
rate = copysign(rate, maxAngle);
info->torsoZrot += std::min(abs(rate), abs(maxAngle - info->torsoZrot) / 6) * sign;
if (!(TrInput & IN_LOOK) &&
item->currentAnimState != LS_CRAWL_BACK)
{
info->headZrot = info->torsoZrot / 2;
info->headYrot = info->headZrot;
}
}
void SetLaraFallState(ITEM_INFO* item)
{
SetAnimation(item, LA_FALL_START);
item->fallspeed = 0;
item->gravityStatus = true;
}
void SetLaraFallBackState(ITEM_INFO* item)
{
SetAnimation(item, LA_FALL_BACK);
item->fallspeed = 0;
item->gravityStatus = true;
}
void ResetLaraFlex(ITEM_INFO* item, float rate)
{
LaraInfo*& info = item->data;
// Reset head.
if (abs(info->headXrot) > ANGLE(0.1f))
info->headXrot += info->headXrot / -rate;
else
info->headXrot = 0;
if (abs(info->headYrot) > ANGLE(0.1f))
info->headYrot += info->headYrot / -rate;
else
info->headYrot = 0;
if (abs(info->headZrot) > ANGLE(0.1f))
info->headZrot += info->headZrot / -rate;
else
info->headZrot = 0;
// Reset torso.
if (abs(info->torsoXrot) > ANGLE(0.1f))
info->torsoXrot += info->torsoXrot / -rate;
else
info->torsoXrot = 0;
if (abs(info->torsoYrot) > ANGLE(0.1f))
info->torsoYrot += info->torsoYrot / -rate;
else
info->torsoYrot = 0;
if (abs(info->torsoZrot) > ANGLE(0.1f))
info->torsoZrot += info->torsoZrot / -rate;
else
info->torsoZrot = 0;
}
void HandleLaraMovementParameters(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
// Reset running jump timer.
if (item->currentAnimState != LS_RUN_FORWARD &&
item->currentAnimState != LS_WALK_FORWARD &&
item->currentAnimState != LS_JUMP_FORWARD &&
item->currentAnimState != LS_SPRINT &&
item->currentAnimState != LS_SPRINT_DIVE)
{
info->jumpCount = 0;
}
// Reset jump action queue.
if (item->currentAnimState != LS_RUN_FORWARD)
info->jumpQueued = false;
// Increment/reset AFK pose timer.
if (info->poseCount < LARA_POSE_TIME &&
TestLaraPose(item, coll) &&
!(TrInput & (IN_WAKE | IN_LOOK)) &&
g_GameFlow->Animations.Pose)
{
info->poseCount++;
}
else
info->poseCount = 0;
// Reset lean.
if (!info->isMoving || (info->isMoving && !(TrInput & (IN_LEFT | IN_RIGHT))))
{
if (abs(item->pos.zRot) > ANGLE(0.1f))
item->pos.zRot += item->pos.zRot / -6;
else
item->pos.zRot = 0;
}
// Reset crawl flex.
if (!(TrInput & IN_LOOK) &&
coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM &&
(!item->speed || (item->speed && !(TrInput & (IN_LEFT | IN_RIGHT)))))
{
ResetLaraFlex(item, 12);
}
// Reset turn rate.
int sign = copysign(1, info->turnRate);
if (abs(info->turnRate) > ANGLE(2.0f))
info->turnRate -= ANGLE(2.0f) * sign;
else if (abs(info->turnRate) > ANGLE(0.5f))
info->turnRate -= ANGLE(0.5f) * sign;
else
info->turnRate = 0;
item->pos.yRot += info->turnRate;
}

View file

@ -0,0 +1,19 @@
#pragma once
struct ITEM_INFO;
struct COLL_INFO;
// -----------------------------
// HELPER FUNCTIONS
// For State Control & Collision
// -----------------------------
void DoLaraStep(ITEM_INFO* item, COLL_INFO* coll);
void DoLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll);
void DoLaraCrawlToHangSnap(ITEM_INFO* item, COLL_INFO* coll);
void DoLaraLean(ITEM_INFO* item, COLL_INFO* coll, int maxAngle, short rate);
void DoLaraCrawlFlex(ITEM_INFO* item, COLL_INFO* coll, short maxAngle, short rate);
void SetLaraFallState(ITEM_INFO* item);
void SetLaraFallBackState(ITEM_INFO* item);
void ResetLaraFlex(ITEM_INFO* item, float rate = 1.0f);
void HandleLaraMovementParameters(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -35,6 +35,7 @@ void InitialiseLara(int restore)
Lara.look = true;
Lara.itemNumber = itemNumber;
Lara.hitDirection = -1;
Lara.sprintTimer = LARA_SPRINT_MAX;
Lara.air = LARA_AIR_MAX;
Lara.weaponItem = NO_ITEM;
PoisonFlag = 0;
@ -60,7 +61,7 @@ void InitialiseLara(int restore)
Lara.highestLocation = -1;
Lara.ropePtr = -1;
LaraItem->hitPoints = LARA_HEALTH_MAX;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
LARA_WEAPON_TYPE gun = WEAPON_NONE;
@ -98,7 +99,6 @@ void InitialiseLara(int restore)
InitialiseLaraAnims(LaraItem);
Lara.BeetleLife = 3;
Lara.sprintTimer = LARA_SPRINT_MAX;
}
void LaraInitialiseMeshes()
@ -126,7 +126,7 @@ void LaraInitialiseMeshes()
Lara.holsterInfo.backHolster = HOLSTER_SLOT::Empty;
}
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.leftArm.frameNumber = 0;
Lara.rightArm.frameNumber = 0;
Lara.target = NULL;

View file

@ -0,0 +1,657 @@
#include "framework.h"
#include "control.h"
#include "input.h"
#include "level.h"
#include "setup.h"
#include "sound.h"
#include "camera.h"
#include "lara.h"
#include "lara_collide.h"
#include "lara_tests.h"
#include "lara_helpers.h"
#include "lara_jump.h"
#include "lara_basic.h"
#include "lara_slide.h"
#include "Scripting/GameFlowScript.h"
// -----------------------------
// JUMP
// Control & Collision Functions
// -----------------------------
void lara_as_forwardjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
// Update running jump counter in preparation for possible dispatch soon after landing.
info->jumpCount++;
if (info->jumpCount > LARA_JUMP_TIME / 2)
info->jumpCount = LARA_JUMP_TIME / 2;
/*state 3*/
/*collision: */
if (item->goalAnimState == LS_SWANDIVE_START ||
item->goalAnimState == LS_REACH)
item->goalAnimState = LS_JUMP_FORWARD;
if (item->goalAnimState != LS_DEATH &&
item->goalAnimState != LS_IDLE &&
item->goalAnimState != LS_RUN_FORWARD)
{
if (info->gunStatus == LG_HANDS_FREE && TrInput & IN_ACTION)
item->goalAnimState = LS_REACH;
if (TrInput & IN_BACK || TrInput & IN_ROLL)
item->goalAnimState = LS_JUMP_ROLL_180;
if (info->gunStatus == LG_HANDS_FREE && TrInput & IN_WALK)
item->goalAnimState = LS_SWANDIVE_START;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
if (TrInput & IN_LEFT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_JUMP_TURN_MAX)
info->turnRate = -LARA_JUMP_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_JUMP_TURN_MAX)
info->turnRate = LARA_JUMP_TURN_MAX;
}
}
void lara_col_forwardjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 3*/
/*state code: lara_as_forwardjump*/
if (item->speed < 0)
info->moveAngle = item->pos.yRot + ANGLE(180);
else
info->moveAngle = item->pos.yRot;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (item->speed < 0)
info->moveAngle = item->pos.yRot;
if (item->fallspeed > 0 && (coll->Middle.Floor <= 0 || TestLaraSwamp(item)))
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
{
if (info->waterStatus == LW_WADE)
item->goalAnimState = LS_IDLE;
else
{
if (TrInput & IN_FORWARD && !(TrInput & IN_WALK))
SetAnimation(item, LA_LAND_TO_RUN);
else
item->goalAnimState = LS_IDLE;
}
}
item->gravityStatus = false;
item->fallspeed = 0;
item->speed = 0;
LaraSnapToHeight(item, coll);
}
}
void lara_as_fastfall(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 9*/
/*collision: lara_col_fastfall*/
item->speed = (item->speed * 95) / 100;
if (item->fallspeed == 154)
SoundEffect(SFX_TR4_LARA_FALL, &item->pos, 0);
}
void lara_col_fastfall(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 9*/
/*state code: lara_as_fastfall*/
item->gravityStatus = true;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
LaraSlideEdgeJump(item, coll);
if (coll->Middle.Floor <= 0 || TestLaraSwamp(item))
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
SetAnimation(item, LA_FREEFALL_LAND);
StopSoundEffect(SFX_TR4_LARA_FALL);
item->fallspeed = 0;
item->gravityStatus = false;
LaraSnapToHeight(item, coll);
}
}
void lara_as_reach(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 11*/
/*collision: lara_col_reach*/
Camera.targetAngle = ANGLE(85.0f);
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 11*/
/*state code: lara_as_reach*/
if (info->ropePtr == -1)
item->gravityStatus = true;
info->moveAngle = item->pos.yRot;
coll->Setup.Height = LARA_HEIGHT_STRETCH;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = 0;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
coll->Setup.Radius = coll->Setup.Radius * 1.2f;
coll->Setup.Mode = COLL_PROBE_MODE::FREE_FORWARD;
GetCollisionInfo(coll, item);
if (TestLaraHangJump(item, coll))
return;
LaraSlideEdgeJump(item, coll);
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
ShiftItem(item, coll);
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = LS_DEATH;
}
else
{
item->goalAnimState = LS_IDLE;
item->fallspeed = 0;
item->gravityStatus = false;
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
}
void lara_col_land(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 14*/
/*state code: lara_void_func*/
lara_col_idle(item, coll);
}
// State: LS_JUMP_PREPARE (15)
// Collision: lara_col_compress()
void lara_as_compress(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
// TODO: dispatch
/*if (item->hitPoints <= 0)
{
item->goalAnimState = LS_DEATH;
return;
}*/
if (info->waterStatus == LW_WADE)
{
item->goalAnimState = LS_JUMP_UP;
return;
}
if (TrInput & IN_LEFT &&
TrInput & (IN_FORWARD | IN_BACK))
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_SLOW_TURN_MAX)
info->turnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT &&
TrInput & (IN_FORWARD | IN_BACK))
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_SLOW_TURN_MAX)
info->turnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & IN_FORWARD &&
TestLaraStandingJump(item, coll, item->pos.yRot))
{
info->moveAngle = item->pos.yRot;
item->goalAnimState = LS_JUMP_FORWARD;
return;
}
else if (TrInput & IN_BACK &&
TestLaraStandingJump(item, coll, item->pos.yRot + ANGLE(180.0f)))
{
info->moveAngle = item->pos.yRot + ANGLE(180.0f);
item->goalAnimState = LS_JUMP_BACK;
return;
}
if (TrInput & IN_LEFT &&
TestLaraStandingJump(item, coll, item->pos.yRot - ANGLE(90.0f)))
{
info->moveAngle = item->pos.yRot - ANGLE(90.0f);
item->goalAnimState = LS_JUMP_LEFT;
return;
}
else if (TrInput & IN_RIGHT &&
TestLaraStandingJump(item, coll, item->pos.yRot + ANGLE(90.0f)))
{
info->moveAngle = item->pos.yRot + ANGLE(90.0f);
item->goalAnimState = LS_JUMP_RIGHT;
return;
}
item->goalAnimState = LS_JUMP_UP;
// TODO: What is this? @Sezz 2021.11.13
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
}
// State: LS_JUMP_PREPARE (15)
// Collision: lara_as_compress()
void lara_col_compress(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
item->fallspeed = 0;
item->gravityStatus = false;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = NO_HEIGHT;
coll->Setup.BadCeilingHeight = 0;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
if (TestLaraFall(item, coll))
{
SetLaraFallState(item);
return;
}
if (TestLaraSlide(item, coll))
return;
// TODO: Better handling.
if (coll->Middle.Ceiling > -100)
{
SetAnimation(item, LA_STAND_SOLID);
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
item->pos.xPos = coll->Setup.OldPosition.x;
item->pos.yPos = coll->Setup.OldPosition.y;
item->pos.zPos = coll->Setup.OldPosition.z;
}
if (coll->Middle.Floor > -STEP_SIZE && coll->Middle.Floor < STEP_SIZE)
item->pos.yPos += coll->Middle.Floor;
}
void lara_as_backjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 25*/
/*collision: lara_col_backjump*/
info->look = false;
Camera.targetAngle = ANGLE(135.0f);
if (item->fallspeed <= LARA_FREEFALL_SPEED)
{
if (item->goalAnimState == LS_RUN_FORWARD)
{
item->goalAnimState = LS_IDLE;
}
else if ((TrInput & IN_FORWARD || TrInput & IN_ROLL) && item->goalAnimState != LS_IDLE)
{
item->goalAnimState = LS_JUMP_ROLL_180;
}
}
else
{
item->goalAnimState = LS_FREEFALL;
}
}
void lara_col_backjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 25*/
/*state code: lara_as_backjump*/
info->moveAngle = item->pos.yRot + ANGLE(180);
LaraJumpCollision(item, coll);
}
void lara_as_rightjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 26*/
/*collision: lara_col_rightjump*/
info->look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
else if (TrInput & IN_LEFT && item->goalAnimState != LS_IDLE)
item->goalAnimState = LS_JUMP_ROLL_180;
}
void lara_col_rightjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 26*/
/*state code: lara_as_rightjump*/
info->moveAngle = item->pos.yRot + ANGLE(90);
LaraJumpCollision(item, coll);
}
void lara_as_leftjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 27*/
/*collision: lara_col_leftjump*/
info->look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
else if (TrInput & IN_RIGHT && item->goalAnimState != LS_IDLE)
item->goalAnimState = LS_JUMP_ROLL_180;
}
void lara_col_leftjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 27*/
/*state code: lara_as_leftjump*/
info->moveAngle = item->pos.yRot - ANGLE(90);
LaraJumpCollision(item, coll);
}
void lara_as_upjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
info->look = false;
/*state 28*/
/*collision: lara_col_upjump*/
if (item->fallspeed > LARA_FREEFALL_SPEED)
{
item->goalAnimState = LS_FREEFALL;
}
}
void lara_col_upjump(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 28*/
/*state code: lara_as_upjump*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_IDLE;
return;
}
info->moveAngle = item->pos.yRot;
coll->Setup.Height = LARA_HEIGHT_STRETCH;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = item->speed < 0 ? info->moveAngle + ANGLE(180.0f) : info->moveAngle;
coll->Setup.Mode = COLL_PROBE_MODE::FREE_FORWARD;
GetCollisionInfo(coll, item);
if (TestLaraHangJumpUp(item, coll))
return;
if (coll->CollisionType == CT_CLAMP ||
coll->CollisionType == CT_TOP ||
coll->CollisionType == CT_TOP_FRONT)
item->fallspeed = 1;
ShiftItem(item, coll);
if (coll->CollisionType == CT_NONE)
{
if (item->fallspeed < -70)
{
if (TrInput & IN_FORWARD && item->speed < 5)
{
item->speed++;
}
else if (TrInput & IN_BACK && item->speed > -5)
{
item->speed -= 2;
}
}
}
else
{
item->speed = item->speed <= 0 ? -2 : 2;
}
if (item->fallspeed > 0 && coll->Middle.Floor <= 0)
{
item->goalAnimState = LaraLandedBad(item, coll) ? LS_DEATH : LS_IDLE;
item->gravityStatus = false;
item->fallspeed = 0;
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}
void lara_as_fallback(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 29*/
/*collision: lara_col_fallback*/
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = LS_FREEFALL;
if (TrInput & IN_ACTION)
if (info->gunStatus == LG_HANDS_FREE)
item->goalAnimState = LS_REACH;
}
void lara_col_fallback(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 29*/
/*state code: lara_as_fallback*/
info->moveAngle = item->pos.yRot + ANGLE(180);
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (item->fallspeed > 0 && (coll->Middle.Floor <= 0 || TestLaraSwamp(item)))
{
if (LaraLandedBad(item, coll))
item->goalAnimState = LS_DEATH;
else
item->goalAnimState = LS_IDLE;
LaraResetGravityStatus(item, coll);
LaraSnapToHeight(item, coll);
}
}
// State: LS_SWANDIVE_START (52)
// Control: lara_col_swandive()
void lara_as_swandive(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
info->gunStatus = LG_HANDS_BUSY;
info->look = false;
coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpaz = false;
if (TrInput & IN_LEFT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_JUMP_TURN_MAX)
info->turnRate = -LARA_JUMP_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
}
else if (TrInput & IN_RIGHT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_JUMP_TURN_MAX)
info->turnRate = LARA_JUMP_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
}
// TODO: Why?
if (item->fallspeed > LARA_FREEFALL_SPEED && item->goalAnimState != LS_DIVE)
item->goalAnimState = LS_SWANDIVE_END;
}
void lara_col_swandive(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
auto bounds = GetBoundsAccurate(item);
auto realHeight = bounds->Y2 - bounds->Y1;
/*state 52*/
/*state code: lara_as_swandive*/
info->moveAngle = item->pos.yRot;
info->keepCrouched = TestLaraKeepCrouched(item, coll);
coll->Setup.Height = std::max(LARA_HEIGHT_CRAWL, (int)(realHeight * 0.7f));
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
if (LaraDeflectEdgeJump(item, coll))
info->gunStatus = LG_HANDS_FREE;
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
auto probe = GetCollisionResult(item, coll->Setup.ForwardAngle, coll->Setup.Radius, 0);
if (TestLaraSlide(item, coll))
;
else if (info->keepCrouched ||
abs(probe.Position.Ceiling - probe.Position.Floor) < LARA_HEIGHT &&
g_GameFlow->Animations.CrawlspaceSwandive)
{
SetAnimation(item, LA_SPRINT_TO_CROUCH_LEFT, 10);
if (!info->keepCrouched) // HACK: If Lara landed on the edge, shift forward to avoid standing up or falling out.
MoveItem(item, coll->Setup.ForwardAngle, STEP_SIZE / 2);
}
else [[likely]]
SetAnimation(item, LA_SWANDIVE_ROLL, 0);
item->fallspeed = 0;
item->gravityStatus = false;
info->gunStatus = LG_HANDS_FREE;
LaraSnapToHeight(item, coll);
}
}
void lara_as_fastdive(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 53*/
/*collision: lara_col_fastdive*/
if (TrInput & IN_ROLL && item->goalAnimState == LS_SWANDIVE_END)
item->goalAnimState = LS_JUMP_ROLL_180;
coll->Setup.EnableObjectPush = true;
coll->Setup.EnableSpaz = false;
item->speed = (item->speed * 95) / 100;
}
void lara_col_fastdive(ITEM_INFO* item, COLL_INFO* coll)
{
LaraInfo*& info = item->data;
/*state 53*/
/*state code: lara_as_fastdive*/
info->moveAngle = item->pos.yRot;
coll->Setup.BadHeightDown = NO_BAD_POS;
coll->Setup.BadHeightUp = -STEPUP_HEIGHT;
coll->Setup.BadCeilingHeight = BAD_JUMP_CEILING;
coll->Setup.ForwardAngle = info->moveAngle;
GetCollisionInfo(coll, item);
LaraDeflectEdgeJump(item, coll);
if (coll->Middle.Floor <= 0 && item->fallspeed > 0)
{
if (item->fallspeed <= 133)
item->goalAnimState = LS_IDLE;
else
item->goalAnimState = LS_DEATH;
item->fallspeed = 0;
item->gravityStatus = 0;
if (coll->Middle.Floor != NO_HEIGHT)
item->pos.yPos += coll->Middle.Floor;
}
}

View file

@ -0,0 +1,33 @@
#pragma once
struct ITEM_INFO;
struct COLL_INFO;
// -----------------------------
// JUMP
// Control & Collision Functions
// -----------------------------
void lara_as_forwardjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_forwardjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastfall(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastfall(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_reach(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_land(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_compress(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_compress(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_backjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_backjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rightjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_rightjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_leftjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_leftjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_upjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_upjump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fallback(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fallback(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swandive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_swandive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fastdive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fastdive(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -23,7 +23,7 @@ void lara_as_monkey_idle(ITEM_INFO* item, COLL_INFO* coll)
/*collision: lara_col_hang2*/
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
return;
}
@ -90,7 +90,7 @@ void lara_col_monkey_idle(ITEM_INFO* item, COLL_INFO* coll)
{
item->goalAnimState = LS_MONKEYSWING_TURN_RIGHT;
}
else if (TrInput & IN_ROLL && g_GameFlow->Animations.MonkeyRoll)
else if (TrInput & IN_ROLL && g_GameFlow->Animations.MonkeyTurn180)
{
item->goalAnimState = LS_MONKEYSWING_TURN_180;
}
@ -530,6 +530,6 @@ void MonkeySwingFall(ITEM_INFO* item)
item->fallspeed = 1;
item->pos.yPos += 256;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}

View file

@ -1,5 +1,6 @@
#include "framework.h"
#include "lara.h"
#include "lara_tests.h"
#include "input.h"
#include "level.h"
#include "Sound/sound.h"
@ -54,7 +55,7 @@ void lara_as_pickupflare(ITEM_INFO* item, COLL_INFO* coll)
Camera.targetDistance = WALL_SIZE;
if (item->frameNumber == g_Level.Anims[item->animNumber].frameEnd - 1)
info->gunStatus = LG_NO_ARMS;
info->gunStatus = LG_HANDS_FREE;
}
// ------
@ -94,7 +95,7 @@ void lara_as_switchoff(ITEM_INFO* item, COLL_INFO* coll)
void lara_col_turnswitch(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 95*/
/*state code: lara_as_controlledl*/
/*state code: lara_as_controlled_no_look*/
if (coll->Setup.OldPosition.x != item->pos.xPos || coll->Setup.OldPosition.z != item->pos.zPos)
{
if (item->animNumber == LA_TURNSWITCH_PUSH_COUNTER_CLOCKWISE_CONTINUE)
@ -200,7 +201,7 @@ void lara_as_ppready(ITEM_INFO* item, COLL_INFO* coll)
Camera.targetAngle = ANGLE(75.0f);
if (!(TrInput & IN_ACTION))
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
}
// ------
@ -222,7 +223,7 @@ void lara_as_pulley(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_ACTION && pulley->triggerFlags)
item->goalAnimState = LS_PULLEY;
else
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
if (item->animNumber == LA_PULLEY_PULL &&
item->frameNumber == g_Level.Anims[item->animNumber].frameBase + 44)
@ -257,7 +258,7 @@ void lara_as_pulley(ITEM_INFO* item, COLL_INFO* coll)
if (item->animNumber == LA_PULLEY_RELEASE &&
item->frameNumber == g_Level.Anims[item->animNumber].frameEnd - 1)
{
info->gunStatus = LG_NO_ARMS;
info->gunStatus = LG_HANDS_FREE;
}
}
@ -773,24 +774,6 @@ void lara_as_climbroped(ITEM_INFO* item, COLL_INFO* coll)
// VERTICAL POLE
// -------------
// TODO: Move test functions to lara_tests.cpp when lara_state_cleaning_etc branch is merged.
bool TestLaraPoleUp(ITEM_INFO* item, COLL_INFO* coll)
{
if (!TestLaraPoleCollision(item, coll, true, STEP_SIZE))
return false;
// TODO: Accuracy.
return (coll->Middle.Ceiling < -STEP_SIZE);
}
bool TestLaraPoleDown(ITEM_INFO* item, COLL_INFO* coll)
{
if (!TestLaraPoleCollision(item, coll, false))
return false;
return (coll->Middle.Floor > 0);
}
// State: LS_POLE_IDLE (99)
// Collision: lara_col_pole_idle()
void lara_as_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
@ -815,15 +798,15 @@ void lara_as_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
{
if (TrInput & IN_LEFT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_SLOW_TURN)
info->turnRate = LARA_SLOW_TURN;
info->turnRate += LARA_POLE_TURN_RATE;
if (info->turnRate > LARA_POLE_TURN_MAX)
info->turnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_SLOW_TURN)
info->turnRate = -LARA_SLOW_TURN;
info->turnRate -= LARA_POLE_TURN_RATE;
if (info->turnRate < -LARA_POLE_TURN_MAX)
info->turnRate = -LARA_POLE_TURN_MAX;
}
}
@ -831,7 +814,6 @@ void lara_as_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_JUMP_BACK;
info->gunStatus = LG_NO_ARMS;
return;
}
@ -842,8 +824,8 @@ void lara_as_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
}
else if (TrInput & IN_BACK && TestLaraPoleDown(item, coll))
{
item->itemFlags[2] = 0; // Doesn't seem necessary?
item->goalAnimState = LS_POLE_DOWN;
item->itemFlags[2] = 0; // Doesn't seem necessary?
return;
}
@ -862,18 +844,21 @@ void lara_as_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
return;
}
info->gunStatus = LG_NO_ARMS;
if (coll->Middle.Floor <= 0)
GetCollisionInfo(coll, item); // HACK: Lara may step off poles in mid-air upon reload without this.
if (coll->Middle.Floor <= 0 &&
item->animNumber != LA_POLE_JUMP_BACK) // Hack.
{
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
return;
}
else if (item->animNumber == LA_POLE_IDLE)
{
item->goalAnimState = LS_FREEFALL;
// TODO: This should not be required. Update anim's root displacement + set position distance.
//item->pos.xPos -= phd_sin(item->pos.yRot) * 64;
//item->pos.zPos -= phd_cos(item->pos.yRot) * 64;
item->goalAnimState = LS_FREEFALL;
// TODO: This shouldn't be required, but the set position command doesn't move Lara correctly.
item->pos.xPos -= phd_sin(item->pos.yRot) * 64;
item->pos.zPos -= phd_cos(item->pos.yRot) * 64;
}
}
// State: LS_POLE_IDLE (99)
@ -891,6 +876,7 @@ void lara_col_pole_idle(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.SlopesAreWalls = true;
GetCollisionInfo(coll, item);
// TODO: There's a visible snap if Lara hits the ground at a high velocity.
if (coll->Middle.Floor < 0)
item->pos.yPos += coll->Middle.Floor;
}
@ -914,15 +900,21 @@ void lara_as_pole_up(ITEM_INFO* item, COLL_INFO* coll)
{
if (TrInput & IN_LEFT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_SLOW_TURN)
info->turnRate = LARA_SLOW_TURN;
info->turnRate += LARA_POLE_TURN_RATE;
if (info->turnRate > LARA_POLE_TURN_MAX)
info->turnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_SLOW_TURN)
info->turnRate = -LARA_SLOW_TURN;
info->turnRate -= LARA_POLE_TURN_RATE;
if (info->turnRate < -LARA_POLE_TURN_MAX)
info->turnRate = -LARA_POLE_TURN_MAX;
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_POLE_IDLE;
return;
}
if (TrInput & IN_FORWARD && TestLaraPoleUp(item, coll))
@ -936,7 +928,6 @@ void lara_as_pole_up(ITEM_INFO* item, COLL_INFO* coll)
}
item->goalAnimState = LS_POLE_IDLE; // TODO: Dispatch to freefall?
}
// State: LS_POLE_UP (100)
@ -968,15 +959,21 @@ void lara_as_pole_down(ITEM_INFO* item, COLL_INFO* coll)
{
if (TrInput & IN_LEFT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_SLOW_TURN)
info->turnRate = LARA_SLOW_TURN;
info->turnRate += LARA_POLE_TURN_RATE;
if (info->turnRate > LARA_POLE_TURN_MAX)
info->turnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -LARA_SLOW_TURN)
info->turnRate = -LARA_SLOW_TURN;
info->turnRate -= LARA_POLE_TURN_RATE;
if (info->turnRate < -LARA_POLE_TURN_MAX)
info->turnRate = -LARA_POLE_TURN_MAX;
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_POLE_IDLE;
return;
}
if (TrInput & IN_BACK && TestLaraPoleDown(item, coll))
@ -985,9 +982,8 @@ void lara_as_pole_down(ITEM_INFO* item, COLL_INFO* coll)
return;
}
item->itemFlags[2] = 0; // ??
item->itemFlags[2] = 0; // Vertical velocity.
item->goalAnimState = LS_POLE_IDLE;
return;
}
@ -1061,9 +1057,9 @@ void lara_as_pole_turn_clockwise(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_LEFT)
{
info->turnRate += LARA_TURN_RATE;
if (info->turnRate > LARA_SLOW_TURN + ANGLE(0.5f))
info->turnRate = LARA_SLOW_TURN + ANGLE(0.5f);
info->turnRate += LARA_POLE_TURN_RATE;
if (info->turnRate > LARA_POLE_TURN_MAX)
info->turnRate = LARA_POLE_TURN_MAX;
item->goalAnimState = LS_POLE_TURN_CLOCKWISE;
return;
@ -1095,7 +1091,6 @@ void lara_as_pole_turn_counter_clockwise(ITEM_INFO* item, COLL_INFO* coll)
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_POLE_IDLE; // TODO: Death state dispatch.
return;
}
@ -1117,9 +1112,9 @@ void lara_as_pole_turn_counter_clockwise(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_RIGHT)
{
info->turnRate -= LARA_TURN_RATE;
if (info->turnRate < -(LARA_SLOW_TURN + ANGLE(0.5f)))
info->turnRate = -(LARA_SLOW_TURN + ANGLE(0.5f));
info->turnRate -= LARA_POLE_TURN_RATE;
if (info->turnRate < -LARA_POLE_TURN_MAX)
info->turnRate = -LARA_POLE_TURN_MAX;
item->goalAnimState = LS_POLE_TURN_COUNTER_CLOCKWISE;
return;

View file

@ -1817,7 +1817,7 @@ void undraw_shotgun(int weapon)
if (item->status == ITEM_DEACTIVATED)
{
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.target = nullptr;
Lara.rightArm.lock = false;
Lara.leftArm.lock = false;

View file

@ -20,6 +20,14 @@ void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll)
coll->Setup.ForwardAngle = Lara.moveAngle;
GetCollisionInfo(coll, item);
// Temporary measure. @Sezz 2021.12.16
if (TestLaraSwamp(item))
{
item->goalAnimState = LS_IDLE;
StopSoundEffect(SFX_TR4_LARA_SLIPPING);
return;
}
if (!LaraHitCeiling(item, coll))
{
LaraDeflectEdge(item, coll);
@ -37,7 +45,7 @@ void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll)
item->goalAnimState = LS_RUN_FORWARD;
}
else
item->goalAnimState = LS_STOP;
item->goalAnimState = LS_IDLE;
StopSoundEffect(SFX_TR4_LARA_SLIPPING);
}

View file

@ -19,17 +19,16 @@ namespace TEN::Renderer {
struct RendererMesh;
}
#pragma region state_and_animation
enum LARA_STATE
{
// TR1
LS_WALK_FORWARD = 0,
LS_RUN_FORWARD = 1,
LS_STOP = 2,
LS_IDLE = 2,
LS_JUMP_FORWARD = 3,
LS_POSE = 4,
LS_HOP_BACK = 5,
LS_RUN_BACK = 5,
LS_TURN_RIGHT_SLOW = 6,
LS_TURN_LEFT_SLOW = 7,
LS_DEATH = 8,
@ -44,7 +43,7 @@ enum LARA_STATE
LS_UNDERWATER_FORWARD = 17,
LS_UNDERWATER_INERTIA = 18,
LS_GRABBING = 19,
LS_TURN_FAST = 20,
LS_TURN_RIGHT_FAST = 20,
LS_STEP_RIGHT = 21,
LS_STEP_LEFT = 22,
LS_ROLL_BACK = 23,
@ -102,7 +101,7 @@ enum LARA_STATE
LS_CROUCH_IDLE = 71,
LS_CROUCH_ROLL = 72,
LS_SPRINT = 73,
LS_SPRINT_ROLL = 74,
LS_SPRINT_DIVE = 74,
LS_MONKEYSWING_IDLE = 75,
LS_MONKEYSWING_FORWARD = 76,
LS_MONKEYSWING_LEFT = 77,
@ -173,9 +172,9 @@ enum LARA_STATE
LS_LADDER_TO_CROUCH = 138,
// TombEngine
LS_SHIMMY_45_OUTER_LEFT = 139,
LS_SHIMMY_45_OUTER_LEFT = 139,
LS_SHIMMY_45_OUTER_RIGHT = 140,
LS_SHIMMY_45_INNER_LEFT = 141,
LS_SHIMMY_45_INNER_LEFT = 141,
LS_SHIMMY_45_INNER_RIGHT = 142,
LS_UNUSED1 = 143, // Foot hang leftovers - may be safely reused
LS_UNUSED2 = 144, // Foot hang leftovers - may be safely reused
@ -183,11 +182,18 @@ enum LARA_STATE
LS_COGWHEEL_UNGRAB = 146,
LS_STEP_UP = 147,
LS_STEP_DOWN = 148,
LS_STEP_BACK_DOWN = 149,
LS_UNUSED4 = 149, // Vestige of step back down; a new state can be added in its place.
LS_LADDER_DISMOUNT_LEFT = 150,
LS_LADDER_DISMOUNT_RIGHT = 151,
LS_TURN_LEFT_FAST = 152,
LS_CRAWL_EXIT_DOWN_STEP = 153,
LS_CRAWL_EXIT_JUMP = 154,
LS_CRAWL_EXIT_FLIP = 155,
NUM_LARA_STATES
// TRASHED STATES (please reuse slots before going any higher and remove entries from this list as you go):
// 143, 144, 145, 149
};
enum LARA_ANIM
@ -205,7 +211,7 @@ enum LARA_ANIM
LA_RUN_TO_WALK_LEFT = 9, // Run > walk, right foot first
LA_RUN_TO_STAND_RIGHT = 10, // Run > stand, right foot first
LA_STAND_SOLID = 11, // Stand solid
// TODO: gradually remove reliance on this anim for erroneous collisions.
// TODO: gradually reduce reliance on this anim for erroneous collisions.
LA_TURN_RIGHT_SLOW = 12, // Rotate right slowly
LA_TURN_LEFT_SLOW = 13, // Rotate left slowly
LA_JUMP_FORWARD_LAND_START_UNUSED = 14, // Forward jump > land (1/2)
@ -243,7 +249,6 @@ enum LARA_ANIM
// TODO: implement properly.
LA_TURN_RIGHT_FAST = 44, // Rotate right quickly
LA_JUMP_FORWARD_TO_FREEFALL_OG = 45, // Jump forward > fall
// TODO: this is the original, but incorrect, linking animation; in WAD should be 49 instead.
LA_REACH_TO_FREEFALL_ALTERNATE_UNUSED = 46, // Reach > freefall
LA_ROLL_180_START_ALTERNATE_UNUSED = 47, // Standing roll 180 (1/2)
LA_ROLL_180_END_ALTERNATE_UNUSED = 48, // Standing roll 180 (2/2)
@ -361,7 +366,7 @@ enum LARA_ANIM
LA_SWANDIVE_RIGHT_START = 157, // Run > swan dive, right foot first
LA_SWANDIVE = 158, // Swan dive
LA_HANG_HANDSTAND = 159, // Hang > stand via handstand
// TR2
LA_STAND_TO_LADDER = 160, // Stand > ladder idle
LA_LADDER_UP = 161, // Ascend ladder (looped)
@ -424,70 +429,66 @@ enum LARA_ANIM
LA_ZIPLINE_MOUNT = 214, // Stand > ride sipline
LA_ZIPLINE_RIDE = 215, // Ride zipline (looped)
LA_ZIPLINE_DISMOUNT = 216, // Ride zipline > jump forward
// TR3
LA_STAND_TO_CROUCH_START = 217, // Stand > crouch (1/2)
LA_CROUCH_ROLL_FORWARD_START_ALTERNATE = 218, // Crouch roll forward (1/3)
// TODO: this is the original, but incorrect, linking animation; in WAD it should be 47 instead.
LA_CROUCH_ROLL_FORWARD_CONTINUE = 219, // Crouch roll forward (2/3)
LA_CROUCH_ROLL_FORWARD_END = 220, // Crouch roll forward (3/3)
LA_CROUCH_TO_STAND = 221, // Crouch > stand
LA_CROUCH_IDLE = 222, // Crouch (looped)
LA_SPRINT = 223, // Sprint (looped)
LA_RUN_TO_SPRINT_LEFT = 224, // Run > sprint, left foot first
LA_RUN_TO_SPRINT_RIGHT = 225, // Run > sprint, right foot first
LA_SPRINT_TO_STAND_RIGHT = 226, // Sprint > stand, right foot first
LA_SPRINT_TO_STAND_RIGHT_END_ALTERNATE_UNUSED = 227, // Sprint > stand, right foot first end
LA_SPRINT_TO_STAND_LEFT = 228, // Sprint > stand, left foot first
LA_SPRINT_TO_STAND_LEFT_END_ALTERNATE_UNUSED = 229, // Sprint > stand, left foot first end
LA_SPRINT_ROLL_TO_RUN_LEFT_START = 230, // Sprint roll, left foot first > run (1/2)
LA_STAND_TO_CROUCH_START = 217, // Stand > crouch (1/2)
LA_CROUCH_ROLL_FORWARD_START_ALTERNATE = 218, // Crouch roll forward (1/3)
LA_CROUCH_ROLL_FORWARD_CONTINUE = 219, // Crouch roll forward (2/3)
LA_CROUCH_ROLL_FORWARD_END = 220, // Crouch roll forward (3/3)
LA_CROUCH_TO_STAND = 221, // Crouch > stand
LA_CROUCH_IDLE = 222, // Crouch (looped)
LA_SPRINT = 223, // Sprint (looped)
LA_RUN_TO_SPRINT_LEFT = 224, // Run > sprint, left foot first
LA_RUN_TO_SPRINT_RIGHT = 225, // Run > sprint, right foot first
LA_SPRINT_TO_STAND_RIGHT = 226, // Sprint > stand, right foot first
LA_SPRINT_TO_STAND_RIGHT_END_ALTERNATE_UNUSED = 227, // Sprint > stand, right foot first end
LA_SPRINT_TO_STAND_LEFT = 228, // Sprint > stand, left foot first
LA_SPRINT_TO_STAND_LEFT_END_ALTERNATE_UNUSED = 229, // Sprint > stand, left foot first end
LA_SPRINT_ROLL_TO_RUN_LEFT_START = 230, // Sprint roll, left foot first > run (1/2)
LA_SPRINT_ROLL_TO_RUN_RIGHT_CONTINUE_ALTERNATE_UNUSED = 231, // Sprint roll, left foot first > run (2/3)
LA_SPRINT_ROLL_TO_RUN_LEFT_END = 232, // Sprint roll, left foot first > run (2/2)
LA_JUMP_UP_TO_MONKEYSWING = 233, // Jump up > monkey swing
LA_MONKEYSWING_IDLE = 234, // Monkey swing idle (looped)
LA_MONKEYSWING_TO_FREEFALL = 235, // Monkey swing > freefall
LA_MONKEYSWING_FORWARD = 236, // Monkey swing forward (looped)
LA_MONKEYSWING_FORWARD_TO_IDLE_RIGHT = 237, // Monkey-swing forward > monkey swing idle, right hand first
LA_MONKEYSWING_FORWARD_TO_IDLE_LEFT = 238, // Monkey-swing forward > monkey swing idle, left hand first
LA_MONKEYSWING_IDLE_TO_FORWARD_LEFT = 239, // Monkey idle > monkey forward, left hand first
LA_SPRINT_ROLL_TO_RUN_LEFT_START_ALTERNATE_UNUSED = 240, // Sprint roll, left foot first > run (1/3)
LA_SPRINT_ROLL_TO_RUN_LEFT_CONTINUE_ALTERNATE_UNUSED = 241, // Sprint roll, left foot first > run (2/3)
LA_SPRINT_ROLL_TO_RUN_LEFT_END_ALTERNATE_UNUSED = 242, // Sprint roll, left foot first > run (3/3)
LA_SPRINT_TO_RUN_LEFT = 243, // Sprint > run, left foot first
LA_SPRINT_TO_RUN_RIGHT = 244, // Sprint > run, right foot first
LA_STAND_TO_CROUCH_END = 245, // Stand > crouch (2/2)
LA_SLIDE_TO_RUN = 246, // Slide forward > run
LA_CROUCH_ROLL_FORWARD_START = 247, // Crouch roll forward (1/3)
LA_JUMP_FORWARD_TO_REACH_1 = 248, // Jump forward > reach, 1st opportunity
LA_JUMP_FORWARD_TO_REACH_2 = 249, // Jump forward > reach, 2nd opportunity
LA_RUN_JUMP_LEFT_TO_REACH = 251, // Run jump, left foot first > reach
LA_MONKEYSWING_IDLE_TO_FORWARD_RIGHT = 252, // Monkey swing idle > monkey swing forward, right hand first
LA_MONKEYSWING_SHIMMY_LEFT = 253, // Monkey swing shimmy left (looped)
LA_MONKEYSWING_SHIMMY_LEFT_END = 254, // Monkey swing shimmy left > monkey swing idle
LA_MONKEYSWING_SHIMMY_RIGHT = 255, // Monkey swing shimmy right (looped)
LA_MONKEYSWING_SHIMMY_RIGHT_END = 256, // Monkey swing shimmy right > monkey swing idle
// TODO: generic shimmy anims between ledges and ladders?
LA_SPRINT_ROLL_TO_RUN_LEFT_END = 232, // Sprint roll, left foot first > run (2/2)
LA_JUMP_UP_TO_MONKEYSWING = 233, // Jump up > monkey swing
LA_MONKEYSWING_IDLE = 234, // Monkey swing idle (looped)
LA_MONKEYSWING_TO_FREEFALL = 235, // Monkey swing > freefall
LA_MONKEYSWING_FORWARD = 236, // Monkey swing forward (looped)
LA_MONKEYSWING_FORWARD_TO_IDLE_RIGHT = 237, // Monkey-swing forward > monkey swing idle, right hand first
LA_MONKEYSWING_FORWARD_TO_IDLE_LEFT = 238, // Monkey-swing forward > monkey swing idle, left hand first
LA_MONKEYSWING_IDLE_TO_FORWARD_LEFT = 239, // Monkey idle > monkey forward, left hand first
LA_SPRINT_ROLL_TO_RUN_LEFT_START_ALTERNATE_UNUSED = 240, // Sprint roll, left foot first > run (1/3)
LA_SPRINT_ROLL_TO_RUN_LEFT_CONTINUE_ALTERNATE_UNUSED = 241, // Sprint roll, left foot first > run (2/3)
LA_SPRINT_ROLL_TO_RUN_LEFT_END_ALTERNATE_UNUSED = 242, // Sprint roll, left foot first > run (3/3)
LA_SPRINT_TO_RUN_LEFT = 243, // Sprint > run, left foot first
LA_SPRINT_TO_RUN_RIGHT = 244, // Sprint > run, right foot first
LA_STAND_TO_CROUCH_END = 245, // Stand > crouch (2/2)
LA_SLIDE_TO_RUN = 246, // Slide forward > run
LA_CROUCH_ROLL_FORWARD_START = 247, // Crouch roll forward (1/3)
LA_JUMP_FORWARD_TO_REACH_1 = 248, // Jump forward > reach, 1st opportunity
LA_JUMP_FORWARD_TO_REACH_2 = 249, // Jump forward > reach, 2nd opportunity
LA_RUN_JUMP_LEFT_TO_REACH = 251, // Run jump, left foot first > reach
LA_MONKEYSWING_IDLE_TO_FORWARD_RIGHT = 252, // Monkey swing idle > monkey swing forward, right hand first
LA_MONKEYSWING_SHIMMY_LEFT = 253, // Monkey swing shimmy left (looped)
LA_MONKEYSWING_SHIMMY_LEFT_END = 254, // Monkey swing shimmy left > monkey swing idle
LA_MONKEYSWING_SHIMMY_RIGHT = 255, // Monkey swing shimmy right (looped)
LA_MONKEYSWING_SHIMMY_RIGHT_END = 256, // Monkey swing shimmy right > monkey swing idle
// TODO: generic shimmy anims between ledges and ladders?
LA_MONKEYSWING_TURN_180 = 257, // Monkey swing turn 180
LA_CROUCH_TO_CRAWL_START = 258, // Crouch > crawl (1/3)
LA_CRAWL_TO_CROUCH_START = 259, // Crawl > crouch (1/3)
LA_CRAWL = 260, // Crawl forward (looped)
LA_CRAWL_IDLE_TO_FORWARD = 261, // Crawl idle > crawl forward
LA_CRAWL_TO_IDLE_LEFT = 262, // Crawl forward > crawl idle, left leg first
// TODO: in WAD, link next to 263
LA_CRAWL_IDLE = 263, // Crwal idle
LA_CROUCH_TO_CRAWL_END = 264, // Crawl > crouch (2/2)
LA_CRAWL_TO_CROUCH_END_UNUSED = 265, // Crouch > crawl (3/3)
LA_CRAWL_TO_IDLE_END_RIGHT_POINTLESS = 266, // TODO: remove.//no dont remove thanks
LA_CRAWL_TO_IDLE_END_RIGHT_POINTLESS = 266, // TODO: remove.
LA_CRAWL_TO_IDLE_RIGHT = 267, // Crawl forward > crawl idle, right leg first
// TODO: in WAD, link next to 263
LA_CRAWL_TO_IDLE_END_LEFT_POINTLESS = 268, // TODO: remove. //no dont remove thanks
LA_CRAWL_TO_IDLE_END_LEFT_POINTLESS = 268, // TODO: remove.
LA_CRAWL_TURN_LEFT = 269, // Crawl rotate left (looped)
LA_CRAWL_TURN_RIGHT = 270, // Crawl rotate right (looped)
LA_MONKEYSWING_TURN_LEFT = 271, // Monkey swing rotate left
LA_MONKEYSWING_TURN_RIGHT = 272, // Monkey swing rotate right
LA_CROUCH_TO_CRAWL_CONTINUE = 273, // Crouch > crawl (2/3)
LA_CRAWL_TO_CROUCH_CONTINUE = 274, // Crouch > crawl (2/3)
// TODO: properly link to 265 (adjustments to next anim necessary?)
LA_CRAWL_IDLE_TO_CRAWL_BACK = 275, // Crawl > crawl back
LA_CRAWL_BACK = 276, // Crawl back (looped)
LA_CRAWL_BACK_TO_IDLE_RIGHT_START = 277, // Crawl back > crawl idle, right foot first (1/2)
@ -518,7 +519,6 @@ enum LARA_ANIM
LA_CRAWL_DEATH = 301, // Crawl death
LA_CRAWL_TO_HANG_END = 302, // Crawl > hang (3/3)
LA_STAND_TO_CROUCH_ABORT = 303, // Stand > crouch abort
// TODO: implement this, OR the ability for any animation to be wound back like pistol aiming.
LA_RUN_TO_CROUCH_LEFT_START = 304, // Run > crouch, left foot first (1/2)
LA_RUN_TO_CROUCH_RIGHT_START = 305, // Run > crouch, right foot first (1/2)
LA_RUN_TO_CROUCH_LEFT_END = 306, // Run > crouch, left foot first (2/2)
@ -711,17 +711,17 @@ enum LARA_ANIM
LA_ONWATER_TO_CROUCH_1CLICK = 481, // Pull up 1-click from tread > stand
LA_ONWATER_TO_CROUCH_0CLICK = 482, // Pull up 0-click from tread > stand
LA_ONWATER_TO_CROUCH_M1CLICK = 483, // Pull up -1-click from tread > stand
LA_UNUSED1 = 484, // Foot hang leftovers - may be safely reused
LA_UNUSED2 = 485, // Foot hang leftovers - may be safely reused
LA_UNUSED3 = 486, // Foot hang leftovers - may be safely reused
LA_UNUSED4 = 487, // Foot hang leftovers - may be safely reused
LA_UNUSED5 = 488, // Foot hang leftovers - may be safely reused
LA_UNUSED6 = 489, // Foot hang leftovers - may be safely reused
LA_UNUSED7 = 490, // Foot hang leftovers - may be safely reused
LA_UNUSED8 = 491, // Foot hang leftovers - may be safely reused
LA_UNUSED9 = 492, // Foot hang leftovers - may be safely reused
LA_UNUSED10 = 493, // Foot hang leftovers - may be safely reused
LA_UNUSED11 = 494, // Foot hang leftovers - may be safely reused
LA_UNUSED1 = 484, // Foot hang leftovers - may be safely reused
LA_UNUSED2 = 485, // Foot hang leftovers - may be safely reused
LA_UNUSED3 = 486, // Foot hang leftovers - may be safely reused
LA_UNUSED4 = 487, // Foot hang leftovers - may be safely reused
LA_UNUSED5 = 488, // Foot hang leftovers - may be safely reused
LA_UNUSED6 = 489, // Foot hang leftovers - may be safely reused
LA_UNUSED7 = 490, // Foot hang leftovers - may be safely reused
LA_UNUSED8 = 491, // Foot hang leftovers - may be safely reused
LA_UNUSED9 = 492, // Foot hang leftovers - may be safely reused
LA_UNUSED10 = 493, // Foot hang leftovers - may be safely reused
LA_UNUSED11 = 494, // Foot hang leftovers - may be safely reused
LA_REACH_TO_HANG_OSCILLATE = 495, // Reach > hang, thin ledge
LA_SWANDIVE_ROLL_TO_RUN = 496, // Swandive roll > run
LA_LADDER_DISMOUNT_LEFT_START = 497, // Ladder dismount left (1/2)
@ -729,8 +729,17 @@ enum LARA_ANIM
LA_LADDER_DISMOUNT_RIGHT_START = 499, // Ladder dismount right (1/2)
LA_LADDER_DISMOUNT_RIGHT_END = 500, // Ladder dismount right (2/2)
LA_ONWATER_TO_LADDER = 501, // Tread water > climb to ladder idle
LA_POSE_START = 502, // Stand > AFK pose
LA_POSE_CONTINUE = 503, // AFK pose (looped)
LA_POSE_END = 504, // AFK pose > stand
NUM_LARA_ANIMS
// TRASHED ANIMS (please reuse slots before going any higher and remove entries from this list as you go):
// 45,
// 245, 265, 266, 268, 273, 274, 278, 280,
// 364, 366, 368, 370,
// 484, 485, 486, 487, 488, 499, 490, 491, 492, 493, 494
};
#pragma endregion
@ -745,7 +754,7 @@ enum LARA_WATER_STATUS
enum LARA_GUN_STATUS
{
LG_NO_ARMS,
LG_HANDS_FREE,
LG_HANDS_BUSY,
LG_DRAW_GUNS,
LG_UNDRAW_GUNS,
@ -967,26 +976,6 @@ struct LARA_ARM
short flash_gun;
};
struct AnimsNew
{
bool CrouchRoll; // crouch roll
bool Monkey180Roll; // the 180 degrees roll on monkeybars
bool Crawl1clickup; // going 1 click up in crawlspaces
bool Crawl1clickdown; // going 1 click down in crawlspaces
bool CrawlExit1click; // crawlspace exit at 1 click
bool CrawlExit2click; // crawlspace exit at 2 clicks
bool CrawlExit3click; // crawlspace exit at 3 clicks
bool CrawlVault1click; // vault into crawlspace at 1 click
bool CrawlVault2click; // vault into crawlspace at 2 clicks
bool CrawlVault3click; // vault into crawlspace at 3 clicks
bool MonkeyVault; // vault up to monkeybars when pressing up + action underneath them. super annoying :)
bool CrawlExitJump; // TR5 crawlspace exit with jump!
bool SwandiveRollRun; // the transition from swandive roll to run
bool OscillateHanging; // the thin ledge grab animation from TR1 and 2
bool CrawlFlexWaterPullUp;
bool CrawlFlexSubmerged;
};
#ifdef NEW_TIGHTROPE
struct LaraTightrope
{
@ -1008,6 +997,8 @@ struct LaraInfo
LARA_WATER_STATUS waterStatus; // LW_enum
short climbStatus;
short poseCount;
int jumpCount;
bool jumpQueued;
short hitFrame;
short hitDirection;
int sprintTimer;
@ -1029,7 +1020,7 @@ struct LaraInfo
bool flareControlLeft;
bool look;
bool burn;
bool keepDucked;
bool keepCrouched;
bool isMoving;
bool canMonkeySwing;
byte burnBlue;

View file

@ -1,4 +1,5 @@
#include "framework.h"
#include "lara_helpers.h"
#include "lara_swim.h"
#include "control/control.h"
#include "camera.h"
@ -107,6 +108,7 @@ void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_ROLL && level->LaraType != LaraType::Divesuit)
{
SetAnimation(item, LA_UNDERWATER_ROLL_180_START);
return;
}
@ -116,7 +118,7 @@ void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)
if (level->LaraType == LaraType::Divesuit)
SwimTurnSubsuit(item);
else
SwimTurn(item);
SwimTurn(item, coll);
if (TrInput & IN_JUMP)
item->goalAnimState = LS_UNDERWATER_FORWARD;
@ -127,7 +129,7 @@ void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 0;
if (Lara.gunStatus == LG_HANDS_BUSY)
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)
@ -143,11 +145,12 @@ void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_ROLL && level->LaraType != LaraType::Divesuit)
{
SetAnimation(item, LA_UNDERWATER_ROLL_180_START);
return;
}
if (level->LaraType != LaraType::Divesuit)
SwimTurn(item);
SwimTurn(item, coll);
else
SwimTurnSubsuit(item);
@ -175,11 +178,12 @@ void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll)
if (TrInput & IN_ROLL && level->LaraType != LaraType::Divesuit)
{
SetAnimation(item, LA_UNDERWATER_ROLL_180_START);
return;
}
if (level->LaraType != LaraType::Divesuit)
SwimTurn(item);
SwimTurn(item, coll);
else
SwimTurnSubsuit(item);
@ -275,23 +279,23 @@ void SwimTurnSubsuit(ITEM_INFO* item)
if (TrInput & IN_LEFT)
{
Lara.turnRate -= SUB_SUIT_TURN_RATE;
if (Lara.turnRate < -LARA_MED_TURN)
Lara.turnRate = -LARA_MED_TURN;
Lara.turnRate -= LARA_SUBSUIT_TURN_RATE;
if (Lara.turnRate < -LARA_MED_TURN_MAX)
Lara.turnRate = -LARA_MED_TURN_MAX;
item->pos.zRot -= LARA_LEAN_RATE * 2;
item->pos.zRot -= LARA_LEAN_RATE;
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += SUB_SUIT_TURN_RATE;
if (Lara.turnRate > LARA_MED_TURN)
Lara.turnRate = LARA_MED_TURN;
Lara.turnRate += LARA_SUBSUIT_TURN_RATE;
if (Lara.turnRate > LARA_MED_TURN_MAX)
Lara.turnRate = LARA_MED_TURN_MAX;
item->pos.zRot += LARA_LEAN_RATE * 2;
item->pos.zRot += LARA_LEAN_RATE;
}
}
void SwimTurn(ITEM_INFO* item)
void SwimTurn(ITEM_INFO* item, COLL_INFO* coll)
{
if (TrInput & IN_FORWARD)
item->pos.xRot -= ANGLE(2.0f);
@ -301,18 +305,18 @@ void SwimTurn(ITEM_INFO* item)
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_MED_TURN)
Lara.turnRate = -LARA_MED_TURN;
if (Lara.turnRate < -LARA_MED_TURN_MAX)
Lara.turnRate = -LARA_MED_TURN_MAX;
item->pos.zRot -= LARA_LEAN_RATE * 2;
item->pos.zRot -= LARA_LEAN_RATE;
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_MED_TURN)
Lara.turnRate = LARA_MED_TURN;
if (Lara.turnRate > LARA_MED_TURN_MAX)
Lara.turnRate = LARA_MED_TURN_MAX;
item->pos.zRot += LARA_LEAN_RATE * 2;
item->pos.zRot += LARA_LEAN_RATE;
}
}

View file

@ -15,6 +15,6 @@ void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll);
void UpdateSubsuitAngles();
void SwimTurnSubsuit(ITEM_INFO* item);
void SwimTurn(ITEM_INFO* item);
void SwimTurn(ITEM_INFO* item, COLL_INFO* coll);
void SwimDive(ITEM_INFO* item);
void LaraWaterCurrent(COLL_INFO* coll);
void LaraWaterCurrent(COLL_INFO* coll);

File diff suppressed because it is too large Load diff

View file

@ -1,18 +1,23 @@
#pragma once
#include "collide.h"
#include "lara_struct.h"
struct ITEM_INFO;
struct COLL_INFO;
// -----------------------------
// TEST FUNCTIONS
// For State Control & Collision
// -----------------------------
SPLAT_COLL TestLaraWall(ITEM_INFO* item, int front, int right, int down);
bool TestValidLedge(ITEM_INFO* item, COLL_INFO* coll, bool ignoreHeadroom = false, bool heightLimit = false);
bool TestValidLedgeAngle(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraVault(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStandUp(COLL_INFO* coll);
bool TestLaraKeepCrouched(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraSwamp(ITEM_INFO* item);
bool TestLaraWater(ITEM_INFO* item);
bool TestLaraLean(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraHang(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraHangJump(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraHangJumpUp(ITEM_INFO* item, COLL_INFO* coll);
@ -23,8 +28,9 @@ bool TestLaraValidHangPos(ITEM_INFO* item, COLL_INFO* coll);
CORNER_RESULT TestLaraHangCorner(ITEM_INFO* item, COLL_INFO* coll, float testAngle);
bool TestHangSwingIn(ITEM_INFO* item, short angle);
bool TestLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle);
bool LaraFacingCorner(ITEM_INFO* item, short ang, int dist);
bool LaraPositionOnLOS(ITEM_INFO* item, short ang, int dist);
bool TestLaraFacingCorner(ITEM_INFO* item, short angle, int dist);
bool TestLaraStandingJump(ITEM_INFO* item, COLL_INFO* coll, short angle);
int LaraFloorFront(ITEM_INFO* item, short ang, int dist);
int LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h);
@ -32,6 +38,7 @@ COLL_RESULT LaraCollisionFront(ITEM_INFO* item, short ang, int dist);
COLL_RESULT LaraCeilingCollisionFront(ITEM_INFO* item, short ang, int dist, int h);
COLL_RESULT LaraCollisionAboveFront(ITEM_INFO* item, short ang, int dist, int h);
bool TestLaraFall(ITEM_INFO* item, COLL_INFO* coll);
bool LaraFallen(ITEM_INFO* item, COLL_INFO* coll);
bool LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll);
@ -39,8 +46,41 @@ bool TestLaraWaterStepOut(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll);
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraPoleCollision(ITEM_INFO* item, COLL_INFO* coll, bool up, float offset = 0.0f);
#ifndef NEW_TIGHTROPE
void GetTighRopeFallOff(int Regularity);
#endif // !NEW_TIGHTROPE
#endif
bool IsStandingWeapon(LARA_WEAPON_TYPE gunType);
bool TestLaraPose(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStep(COLL_INFO* coll);
bool TestLaraStepUp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepDown(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraMove(ITEM_INFO* item, COLL_INFO* coll, short angle, int lowerBound, int upperBound, bool checkSlope = true, bool checkDeath = true);
bool TestLaraMoveCrawl(ITEM_INFO* item, COLL_INFO* coll, short angle, int lowerBound, int upperBound, bool checkSlope = true, bool checkDeath = true);
bool TestLaraRunForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWalkForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWalkBack(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraHopBack(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepLeft(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepRight(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraWalkBackSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepLeftSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraStepRightSwamp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlForward(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlBack(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrouchToCrawl(ITEM_INFO* item);
bool TestLaraCrouchRoll(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlUpStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlDownStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlExitDownStep(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlExitJump(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlVault(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraCrawlToHang(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraPoleCollision(ITEM_INFO* item, COLL_INFO* coll, bool up, float offset = 0.0f);
bool TestLaraPoleUp(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraPoleDown(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -472,7 +472,7 @@ void undraw_pistols(LARA_WEAPON_TYPE weaponType)
if (frameLeft == p->draw1Anim && frameRight == p->draw1Anim)
{
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.leftArm.frameNumber = 0;
Lara.rightArm.frameNumber = 0;
Lara.target = NULL;

View file

@ -198,13 +198,13 @@ void TranslateItem(ITEM_INFO* item, int x, int y, int z)
item->pos.zPos += -s * x + c * z;
}
int GetChange(ITEM_INFO* item, ANIM_STRUCT* anim)
bool GetChange(ITEM_INFO* item, ANIM_STRUCT* anim)
{
if (item->currentAnimState == item->goalAnimState)
return 0;
return false;
if (anim->numberChanges <= 0)
return 0;
return false;
for (int i = 0; i < anim->numberChanges; i++)
{
@ -219,13 +219,13 @@ int GetChange(ITEM_INFO* item, ANIM_STRUCT* anim)
item->animNumber = range->linkAnimNum;
item->frameNumber = range->linkFrameNum;
return 1;
return true;
}
}
}
}
return 0;
return false;
}
BOUNDING_BOX* GetBoundsAccurate(ITEM_INFO* item)

View file

@ -61,7 +61,7 @@ short GetFrameNumber(short objectID, short animNumber, short frameToStart);
int GetFrameCount(short animNumber);
int GetNextAnimState(ITEM_INFO* item);
int GetNextAnimState(short objectID, short animNumber);
int GetChange(ITEM_INFO* item, ANIM_STRUCT* anim);
bool GetChange(ITEM_INFO* item, ANIM_STRUCT* anim);
int GetFrame(ITEM_INFO* item, ANIM_FRAME* framePtr[], int* rate);
ANIM_FRAME* GetBestFrame(ITEM_INFO* item);
BOUNDING_BOX* GetBoundsAccurate(ITEM_INFO* item);

View file

@ -1758,34 +1758,44 @@ void LookUpDown()
}
}
void ResetLook()
void ResetLook(ITEM_INFO* item)
{
LaraInfo*& info = item->data;
if (Camera.type != CAMERA_TYPE::LOOK_CAMERA)
{
if (Lara.headXrot <= -ANGLE(2.0f) || Lara.headXrot >= ANGLE(2.0f))
Lara.headXrot = Lara.headXrot / -8 + Lara.headXrot;
if (abs(info->headXrot) > ANGLE(0.1f))
info->headXrot += info->headXrot / -8;
else
Lara.headXrot = 0;
info->headXrot = 0;
if (Lara.headYrot <= -ANGLE(2.0f) || Lara.headYrot >= ANGLE(2.0f))
Lara.headYrot = Lara.headYrot / -8 + Lara.headYrot;
if (abs(info->headYrot) > ANGLE(0.1f))
info->headYrot += info->headYrot / -8;
else
Lara.headYrot = 0;
info->headYrot = 0;
if (Lara.gunStatus != LG_HANDS_BUSY &&
!Lara.leftArm.lock &&
!Lara.rightArm.lock &&
Lara.Vehicle == NO_ITEM)
if (abs(info->headZrot) > ANGLE(0.1f))
info->headZrot += info->headZrot / -8;
else
info->headZrot = 0;
if (info->gunStatus != LG_HANDS_BUSY &&
!info->leftArm.lock &&
!info->rightArm.lock &&
info->Vehicle == NO_ITEM)
{
Lara.torsoYrot = Lara.headYrot;
Lara.torsoXrot = Lara.headXrot;
info->torsoXrot = info->headXrot;
info->torsoYrot = info->headYrot;
info->torsoZrot = info->headZrot;
}
else
{
if (!Lara.headXrot)
Lara.torsoXrot = 0;
if (!Lara.headYrot)
Lara.torsoYrot = 0;
if (!info->headXrot)
info->torsoXrot = 0;
if (!info->headYrot)
info->torsoYrot = 0;
if (!info->headZrot)
info->torsoZrot = 0;
}
}
}

View file

@ -79,7 +79,7 @@ void ConfirmCameraTargetPos();
void CalculateCamera();
void LookLeftRight();
void LookUpDown();
void ResetLook();
void ResetLook(ITEM_INFO* item);
void RumbleScreen();
bool TestBoundsCollideCamera(BOUNDING_BOX* bounds, PHD_3DPOS* pos, short radius);
void ItemPushCamera(BOUNDING_BOX* bounds, PHD_3DPOS* pos, short radius);

View file

@ -610,9 +610,9 @@ void ShiftItem(ITEM_INFO* item, COLL_INFO* coll)
item->pos.xPos += coll->Shift.x;
item->pos.yPos += coll->Shift.y;
item->pos.zPos += coll->Shift.z;
coll->Shift.z = 0;
coll->Shift.y = 0;
coll->Shift.x = 0;
coll->Shift.y = 0;
coll->Shift.z = 0;
}
void MoveItem(ITEM_INFO* item, short angle, int x, int y)
@ -845,7 +845,7 @@ bool ItemPushStatic(ITEM_INFO* item, MESH_INFO* mesh, COLL_INFO* coll) // previo
if (item == LaraItem && Lara.isMoving && Lara.moveCount > 15)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
return true;
@ -965,7 +965,7 @@ bool ItemPushItem(ITEM_INFO* item, ITEM_INFO* item2, COLL_INFO* coll, bool spazo
if (lara != nullptr && lara->moveCount > 15)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
return true;
@ -1190,7 +1190,7 @@ bool MoveLaraPosition(PHD_VECTOR* vec, ITEM_INFO* item, ITEM_INFO* l)
if (Lara.isMoving)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
return false;
@ -1543,7 +1543,7 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->Front.Floor = STOP_SIZE;
}
else if (coll->Setup.DeathFlagIsPit &&
coll->Front.Floor > 0 &&
coll->MiddleLeft.Floor >= STEP_SIZE / 2 &&
collResult.BottomBlock->Flags.Death)
{
coll->Front.Floor = STOP_SIZE;
@ -1591,7 +1591,7 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->MiddleLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.DeathFlagIsPit &&
coll->MiddleLeft.Floor > 0 &&
coll->MiddleLeft.Floor >= STEP_SIZE / 2 &&
collResult.BottomBlock->Flags.Death)
{
coll->MiddleLeft.Floor = STOP_SIZE;
@ -1634,7 +1634,7 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->FrontLeft.Floor = STOP_SIZE;
}
else if (coll->Setup.DeathFlagIsPit &&
coll->FrontLeft.Floor > 0 &&
coll->MiddleLeft.Floor >= STEP_SIZE / 2 &&
collResult.BottomBlock->Flags.Death)
{
coll->FrontLeft.Floor = STOP_SIZE;
@ -1682,7 +1682,7 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->MiddleRight.Floor = STOP_SIZE;
}
else if (coll->Setup.DeathFlagIsPit &&
coll->MiddleRight.Floor > 0 &&
coll->MiddleLeft.Floor >= STEP_SIZE / 2 &&
collResult.BottomBlock->Flags.Death)
{
coll->MiddleRight.Floor = STOP_SIZE;
@ -1725,7 +1725,7 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->FrontRight.Floor = STOP_SIZE;
}
else if (coll->Setup.DeathFlagIsPit &&
coll->FrontRight.Floor > 0 &&
coll->MiddleLeft.Floor >= STEP_SIZE / 2 &&
collResult.BottomBlock->Flags.Death)
{
coll->FrontRight.Floor = STOP_SIZE;
@ -1762,9 +1762,10 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
coll->CollisionType = CT_TOP;
}
if (coll->Front.Floor > coll->Setup.BadHeightDown ||
if (coll->Front.Floor > coll->Setup.BadHeightDown ||
coll->Front.Floor < coll->Setup.BadHeightUp ||
coll->Front.Ceiling > coll->Setup.BadCeilingHeight)
coll->Front.Ceiling > coll->Setup.BadCeilingHeight ||
coll->Front.Floor - coll->Front.Ceiling <= 0)
{
if (coll->Front.HasDiagonalSplit())
{
@ -1804,7 +1805,8 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
if (coll->MiddleLeft.Floor > coll->Setup.BadHeightDown ||
coll->MiddleLeft.Floor < coll->Setup.BadHeightUp ||
coll->MiddleLeft.Ceiling > coll->Setup.BadCeilingHeight)
coll->MiddleLeft.Ceiling > coll->Setup.BadCeilingHeight ||
coll->MiddleLeft.Floor - coll->MiddleLeft.Ceiling <= 0)
{
if (coll->TriangleAtLeft() && !coll->MiddleLeft.Slope)
{
@ -1854,7 +1856,8 @@ void GetCollisionInfo(COLL_INFO* coll, ITEM_INFO* item, PHD_VECTOR offset, bool
if (coll->MiddleRight.Floor > coll->Setup.BadHeightDown ||
coll->MiddleRight.Floor < coll->Setup.BadHeightUp ||
coll->MiddleRight.Ceiling > coll->Setup.BadCeilingHeight)
coll->MiddleRight.Ceiling > coll->Setup.BadCeilingHeight ||
coll->MiddleRight.Floor - coll->MiddleRight.Ceiling <= 0)
{
if (coll->TriangleAtRight() && !coll->MiddleRight.Slope)
{

View file

@ -6,7 +6,6 @@
#include "pickup.h"
#include "camera.h"
#include "Lara.h"
#include "effects/hair.h"
#include "items.h"
#include "flipeffect.h"
#include "gui.h"
@ -22,15 +21,17 @@
#include "input.h"
#include "setup.h"
#include "room.h"
#include "effects/effects.h"
#include "effects/tomb4fx.h"
#include "effects/debris.h"
#include "effects/footprint.h"
#include "effects/smoke.h"
#include "effects/spark.h"
#include "effects/explosion.h"
#include "effects/drip.h"
#include "effects/weather.h"
#include "Game/effects/hair.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/effects/debris.h"
#include "Game/effects/footprint.h"
#include "Game/effects/smoke.h"
#include "Game/effects/spark.h"
#include "Game/effects/explosion.h"
#include "Game/effects/drip.h"
#include "Game/effects/weather.h"
#include "Game/effects/lightning.h"
#include "tr5_rats_emitter.h"
#include "tr5_bats_emitter.h"
#include "tr5_spider_emitter.h"
@ -40,9 +41,10 @@
#include "Specific/prng.h"
#include "Specific/clock.h"
#include "Lara/lara_one_gun.h"
#include "Lara/lara_cheat.h"
#include "Lara/lara_helpers.h"
#include "generic_switch.h"
#include "Scripting/GameFlowScript.h"
#include "Game/effects/lightning.h"
using std::vector;
using std::unordered_map;
@ -110,8 +112,8 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
g_GameScript->ProcessDisplayStrings(DELTA_TIME);
static int FramesCount = 0;
for (FramesCount += numFrames; FramesCount > 0; FramesCount -= 2)
static int framesCount = 0;
for (framesCount += numFrames; framesCount > 0; framesCount -= 2)
{
GlobalCounter++;
@ -210,7 +212,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
if (CurrentLevel != 0)
{
if (!(TrInput & IN_LOOK) || UseSpotCam || TrackCameraInit ||
((LaraItem->currentAnimState != LS_STOP || LaraItem->animNumber != LA_STAND_IDLE) && (!Lara.isDucked || TrInput & IN_DUCK || LaraItem->animNumber != LA_CROUCH_IDLE || LaraItem->goalAnimState != LS_CROUCH_IDLE)))
((LaraItem->currentAnimState != LS_IDLE || LaraItem->animNumber != LA_STAND_IDLE) && (!Lara.isDucked || TrInput & IN_DUCK || LaraItem->animNumber != LA_CROUCH_IDLE || LaraItem->goalAnimState != LS_CROUCH_IDLE)))
{
if (BinocularRange == 0)
{
@ -232,11 +234,7 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
Lara.busy = false;
Camera.type = BinocularOldCamera;
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
ResetLaraFlex(LaraItem);
Camera.bounce = 0;
BinocularOn = -8;
@ -325,7 +323,6 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
if (CurrentLevel != 0)
{
// Control Lara
InItemControlLoop = true;
LaraControl(LaraItem, &LaraCollision);
@ -340,10 +337,11 @@ GAME_STATUS ControlPhase(int numFrames, int demoMode)
g_Gui.SetInventoryItemChosen(NO_ITEM);
}
LaraCheatyBits();
TriggerLaraDrips(LaraItem);
// Update Lara's ponytails
HairControl(0, 0, 0);
if (level->LaraType == LaraType::Young)
HairControl(0, 1, 0);
HairControl(LaraItem, level->LaraType == LaraType::Young);
}
if (UseSpotCam)

View file

@ -1238,16 +1238,12 @@ void WadeSplash(ITEM_INFO* item, int wh, int wd)
{
if (!(Wibble & 0xF))
{
if (!(GetRandomControl() & 0xF) || item->currentAnimState != LS_STOP)
if (!(GetRandomControl() & 0xF) || item->currentAnimState != LS_IDLE)
{
if (item->currentAnimState == LS_STOP)
{
if (item->currentAnimState == LS_IDLE)
SetupRipple(item->pos.xPos, wh - 1, item->pos.zPos, (GetRandomControl() & 0xF) + 112, RIPPLE_FLAG_RAND_ROT | RIPPLE_FLAG_RAND_POS, Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_RIPPLES);
}
else
{
SetupRipple(item->pos.xPos, wh - 1, item->pos.zPos, (GetRandomControl() & 0xF) + 112, RIPPLE_FLAG_RAND_ROT | RIPPLE_FLAG_RAND_POS, Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_RIPPLES);
}
}
}
}

View file

@ -41,7 +41,14 @@ void InitialiseHair()
}
}
void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
void HairControl(ITEM_INFO* item, bool young)
{
HairControl(item, 0, 0);
if (young)
HairControl(item, 1, 0);
}
void HairControl(ITEM_INFO* item, int ponytail, ANIM_FRAME* framePtr)
{
SPHERE sphere[HAIR_SPHERE];
OBJECT_INFO* object = &Objects[ID_LARA];
@ -49,45 +56,47 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
int spaz;
bool youngLara = g_GameFlow->GetLevel(CurrentLevel)->LaraType == LaraType::Young;
LaraInfo*& lara = item->data;
if (framePtr == NULL)
{
if (Lara.hitDirection >= 0)
if (lara->hitDirection >= 0)
{
switch (Lara.hitDirection)
switch (lara->hitDirection)
{
case NORTH:
if (Lara.isDucked)
if (lara->isDucked)
spaz = 294;
else
spaz = 125;
break;
case SOUTH:
if (Lara.isDucked)
if (lara->isDucked)
spaz = 293;
else
spaz = 126;
break;
case EAST:
if (Lara.isDucked)
if (lara->isDucked)
spaz = 295;
else
spaz = 127;
break;
default:
if (Lara.isDucked)
if (lara->isDucked)
spaz = 296;
else
spaz = 128;
break;
}
frame = &g_Level.Frames[g_Level.Anims[spaz].framePtr + Lara.hitFrame];
frame = &g_Level.Frames[g_Level.Anims[spaz].framePtr + lara->hitFrame];
}
else
frame = GetBestFrame(LaraItem);
frame = GetBestFrame(item);
}
else
{
@ -95,7 +104,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
}
// Get Lara's spheres in absolute coords, for head, torso, hips and upper arms
MESH* mesh = &g_Level.Meshes[Lara.meshPtrs[LM_HIPS]];
MESH* mesh = &g_Level.Meshes[lara->meshPtrs[LM_HIPS]];
PHD_VECTOR pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_HIPS);
sphere[0].x = pos.x;
@ -103,7 +112,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
sphere[0].z = pos.z;
sphere[0].r = (int)mesh->sphere.Radius;
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_TORSO]];
mesh = &g_Level.Meshes[lara->meshPtrs[LM_TORSO]];
pos = { (int)mesh->sphere.Center.x - 10, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z + 25 }; // Repositioning sphere - from tomb5
GetLaraJointPosition(&pos, LM_TORSO);
sphere[1].x = pos.x;
@ -113,7 +122,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
if (youngLara)
sphere[1].r = sphere[1].r - ((sphere[1].r >> 2) + (sphere[1].r >> 3));
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_HEAD]];
mesh = &g_Level.Meshes[lara->meshPtrs[LM_HEAD]];
pos = { (int)mesh->sphere.Center.x - 2, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z }; // Repositioning sphere - from tomb5
GetLaraJointPosition(&pos, LM_HEAD);
sphere[2].x = pos.x;
@ -121,7 +130,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
sphere[2].z = pos.z;
sphere[2].r = (int)mesh->sphere.Radius;
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_RINARM]];
mesh = &g_Level.Meshes[lara->meshPtrs[LM_RINARM]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_RINARM);
sphere[3].x = pos.x;
@ -129,7 +138,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
sphere[3].z = pos.z;
sphere[3].r = (int)(4.0f * mesh->sphere.Radius / 3.0f); // Resizing sphere - from tomb5
mesh = &g_Level.Meshes[Lara.meshPtrs[LM_LINARM]];
mesh = &g_Level.Meshes[lara->meshPtrs[LM_LINARM]];
pos = { (int)mesh->sphere.Center.x, (int)mesh->sphere.Center.y, (int)mesh->sphere.Center.z };
GetLaraJointPosition(&pos, LM_LINARM);
sphere[4].x = pos.x;
@ -151,7 +160,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
sphere[5].r = youngLara ? 0 : (int)(3.0f * (float)sphere[2].r / 4.0f);
Matrix world;
g_Renderer.getBoneMatrix(Lara.itemNumber, LM_HEAD, &world);
g_Renderer.getBoneMatrix(lara->itemNumber, LM_HEAD, &world);
if (ponytail)
{
@ -197,20 +206,11 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
Hairs[ponytail][0].pos.yPos = pos.y;
Hairs[ponytail][0].pos.zPos = pos.z;
short roomNumber = LaraItem->roomNumber;
int wh;
if (cutscene)
{
wh = NO_HEIGHT;
}
else
{
int x = LaraItem->pos.xPos + (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
int y = LaraItem->pos.yPos + (frame->boundingBox.Y1 + frame->boundingBox.Y2) / 2;
int z = LaraItem->pos.zPos + (frame->boundingBox.Z1 + frame->boundingBox.Z2) / 2;
wh = GetWaterHeight(x, y, z, roomNumber);
}
short roomNumber = item->roomNumber;
int x = item->pos.xPos + (frame->boundingBox.X1 + frame->boundingBox.X2) / 2;
int y = item->pos.yPos + (frame->boundingBox.Y1 + frame->boundingBox.Y2) / 2;
int z = item->pos.zPos + (frame->boundingBox.Z1 + frame->boundingBox.Z2) / 2;
int wh = GetWaterHeight(x, y, z, roomNumber);
for (int i = 1; i < HAIR_SEGMENTS + 1; i++, bone += 4)
{
@ -218,17 +218,8 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
Hairs[ponytail][0].hvel.y = Hairs[ponytail][i].pos.yPos;
Hairs[ponytail][0].hvel.z = Hairs[ponytail][i].pos.zPos;
int height;
if (!cutscene)
{
FLOOR_INFO* floor = GetFloor(Hairs[ponytail][i].pos.xPos, Hairs[ponytail][i].pos.yPos, Hairs[ponytail][i].pos.zPos, &roomNumber);
height = GetFloorHeight(floor, Hairs[ponytail][i].pos.xPos, Hairs[ponytail][i].pos.yPos, Hairs[ponytail][i].pos.zPos);
}
else
{
height = 32767;
}
auto floor = GetFloor(Hairs[ponytail][i].pos.xPos, Hairs[ponytail][i].pos.yPos, Hairs[ponytail][i].pos.zPos, &roomNumber);
int height = GetFloorHeight(floor, Hairs[ponytail][i].pos.xPos, Hairs[ponytail][i].pos.yPos, Hairs[ponytail][i].pos.zPos);
Hairs[ponytail][i].pos.xPos += Hairs[ponytail][i].hvel.x * 3 / 4;
Hairs[ponytail][i].pos.yPos += Hairs[ponytail][i].hvel.y * 3 / 4;
@ -236,7 +227,7 @@ void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr)
// TR3 UPV uses a hack which forces Lara water status to dry.
// Therefore, we can't directly use water status value to determine hair mode.
bool dryMode = (Lara.waterStatus == LW_ABOVE_WATER) && (Lara.Vehicle == -1 || g_Level.Items[Lara.Vehicle].objectNumber != ID_UPV);
bool dryMode = (lara->waterStatus == LW_ABOVE_WATER) && (lara->Vehicle == -1 || g_Level.Items[lara->Vehicle].objectNumber != ID_UPV);
if (dryMode)
{

View file

@ -7,6 +7,7 @@ constexpr auto HAIR_SEGMENTS = 6; // classic = 7, young = 14
constexpr auto HAIR_SPHERE = 6; // current hair max collision
struct ANIM_FRAME;
struct ITEM_INFO;
struct HAIR_STRUCT
{
@ -19,4 +20,5 @@ struct HAIR_STRUCT
extern HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];
void InitialiseHair();
void HairControl(int cutscene, int ponytail, ANIM_FRAME* framePtr);
void HairControl(ITEM_INFO* item, bool young);
void HairControl(ITEM_INFO* item, int ponytail, ANIM_FRAME* framePtr);

View file

@ -1157,12 +1157,12 @@ void UpdateDrips()
void TriggerLaraDrips(ITEM_INFO* item)
{
auto pos = PHD_VECTOR();
if (!(Wibble & 0xF))
{
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
auto pos = PHD_VECTOR();
GetLaraJointPosition(&pos, (LARA_MESHES)i);
auto room = GetRoom(item->location, pos.x, pos.y, pos.z).roomNumber;

View file

@ -172,7 +172,7 @@ void ShootRightGun(ITEM_INFO* item)
void LaraHandsFree(ITEM_INFO* item)
{
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
void KillActiveBaddies(ITEM_INFO* item)

View file

@ -2008,7 +2008,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_PISTOLS;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_PISTOLS)
@ -2021,7 +2021,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_UZI;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_UZI)
@ -2036,7 +2036,7 @@ void GuiController::UseCurrentItem()
{
if (gmeobject == ID_FLARE_INV_ITEM)
{
if (Lara.gunStatus == LG_NO_ARMS)
if (Lara.gunStatus == LG_HANDS_FREE)
{
if (LaraItem->currentAnimState != LS_CRAWL_IDLE &&
LaraItem->currentAnimState != LS_CRAWL_FORWARD &&
@ -2064,7 +2064,7 @@ void GuiController::UseCurrentItem()
{
case INV_OBJECT_BINOCULARS:
if (((LaraItem->currentAnimState == LS_STOP && LaraItem->animNumber == LA_STAND_IDLE)
if (((LaraItem->currentAnimState == LS_IDLE && LaraItem->animNumber == LA_STAND_IDLE)
|| (Lara.isDucked && !(TrInput & IN_DUCK)))
&& !UseSpotCam
&& !TrackCameraInit)
@ -2072,7 +2072,7 @@ void GuiController::UseCurrentItem()
Lara.oldBusy = true;
BinocularRange = 128;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
Lara.gunStatus = LG_UNDRAW_GUNS;
}
@ -2166,7 +2166,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_SHOTGUN;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_SHOTGUN)
@ -2179,7 +2179,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_REVOLVER;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_REVOLVER)
@ -2191,7 +2191,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_HK;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_HK)
@ -2203,7 +2203,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_CROSSBOW;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_CROSSBOW)
@ -2215,7 +2215,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_GRENADE_LAUNCHER;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_GRENADE_LAUNCHER)
@ -2227,7 +2227,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_HARPOON_GUN;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_HARPOON_GUN)
@ -2239,7 +2239,7 @@ void GuiController::UseCurrentItem()
{
Lara.requestGunType = WEAPON_ROCKET_LAUNCHER;
if (Lara.gunStatus != LG_NO_ARMS)
if (Lara.gunStatus != LG_HANDS_FREE)
return;
if (Lara.gunType == WEAPON_ROCKET_LAUNCHER)

View file

@ -106,7 +106,7 @@ void TightRopeCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
ITEM_INFO* item = &g_Level.Items[itemNum];
if (((TrInput & IN_ACTION) == 0
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| l->status == ITEM_INVISIBLE
|| Lara.gunStatus)

View file

@ -10,6 +10,7 @@
#include "items.h"
#include "lara_fire.h"
#include "lara_flare.h"
#include "lara_helpers.h"
#include "lara_one_gun.h"
#include "lara_two_guns.h"
#include "setup.h"
@ -30,7 +31,7 @@ using namespace TEN::Entities::Generic;
static PHD_VECTOR PickUpPosition(0, 0, -100);
OBJECT_COLLISION_BOUNDS PickUpBounds =
{ -256, 256, -200, 200, -256, 256, ANGLE(-10), ANGLE(10), 0, 0, 0, 0 };
{ -256, 256, -200, 200, -256, 256, -ANGLE(10.0f), ANGLE(10.0f), 0, 0, -ANGLE(2.0f), ANGLE(2.0f) }; // TODO: Adjust these bounds when crawl surface alignment is implemented. @Sezz 2021.11.04
static PHD_VECTOR HiddenPickUpPosition(0, 0, -690);
OBJECT_COLLISION_BOUNDS HiddenPickUpBounds =
@ -323,8 +324,8 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (lara->interactedItem == itemNum)
{
getThisItemPlease = itemNum;
lara->isMoving = false;
lara->gunStatus = LG_NO_ARMS;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_FREE;
}
}
}
@ -345,7 +346,7 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (!(TrInput & IN_ACTION) &&
(g_Gui.GetInventoryItemChosen() == NO_ITEM || triggerFlags != 2) ||
BinocularRange ||
(l->currentAnimState != LS_STOP || l->animNumber != LA_STAND_IDLE || lara->gunStatus) &&
(l->currentAnimState != LS_IDLE || l->animNumber != LA_STAND_IDLE || lara->gunStatus) &&
(l->currentAnimState != LS_CROUCH_IDLE || l->animNumber != LA_CROUCH_IDLE || lara->gunStatus) &&
(l->currentAnimState != LS_CRAWL_IDLE || l->animNumber != LA_CRAWL_IDLE))
{
@ -393,8 +394,8 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
{
if (lara->interactedItem == itemNum)
{
lara->isMoving = false;
lara->gunStatus = LG_NO_ARMS;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_FREE;
}
}
@ -427,8 +428,8 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (lara->interactedItem == itemNum)
{
lara->isMoving = false;
lara->gunStatus = LG_NO_ARMS;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.xRot = oldXrot;
@ -528,8 +529,8 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (lara->interactedItem == itemNum)
{
lara->isMoving = false;
lara->gunStatus = LG_NO_ARMS;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.xRot = oldXrot;
@ -571,8 +572,8 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (lara->interactedItem == itemNum)
{
lara->isMoving = false;
lara->gunStatus = LG_NO_ARMS;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.xRot = oldXrot;
@ -653,10 +654,7 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (flag)
{
lara->headYrot = 0;
lara->headXrot = 0;
lara->torsoYrot = 0;
lara->torsoXrot = 0;
ResetLaraFlex(l);
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
lara->isMoving = false;
lara->gunStatus = LG_HANDS_BUSY;
@ -895,9 +893,9 @@ void SearchObjectCollision(short itemNumber, ITEM_INFO* laraitem, COLL_INFO* lar
objNumber = (item->objectNumber - ID_SEARCH_OBJECT1) / 2;
if (TrInput & IN_ACTION
&& laraitem->currentAnimState == LS_STOP
&& laraitem->currentAnimState == LS_IDLE
&& laraitem->animNumber == LA_STAND_IDLE
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.gunStatus == LG_HANDS_FREE
&& (item->status == ITEM_NOT_ACTIVE
&& item->objectNumber != ID_SEARCH_OBJECT4 || !item->itemFlags[0])
|| Lara.isMoving && Lara.interactedItem == itemNumber)
@ -925,10 +923,7 @@ void SearchObjectCollision(short itemNumber, ITEM_INFO* laraitem, COLL_INFO* lar
laraitem->animNumber = SearchAnims[objNumber];
laraitem->frameNumber = g_Level.Anims[laraitem->animNumber].frameBase;
Lara.isMoving = false;
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
ResetLaraFlex(laraitem);
Lara.gunStatus = LG_HANDS_BUSY;
if (item->objectNumber == ID_SEARCH_OBJECT4)
@ -953,7 +948,7 @@ void SearchObjectCollision(short itemNumber, ITEM_INFO* laraitem, COLL_INFO* lar
else if (Lara.isMoving && Lara.interactedItem == itemNumber)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}
else if (laraitem->currentAnimState != LS_MISC_CONTROL)
@ -1064,7 +1059,7 @@ int UseSpecialItem(ITEM_INFO* item)
int flag = 0;
int use = g_Gui.GetInventoryItemChosen();
if (item->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_NO_ARMS && use != NO_ITEM)
if (item->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_HANDS_FREE && use != NO_ITEM)
{
if ((use >= ID_WATERSKIN1_EMPTY) && (use <= ID_WATERSKIN2_5))
{

View file

@ -54,7 +54,7 @@ void PuzzleHoleCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM)
&& !BinocularRange
&& !Lara.gunStatus
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& GetKeyTrigger(&g_Level.Items[itemNum]))
|| (Lara.isMoving
@ -141,7 +141,7 @@ void PuzzleHoleCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}
@ -248,7 +248,7 @@ void KeyHoleCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (!((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM)
&& !BinocularRange
&& !Lara.gunStatus
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE)
&& (!Lara.isMoving || Lara.interactedItem != itemNum))
{
@ -315,7 +315,7 @@ void KeyHoleCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}

View file

@ -283,7 +283,9 @@ bool SaveGame::Save(int slot)
lara.add_is_ducked(Lara.isDucked);
lara.add_is_moving(Lara.isMoving);
lara.add_item_number(Lara.itemNumber);
lara.add_keep_ducked(Lara.keepDucked);
lara.add_jump_count(Lara.jumpCount);
lara.add_jump_queued(Lara.jumpQueued);
lara.add_keep_crouched(Lara.keepCrouched);
lara.add_keys(keysOffset);
lara.add_keys_combo(keysComboOffset);
lara.add_lasersight(Lara.Lasersight);
@ -331,6 +333,7 @@ bool SaveGame::Save(int slot)
lara.add_silencer(Lara.Silencer);
lara.add_small_waterskin(Lara.small_waterskin);
lara.add_spaz_effect_count(Lara.spazEffectCount);
lara.add_sprint_timer(Lara.sprintTimer);
lara.add_target_angles(laraTargetAnglesOffset);
lara.add_target_item_number(Lara.target - g_Level.Items.data());
lara.add_torch(Lara.Torch);
@ -1197,7 +1200,9 @@ bool SaveGame::Load(int slot)
Lara.isDucked = s->lara()->is_ducked();
Lara.isMoving = s->lara()->is_moving();
Lara.itemNumber = s->lara()->item_number();
Lara.keepDucked = s->lara()->keep_ducked();
Lara.jumpCount = s->lara()->jump_count();
Lara.jumpQueued = s->lara()->jump_queued();
Lara.keepCrouched = s->lara()->keep_crouched();
Lara.Lasersight = s->lara()->lasersight();
Lara.lastGunType = (LARA_WEAPON_TYPE)s->lara()->last_gun_type();
Lara.lastPos = PHD_VECTOR(
@ -1255,6 +1260,7 @@ bool SaveGame::Load(int slot)
Lara.Silencer = s->lara()->silencer();
Lara.small_waterskin = s->lara()->small_waterskin();
Lara.spazEffectCount = s->lara()->spaz_effect_count();
Lara.sprintTimer = s->lara()->sprint_timer();
Lara.target = (s->lara()->target_item_number() >= 0 ? &g_Level.Items[s->lara()->target_item_number()] : nullptr);
Lara.targetAngles[0] = s->lara()->target_angles()->Get(0);
Lara.targetAngles[1] = s->lara()->target_angles()->Get(1);

View file

@ -645,7 +645,7 @@ namespace TEN::Entities::Effects
|| Lara.litTorch == (item->status & 1)
|| item->timer == -1
|| !(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus)
{

View file

@ -139,7 +139,7 @@ namespace TEN::Entities::TR4
//if (LaraItem == nullptr)
// LaraItem = LaraItem;
if ((Lara.keepDucked || LaraItem->hitPoints <= 0)
if ((Lara.keepCrouched || LaraItem->hitPoints <= 0)
&& locust->counter >= 90
&& !(GetRandomControl() & 7))
locust->counter = 90;

View file

@ -37,7 +37,7 @@ namespace TEN::Entities::Doors
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& !(item->status && item->gravityStatus)
&& !(l->hitStatus)
@ -72,7 +72,7 @@ namespace TEN::Entities::Doors
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot ^= ANGLE(180);
}

View file

@ -167,10 +167,10 @@ namespace TEN::Entities::Doors
if (item->triggerFlags == 2
&& item->status == ITEM_NOT_ACTIVE && !item->gravityStatus // CHECK
&& ((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() == ID_CROWBAR_ITEM)
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& !l->hitStatus
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.gunStatus == LG_HANDS_FREE
|| Lara.isMoving && Lara.interactedItem == itemNum))
{
item->pos.yRot ^= ANGLE(180);
@ -229,7 +229,7 @@ namespace TEN::Entities::Doors
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = 0;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot ^= ANGLE(180);

View file

@ -47,7 +47,7 @@ namespace TEN::Entities::Doors
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& item->status != ITEM_ACTIVE
&& !(l->hitStatus)
@ -115,7 +115,7 @@ namespace TEN::Entities::Doors
item->status = ITEM_ACTIVE;
l->currentAnimState = LS_MISC_CONTROL;
l->goalAnimState = LS_STOP;
l->goalAnimState = LS_IDLE;
Lara.isMoving = false;
Lara.gunStatus = LG_HANDS_BUSY;
}
@ -123,7 +123,7 @@ namespace TEN::Entities::Doors
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
if (pull)

View file

@ -73,7 +73,7 @@ namespace TEN::Entities::Doors
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
l->pos.yRot ^= ANGLE(180);
}

View file

@ -111,7 +111,7 @@ namespace TEN::Entities::Generic
Lara.leftArm.lock = false;
Lara.gunType = Lara.lastGunType;
Lara.requestGunType = WEAPON_NONE;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
else if (Lara.leftArm.frameNumber == 12)
{
@ -131,7 +131,7 @@ namespace TEN::Entities::Generic
Lara.leftArm.lock = false;
Lara.lastGunType = WEAPON_NONE;
Lara.gunType = WEAPON_NONE;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
else if (Lara.leftArm.frameNumber == 36)
{
@ -293,7 +293,7 @@ namespace TEN::Entities::Generic
|| Lara.litTorch == (item->status == ITEM_ACTIVE)
|| item->timer == -1
|| !(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus)
{

View file

@ -45,7 +45,7 @@ void CeilingTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
bool result2 = TestLaraPosition(&CeilingTrapDoorBounds, item, l);
l->pos.yRot += ANGLE(180);
if (TrInput & IN_ACTION && item->status != ITEM_ACTIVE && l->currentAnimState == LS_JUMP_UP && l->gravityStatus && Lara.gunStatus == LG_NO_ARMS && itemIsAbove && (result || result2))
if (TrInput & IN_ACTION && item->status != ITEM_ACTIVE && l->currentAnimState == LS_JUMP_UP && l->gravityStatus && Lara.gunStatus == LG_HANDS_FREE && itemIsAbove && (result || result2))
{
AlignLaraPosition(&CeilingTrapDoorPos, item, l);
if (result2)
@ -85,7 +85,7 @@ void FloorTrapDoorCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
ITEM_INFO* item;
item = &g_Level.Items[itemNumber];
if (TrInput & IN_ACTION && item->status != ITEM_ACTIVE && l->currentAnimState == LS_STOP && l->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_NO_ARMS
if (TrInput & IN_ACTION && item->status != ITEM_ACTIVE && l->currentAnimState == LS_IDLE && l->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_HANDS_FREE
|| Lara.isMoving && Lara.interactedItem == itemNumber)
{
if (TestLaraPosition(&FloorTrapDoorBounds, item, l))

View file

@ -33,9 +33,9 @@ namespace TEN::Entities::Generic
auto isLara = (!item->data.is<LaraInfo*>());
if (isLara &&
(TrInput & IN_ACTION) &&
TrInput & IN_ACTION &&
!Lara.gunStatus &&
l->currentAnimState == LS_STOP &&
l->currentAnimState == LS_IDLE &&
l->animNumber == LA_STAND_IDLE || Lara.isMoving &&
Lara.interactedItem == itemNumber)
{
@ -63,7 +63,7 @@ namespace TEN::Entities::Generic
if (Lara.isMoving && Lara.interactedItem == itemNumber)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot = rot;
}

View file

@ -187,7 +187,7 @@ namespace TEN::Entities::Generic
rope = &Ropes[item->triggerFlags];
if (TrInput & IN_ACTION
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.gunStatus == LG_HANDS_FREE
&& (l->currentAnimState == LS_REACH
|| l->currentAnimState == LS_JUMP_UP)
&& l->gravityStatus
@ -643,7 +643,7 @@ namespace TEN::Entities::Generic
item->pos.xRot = 0;
item->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
if (item->frameNumber - g_Level.Anims[LA_ROPE_SWING].frameBase > 42)
{
@ -680,7 +680,7 @@ namespace TEN::Entities::Generic
item->fallspeed = 0;
item->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.ropePtr = -1;
}

View file

@ -68,7 +68,7 @@ namespace TEN::Entities::Switches
&& (TrInput & IN_ACTION
&& !Lara.gunStatus
&& !item->gravityStatus
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
|| Lara.isMoving
&& Lara.interactedItem == itemNum))
@ -111,7 +111,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}
@ -129,7 +129,7 @@ namespace TEN::Entities::Switches
{
if (item->goalAnimState == SWITCH_ON && !(TrInput & IN_ACTION))
{
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
item->goalAnimState = SWITCH_OFF;
}
@ -153,9 +153,9 @@ namespace TEN::Entities::Switches
LaraItem->animNumber = LA_STAND_SOLID;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->goalAnimState = LS_STOP;
LaraItem->currentAnimState = LS_STOP;
Lara.gunStatus = LG_NO_ARMS;
LaraItem->goalAnimState = LS_IDLE;
LaraItem->currentAnimState = LS_IDLE;
Lara.gunStatus = LG_HANDS_FREE;
}
}
}

View file

@ -43,9 +43,9 @@ namespace TEN::Entities::Switches
ITEM_INFO* item = &g_Level.Items[itemNum];
if ((((TrInput & IN_ACTION) || g_Gui.GetInventoryItemChosen() == ID_CROWBAR_ITEM)
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.gunStatus == LG_HANDS_FREE
&& item->itemFlags[0] == 0)
|| (Lara.isMoving && Lara.interactedItem == itemNum))
{
@ -79,7 +79,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
l->pos.yRot ^= (short)ANGLE(180);
}
@ -111,7 +111,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}
}

View file

@ -37,7 +37,7 @@ namespace TEN::Entities::Switches
|| item->flags & 0x100
|| CurrentSequence >= 3
|| Lara.gunStatus
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE)
&& (!Lara.isMoving || Lara.interactedItem !=itemNum))
{
@ -55,7 +55,7 @@ namespace TEN::Entities::Switches
l->animNumber = LA_BUTTON_GIANT_PUSH;
item->goalAnimState = 0;
}
l->goalAnimState = LS_STOP;
l->goalAnimState = LS_IDLE;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
item->status = ITEM_ACTIVE;
@ -77,7 +77,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}

View file

@ -50,7 +50,7 @@ namespace TEN::Entities::Switches
{
ITEM_INFO* item = &g_Level.Items[itemNum];
if (TrInput & IN_ACTION
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& !Lara.gunStatus
&& item->status == ITEM_NOT_ACTIVE
@ -151,7 +151,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
return;

View file

@ -43,8 +43,8 @@ namespace TEN::Entities::Switches
ITEM_INFO* item = &g_Level.Items[itemNum];
if ((TrInput & IN_ACTION)
&& Lara.gunStatus == LG_NO_ARMS
&& l->currentAnimState == LS_STOP
&& Lara.gunStatus == LG_HANDS_FREE
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& l->gravityStatus == false
|| Lara.isMoving && Lara.interactedItem == itemNum)
@ -93,7 +93,7 @@ namespace TEN::Entities::Switches
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot = oldYrot;
}

View file

@ -40,7 +40,7 @@ namespace TEN::Entities::Switches
ITEM_INFO* item = &g_Level.Items[itemNum];
if ((!(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| Lara.gunStatus)
&& (!Lara.isMoving
@ -69,7 +69,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
l->pos.yRot ^= (short)ANGLE(180);
@ -129,7 +129,7 @@ namespace TEN::Entities::Switches
if (Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}

View file

@ -52,10 +52,10 @@ namespace TEN::Entities::Switches
if (item->currentAnimState == TURN_SWITCH_STOP
&& TrInput & IN_ACTION
&& l->currentAnimState == LS_STOP
&& l->currentAnimState == LS_IDLE
&& l->animNumber == LA_STAND_IDLE
&& l->gravityStatus == false
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.gunStatus == LG_HANDS_FREE
|| Lara.isMoving && Lara.interactedItem == itemNum)
{
if (TestLaraPosition(&TurnSwitchBoundsA, item, l))
@ -99,7 +99,7 @@ namespace TEN::Entities::Switches
else if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
l->pos.yRot ^= (short)ANGLE(180);
}
@ -225,7 +225,7 @@ namespace TEN::Entities::Switches
if (item->itemFlags[1] == 1)
{
l->animNumber = LA_STAND_IDLE;
l->currentAnimState = LS_STOP;
l->currentAnimState = LS_IDLE;
l->frameNumber = g_Level.Anims[l->animNumber].frameBase;
item->animNumber = Objects[item->objectNumber].animIndex;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
@ -233,7 +233,7 @@ namespace TEN::Entities::Switches
RemoveActiveItem(itemNum);
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
UseForcedFixedCamera = 0;
item->itemFlags[1] = 2;
}

View file

@ -16,7 +16,7 @@ void SpringBoardControl(short itemNumber)
if (LaraItem->hitPoints <= 0)
return;
if (LaraItem->currentAnimState == LS_WALK_BACK || LaraItem->currentAnimState == LS_HOP_BACK)
if (LaraItem->currentAnimState == LS_WALK_BACK || LaraItem->currentAnimState == LS_RUN_BACK)
LaraItem->speed = -LaraItem->speed;
LaraItem->fallspeed = -240;

View file

@ -180,7 +180,7 @@ BoatMountType GetSpeedBoatMountType(ITEM_INFO* laraItem, ITEM_INFO* sBoatItem, C
BoatMountType mountType = BoatMountType::None;
if (laraInfo->gunStatus != LG_NO_ARMS)
if (laraInfo->gunStatus != LG_HANDS_FREE)
return mountType;
if (!TestBoundsCollide(sBoatItem, laraItem, coll->Setup.Radius))

View file

@ -302,7 +302,7 @@ bool SkidooCheckGetOff(ITEM_INFO* lara, ITEM_INFO* skidoo)
lara->pos.xRot = 0;
lara->pos.zRot = 0;
laraInfo->Vehicle = NO_ITEM;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
}
else if (lara->currentAnimState == SKIDOO_STATE_JUMP_OFF &&
(skidoo->pos.yPos == skidoo->floor || TestLastFrame(lara)))
@ -328,7 +328,7 @@ bool SkidooCheckGetOff(ITEM_INFO* lara, ITEM_INFO* skidoo)
lara->pos.xRot = 0;
lara->pos.zRot = 0;
lara->gravityStatus = true;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
laraInfo->moveAngle = skidoo->pos.yRot;
skidoo->flags |= ONESHOT;
skidoo->collidable = false;
@ -618,7 +618,7 @@ int SkidooCheckGetOn(ITEM_INFO* lara, ITEM_INFO* skidoo, COLL_INFO* coll)
int mountType = 0;
if (!(TrInput & IN_ACTION) ||
laraInfo->gunStatus != LG_NO_ARMS ||
laraInfo->gunStatus != LG_HANDS_FREE ||
lara->gravityStatus)
{
return mountType = 0;
@ -668,7 +668,7 @@ void SkidooCollision(short itemNum, ITEM_INFO* lara, COLL_INFO* coll)
UndrawFlareMeshes(lara);
laraInfo->flareControlLeft = 0;
laraInfo->requestGunType = WEAPON_NONE;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
}
if (mountType == 1)

View file

@ -96,7 +96,7 @@ static bool CanUseGun(ITEM_INFO* lara, ITEM_INFO* bigGun)
//LaraInfo*& laraInfo = lara->data; // This function is presumably called before Lara is initialised, so global must be used. @Sezz 2021.11.16
if (!(TrInput & IN_ACTION) ||
Lara.gunStatus != LG_NO_ARMS ||
Lara.gunStatus != LG_HANDS_FREE ||
lara->gravityStatus) // BUG: Lara can still mount when jumping up. @Sezz 2021.11.16
{
return false;
@ -255,7 +255,7 @@ bool BigGunControl(ITEM_INFO* lara, COLL_INFO* coll)
{
SetAnimation(lara, LA_STAND_IDLE);
laraInfo->Vehicle = NO_ITEM;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
bigGun->hitPoints = 0;
}

View file

@ -213,7 +213,7 @@ int KayakGetIn(short itemNumber, COLL_INFO* coll)
ITEM_INFO* l = LaraItem;
if ((!(TrInput & IN_ACTION))
|| (Lara.gunStatus != LG_NO_ARMS)
|| (Lara.gunStatus != LG_HANDS_FREE)
|| (l->gravityStatus))
return 0;
@ -1028,7 +1028,7 @@ void KayakUserInput(ITEM_INFO* v, ITEM_INFO* l, KAYAK_INFO* Kayak)
l->fallspeed = 0;
l->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.Vehicle = NO_ITEM;
}
break;
@ -1055,7 +1055,7 @@ void KayakUserInput(ITEM_INFO* v, ITEM_INFO* l, KAYAK_INFO* Kayak)
l->fallspeed = 0;
l->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.Vehicle = NO_ITEM;
}
}

View file

@ -116,7 +116,7 @@ static bool GetInMineCart(ITEM_INFO* v, ITEM_INFO* l, COLL_INFO* coll)
FLOOR_INFO* floor;
short roomNumber;
if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_NO_ARMS || l->gravityStatus)
if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_HANDS_FREE || l->gravityStatus)
return 0;
if (!TestBoundsCollide(v, l, coll->Setup.Radius))
@ -617,7 +617,7 @@ static void DoUserInput(ITEM_INFO* v, ITEM_INFO* l, CART_INFO* cart)
SetAnimation(l, LA_STAND_SOLID);
Lara.Vehicle = NO_ITEM;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
break;
@ -636,7 +636,7 @@ static void DoUserInput(ITEM_INFO* v, ITEM_INFO* l, CART_INFO* cart)
SetAnimation(l, LA_STAND_SOLID);
Lara.Vehicle = NO_ITEM;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
break;

View file

@ -251,7 +251,7 @@ static bool QuadCheckGetOff(ITEM_INFO* lara, ITEM_INFO* quad)
lara->pos.xRot = 0;
lara->pos.zRot = 0;
laraInfo->Vehicle = NO_ITEM;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
if (lara->currentAnimState == QUAD_STATE_FALL_OFF)
{
@ -268,7 +268,7 @@ static bool QuadCheckGetOff(ITEM_INFO* lara, ITEM_INFO* quad)
lara->pos.xRot = 0;
lara->pos.zRot = 0;
lara->hitPoints = 0;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
quad->flags |= ONESHOT;
return false;
@ -295,7 +295,7 @@ static int GetOnQuadBike(ITEM_INFO* lara, ITEM_INFO* quad, COLL_INFO* coll)
if (!(TrInput & IN_ACTION) ||
lara->gravityStatus ||
laraInfo->gunStatus != LG_NO_ARMS ||
laraInfo->gunStatus != LG_HANDS_FREE ||
quad->flags & ONESHOT ||
abs(quad->pos.yPos - lara->pos.yPos) > STEP_SIZE)
{

View file

@ -125,7 +125,7 @@ RubberBoatMountType RubberBoatCheckGeton(short itemNum, ITEM_INFO* lara, COLL_IN
RubberBoatMountType getOn = RBOAT_MOUNT_NONE;
if (!(TrInput & IN_ACTION) ||
Lara.gunStatus != LG_NO_ARMS ||
Lara.gunStatus != LG_HANDS_FREE ||
lara->gravityStatus ||
rBoat->speed)
{

View file

@ -329,7 +329,7 @@ static bool TestUPVMount(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
LaraInfo*& laraInfo = laraItem->data;
if (!(TrInput & IN_ACTION) ||
laraInfo->gunStatus != LG_NO_ARMS ||
laraInfo->gunStatus != LG_HANDS_FREE ||
laraItem->gravityStatus)
{
return false;
@ -694,7 +694,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
UpdateItemRoom(laraItem, 0);
laraInfo->waterStatus = LW_UNDERWATER;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
laraInfo->Vehicle = NO_ITEM;
UPVItem->hitPoints = 0;
@ -738,7 +738,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
laraInfo->torsoYrot = 0;
laraInfo->headXrot = 0;
laraInfo->headYrot = 0;
laraInfo->gunStatus = LG_NO_ARMS;
laraInfo->gunStatus = LG_HANDS_FREE;
laraInfo->Vehicle = NO_ITEM;
UPVItem->hitPoints = 0;

View file

@ -1049,7 +1049,7 @@ namespace TEN::Entities::TR4
LaraItem->speed = 2;
LaraItem->fallspeed = 1;
LaraItem->pos.yPos += (STEP_SIZE * 0.75f);
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
currentCreature->flags = 1;
}
}

View file

@ -748,7 +748,7 @@ namespace TEN::Entities::TR4
LaraItem->hitStatus = true;
LaraItem->speed = 2;
LaraItem->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}

View file

@ -690,7 +690,7 @@ namespace TEN::Entities::TR4
ITEM_INFO* item = &g_Level.Items[itemNumber];
if ((!(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| Lara.gunStatus
|| l->gravityStatus

View file

@ -307,10 +307,10 @@ void UseClockworkBeetle(short flag)
short itemNum;
if (flag
|| LaraItem->currentAnimState == LS_STOP
|| LaraItem->currentAnimState == LS_IDLE
&& LaraItem->animNumber == LA_STAND_IDLE
&& !LaraItem->hitStatus
&& Lara.gunStatus == LG_NO_ARMS)
&& Lara.gunStatus == LG_HANDS_FREE)
{
itemNum = CreateItem();

View file

@ -244,7 +244,7 @@ namespace TEN::Entities::TR4
|| !(TrInput & IN_ACTION)
|| item->triggerFlags != 1
|| item->itemFlags[0] != 1
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| !Lara.litTorch
|| l->gravityStatus)

View file

@ -23,9 +23,9 @@ void SarcophagusCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (TrInput & IN_ACTION &&
item->status != ITEM_ACTIVE &&
l->currentAnimState == LS_STOP &&
l->currentAnimState == LS_IDLE &&
l->animNumber == LA_STAND_IDLE &&
Lara.gunStatus == LG_NO_ARMS ||
Lara.gunStatus == LG_HANDS_FREE ||
Lara.isMoving && Lara.interactedItem == itemNum)
{
if (TestLaraPosition(&SarcophagusBounds, item, l))
@ -57,7 +57,7 @@ void SarcophagusCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
}
}

View file

@ -413,7 +413,7 @@ void GameStixCollision(short item_num, ITEM_INFO* laraitem, COLL_INFO* coll)
{
ITEM_INFO* item = &g_Level.Items[item_num];
if (TrInput & IN_ACTION && laraitem->currentAnimState == LS_STOP && laraitem->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_NO_ARMS &&
if (TrInput & IN_ACTION && laraitem->currentAnimState == LS_IDLE && laraitem->animNumber == LA_STAND_IDLE && Lara.gunStatus == LG_HANDS_FREE &&
!item->active || Lara.isMoving && Lara.interactedItem == item_num)
{
laraitem->pos.yRot ^= 0x8000;

View file

@ -401,14 +401,14 @@ static int JeepCheckGetOff()
LaraItem->pos.yRot += ANGLE(90);
LaraItem->animNumber = LA_STAND_SOLID;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->goalAnimState = LS_STOP;
LaraItem->currentAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
LaraItem->currentAnimState = LS_IDLE;
LaraItem->pos.xPos -= JEEP_GETOFF_DISTANCE * phd_sin(LaraItem->pos.yRot);
LaraItem->pos.zPos -= JEEP_GETOFF_DISTANCE * phd_cos(LaraItem->pos.yRot);
LaraItem->pos.xRot = 0;
LaraItem->pos.zRot = 0;
Lara.Vehicle = NO_ITEM;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
return false;
}
}
@ -429,7 +429,7 @@ static int GetOnJeep(int itemNumber)
if (Lara.gunStatus)
return 0;
if (LaraItem->currentAnimState != LS_STOP)
if (LaraItem->currentAnimState != LS_IDLE)
return 0;
if (LaraItem->animNumber != LA_STAND_IDLE)

View file

@ -298,7 +298,7 @@ static BOOL GetOnMotorBike(short itemNumber)
short room_number;
item = &g_Level.Items[itemNumber];
if (item->flags & ONESHOT || Lara.gunStatus != LG_NO_ARMS || LaraItem->gravityStatus)
if (item->flags & ONESHOT || Lara.gunStatus != LG_HANDS_FREE || LaraItem->gravityStatus)
return false;
if ((abs(item->pos.yPos - LaraItem->pos.yPos) >= STEP_SIZE || !(TrInput & IN_ACTION)) && g_Gui.GetInventoryItemChosen() != ID_PUZZLE_ITEM1)
@ -364,7 +364,7 @@ void MotorbikeCollision(short itemNumber, ITEM_INFO* laraitem, COLL_INFO* coll)
Lara.flareAge = 0;
}
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
short angle = phd_atan(item->pos.zPos - laraitem->pos.zPos, item->pos.xPos - laraitem->pos.xPos) - item->pos.yRot;
if (angle <= -ANGLE(45.0f) || angle >= ANGLE(135.0f))
@ -547,14 +547,14 @@ static int MotorBikeCheckGetOff(void)
LaraItem->pos.yRot -= 0x4000;
LaraItem->animNumber = LA_STAND_SOLID;
LaraItem->frameNumber = g_Level.Anims[LaraItem->animNumber].frameBase;
LaraItem->goalAnimState = LS_STOP;
LaraItem->currentAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
LaraItem->currentAnimState = LS_IDLE;
LaraItem->pos.xPos -= 2 * phd_sin(item->pos.yRot);
LaraItem->pos.zPos -= 2 * phd_cos(item->pos.yRot);
LaraItem->pos.xRot = 0;
LaraItem->pos.zRot = 0;
Lara.Vehicle = NO_ITEM;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
Lara.sprintTimer = 120;
return true;
}

View file

@ -243,7 +243,7 @@ void PushableBlockControl(short itemNumber)
MoveStackXZ(itemNumber);
//SoundEffect(pushable->stopSound, &item->pos, 2);
DoPushPull = 0;
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
item->gravityStatus = true; // do fall
return;
@ -255,7 +255,7 @@ void PushableBlockControl(short itemNumber)
{
if (!TestBlockPush(item, blockHeight, quadrant))
{
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
}
else
{
@ -266,7 +266,7 @@ void PushableBlockControl(short itemNumber)
}
else
{
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
}
}
break;
@ -317,7 +317,7 @@ void PushableBlockControl(short itemNumber)
{
if (!TestBlockPull(item, blockHeight, quadrant))
{
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
}
else
{
@ -328,7 +328,7 @@ void PushableBlockControl(short itemNumber)
}
else
{
LaraItem->goalAnimState = LS_STOP;
LaraItem->goalAnimState = LS_IDLE;
}
}
break;
@ -375,7 +375,7 @@ void PushableBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
int blockHeight = GetStackHeight(item);
if ((!(TrInput & IN_ACTION)
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus
|| Lara.gunStatus
@ -515,7 +515,7 @@ void PushableBlockCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot = rot;
}

View file

@ -38,7 +38,7 @@ namespace TEN::Entities::TR5
|| !(item->meshBits & 4)
|| (!(TrInput & IN_ACTION)
|| Lara.gunStatus
|| l->currentAnimState != LS_STOP
|| l->currentAnimState != LS_IDLE
|| l->animNumber != LA_STAND_IDLE
|| l->gravityStatus)
&& (!Lara.isMoving || Lara.interactedItem != itemNum))
@ -85,7 +85,7 @@ namespace TEN::Entities::TR5
if (Lara.isMoving && Lara.interactedItem == itemNum)
{
Lara.isMoving = false;
Lara.gunStatus = LG_NO_ARMS;
Lara.gunStatus = LG_HANDS_FREE;
}
item->pos.yRot = oldYrot;
}

View file

@ -25,7 +25,7 @@ void InitialiseDeathSlide(short itemNumber)
void DeathSlideCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
{
if (!(TrInput & IN_ACTION) || l->gravityStatus || Lara.gunStatus != LG_NO_ARMS || l->currentAnimState != LS_STOP)
if (!(TrInput & IN_ACTION) || l->gravityStatus || Lara.gunStatus != LG_HANDS_FREE || l->currentAnimState != LS_IDLE)
return;
ITEM_INFO* item = &g_Level.Items[itemNumber];

View file

@ -26,7 +26,7 @@ bool shouldAnimateUpperBody(const LARA_WEAPON_TYPE& weapon) {
case WEAPON_GRENADE_LAUNCHER:
case WEAPON_CROSSBOW:
case WEAPON_SHOTGUN:
return (LaraItem->currentAnimState == LS_STOP || LaraItem->currentAnimState == LS_TURN_FAST || LaraItem->currentAnimState == LS_TURN_LEFT_SLOW || LaraItem->currentAnimState == LS_TURN_RIGHT_SLOW);
return (LaraItem->currentAnimState == LS_IDLE || LaraItem->currentAnimState == LS_TURN_LEFT_FAST || LaraItem->currentAnimState == LS_TURN_RIGHT_FAST || LaraItem->currentAnimState == LS_TURN_LEFT_SLOW || LaraItem->currentAnimState == LS_TURN_RIGHT_SLOW);
break;
case WEAPON_HK:
{
@ -35,7 +35,7 @@ bool shouldAnimateUpperBody(const LARA_WEAPON_TYPE& weapon) {
if(laraInfo.rightArm.animNumber - baseAnim == 0 || laraInfo.rightArm.animNumber - baseAnim == 2 || laraInfo.rightArm.animNumber - baseAnim == 4){
return true;
} else
return (LaraItem->currentAnimState == LS_STOP || LaraItem->currentAnimState == LS_TURN_FAST || LaraItem->currentAnimState == LS_TURN_LEFT_SLOW || LaraItem->currentAnimState == LS_TURN_RIGHT_SLOW);
return (LaraItem->currentAnimState == LS_IDLE || LaraItem->currentAnimState == LS_TURN_LEFT_FAST || LaraItem->currentAnimState == LS_TURN_RIGHT_FAST || LaraItem->currentAnimState == LS_TURN_LEFT_SLOW || LaraItem->currentAnimState == LS_TURN_RIGHT_SLOW);
}
break;
default:
@ -86,7 +86,7 @@ void Renderer11::updateLaraAnimations(bool force)
updateAnimation(item, laraObj, framePtr, frac, rate, mask);
// Then the arms, based on current weapon status
if (Lara.gunType != WEAPON_FLARE && (Lara.gunStatus == LG_NO_ARMS || Lara.gunStatus == LG_HANDS_BUSY) || Lara.gunType == WEAPON_FLARE && !Lara.flareControlLeft)
if (Lara.gunType != WEAPON_FLARE && (Lara.gunStatus == LG_HANDS_FREE || Lara.gunStatus == LG_HANDS_BUSY) || Lara.gunType == WEAPON_FLARE && !Lara.flareControlLeft)
{
// Both arms
mask = MESH_BITS(LM_LINARM) | MESH_BITS(LM_LOUTARM) | MESH_BITS(LM_LHAND) | MESH_BITS(LM_RINARM) | MESH_BITS(LM_ROUTARM) | MESH_BITS(LM_RHAND);

View file

@ -10,11 +10,12 @@ New custom animations which Lara can perform.
void GameScriptAnimations::Register(sol::state* lua)
{
lua->new_usertype<GameScriptAnimations>("Animations",
"crawlExtra", &GameScriptAnimations::CrawlExtra,
"crawlExtended", &GameScriptAnimations::CrawlExtended,
"crouchRoll", &GameScriptAnimations::CrouchRoll,
"monkeyRoll", &GameScriptAnimations::MonkeyRoll,
"monkeyVault", &GameScriptAnimations::MonkeyVault,
"oscillateHanging", &GameScriptAnimations::OscillateHanging,
"swandiveRollRun", &GameScriptAnimations::SwandiveRollRun
"crawlspaceSwandive", &GameScriptAnimations::CrawlspaceSwandive,
"monkeyTurn180", &GameScriptAnimations::MonkeyTurn180,
"monkeyAutoJump", &GameScriptAnimations::MonkeyAutoJump,
"oscillateHang", &GameScriptAnimations::OscillateHang,
"pose", &GameScriptAnimations::Pose
);
}

View file

@ -9,12 +9,13 @@ namespace sol {
struct GameScriptAnimations
{
bool CrawlExtended; // Extended crawl moveset
bool CrouchRoll; // Crouch roll
bool MonkeyRoll; // The 180 degrees roll on monkeybars
bool CrawlExtra; // All extra crawl moves
bool MonkeyVault; // Vault up to monkeybars when pressing up + action underneath them
bool SwandiveRollRun; // The transition from swandive roll to run
bool OscillateHanging; // The thin ledge grab animation from TR1 and 2
bool CrawlspaceSwandive; // Swandive into crawlspaces
bool MonkeyTurn180; // 180 degree turn on monkey swing
bool MonkeyAutoJump; // Auto jump to monkey swing when pressing UP + ACTION beneath
bool OscillateHang; // Grab thin ledge animation from TR1 and 2
bool Pose; // Crossed arms AFK posing
static void Register(sol::state* lua);
};

View file

@ -250,9 +250,9 @@ int S_UpdateInput()
if (Key(KEY_OPTION))
linput |= IN_OPTION;
if (Key(KEY_STEPL))
linput |= IN_WALK | IN_LEFT;
linput |= IN_LSTEP;
if (Key(KEY_STEPR))
linput |= IN_WALK | IN_RIGHT;
linput |= IN_RSTEP;
if (Key(KEY_PAUSE))
linput |= IN_PAUSE;
if (Key(KEY_SELECT))

View file

@ -187,6 +187,7 @@ enum INPUT_BUTTONS
};
#define IN_OPTIC_CONTROLS (IN_FORWARD | IN_BACK | IN_LEFT | IN_RIGHT | IN_ACTION | IN_SELECT | IN_DUCK | IN_SPRINT)
#define IN_WAKE (IN_FORWARD | IN_BACK | IN_LEFT | IN_RIGHT | IN_LSTEP | IN_RSTEP | IN_WALK | IN_JUMP | IN_SPRINT | IN_ROLL | IN_DUCK | IN_DRAW | IN_FLARE | IN_ACTION)
enum IKEYS
{

View file

@ -1389,8 +1389,11 @@ struct LaraT : public flatbuffers::NativeTable {
int32_t water_status = 0;
int32_t climb_status = 0;
int32_t pose_count = 0;
int32_t jump_count = 0;
bool jump_queued = false;
int32_t hit_frame = 0;
int32_t hit_direction = 0;
int32_t sprint_timer = 0;
int32_t air = 0;
int32_t dive_count = 0;
int32_t death_count = 0;
@ -1409,7 +1412,7 @@ struct LaraT : public flatbuffers::NativeTable {
int32_t flare_control_left = 0;
bool look = false;
bool burn = false;
bool keep_ducked = false;
bool keep_crouched = false;
bool is_moving = false;
bool can_monkey_swing = false;
int32_t burn_blue = 0;
@ -1506,104 +1509,107 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_WATER_STATUS = 22,
VT_CLIMB_STATUS = 24,
VT_POSE_COUNT = 26,
VT_HIT_FRAME = 28,
VT_HIT_DIRECTION = 30,
VT_AIR = 32,
VT_DIVE_COUNT = 34,
VT_DEATH_COUNT = 36,
VT_CURRENT_ACTIVE = 38,
VT_CURRENT_X_VEL = 40,
VT_CURRENT_Y_VEL = 42,
VT_CURRENT_Z_VEL = 44,
VT_SPAZ_EFFECT_COUNT = 46,
VT_FLARE_AGE = 48,
VT_BURN_COUNT = 50,
VT_WEAPON_ITEM = 52,
VT_HOLSTER_INFO = 54,
VT_FLARE_FRAME = 56,
VT_POISONED = 58,
VT_WET = 60,
VT_FLARE_CONTROL_LEFT = 62,
VT_LOOK = 64,
VT_BURN = 66,
VT_KEEP_DUCKED = 68,
VT_IS_MOVING = 70,
VT_CAN_MONKEY_SWING = 72,
VT_BURN_BLUE = 74,
VT_BURN_SMOKE = 76,
VT_IS_DUCKED = 78,
VT_HAS_FIRED = 80,
VT_BUSY = 82,
VT_OLD_BUSY = 84,
VT_UNCONTROLLABLE = 86,
VT_LIT_TORCH = 88,
VT_IS_CLIMBING = 90,
VT_FIRED = 92,
VT_WATER_SURFACE_DIST = 94,
VT_LAST_POSITION = 96,
VT_NEXT_CORNER_POSITION = 98,
VT_NEXT_CORNER_ROTATION = 100,
VT_MESH_PTRS = 102,
VT_TARGET_ANGLES = 104,
VT_TURN_RATE = 106,
VT_MOVE_ANGLE = 108,
VT_HEAD_X_ROT = 110,
VT_HEAD_Y_ROT = 112,
VT_HEAD_Z_ROT = 114,
VT_TORSO_X_ROT = 116,
VT_TORSO_Y_ROT = 118,
VT_TORSO_Z_ROT = 120,
VT_LEFT_ARM = 122,
VT_RIGHT_ARM = 124,
VT_ROPE_SEGMENT = 126,
VT_ROPE_DIRECTION = 128,
VT_ROPE_ARC_FRONT = 130,
VT_ROPE_ARC_BACK = 132,
VT_ROPE_LAST_X = 134,
VT_ROPE_MAX_X_FORWARD = 136,
VT_ROPE_MAX_X_BACKWARD = 138,
VT_ROPE_DFRAME = 140,
VT_ROPE_FRAME = 142,
VT_ROPE_FRAMERATE = 144,
VT_ROPE_Y = 146,
VT_ROPE_PTR = 148,
VT_INTERACTED_ITEM = 150,
VT_ROPE_OFFSET = 152,
VT_ROPE_DOWN_VEL = 154,
VT_ROPE_FLAG = 156,
VT_ROPE_COUNT = 158,
VT_MOVE_COUNT = 160,
VT_LOCATION = 162,
VT_HIGHEST_LOCATION = 164,
VT_LOCATION_PAD = 166,
VT_TIGHTROPE = 168,
VT_BEETLE_LIFE = 170,
VT_HAS_BEETLE_THINGS = 172,
VT_SMALL_WATERSKIN = 174,
VT_BIG_WATERSKIN = 176,
VT_VEHICLE = 178,
VT_EXTRA_ANIM = 180,
VT_MINE_L = 182,
VT_MINE_R = 184,
VT_WEAPONS = 186,
VT_PUZZLES = 188,
VT_KEYS = 190,
VT_PICKUPS = 192,
VT_EXAMINES = 194,
VT_PUZZLES_COMBO = 196,
VT_KEYS_COMBO = 198,
VT_PICKUPS_COMBO = 200,
VT_EXAMINES_COMBO = 202,
VT_SECRETS = 204,
VT_LASERSIGHT = 206,
VT_CROWBAR = 208,
VT_TORCH = 210,
VT_SILENCER = 212,
VT_BINOCULARS = 214,
VT_NUM_LARGE_MEDIPACKS = 216,
VT_NUM_SMALL_MEDIPACKS = 218,
VT_NUM_FLARES = 220,
VT_TARGET_ITEM_NUMBER = 222
VT_JUMP_COUNT = 28,
VT_JUMP_QUEUED = 30,
VT_HIT_FRAME = 32,
VT_HIT_DIRECTION = 34,
VT_SPRINT_TIMER = 36,
VT_AIR = 38,
VT_DIVE_COUNT = 40,
VT_DEATH_COUNT = 42,
VT_CURRENT_ACTIVE = 44,
VT_CURRENT_X_VEL = 46,
VT_CURRENT_Y_VEL = 48,
VT_CURRENT_Z_VEL = 50,
VT_SPAZ_EFFECT_COUNT = 52,
VT_FLARE_AGE = 54,
VT_BURN_COUNT = 56,
VT_WEAPON_ITEM = 58,
VT_HOLSTER_INFO = 60,
VT_FLARE_FRAME = 62,
VT_POISONED = 64,
VT_WET = 66,
VT_FLARE_CONTROL_LEFT = 68,
VT_LOOK = 70,
VT_BURN = 72,
VT_KEEP_CROUCHED = 74,
VT_IS_MOVING = 76,
VT_CAN_MONKEY_SWING = 78,
VT_BURN_BLUE = 80,
VT_BURN_SMOKE = 82,
VT_IS_DUCKED = 84,
VT_HAS_FIRED = 86,
VT_BUSY = 88,
VT_OLD_BUSY = 90,
VT_UNCONTROLLABLE = 92,
VT_LIT_TORCH = 94,
VT_IS_CLIMBING = 96,
VT_FIRED = 98,
VT_WATER_SURFACE_DIST = 100,
VT_LAST_POSITION = 102,
VT_NEXT_CORNER_POSITION = 104,
VT_NEXT_CORNER_ROTATION = 106,
VT_MESH_PTRS = 108,
VT_TARGET_ANGLES = 110,
VT_TURN_RATE = 112,
VT_MOVE_ANGLE = 114,
VT_HEAD_X_ROT = 116,
VT_HEAD_Y_ROT = 118,
VT_HEAD_Z_ROT = 120,
VT_TORSO_X_ROT = 122,
VT_TORSO_Y_ROT = 124,
VT_TORSO_Z_ROT = 126,
VT_LEFT_ARM = 128,
VT_RIGHT_ARM = 130,
VT_ROPE_SEGMENT = 132,
VT_ROPE_DIRECTION = 134,
VT_ROPE_ARC_FRONT = 136,
VT_ROPE_ARC_BACK = 138,
VT_ROPE_LAST_X = 140,
VT_ROPE_MAX_X_FORWARD = 142,
VT_ROPE_MAX_X_BACKWARD = 144,
VT_ROPE_DFRAME = 146,
VT_ROPE_FRAME = 148,
VT_ROPE_FRAMERATE = 150,
VT_ROPE_Y = 152,
VT_ROPE_PTR = 154,
VT_INTERACTED_ITEM = 156,
VT_ROPE_OFFSET = 158,
VT_ROPE_DOWN_VEL = 160,
VT_ROPE_FLAG = 162,
VT_ROPE_COUNT = 164,
VT_MOVE_COUNT = 166,
VT_LOCATION = 168,
VT_HIGHEST_LOCATION = 170,
VT_LOCATION_PAD = 172,
VT_TIGHTROPE = 174,
VT_BEETLE_LIFE = 176,
VT_HAS_BEETLE_THINGS = 178,
VT_SMALL_WATERSKIN = 180,
VT_BIG_WATERSKIN = 182,
VT_VEHICLE = 184,
VT_EXTRA_ANIM = 186,
VT_MINE_L = 188,
VT_MINE_R = 190,
VT_WEAPONS = 192,
VT_PUZZLES = 194,
VT_KEYS = 196,
VT_PICKUPS = 198,
VT_EXAMINES = 200,
VT_PUZZLES_COMBO = 202,
VT_KEYS_COMBO = 204,
VT_PICKUPS_COMBO = 206,
VT_EXAMINES_COMBO = 208,
VT_SECRETS = 210,
VT_LASERSIGHT = 212,
VT_CROWBAR = 214,
VT_TORCH = 216,
VT_SILENCER = 218,
VT_BINOCULARS = 220,
VT_NUM_LARGE_MEDIPACKS = 222,
VT_NUM_SMALL_MEDIPACKS = 224,
VT_NUM_FLARES = 226,
VT_TARGET_ITEM_NUMBER = 228
};
int32_t item_number() const {
return GetField<int32_t>(VT_ITEM_NUMBER, 0);
@ -1641,12 +1647,21 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t pose_count() const {
return GetField<int32_t>(VT_POSE_COUNT, 0);
}
int32_t jump_count() const {
return GetField<int32_t>(VT_JUMP_COUNT, 0);
}
bool jump_queued() const {
return GetField<uint8_t>(VT_JUMP_QUEUED, 0) != 0;
}
int32_t hit_frame() const {
return GetField<int32_t>(VT_HIT_FRAME, 0);
}
int32_t hit_direction() const {
return GetField<int32_t>(VT_HIT_DIRECTION, 0);
}
int32_t sprint_timer() const {
return GetField<int32_t>(VT_SPRINT_TIMER, 0);
}
int32_t air() const {
return GetField<int32_t>(VT_AIR, 0);
}
@ -1701,8 +1716,8 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool burn() const {
return GetField<uint8_t>(VT_BURN, 0) != 0;
}
bool keep_ducked() const {
return GetField<uint8_t>(VT_KEEP_DUCKED, 0) != 0;
bool keep_crouched() const {
return GetField<uint8_t>(VT_KEEP_CROUCHED, 0) != 0;
}
bool is_moving() const {
return GetField<uint8_t>(VT_IS_MOVING, 0) != 0;
@ -1949,8 +1964,11 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<int32_t>(verifier, VT_WATER_STATUS) &&
VerifyField<int32_t>(verifier, VT_CLIMB_STATUS) &&
VerifyField<int32_t>(verifier, VT_POSE_COUNT) &&
VerifyField<int32_t>(verifier, VT_JUMP_COUNT) &&
VerifyField<uint8_t>(verifier, VT_JUMP_QUEUED) &&
VerifyField<int32_t>(verifier, VT_HIT_FRAME) &&
VerifyField<int32_t>(verifier, VT_HIT_DIRECTION) &&
VerifyField<int32_t>(verifier, VT_SPRINT_TIMER) &&
VerifyField<int32_t>(verifier, VT_AIR) &&
VerifyField<int32_t>(verifier, VT_DIVE_COUNT) &&
VerifyField<int32_t>(verifier, VT_DEATH_COUNT) &&
@ -1971,7 +1989,7 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<int32_t>(verifier, VT_FLARE_CONTROL_LEFT) &&
VerifyField<uint8_t>(verifier, VT_LOOK) &&
VerifyField<uint8_t>(verifier, VT_BURN) &&
VerifyField<uint8_t>(verifier, VT_KEEP_DUCKED) &&
VerifyField<uint8_t>(verifier, VT_KEEP_CROUCHED) &&
VerifyField<uint8_t>(verifier, VT_IS_MOVING) &&
VerifyField<uint8_t>(verifier, VT_CAN_MONKEY_SWING) &&
VerifyField<int32_t>(verifier, VT_BURN_BLUE) &&
@ -2111,12 +2129,21 @@ struct LaraBuilder {
void add_pose_count(int32_t pose_count) {
fbb_.AddElement<int32_t>(Lara::VT_POSE_COUNT, pose_count, 0);
}
void add_jump_count(int32_t jump_count) {
fbb_.AddElement<int32_t>(Lara::VT_JUMP_COUNT, jump_count, 0);
}
void add_jump_queued(bool jump_queued) {
fbb_.AddElement<uint8_t>(Lara::VT_JUMP_QUEUED, static_cast<uint8_t>(jump_queued), 0);
}
void add_hit_frame(int32_t hit_frame) {
fbb_.AddElement<int32_t>(Lara::VT_HIT_FRAME, hit_frame, 0);
}
void add_hit_direction(int32_t hit_direction) {
fbb_.AddElement<int32_t>(Lara::VT_HIT_DIRECTION, hit_direction, 0);
}
void add_sprint_timer(int32_t sprint_timer) {
fbb_.AddElement<int32_t>(Lara::VT_SPRINT_TIMER, sprint_timer, 0);
}
void add_air(int32_t air) {
fbb_.AddElement<int32_t>(Lara::VT_AIR, air, 0);
}
@ -2171,8 +2198,8 @@ struct LaraBuilder {
void add_burn(bool burn) {
fbb_.AddElement<uint8_t>(Lara::VT_BURN, static_cast<uint8_t>(burn), 0);
}
void add_keep_ducked(bool keep_ducked) {
fbb_.AddElement<uint8_t>(Lara::VT_KEEP_DUCKED, static_cast<uint8_t>(keep_ducked), 0);
void add_keep_crouched(bool keep_crouched) {
fbb_.AddElement<uint8_t>(Lara::VT_KEEP_CROUCHED, static_cast<uint8_t>(keep_crouched), 0);
}
void add_is_moving(bool is_moving) {
fbb_.AddElement<uint8_t>(Lara::VT_IS_MOVING, static_cast<uint8_t>(is_moving), 0);
@ -2430,8 +2457,11 @@ inline flatbuffers::Offset<Lara> CreateLara(
int32_t water_status = 0,
int32_t climb_status = 0,
int32_t pose_count = 0,
int32_t jump_count = 0,
bool jump_queued = false,
int32_t hit_frame = 0,
int32_t hit_direction = 0,
int32_t sprint_timer = 0,
int32_t air = 0,
int32_t dive_count = 0,
int32_t death_count = 0,
@ -2450,7 +2480,7 @@ inline flatbuffers::Offset<Lara> CreateLara(
int32_t flare_control_left = 0,
bool look = false,
bool burn = false,
bool keep_ducked = false,
bool keep_crouched = false,
bool is_moving = false,
bool can_monkey_swing = false,
int32_t burn_blue = 0,
@ -2604,8 +2634,10 @@ inline flatbuffers::Offset<Lara> CreateLara(
builder_.add_death_count(death_count);
builder_.add_dive_count(dive_count);
builder_.add_air(air);
builder_.add_sprint_timer(sprint_timer);
builder_.add_hit_direction(hit_direction);
builder_.add_hit_frame(hit_frame);
builder_.add_jump_count(jump_count);
builder_.add_pose_count(pose_count);
builder_.add_climb_status(climb_status);
builder_.add_water_status(water_status);
@ -2636,9 +2668,10 @@ inline flatbuffers::Offset<Lara> CreateLara(
builder_.add_burn_smoke(burn_smoke);
builder_.add_can_monkey_swing(can_monkey_swing);
builder_.add_is_moving(is_moving);
builder_.add_keep_ducked(keep_ducked);
builder_.add_keep_crouched(keep_crouched);
builder_.add_burn(burn);
builder_.add_look(look);
builder_.add_jump_queued(jump_queued);
return builder_.Finish();
}
@ -2661,8 +2694,11 @@ inline flatbuffers::Offset<Lara> CreateLaraDirect(
int32_t water_status = 0,
int32_t climb_status = 0,
int32_t pose_count = 0,
int32_t jump_count = 0,
bool jump_queued = false,
int32_t hit_frame = 0,
int32_t hit_direction = 0,
int32_t sprint_timer = 0,
int32_t air = 0,
int32_t dive_count = 0,
int32_t death_count = 0,
@ -2681,7 +2717,7 @@ inline flatbuffers::Offset<Lara> CreateLaraDirect(
int32_t flare_control_left = 0,
bool look = false,
bool burn = false,
bool keep_ducked = false,
bool keep_crouched = false,
bool is_moving = false,
bool can_monkey_swing = false,
int32_t burn_blue = 0,
@ -2785,8 +2821,11 @@ inline flatbuffers::Offset<Lara> CreateLaraDirect(
water_status,
climb_status,
pose_count,
jump_count,
jump_queued,
hit_frame,
hit_direction,
sprint_timer,
air,
dive_count,
death_count,
@ -2805,7 +2844,7 @@ inline flatbuffers::Offset<Lara> CreateLaraDirect(
flare_control_left,
look,
burn,
keep_ducked,
keep_crouched,
is_moving,
can_monkey_swing,
burn_blue,
@ -5071,8 +5110,11 @@ inline void Lara::UnPackTo(LaraT *_o, const flatbuffers::resolver_function_t *_r
{ auto _e = water_status(); _o->water_status = _e; }
{ auto _e = climb_status(); _o->climb_status = _e; }
{ auto _e = pose_count(); _o->pose_count = _e; }
{ auto _e = jump_count(); _o->jump_count = _e; }
{ auto _e = jump_queued(); _o->jump_queued = _e; }
{ auto _e = hit_frame(); _o->hit_frame = _e; }
{ auto _e = hit_direction(); _o->hit_direction = _e; }
{ auto _e = sprint_timer(); _o->sprint_timer = _e; }
{ auto _e = air(); _o->air = _e; }
{ auto _e = dive_count(); _o->dive_count = _e; }
{ auto _e = death_count(); _o->death_count = _e; }
@ -5091,7 +5133,7 @@ inline void Lara::UnPackTo(LaraT *_o, const flatbuffers::resolver_function_t *_r
{ auto _e = flare_control_left(); _o->flare_control_left = _e; }
{ auto _e = look(); _o->look = _e; }
{ auto _e = burn(); _o->burn = _e; }
{ auto _e = keep_ducked(); _o->keep_ducked = _e; }
{ auto _e = keep_crouched(); _o->keep_crouched = _e; }
{ auto _e = is_moving(); _o->is_moving = _e; }
{ auto _e = can_monkey_swing(); _o->can_monkey_swing = _e; }
{ auto _e = burn_blue(); _o->burn_blue = _e; }
@ -5191,8 +5233,11 @@ inline flatbuffers::Offset<Lara> CreateLara(flatbuffers::FlatBufferBuilder &_fbb
auto _water_status = _o->water_status;
auto _climb_status = _o->climb_status;
auto _pose_count = _o->pose_count;
auto _jump_count = _o->jump_count;
auto _jump_queued = _o->jump_queued;
auto _hit_frame = _o->hit_frame;
auto _hit_direction = _o->hit_direction;
auto _sprint_timer = _o->sprint_timer;
auto _air = _o->air;
auto _dive_count = _o->dive_count;
auto _death_count = _o->death_count;
@ -5211,7 +5256,7 @@ inline flatbuffers::Offset<Lara> CreateLara(flatbuffers::FlatBufferBuilder &_fbb
auto _flare_control_left = _o->flare_control_left;
auto _look = _o->look;
auto _burn = _o->burn;
auto _keep_ducked = _o->keep_ducked;
auto _keep_crouched = _o->keep_crouched;
auto _is_moving = _o->is_moving;
auto _can_monkey_swing = _o->can_monkey_swing;
auto _burn_blue = _o->burn_blue;
@ -5303,8 +5348,11 @@ inline flatbuffers::Offset<Lara> CreateLara(flatbuffers::FlatBufferBuilder &_fbb
_water_status,
_climb_status,
_pose_count,
_jump_count,
_jump_queued,
_hit_frame,
_hit_direction,
_sprint_timer,
_air,
_dive_count,
_death_count,
@ -5323,7 +5371,7 @@ inline flatbuffers::Offset<Lara> CreateLara(flatbuffers::FlatBufferBuilder &_fbb
_flare_control_left,
_look,
_burn,
_keep_ducked,
_keep_crouched,
_is_moving,
_can_monkey_swing,
_burn_blue,

View file

@ -99,8 +99,11 @@ table Lara {
water_status: int32;
climb_status: int32;
pose_count: int32;
jump_count: int32;
jump_queued: bool;
hit_frame: int32;
hit_direction: int32;
sprint_timer: int32;
air: int32;
dive_count: int32;
death_count: int32;
@ -119,7 +122,7 @@ table Lara {
flare_control_left: int32;
look: bool;
burn: bool;
keep_ducked: bool;
keep_crouched: bool;
is_moving: bool;
can_monkey_swing: bool;
burn_blue: int32;

View file

@ -161,6 +161,8 @@ CALL gen.bat</Command>
<ClInclude Include="Game\effects\weather.h" />
<ClInclude Include="Game\floordata.h" />
<ClInclude Include="Game\effects\footprint.h" />
<ClInclude Include="Game\Lara\lara_helpers.h" />
<ClInclude Include="Game\Lara\lara_jump.h" />
<ClInclude Include="Game\roomvector.h" />
<ClInclude Include="Objects\Generic\Object\burning_torch.h" />
<ClInclude Include="Objects\Generic\Object\polerope.h" />
@ -560,7 +562,9 @@ CALL gen.bat</Command>
<ClCompile Include="Game\Lara\lara_collide.cpp" />
<ClCompile Include="Game\Lara\lara_crawl.cpp" />
<ClCompile Include="Game\Lara\lara_hang.cpp" />
<ClCompile Include="Game\Lara\lara_helpers.cpp" />
<ClCompile Include="Game\Lara\lara_initialise.cpp" />
<ClCompile Include="Game\Lara\lara_jump.cpp" />
<ClCompile Include="Game\Lara\lara_monkey.cpp" />
<ClCompile Include="Game\Lara\lara_objects.cpp" />
<ClCompile Include="Game\Lara\lara_slide.cpp" />

View file

@ -316,6 +316,8 @@
<ClCompile Include="Objects\Effects\enemy_missile.cpp" />
<ClCompile Include="Game\gui.cpp" />
<ClCompile Include="Game\effects\lara_fx.cpp" />
<ClCompile Include="Game\Lara\lara_helpers.cpp" />
<ClCompile Include="Game\Lara\lara_jump.cpp" />
<ClCompile Include="Scripting\GameScriptAnimations.cpp" />
</ItemGroup>
<ItemGroup>
@ -709,6 +711,8 @@
<ClInclude Include="Objects\TR5\Object\tr5_expandingplatform.h" />
<ClInclude Include="Game\gui.h" />
<ClInclude Include="Game\effects\lara_fx.h" />
<ClInclude Include="Game\Lara\lara_helpers.h" />
<ClInclude Include="Game\Lara\lara_jump.h" />
<ClInclude Include="Scripting\GameScriptAnimations.h" />
</ItemGroup>
<ItemGroup>