Cleanup, control code standardisation, some command-query separation, un-hardcoding of animation state dispatches, QOL improvements to Lara's basic moveset.

This commit is contained in:
Sezz 2020-09-26 03:28:30 +10:00
parent 856d11150a
commit 2ee7059470
33 changed files with 6256 additions and 4054 deletions

View file

@ -1,5 +1,5 @@
#include "framework.h"
#include "Lara.h"
#include "lara.h"
#include "lara_basic.h"
#include "lara_tests.h"
#include "lara_monkey.h"
@ -49,52 +49,58 @@ ITEM_INFO* LaraItem;
COLL_INFO lara_coll;
byte LaraNodeUnderwater[NUM_LARA_MESHES];
// For later.
bool EnableActionToggle;
bool EnableJumpUpAlign;
bool EnableClimbAssist;
bool EnableSafetyDrop;
function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
lara_as_walk,
lara_as_run,
lara_as_stop,
lara_as_forwardjump,
lara_as_walk_forward,//0
lara_as_run,//1
lara_as_stop,//2
lara_as_jump_forward,//3
lara_void_func,//4
lara_as_fastback,//5
lara_as_turn_r,//6
lara_as_turn_l,//7
lara_as_hop_back,//5
lara_as_turn_right,//6
lara_as_turn_left,//7
lara_as_death,//8
lara_as_fastfall,
lara_as_hang,
lara_as_reach,
lara_as_splat,
lara_as_tread,
lara_void_func,
lara_as_compress,//15
lara_as_back,//16
lara_as_swim,//17
lara_as_freefall,//9
lara_as_hang,//10
lara_as_reach,//11
lara_as_splat,//12
lara_as_underwater_stop,//13
lara_void_func,//14
lara_as_jump_prepare,//15
lara_as_walk_back,//16
lara_as_underwater_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_turn_right_fast,//20
lara_as_step_right,//21
lara_as_step_left,//22
lara_void_func,//23
lara_as_slide,//24
lara_as_backjump,//25
lara_as_rightjump,//26
lara_as_leftjump,//27
lara_as_upjump,//28
lara_as_fallback,//29
lara_as_hangleft,//30
lara_as_hangright,//31
lara_as_slideback,//32
lara_as_surftread,
lara_as_surfswim,
lara_as_dive,
lara_as_pushblock,//36
lara_as_pullblock,//37
lara_as_ppready,//38
lara_as_jump_back,//25
lara_as_jump_right,//26
lara_as_jump_left,//27
lara_as_jump_up,//28
lara_as_fall_back,//29
lara_as_shimmy_left,//30
lara_as_shimmy_right,//31
lara_as_slide_back,//32
lara_as_surftread,//33
lara_as_surfswim,//34
lara_as_dive,//35
lara_as_pushable_push,//36
lara_as_pushable_pull,//37
lara_as_pushable_ready,//38
lara_as_pickup,//39
lara_as_switchon,//40
lara_as_switchoff,//41
lara_as_usekey,//42
lara_as_usepuzzle,//43
lara_as_uwdeath,//44
lara_as_switch,//40
lara_as_switch,//41 //
lara_as_use_key,//42
lara_as_use_puzzle,//43
lara_as_underwater_death,//44
lara_void_func,//45
lara_as_special,//46
lara_as_surfback,//47
@ -102,8 +108,8 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
lara_as_surfright,//49
lara_void_func,//50
lara_void_func,//51
lara_as_swandive,//52
lara_as_fastdive,//53
lara_as_swandive_start,//52
lara_as_swandive_freefall,//53
lara_as_gymnast,//54
lara_as_waterout,
lara_as_climbstnc,
@ -111,37 +117,37 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
lara_as_climbleft,
lara_as_climbend,
lara_as_climbright,
lara_as_climbdown,//
lara_as_climbdown, //
lara_void_func,
lara_void_func,
lara_void_func,
lara_as_wade,//65
lara_as_waterroll,//66
lara_as_pickupflare,//67
lara_as_underwater_roll_180,//66
lara_as_pickup_flare,//67
lara_void_func,//68
lara_void_func,//69
lara_as_deathslide,//70
lara_as_duck,//71
lara_as_zipline,//70
lara_as_crouch,//71
lara_as_crouch_roll,//72
lara_as_dash,
lara_as_dashdive,
lara_as_sprint,
lara_as_sprint_roll,
lara_as_hang2,
lara_as_monkeyswing,
lara_as_monkeyl,
lara_as_monkeyr,
lara_as_monkey180,
lara_as_all4s,//80
lara_as_crawl,//81
lara_as_hangturnl,
lara_as_hangturnr,
lara_as_all4turnl,//84
lara_as_all4turnr,//85
lara_as_crawlb,//86
lara_as_crawl_stop,//80
lara_as_crawl_forward,//81
lara_as_hangturnl,//82
lara_as_hangturnr,//83
lara_as_crawl_turn_left,//84
lara_as_crawl_turn_right,//85
lara_as_crawl_back,//86
lara_as_null,
lara_as_null,
lara_as_controlled,
lara_as_ropel,
lara_as_roper,
lara_as_rope_turn_clockwise,
lara_as_rope_turn_counter_clockwise,
lara_as_controlled,
lara_as_controlled,
lara_as_controlled,
@ -152,34 +158,34 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
lara_as_null,//99
lara_as_null,//100
lara_as_null,//101
lara_as_poleleft,//102
lara_as_poleright,//103
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_extcornerl,//107
lara_as_extcornerr,//108
lara_as_intcornerl,//109
lara_as_intcornerr,//110
lara_as_rope,//111
lara_as_climbrope,//112
lara_as_climbroped,//113
lara_as_rope_up,//112
lara_as_rope_down,//113
lara_as_rope,//114
lara_as_rope,//115
lara_void_func,
lara_as_controlled,
lara_as_swimcheat,
lara_as_trpose,//119
lara_void_func,//116
lara_as_controlled,//117
lara_as_swim_cheat,//118
lara_as_tightrope_stop,//119
lara_as_null,//120
lara_as_trwalk,//121
lara_as_trfall,//122
lara_as_trfall,//123
lara_as_tightrope_walk,//121
lara_as_tightrope_fall,//122
lara_as_tightrope_fall,//123
lara_as_null,//124
lara_as_null,//125
lara_as_switchon,//126
lara_as_switch,//126
lara_as_null,//127
lara_as_parallelbars,//128
lara_as_pbleapoff,//129
lara_as_swing_bar,//128
lara_as_swing_bar_leap,//129
lara_as_null,//130
lara_as_null,//131
lara_as_null,//132
@ -190,53 +196,60 @@ function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
lara_as_null,//137
lara_as_null,//138
lara_as_hang_feet,//139
lara_as_hang_feet_shimmyr,//140
lara_as_hang_feet_shimmyl,//141
lara_as_hang_feet_inRcorner,//142
lara_as_hang_feet_inLcorner,//143
lara_as_hang_feet_outRcorner,//144
lara_as_hang_feet_outLcorner,//145
lara_as_shimmy_feet_right,//140
lara_as_shimmy_feet_left,//141
lara_as_hang_feet_right_corner_inner,//142
lara_as_hang_feet_left_corner_inner,//143
lara_as_hang_feet_right_corner_outer,//144
lara_as_hang_feet_left_corner_outer,//145
lara_as_controlledl,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_stepoff_left,
lara_as_stepoff_right
lara_as_stepoff_left,//150
lara_as_stepoff_right,
lara_as_steep_slide,
lara_as_steep_slide_back,
lara_as_slide_turn_180,
lara_as_jump_forward,
lara_as_turn_left_fast,//156
lara_as_null,//157
};
function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_walk,
lara_col_walk_forward,
lara_col_run,
lara_col_stop,
lara_col_forwardjump,
lara_col_jump_forward,
lara_col_pose,
lara_col_fastback,
lara_col_turn_r,
lara_col_turn_l,
lara_col_hop_back,
lara_col_turn_right,
lara_col_turn_left,
lara_col_death,
lara_col_fastfall,
lara_col_freefall,
lara_col_hang,
lara_col_reach,
lara_col_splat,
lara_col_tread,
lara_col_land,
lara_col_compress,
lara_col_back,
lara_col_swim,
lara_col_underwater_stop,
lara_col_stop,
lara_col_jump_prepare,
lara_col_walk_back,
lara_col_underwater_swim,
lara_col_glide,
lara_default_col,
lara_col_fastturn,
lara_col_stepright,
lara_col_stepleft,
lara_col_turn_right_fast,//20
lara_col_step_right,
lara_col_step_left,
lara_col_roll2,
lara_col_slide,
lara_col_backjump,
lara_col_rightjump,
lara_col_leftjump,
lara_col_upjump,
lara_col_fallback,
lara_col_hangleft,
lara_col_hangright,
lara_col_slideback,
lara_col_jump_back,
lara_col_jump_right,
lara_col_jump_left,
lara_col_jump_up,
lara_col_fall_back,
lara_col_shimmy_left,
lara_col_shimmy_right,
lara_col_slide_back,
lara_col_surftread,
lara_col_surfswim,
lara_col_dive,
@ -248,7 +261,7 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_uwdeath,
lara_col_underwater_death,
lara_col_roll,
lara_void_func,
lara_col_surfback,
@ -256,8 +269,8 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_surfright,
lara_void_func,
lara_void_func,
lara_col_swandive,
lara_col_fastdive,
lara_col_swandive_start,
lara_col_swandive_freefall,
lara_default_col,
lara_default_col,
lara_col_climbstnc,
@ -270,29 +283,29 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_col_wade,
lara_col_waterroll,
lara_col_underwater_roll_180,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_duck,
lara_col_crouch,
lara_col_crouch_roll,
lara_col_dash,
lara_col_dashdive,
lara_col_sprint,
lara_col_sprint_roll,
lara_col_hang2,
lara_col_monkeyswing,
lara_col_monkeyl,
lara_col_monkeyr,
lara_col_monkey180,
lara_col_all4s,
lara_col_crawl,
lara_col_crawl_stop,
lara_col_crawl_forward,
lara_col_hangturnlr,
lara_col_hangturnlr,
lara_col_all4turnlr,
lara_col_all4turnlr,
lara_col_crawlb,
lara_col_crawl_turn,
lara_col_crawl_turn,
lara_col_crawl_back,
lara_void_func,
lara_col_crawl2hang,
lara_col_crawl_to_hang,
lara_default_col,
lara_void_func,
lara_void_func,
@ -303,14 +316,14 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_polestat,
lara_col_poleup,
lara_col_poledown,
lara_col_pole_stop,
lara_col_pole_up,
lara_col_pole_down,
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_ducklr,
lara_col_ducklr,
lara_col_crouch_turn,
lara_col_crouch_turn,
lara_default_col,
lara_default_col,
lara_default_col,
@ -318,11 +331,11 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_col_rope,
lara_void_func,
lara_void_func,
lara_col_ropefwd,
lara_col_ropefwd,
lara_col_rope_swing,
lara_col_rope_swing,
lara_void_func,
lara_void_func,
lara_col_swim,
lara_col_underwater_swim,
lara_default_col,
lara_default_col,
lara_default_col,
@ -344,8 +357,8 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_col_hang_feet,
lara_col_hang_feet_shimmyr,
lara_col_hang_feet_shimmyl,
lara_col_shimmy_feet_right,
lara_col_shimmy_feet_right,
lara_default_col,
lara_default_col,
lara_default_col,
@ -354,8 +367,14 @@ function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
lara_void_func,
lara_void_func,
lara_void_func,
lara_default_col,//150
lara_default_col,//151
lara_default_col,
lara_default_col
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_turn_left_fast,//156
lara_default_col,//157
};
void LaraControl(short itemNumber) // (AF) (D)
@ -375,7 +394,9 @@ void LaraControl(short itemNumber) // (AF) (D)
}
if (!DisableLaraControl)
{
Lara.locationPad = 128;
}
int oldX = LaraItem->pos.xPos;
int oldY = LaraItem->pos.yPos;
@ -391,7 +412,9 @@ void LaraControl(short itemNumber) // (AF) (D)
}
if (item->currentAnimState != LS_SPRINT && DashTimer < 120)
{
DashTimer++;
}
Lara.isDucked = false;
@ -402,13 +425,19 @@ void LaraControl(short itemNumber) // (AF) (D)
int hfw;
if (wh != NO_HEIGHT)
{
hfw = item->pos.yPos - wh;
}
else
{
hfw = NO_HEIGHT;
}
Lara.waterSurfaceDist = -hfw;
if (Lara.Vehicle == NO_ITEM)
{
WadeSplash(item, wh, wd);
}
short roomNumber;
@ -430,8 +459,8 @@ void LaraControl(short itemNumber) // (AF) (D)
}
else if (isWater & ENV_FLAG_SWAMP)
{
if (item->currentAnimState == LS_SWANDIVE_START
|| item->currentAnimState == LS_SWANDIVE_END) // Is Lara swan-diving?
if (item->currentAnimState == LS_SWANDIVE_START ||
item->currentAnimState == LS_SWANDIVE_END) // Is Lara swan-diving?
item->pos.yPos = wh + 1000;
item->goalAnimState = LS_WADE_FORWARD;
@ -453,21 +482,21 @@ void LaraControl(short itemNumber) // (AF) (D)
if (item->currentAnimState == LS_SWANDIVE_START)
{
item->pos.xRot = -ANGLE(45);
item->pos.xRot = ANGLE(-45.0f);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else if (item->currentAnimState == LS_SWANDIVE_END)
{
item->pos.xRot = -ANGLE(85);
item->pos.xRot = ANGLE(-85.0f);
item->goalAnimState = LS_DIVE;
AnimateLara(item);
item->fallspeed *= 2;
}
else
{
item->pos.xRot = -ANGLE(45);
item->pos.xRot = ANGLE(-45.0f);
item->animNumber = LA_FREEFALL_DIVE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->currentAnimState = LS_DIVE;
@ -483,7 +512,7 @@ void LaraControl(short itemNumber) // (AF) (D)
Splash(LaraItem);
}
Camera.targetElevation = -ANGLE(22);
Camera.targetElevation = ANGLE(-22.0f);
if (hfw >= 256) /* @ORIGINAL_BUG: checking hfw for equality with 256 results in the wade bug */
{
if (hfw > 730)
@ -540,9 +569,11 @@ void LaraControl(short itemNumber) // (AF) (D)
LaraItem->roomNumber;
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == LS_WADE_FORWARD)
{
item->goalAnimState = LS_RUN_FORWARD;
}
}
}
break;
@ -711,8 +742,10 @@ void LaraControl(short itemNumber) // (AF) (D)
{
Lara.waterStatus = LW_ABOVE_WATER;
if (item->currentAnimState == LS_WADE_FORWARD)
{
item->goalAnimState = LS_RUN_FORWARD;
}
}
break;
}
}
@ -722,7 +755,9 @@ void LaraControl(short itemNumber) // (AF) (D)
item->hitPoints = -1;
if (Lara.deathCount == 0)
{
S_CDStop();
}
Lara.deathCount++;
if ((LaraItem->flags & 0x100))
@ -764,9 +799,11 @@ void LaraControl(short itemNumber) // (AF) (D)
{
Lara.air += 10;
if (Lara.air > 1800)
{
Lara.air = 1800;
}
}
}
LaraAboveWater(item, &lara_coll);
break;
@ -784,7 +821,9 @@ void LaraControl(short itemNumber) // (AF) (D)
if (Lara.air < 0)
{
if (LaraDrawType == LARA_DIVESUIT && Lara.anxiety < 251)
{
Lara.anxiety += 4;
}
Lara.air = -1;
item->hitPoints -= 5;
}
@ -797,8 +836,10 @@ void LaraControl(short itemNumber) // (AF) (D)
{
Lara.air += 10;
if (Lara.air > 1800)
{
Lara.air = 1800;
}
}
LaraSurface(item, &lara_coll);
break;
@ -830,9 +871,13 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll) //hmmmm
coll->trigger = NULL;
if ((TrInput & IN_LOOK) && Lara.ExtraAnim == NO_ITEM && Lara.look)
{
LookLeftRight();
}
else
{
ResetLook();
}
Lara.look = true;
@ -891,23 +936,36 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll) //hmmmm
// Handle current Lara status
lara_control_routines[item->currentAnimState](item, coll);
if (item->pos.zRot >= -ANGLE(1.0f) && item->pos.zRot <= ANGLE(1.0f))
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))
}
else if (item->pos.zRot < ANGLE(-1.0f))
{
item->pos.zRot += ANGLE(1.0f);
}
else
{
item->pos.zRot -= ANGLE(1.0f);
}
if (Lara.turnRate >= -ANGLE(2.0f) && Lara.turnRate <= ANGLE(2.0f))
if (Lara.turnRate >= ANGLE(-2.0f) && Lara.turnRate <= ANGLE(2.0f))
{
Lara.turnRate = 0;
else if (Lara.turnRate < -ANGLE(2.0f))
}
else if (Lara.turnRate < ANGLE(-2.0f))
{
Lara.turnRate += ANGLE(2.0f);
}
else
{
Lara.turnRate -= ANGLE(2.0f);
}
item->pos.yRot += Lara.turnRate;
// OLD
// Animate Lara
AnimateLara(item);
//AnimateLara(item);
if (Lara.ExtraAnim == -1)
{
@ -916,8 +974,13 @@ void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll) //hmmmm
// Handle Lara collision
if (Lara.Vehicle == NO_ITEM)
{
lara_collision_routines[item->currentAnimState](item, coll);
}
}
// Animate Lara after collision.
AnimateLara(item);
UpdateLaraRoom(item, -LARA_HITE / 2);
@ -952,9 +1015,13 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
coll->trigger = NULL;
if (TrInput & IN_LOOK && Lara.look)
{
LookLeftRight();
}
else
{
ResetLook();
}
Lara.look = true;
@ -962,7 +1029,7 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
if (LaraDrawType == LARA_DIVESUIT)
{
if (Lara.turnRate < -ANGLE(0.5))
if (Lara.turnRate < ANGLE(-0.5))
{
Lara.turnRate += ANGLE(0.5);
}
@ -975,13 +1042,13 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
Lara.turnRate = 0;
}
}
else if (Lara.turnRate < -ANGLE(2))
else if (Lara.turnRate < ANGLE(-2.0f))
{
Lara.turnRate += ANGLE(2);
Lara.turnRate += ANGLE(2.0f);
}
else if (Lara.turnRate > ANGLE(2))
else if (Lara.turnRate > ANGLE(2.0f))
{
Lara.turnRate -= ANGLE(2);
Lara.turnRate -= ANGLE(2.0f);
}
else
{
@ -991,37 +1058,59 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
item->pos.yRot += Lara.turnRate;
if (LaraDrawType == LARA_DIVESUIT)
{
UpdateSubsuitAngles();
}
if (item->pos.zRot < -ANGLE(2))
item->pos.zRot += ANGLE(2);
else if (item->pos.zRot > ANGLE(2))
item->pos.zRot -= ANGLE(2);
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 (item->pos.xRot < -ANGLE(85))
item->pos.xRot = -ANGLE(85);
else if (item->pos.xRot > ANGLE(85))
item->pos.xRot = ANGLE(85);
if (item->pos.xRot < ANGLE(-85.0f))
{
item->pos.xRot = ANGLE(-85.0f);
}
else if (item->pos.xRot > ANGLE(85.0f))
{
item->pos.xRot = ANGLE(85.0f);
}
if (LaraDrawType == LARA_DIVESUIT)
{
if (item->pos.zRot > ANGLE(44))
item->pos.zRot = ANGLE(44);
else if (item->pos.zRot < -ANGLE(44))
item->pos.zRot = -ANGLE(44);
if (item->pos.zRot > ANGLE(44.0f))
{
item->pos.zRot = ANGLE(44.0f);
}
else if (item->pos.zRot < ANGLE(44.0f))
{
item->pos.zRot = ANGLE(-44.0f);
}
}
else
{
if (item->pos.zRot > ANGLE(22))
item->pos.zRot = ANGLE(22);
else if (item->pos.zRot < -ANGLE(22))
item->pos.zRot = -ANGLE(22);
if (item->pos.zRot > ANGLE(22.0f))
{
item->pos.zRot = ANGLE(22.0f);
}
else if (item->pos.zRot < ANGLE(-22.0f))
{
item->pos.zRot = ANGLE(-22.0f);
}
}
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
{
LaraWaterCurrent(coll);
}
AnimateLara(item);
@ -1032,7 +1121,9 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
LaraBaddieCollision(item, coll);
if (/*Lara.ExtraAnim == -1 &&*/ Lara.Vehicle == NO_ITEM)
{
lara_collision_routines[item->currentAnimState](item, coll);
}
UpdateLaraRoom(item, 0);
@ -1043,7 +1134,7 @@ void LaraUnderWater(ITEM_INFO* item, COLL_INFO* coll)//4BFB4, 4C418 (F)
void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)//4D684, 4DAE8 (F)
{
Camera.targetElevation = -ANGLE(22);
Camera.targetElevation = ANGLE(-22.0f);
coll->badPos = 32512;
coll->badNeg = -128;
@ -1063,23 +1154,35 @@ void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)//4D684, 4DAE8 (F)
coll->trigger = NULL;
if (TrInput & IN_LOOK && Lara.look)
{
LookLeftRight();
}
else
{
ResetLook();
}
Lara.look = true;
lara_control_routines[item->currentAnimState](item, coll);
if (item->pos.zRot >= -ANGLE(2) && item->pos.zRot <= ANGLE(2))
if (item->pos.zRot >= ANGLE(-2.0f) && item->pos.zRot <= ANGLE(2.0f))
{
item->pos.zRot = 0;
}
else if (item->pos.zRot < 0)
item->pos.zRot += ANGLE(2);
{
item->pos.zRot += ANGLE(2.0f);
}
else
item->pos.zRot -= ANGLE(2);
{
item->pos.zRot -= ANGLE(2.0f);
}
if (Lara.currentActive && Lara.waterStatus != LW_FLYCHEAT)
{
LaraWaterCurrent(coll);
}
AnimateLara(item);
@ -1089,7 +1192,9 @@ void LaraSurface(ITEM_INFO* item, COLL_INFO* coll)//4D684, 4DAE8 (F)
LaraBaddieCollision(item, coll);
if (Lara.Vehicle == NO_ITEM)
{
lara_collision_routines[item->currentAnimState](item, coll);
}
UpdateLaraRoom(item, 100);
@ -1232,7 +1337,6 @@ void AnimateLara(ITEM_INFO* item)
default:
break;
}
}
}
@ -1253,10 +1357,14 @@ void AnimateLara(ITEM_INFO* item)
item->gravityStatus = false;
}
if (item->fallspeed > 128)
{
item->fallspeed >>= 1;
}
item->fallspeed -= item->fallspeed >> 2;
if (item->fallspeed < 4)
{
item->fallspeed = 4;
}
item->pos.yPos += item->fallspeed;
}
else
@ -1276,28 +1384,34 @@ void AnimateLara(ITEM_INFO* item)
{
velocity = (anim->velocity >> 1);
if (anim->acceleration)
{
velocity += (anim->acceleration * (item->frameNumber - anim->frameBase)) >> 2;
}
}
else
{
velocity = anim->velocity;
if (anim->acceleration)
{
velocity += anim->acceleration * (item->frameNumber - anim->frameBase);
}
}
item->speed = velocity >> 16;
}
if (Lara.ropePtr != -1)
{
DelAlignLaraToRope(item);
}
if (!Lara.isMoving) // TokyoSU: i dont know why but it's wreid, in TR3 only the 2 first line there is used and worked fine !
{
item->pos.xPos += item->speed * phd_sin(item->pos.yRot + Lara.moveAngle) >> W2V_SHIFT;
item->pos.zPos += item->speed * phd_cos(item->pos.yRot + Lara.moveAngle) >> W2V_SHIFT;
item->pos.xPos += lateral * phd_sin(item->pos.yRot + Lara.moveAngle + ANGLE(90)) >> W2V_SHIFT;
item->pos.zPos += lateral * phd_cos(item->pos.yRot + Lara.moveAngle + ANGLE(90)) >> W2V_SHIFT;
item->pos.xPos += lateral * phd_sin(item->pos.yRot + Lara.moveAngle + ANGLE(90.0f)) >> W2V_SHIFT;
item->pos.zPos += lateral * phd_cos(item->pos.yRot + Lara.moveAngle + ANGLE(90.0f)) >> W2V_SHIFT;
}
// Update matrices

View file

@ -20,6 +20,12 @@ extern ITEM_INFO* LaraItem;
extern COLL_INFO lara_coll;
extern byte LaraNodeUnderwater[NUM_LARA_MESHES];
// For later.
extern bool EnableActionToggle;
extern bool EnableJumpUpAlign;
extern bool EnableClimbAssist;
extern bool EnableSafetyDrop;
#define LARA_MESHES(slot, mesh) Lara.meshPtrs[mesh] = MESHES(slot, mesh)
#define CHECK_LARA_MESHES(slot, mesh) Lara.meshPtrs[mesh] == MESHES(slot, mesh)
#define INIT_LARA_MESHES(mesh, to, from) Lara.meshPtrs[mesh] = LARA_MESHES(to, mesh) = LARA_MESHES(from, mesh)

File diff suppressed because it is too large Load diff

View file

@ -1,71 +1,76 @@
#pragma once
#include "lara_struct.h"
/*generic functions*/
// Auxiliary functions.
bool TestLaraStepDown(COLL_INFO* coll);
bool TestLaraStepUp(COLL_INFO* coll);
void DoLaraStep(ITEM_INFO* item, COLL_INFO* coll);
// General control & collision functions.
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);
// Basic movement control & collision functions.
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(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_as_jump_forward(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_forward(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_hop_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hop_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_turn_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turn_left(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_freefall(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_freefall(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_as_jump_prepare(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_prepare(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_walk_back(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_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_as_jump_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_jump_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_jump_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_jump_up(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_jump_up(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_fall_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_fall_back(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_swandive_start(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_swandive_start(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swandive_freefall(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_swandive_freefall(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_sprint(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_sprint(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_sprint_roll(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_sprint_roll(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -7,34 +7,37 @@
#include "effect2.h"
#include "sound.h"
extern GameFlow* g_GameFlow;
int NoCheatCounter;
void lara_as_swimcheat(ITEM_INFO* item, COLL_INFO* coll)//4C3A8, 4C80C (F)
void lara_as_swim_cheat(ITEM_INFO* item, COLL_INFO* coll)//4C3A8, 4C80C (F)
{
if (TrInput & IN_FORWARD)
{
item->pos.xRot -= ANGLE(3);
item->pos.xRot -= ANGLE(3.0f);
}
else if (TrInput & IN_BACK)
{
item->pos.xRot += ANGLE(3);
item->pos.xRot += ANGLE(3.0f);
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= 613;
if (Lara.turnRate < -ANGLE(6))
Lara.turnRate = -ANGLE(6);
if (Lara.turnRate < ANGLE(-6.0f))
{
Lara.turnRate = ANGLE(-6.0f);
}
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += 613;
if (Lara.turnRate > ANGLE(6))
Lara.turnRate = ANGLE(6);
if (Lara.turnRate > ANGLE(6.0f))
{
Lara.turnRate = ANGLE(6.0f);
}
}
if (TrInput & IN_ACTION)
@ -44,7 +47,7 @@ void lara_as_swimcheat(ITEM_INFO* item, COLL_INFO* coll)//4C3A8, 4C80C (F)
if (TrInput & IN_OPTION)
{
Lara.turnRate = -ANGLE(12);
Lara.turnRate = ANGLE(-12.0f);
}
if (TrInput & IN_JUMP)
@ -52,15 +55,21 @@ void lara_as_swimcheat(ITEM_INFO* item, COLL_INFO* coll)//4C3A8, 4C80C (F)
item->fallspeed += 16;
if (item->fallspeed > 400)
{
item->fallspeed = 400;
}
}
else
{
if (item->fallspeed >= 8)
{
item->fallspeed -= item->fallspeed >> 3;
}
else
{
item->fallspeed = 0;
}
}
}
void LaraCheatyBits() // (F) (D)
@ -71,10 +80,9 @@ void LaraCheatyBits() // (F) (D)
{
if (Lara.Vehicle == NO_ITEM)
{
LaraCheatGetStuff();
DelsGiveLaraItemsCheat();
GiveLaraItemsCheat();
LaraItem->pos.yPos -= 128;
@ -105,7 +113,9 @@ void LaraCheatyBits() // (F) (D)
}
}
if (NoCheatCounter)
{
NoCheatCounter--;
}
}
void LaraCheatGetStuff() // (F) (D)
@ -115,10 +125,14 @@ void LaraCheatGetStuff() // (F) (D)
Lara.NumLargeMedipacks = -1;
if (Objects[ID_CROWBAR_ITEM].loaded)
{
Lara.Crowbar = true;
}
if (Objects[ID_LASERSIGHT_ITEM].loaded)
{
Lara.Lasersight = true;
}
if (Objects[ID_REVOLVER_ITEM].loaded)
{
@ -198,7 +212,7 @@ void LaraCheatGetStuff() // (F) (D)
g_Inventory.LoadObjects(false);
}
void DelsGiveLaraItemsCheat() // (AF) (D)
void GiveLaraItemsCheat() // (AF) (D)
{
int i;

View file

@ -1,7 +1,6 @@
#pragma once
void lara_as_swimcheat(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swim_cheat(ITEM_INFO* item, COLL_INFO* coll);
void LaraCheatyBits();
void LaraCheatGetStuff();
void DelsGiveLaraItemsCheat();
void GiveLaraItemsCheat();

View file

@ -8,6 +8,12 @@
#include "level.h"
#include "input.h"
// LADDER CLIMBING
// ------------------------------
// Auxiliary Functions
// ------------------------------
short LeftIntRightExtTab[4] = // offset 0xA0B7C
{
0x0800, 0x0100, 0x0200, 0x0400
@ -37,25 +43,106 @@ short GetClimbTrigger(int x, int y, int z, short roomNumber) // (F) (D)
return (*data & DATA_TYPE) == CLIMB_TYPE ? *data : 0;
}
void lara_col_climbend(ITEM_INFO* item, COLL_INFO* coll)//46E30(<), 47294(<) (F)
bool TestLaraLetGo(ITEM_INFO* item)
{
return;
if (((TrInput & IN_ACTION && !EnableActionToggle) ||
(!(TrInput & IN_ACTION) && EnableActionToggle)) && // TODO: Instead, check if button has been RELEASED.
item->hitPoints > 0)
{
return false;
}
return true;
}
void SetLaraLetGo(ITEM_INFO* item, COLL_INFO* coll)
{
item->gravityStatus = false;
item->fallspeed = 0;
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
Lara.gunStatus = LG_NO_ARMS;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->speed = 2;
item->gravityStatus = true;
item->fallspeed = 1;
coll->trigger = TriggerIndex;
}
// TODO: delete.
int LaraCheckForLetGo(ITEM_INFO* item, COLL_INFO* coll)//45434, 45898 (F)
{
short roomNumber = item->roomNumber;
item->gravityStatus = false;
item->fallspeed = 0;
GetFloorHeight(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos);
coll->trigger = TriggerIndex;
if (TrInput & IN_ACTION && item->hitPoints > 0)
return 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->speed = 2;
item->gravityStatus = true;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
return 1;
}
// ------------------------------
// LADDER CLIMBING
// State & Collision Functions
// ------------------------------
void lara_as_climbend(ITEM_INFO* item, COLL_INFO* coll)//46DF8(<), 4725C(<) (F)
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.flags = CF_FOLLOW_CENTER;
Camera.targetAngle = -ANGLE(45);
Camera.targetAngle = ANGLE(-45.0f);
}
void lara_col_climbend(ITEM_INFO* item, COLL_INFO* coll)//46E30(<), 47294(<) (F)
{
return;
}
void lara_col_climbdown(ITEM_INFO* item, COLL_INFO* coll)//46BD0, 47034 (F)
{
if (LaraCheckForLetGo(item, coll)
|| item->animNumber != LA_LADDER_DOWN)
if (TestLaraLetGo(item) || item->animNumber != LA_LADDER_DOWN)
{
SetLaraLetGo(item, coll);
return;
}
int frame = item->frameNumber - g_Level.Anims[LA_LADDER_DOWN].frameBase;
int xShift;
@ -214,10 +301,10 @@ void lara_col_climbing(ITEM_INFO* item, COLL_INFO* coll)//469B0, 46E14 (F)
void lara_as_climbing(ITEM_INFO* item, COLL_INFO* coll)//46984(<), 46DE8(<) (F)
{
Camera.targetElevation = ANGLE(30.0f);
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetElevation = ANGLE(30);
}
void lara_col_climbright(ITEM_INFO* item, COLL_INFO* coll)//46908(<), 46D6C(<) (F)
@ -235,8 +322,8 @@ void lara_as_climbright(ITEM_INFO* item, COLL_INFO* coll)//468B8(<), 46D1C(<) (F
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = ANGLE(30);
Camera.targetElevation = -ANGLE(15);
Camera.targetAngle = ANGLE(30.0f);
Camera.targetElevation = ANGLE(-15.0f);
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
item->goalAnimState = LS_LADDER_IDLE;
@ -247,7 +334,7 @@ void lara_col_climbleft(ITEM_INFO* item, COLL_INFO* coll)//46834(<), 46C98(<) (F
if (!LaraCheckForLetGo(item, coll))
{
int shift = 0;
Lara.moveAngle = -ANGLE(90);
Lara.moveAngle = ANGLE(90.0f);
LaraDoClimbLeftRight(item, coll, LaraTestClimbPos(item, coll->radius, -(coll->radius + 120), -512, 512, &shift), shift);
}
}
@ -257,8 +344,8 @@ void lara_as_climbleft(ITEM_INFO* item, COLL_INFO* coll)//467E4(<), 46C48(<) (F)
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = -ANGLE(30);
Camera.targetElevation = -ANGLE(15);
Camera.targetAngle = ANGLE(30.0f);
Camera.targetElevation = ANGLE(15.0f);
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
item->goalAnimState = LS_LADDER_IDLE;
@ -277,10 +364,14 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
if (!(TrInput & IN_FORWARD))
{
if (!(TrInput & IN_BACK))
{
return;
}
if (item->goalAnimState == LS_HANG)
{
return;
}
item->goalAnimState = LS_LADDER_IDLE;
item->pos.yPos += 256;
@ -291,17 +382,23 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
item->pos.yPos -= 256;
if (!resultRight || !resultLeft || resultLeft == -2 || resultRight == -2)
{
return;
}
yShift = ledgeLeft;
if (ledgeRight && ledgeLeft)
{
if (ledgeLeft < 0 != ledgeRight < 0)
{
return;
}
if (ledgeRight < 0 == ledgeRight < ledgeLeft)
{
yShift = ledgeRight;
}
}
if (resultRight == 1 && resultLeft == 1)
{
@ -320,7 +417,9 @@ void lara_col_climbstnc(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
resultLeft = LaraTestClimbUpPos(item, coll->radius, -120 - coll->radius, &shiftLeft, &ledgeLeft);
if (!resultRight || !resultLeft)
{
return;
}
if (resultRight >= 0 && resultLeft >= 0)
{
@ -367,12 +466,16 @@ void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll)//463F0, 46854 (F)
coll->enableSpaz = false;
coll->enableBaddiePush = false;
Camera.targetElevation = -ANGLE(20);
Camera.targetElevation = ANGLE(-20.0f);
if (item->animNumber == LA_LADDER_DISMOUNT_LEFT_START)
Camera.targetAngle = -ANGLE(60.0f);
{
Camera.targetAngle = ANGLE(-60.0f);
}
if (item->animNumber == LA_LADDER_DISMOUNT_RIGHT_START)
{
Camera.targetAngle = ANGLE(60.0f);
}
if (TrInput & IN_LOOK)
{
@ -382,12 +485,12 @@ void lara_as_climbstnc(ITEM_INFO* item, COLL_INFO* coll)//463F0, 46854 (F)
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
item->goalAnimState = LS_LADDER_LEFT;
Lara.moveAngle = -ANGLE(90);
Lara.moveAngle = ANGLE(-90.0f);
}
else if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
item->goalAnimState = LS_LADDER_RIGHT;
Lara.moveAngle = ANGLE(90);
Lara.moveAngle = ANGLE(90.0f);
}
else if (TrInput & IN_JUMP)
{
@ -405,8 +508,8 @@ void lara_as_stepoff_left(ITEM_INFO* item, COLL_INFO* coll)
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = -ANGLE(60.0f);
Camera.targetElevation = -ANGLE(15.0f);
Camera.targetAngle = ANGLE(-60.0f);
Camera.targetElevation = ANGLE(-15.0f);
item->pos.yRot -= ANGLE(90.0f);
}
@ -417,7 +520,7 @@ void lara_as_stepoff_right(ITEM_INFO* item, COLL_INFO* coll)
coll->enableSpaz = false;
Camera.targetAngle = ANGLE(60.0f);
Camera.targetElevation = -ANGLE(15.0f);
Camera.targetElevation = ANGLE(-15.0f);
item->pos.yRot += ANGLE(90.0f);
}
@ -626,7 +729,7 @@ int LaraClimbRightCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45DE4, 46248
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
item->pos.yRot += ANGLE(90);
item->pos.yRot += ANGLE(90.0f);
Lara.moveAngle = 0;
result = LaraTestClimbPos(item, coll->radius, coll->radius + 120, -512, 512, &shift);
@ -672,7 +775,7 @@ int LaraClimbRightCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45DE4, 46248
Lara.cornerX = newX;
item->pos.zPos = newZ;
Lara.cornerZ = newZ;
item->pos.yRot -= ANGLE(90);
item->pos.yRot -= ANGLE(90.0f);
Lara.moveAngle = 0;
result = LaraTestClimbPos(item, coll->radius, coll->radius + 120, -512, 512, &shift) != 0;
}
@ -724,7 +827,7 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45ABC, 45F20
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
item->pos.yRot -= ANGLE(90);
item->pos.yRot -= ANGLE(90.0f);
Lara.moveAngle = 0;
result = LaraTestClimbPos(item, coll->radius, -coll->radius - 120, -512, 512, &shift);
@ -771,7 +874,7 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45ABC, 45F20
Lara.cornerX = newX;
item->pos.zPos = newZ;
Lara.cornerZ = newZ;
item->pos.yRot += ANGLE(90);
item->pos.yRot += ANGLE(90.0f);
Lara.moveAngle = 0;
item->itemFlags[3] = LaraTestClimbPos(item, coll->radius, -coll->radius - 120, -512, 512, &shift);
result = item->itemFlags[3] != 0;
@ -792,7 +895,6 @@ int LaraClimbLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll)//45ABC, 45F20
int LaraTestClimb(int x, int y, int z, int xFront, int zFront, int itemHeight, int itemRoom, int* shift)//457F0, 45C54
{
*shift = 0;
int hang = 1;
if (!Lara.climbStatus)
@ -986,38 +1088,3 @@ int LaraTestClimbUpPos(ITEM_INFO* item, int front, int right, int* shift, int* l
return -2;
}
int LaraCheckForLetGo(ITEM_INFO* item, COLL_INFO* coll)//45434, 45898 (F)
{
short roomNumber = item->roomNumber;
item->gravityStatus = false;
item->fallspeed = 0;
GetFloorHeight(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos);
coll->trigger = TriggerIndex;
if (TrInput & IN_ACTION && item->hitPoints > 0)
return 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.headYrot = 0;
Lara.headXrot = 0;
item->goalAnimState = LS_JUMP_FORWARD;
item->currentAnimState = LS_JUMP_FORWARD;
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->speed = 2;
item->gravityStatus = true;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
return 1;
}

View file

@ -4,9 +4,53 @@
#include "draw.h"
#include "effect2.h"
/*this file has all the generic **collision** test functions called in lara's state code*/
// Generic collision test functions
int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
bool TestLaraWallDeflect(COLL_INFO* coll)
{
if (coll->collType == CT_FRONT ||
coll->collType == CT_TOP_FRONT ||
coll->collType == CT_LEFT ||
coll->collType == CT_RIGHT)
{
return true;
}
return false;
}
// TODO: For statics?
void SetLaraWallDeflect(ITEM_INFO* item, COLL_INFO* coll)
{
switch (coll->collType)
{
case CT_FRONT:
case CT_TOP_FRONT:
{
ShiftItem(item, coll);
item->goalAnimState = LS_STOP;
item->speed = 0;
item->gravityStatus = false;
break;
}
case CT_LEFT:
{
ShiftItem(item, coll);
item->pos.yRot += ANGLE(5.0f);
break;
}
case CT_RIGHT:
{
ShiftItem(item, coll);
item->pos.yRot -= ANGLE(5.0f);
break;
}
}
}
// Legacy function.
bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
{
@ -16,7 +60,7 @@ int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
item->speed = 0;
item->gravityStatus = false;
return 1;
return true;
}
if (coll->collType == CT_LEFT)
@ -30,7 +74,7 @@ int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
item->pos.yRot -= ANGLE(5.0f);
}
return 0;
return false;
}
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
@ -49,7 +93,6 @@ void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
{
item->goalAnimState = LS_GRAB_TO_FALL;
item->currentAnimState = LS_GRAB_TO_FALL;
item->animNumber = LA_JUMP_UP_LAND;
item->frameNumber = g_Level.Anims[LA_JUMP_UP_LAND].frameBase;
}
@ -58,7 +101,6 @@ void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
{
item->goalAnimState = LS_FREEFALL;
item->currentAnimState = LS_FREEFALL;
item->animNumber = LA_JUMP_WALL_SMASH_START;
item->frameNumber = g_Level.Anims[LA_JUMP_WALL_SMASH_START].frameBase + 1;
}
@ -67,8 +109,10 @@ void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
Lara.moveAngle += ANGLE(180);
if (item->fallspeed <= 0)
{
item->fallspeed = 1;
}
}
break;
case CT_TOP:
@ -96,33 +140,35 @@ void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
}
}
int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
bool TestLaraHitCeiling(COLL_INFO* coll)
{
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
if (coll->collType == CT_TOP ||
coll->collType == CT_CLAMP)
{
ShiftItem(item, coll);
item->gravityStatus = false;
item->speed = 0;
return 1;
return true;
}
if (coll->collType == CT_LEFT)
{
ShiftItem(item, coll);
item->pos.yRot += ANGLE(2.0f);
}
else if (coll->collType == CT_RIGHT)
{
ShiftItem(item, coll);
item->pos.yRot -= ANGLE(2.0f);
}
return 0;
return false;
}
int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
// TODO: Better handling of collision with ceiling when on ground. This function should become obsolete.
void SetLaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll)
{
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
/*item->goalAnimState = LS_STOP;
item->currentAnimState = LS_STOP;
item->animNumber = LA_STAND_SOLID;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;*/
item->speed = 0;
item->fallspeed = 0;// -item->fallspeed;
}
// Legacy function.
bool LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (coll->collType == CT_TOP || coll->collType == CT_CLAMP)
{
@ -140,9 +186,9 @@ int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
item->fallspeed = 0;
item->gravityStatus = false;
return 1;
return true;
}
return 0;
return false;
}
void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)//126F0(<), 127A0(<) (F)
@ -152,7 +198,8 @@ void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)//126F0(<), 127A0(<) (F)
case LS_STOP:
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->oldAnimState;
item->animNumber = coll->oldAnimNumber;
item->frameNumber = coll->oldFrameNumber;

View file

@ -1,11 +1,15 @@
#pragma once
#include "lara_struct.h"
int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll);
bool LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll);
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll);
int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll);
int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll);
bool LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll);
void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll);
void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle);
short GetDirOctant(int rot);
void GetLaraDeadlyBounds();
bool TestLaraWallDeflect(COLL_INFO* coll);
void SetLaraWallDeflect(ITEM_INFO* item, COLL_INFO* coll);
bool TestLaraHitCeiling(COLL_INFO* coll);
void SetLaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll);

File diff suppressed because it is too large Load diff

View file

@ -1,25 +1,30 @@
#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);
// Auxiliary functions.
bool TestLaraKeepCrouched(ITEM_INFO* player, COLL_INFO* coll);
bool TestLaraCrawl(ITEM_INFO* player);
bool TestLaraCrouchTurn(ITEM_INFO* player);
bool TestLaraCrouchRoll(ITEM_INFO* player);
void SetLaraCrawlWallDeflect(ITEM_INFO* item, COLL_INFO* coll);
// Crouching control & collision functions.
void lara_as_crouch(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crouch(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);
// Crawling control & collision functions.
void lara_as_crawl_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_stop(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_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(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_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(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_crawl_to_hang(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -227,7 +227,8 @@ short HoldStates[] = {
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,
@ -841,7 +842,7 @@ void find_target_point(ITEM_INFO* item, GAME_VECTOR* target) // (F) (D)
bounds = (BOUNDING_BOX*)GetBestFrame(item);
x = (int)(bounds->X1 + bounds->X2) / 2;
y = (int) bounds->Y1 + (bounds->Y2 - bounds->Y1) / 3;
y = (int)bounds->Y1 + (bounds->Y2 - bounds->Y1) / 3;
z = (int)(bounds->Z1 + bounds->Z2) / 2;
c = phd_cos(item->pos.yRot);
s = phd_sin(item->pos.yRot);
@ -942,7 +943,7 @@ void LaraGetNewTarget(WEAPON_INFO* weapon) // (F) (D)
GAME_VECTOR src, target;
PHD_VECTOR muzzleOffset;
int bestDistance, maxDistance, targets, slot, x, y, z, distance;
ITEM_INFO* bestItem, *item;
ITEM_INFO* bestItem, * item;
short bestYrot, angle[2], match;
bool flag, loop;
@ -1567,7 +1568,7 @@ void DoProperDetection(short itemNumber, int x, int y, int z, int xv, int yv, in
HOLSTER_SLOT HolsterSlotForWeapon(LARA_WEAPON_TYPE weapon)
{
switch(weapon){
switch (weapon) {
case WEAPON_PISTOLS:
return HOLSTER_SLOT::Pistols;
case WEAPON_UZI:

View file

@ -12,27 +12,24 @@
#include "effect2.h"
#include "chaffFX.h"
constexpr std::array<float, 28> FlareFlickerTable = { 0.7590,0.9880,0.8790,0.920,0.8020,0.7610,0.97878,0.8978,0.9983,0.934763,0.8485,0.762573,0.84642,0.7896,0.817634,0.923424,0.7589,0.81399,0.92834,0.9978,0.7610,0.97878,0.8978,0.9983,0.934763,0.8485,0.762573,0.74642 };
constexpr DirectX::SimpleMath::Vector3 FlareMainColor = Vector3(1,0.52947, 0.3921);
constexpr std::array<float, 28> FlareFlickerTableLow = { 0.7590,0.1880,0.0790,0.920,0.8020,0.07610,0.197878,0.38978,0.09983,0.00934763,0.8485,0.0762573,0.84642,0.7896,0.517634,0.0923424,0.7589,0.081399,0.92834,0.01978,0.17610,0.497878,0.8978,0.69983,0.934763,0.28485,0.1762573,0.374642 };
void FlareControl(short itemNumber) // (AF) (D)
void FlareControl(short itemNum) // (AF) (D)
{
ITEM_INFO* item = &g_Level.Items[itemNumber];
ITEM_INFO* item = &g_Level.Items[itemNum];
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
KillItem(itemNumber);
KillItem(itemNum);
return;
}
if (item->fallspeed)
{
item->pos.xRot += ANGLE(3);
item->pos.zRot += ANGLE(5);
item->pos.xRot += ANGLE(3.0f);
item->pos.zRot += ANGLE(5.0f);
}
else
{
@ -50,25 +47,26 @@ void FlareControl(short itemNumber) // (AF) (D)
item->pos.xPos += xv;
item->pos.zPos += zv;
if (g_Level.Rooms[item->roomNumber].flags & ENV_FLAG_WATER)
{
item->fallspeed += (5 - item->fallspeed) / 2;
item->speed += (5 - item->speed) / 2;
}
else
{
item->fallspeed += 6;
}
item->pos.yPos += item->fallspeed;
DoProperDetection(itemNumber, oldX, oldY, oldZ, xv, item->fallspeed, zv);
DoProperDetection(itemNum, oldX, oldY, oldZ, xv, item->fallspeed, zv);
short age = (short)(item->data) & 0x7FFF;
if (age >= 900)
{
if (!item->fallspeed && !item->speed)
{
KillItem(itemNumber);
KillItem(itemNum);
return;
}
}
@ -327,7 +325,7 @@ void CreateFlare(short objectNum, int thrown) // (F) (D)
if (collided || GetFloorHeight(floor, pos.x, pos.y, pos.z) < pos.y)
{
flag = true;
item->pos.yRot = LaraItem->pos.yRot + ANGLE(180);
item->pos.yRot = LaraItem->pos.yRot + ANGLE(180.0f);
item->pos.xPos = LaraItem->pos.xPos + (320 * phd_sin(item->pos.yRot) >> W2V_SHIFT);
item->pos.zPos = LaraItem->pos.zPos + (320 * phd_cos(item->pos.yRot) >> W2V_SHIFT);
item->roomNumber = LaraItem->roomNumber;
@ -335,9 +333,14 @@ void CreateFlare(short objectNum, int thrown) // (F) (D)
else
{
if (thrown)
{
item->pos.yRot = LaraItem->pos.yRot;
}
else
item->pos.yRot = LaraItem->pos.yRot - ANGLE(45);
{
item->pos.yRot = LaraItem->pos.yRot - ANGLE(45.0f);
}
item->roomNumber = roomNumber;
}
@ -359,15 +362,21 @@ void CreateFlare(short objectNum, int thrown) // (F) (D)
}
if (flag)
{
item->speed >>= 1;
}
if (objectNum == ID_FLARE_ITEM)
{
if (DoFlareLight((PHD_VECTOR*)&item->pos, Lara.flareAge))
{
item->data = (void*)(Lara.flareAge | 0x8000);
}
else
{
item->data = (void*)(Lara.flareAge & 0x7FFF);
}
}
else
{
item->itemFlags[3] = Lara.litTorch;
@ -393,7 +402,9 @@ void DoFlareInHand(int flare_age) // (AF) (D)
GetLaraJointPosition(&pos, LM_LHAND);
if (DoFlareLight(&pos, flare_age))
{
TriggerChaffEffects(flare_age);
}
/* Hardcoded code */
@ -415,7 +426,10 @@ int DoFlareLight(PHD_VECTOR* pos, int age)//49708, 49B6C (F)
float random;
int falloff;
if (age >= 900 || age == 0)
{
return 0;
}
random = frand();
x = pos->x + (random* 120);
@ -431,6 +445,7 @@ int DoFlareLight(PHD_VECTOR* pos, int age)//49708, 49B6C (F)
b = FlareMainColor.z * 255;
TriggerDynamicLight(x, y, z, falloff, r, g, b);
return (random < 0.9f);
}
else if (age < 810)
@ -442,6 +457,7 @@ int DoFlareLight(PHD_VECTOR* pos, int age)//49708, 49B6C (F)
g = FlareMainColor.y * 255 * multiplier;
b = FlareMainColor.z * 255 * multiplier;
TriggerDynamicLight(x, y, z, falloff, r, g, b);
return (random < 0.4f);
}
else
@ -453,8 +469,7 @@ int DoFlareLight(PHD_VECTOR* pos, int age)//49708, 49B6C (F)
g = FlareMainColor.y * 255 * multiplier;
b = FlareMainColor.z * 255 * multiplier;
TriggerDynamicLight(x, y, z, falloff, r, g, b);
return (random < .3f);
}
}

View file

@ -3,15 +3,24 @@
#include "input.h"
#include "lara_tests.h"
/*this file has all the lara_as/lara_col functions related to hanging*/
// HANGING
/*normal hanging and shimmying*/
// ------------------------------
// HANGING AND SHIMMYING
// Control & Collision Functions
// ------------------------------
// State: 10
// Collision: lara_col_hang()
void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll)//19A28, 19B5C (F)
{
/*state 10*/
/*collision: lara_col_hang*/
Camera.targetAngle = 0;
Camera.targetElevation = ANGLE(-45.0f);
Lara.isClimbing = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
@ -19,19 +28,15 @@ void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll)//19A28, 19B5C (F)
}
if (TrInput & IN_LOOK)
{
LookUpDown();
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
}
}
// State: 10
// State code: lara_as_hang()
void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
{
/*state 10*/
/*state code: lara_as_hang*/
item->fallspeed = 0;
item->gravityStatus = false;
@ -41,10 +46,9 @@ void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
if (CanLaraHangSideways(item, coll, -ANGLE(90.0f)))
if (CanLaraHangSideways(item, coll, ANGLE(-90.0f)))
{
item->goalAnimState = LS_SHIMMY_LEFT;
return;
}
@ -52,9 +56,13 @@ void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
if (flag != 0)
{
if (flag <= 0)
{
item->goalAnimState = LS_SHIMMY_INNER_LEFT;
}
else
{
item->goalAnimState = LS_SHIMMY_OUTER_LEFT;
}
return;
}
@ -65,7 +73,6 @@ void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
if (CanLaraHangSideways(item, coll, ANGLE(90.0f)))
{
item->goalAnimState = LS_SHIMMY_RIGHT;
return;
}
@ -73,9 +80,13 @@ void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
if (flag != 0)
{
if (flag <= 0)
{
item->goalAnimState = LS_SHIMMY_INNER_RIGHT;
}
else
{
item->goalAnimState = LS_SHIMMY_OUTER_RIGHT;
}
return;
}
@ -174,127 +185,137 @@ void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
}
}
void lara_as_hangleft(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
// State: 30
// Collision: lara_col_hang_left()
void lara_as_shimmy_left(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
/*state 30*/
/*collision: lara_col_hangleft*/
Camera.targetAngle = 0;
Camera.targetElevation = ANGLE(-45.0f);
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
item->goalAnimState = LS_SHIMMY_LEFT;
return;
}
item->goalAnimState = LS_HANG;
}
// State: 30
// State code: lara_as_hang_left()
void lara_col_shimmy_left(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
Lara.moveAngle = ANGLE(-90.0f);
coll->radius = LARA_RAD; /* @ORIGINAL_BUG: original value, 102, can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
LaraHangTest(item, coll);
Lara.moveAngle = ANGLE(-90.0f);
}
// State: 31
// Collision: lara_col_shimmy_right()
void lara_as_shimmy_right(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
Camera.targetElevation = ANGLE(-45.0f);
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
item->goalAnimState = LS_SHIMMY_RIGHT;
return;
}
item->goalAnimState = LS_HANG;
}
void lara_col_hangleft(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
// State: 31
// State code: lara_as_shimmy_right()
void lara_col_shimmy_right(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
/*state 30*/
/*state code: lara_as_hangleft*/
Lara.moveAngle = -ANGLE(90);
coll->radius = 102; /* @ORIGINAL_BUG: this value (instead of LARA_RAD) can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
Lara.moveAngle = ANGLE(90.0f);
coll->radius = LARA_RAD; /* @ORIGINAL_BUG: original value, 102, can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
LaraHangTest(item, coll);
Lara.moveAngle = -ANGLE(90);
Lara.moveAngle = ANGLE(90.0f);
}
void lara_as_hangright(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
/*state 31*/
/*collision: lara_col_hangright*/
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
item->goalAnimState = LS_HANG;
}
void lara_col_hangright(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
/*state 31*/
/*state code: lara_as_hangright*/
Lara.moveAngle = ANGLE(90);
coll->radius = 102; /* @ORIGINAL_BUG: this value (instead of LARA_RAD) can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
LaraHangTest(item, coll);
Lara.moveAngle = ANGLE(90);
}
/*go around corners*/
// ------------------------------
// SHIMMYING AROUND CORNERS
// Control & Collision Functions
// ------------------------------
// State: 107
// Collision: lara_default_col()
void lara_as_extcornerl(ITEM_INFO* item, COLL_INFO* coll)//1A1F0(<), 1A324(<) (F)
{
/*state 107*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, ANGLE(90.0f),
item->animNumber == LA_SHIMMY_LEFT_CORNER_OUTER_END ||
item->animNumber == LA_LADDER_LEFT_CORNER_OUTER_END);
}
// State: 108
// Collision: lara_default_col()
void lara_as_extcornerr(ITEM_INFO* item, COLL_INFO* coll)//1A244(<), 1A378(<) (F)
{
/*state 108*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, -ANGLE(90.0f),
item->animNumber == LA_SHIMMY_RIGHT_CORNER_OUTER_END ||
item->animNumber == LA_LADDER_RIGHT_CORNER_OUTER_END);
}
// State: 109
// Collision: lara_default_col()
void lara_as_intcornerl(ITEM_INFO* item, COLL_INFO* coll)//1A298(<), 1A3CC(<) (F)
{
/*state 109*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, -ANGLE(90.0f),
item->animNumber == LA_SHIMMY_LEFT_CORNER_INNER_END ||
item->animNumber == LA_LADDER_LEFT_CORNER_INNER_END);
}
// State: 110
// Collision: lara_default_col()
void lara_as_intcornerr(ITEM_INFO* item, COLL_INFO* coll)//1A2EC(<), 1A420(<) (F)
{
/*state 110*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, ANGLE(90.0f),
item->animNumber == LA_SHIMMY_RIGHT_CORNER_INNER_END ||
item->animNumber == LA_LADDER_RIGHT_CORNER_INNER_END);
}
/*feet hanging and shimmying
////obviously, not all animations were made yet, we still need:
// ------------------------------
// HANGING AND SHIMMYING BY FEET
// Control & Collision Functions
// ------------------------------
/*obviously, not all animations were made yet, we still need:
-crouch pull up(works well, tested with placeholder anim)
-corner anims(works well, tested with placeholder anims)
-handstand(not tested)*/
// State: 139
// Collision: lara_col_hang_feet()
void lara_as_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 139*/
/*collision: lara_col_hang_feet*/
Lara.isClimbing = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_STOP;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
lara_as_hang(item, coll);
}
// State: 139
// Collision: lara_as_hang_feet()
void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 139*/
/*state code: lara_as_hang_feet*/
item->fallspeed = 0;
item->gravityStatus = false;
@ -303,7 +324,9 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
LaraHangTest(item, coll);
if (!(TrInput & IN_ACTION))
{
item->goalAnimState = LS_JUMP_UP;
}
if (item->animNumber == LA_HANG_FEET_IDLE)
{
@ -316,6 +339,7 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
item->goalAnimState = LS_SHIMMY_FEET_LEFT;
return;
}
flag = LaraHangLeftCornerTest(item, coll);
if (flag != 0)
{
@ -328,7 +352,6 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
}
if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
if (CanLaraHangSideways(item, coll, ANGLE(90.0f)))
@ -337,6 +360,7 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
return;
}
flag = LaraHangRightCornerTest(item, coll);
if (flag != 0)
{
@ -348,7 +372,6 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
}
}
TestForObjectOnLedge(item, coll);
if (TrInput & IN_FORWARD)
{
@ -378,6 +401,7 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
}
}
}
if (coll->frontFloor < -650 &&
coll->frontFloor - coll->frontCeiling >= -256 &&
coll->frontFloor - coll->leftCeiling2 >= -256 &&
@ -387,6 +411,7 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
{
item->goalAnimState = LS_HANG_TO_CRAWL;
item->requiredAnimState = LS_CROUCH_IDLE;
return;
}
}
@ -412,97 +437,120 @@ void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
}*///commenting till daniel makes anims
Lara.moveAngle = 0;
LaraHangTest(item, coll);
}
}
void lara_as_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll)
// State: 140
// Collision: lara_col_hang_feet_shimmy_right()
void lara_as_shimmy_feet_right(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 140*/
/*collision: lara_col_hang_feet_shimmyr*/
Camera.targetAngle = 0;
Camera.targetElevation = ANGLE(-45.0f);
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
item->goalAnimState = LS_SHIMMY_FEET_RIGHT;
return;
}
item->goalAnimState = LS_HANG_FEET;
}
void lara_col_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll)
// State: 140
// State code: lara_as_hang_feet_shimmy_right()
void lara_col_shimmy_feet_right(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 140*/
/*state code: lara_as_hang_feet_shimmyr*/
Lara.moveAngle = ANGLE(90);
coll->radius = LARA_RAD;
LaraHangTest(item, coll);
Lara.moveAngle = ANGLE(90);
lara_col_shimmy_right(item, coll);
}
void lara_as_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll)
// State: 141
// Collision: lara_as_hang_feet_shimmy_left()
void lara_as_shimmy_feet_left(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 141*/
/*collision: lara_col_hang_feet_shimmyl*/
Camera.targetAngle = 0;
Camera.targetElevation = ANGLE(-45.0f);
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
Camera.targetElevation = -ANGLE(45.0f);
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
item->goalAnimState = LS_SHIMMY_FEET_LEFT;
return;
}
item->goalAnimState = LS_HANG_FEET;
}
void lara_col_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll)
// State: 141
// State code: lara_as_hang_feet_shimmy_left()
void lara_col_shimmy_feet_left(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 141*/
/*state code: lara_as_hang_feet_shimmyl*/
Lara.moveAngle = -ANGLE(90);
coll->radius = LARA_RAD;
LaraHangTest(item, coll);
Lara.moveAngle = -ANGLE(90);
lara_col_shimmy_left(item, coll);
}
/*go around corners feet*/
// ------------------------------
// SHIMMYING BY FEET AROUND CORNERS
// Control & Collision Functions
// ------------------------------
void lara_as_hang_feet_inRcorner(ITEM_INFO* item, COLL_INFO* coll)
// State 142
// Collision: lara_default_col()
void lara_as_hang_feet_right_corner_inner(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 142*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
if (item->frameNumber == g_Level.Anims[LA_SHIMMY_FEET_RIGHT_CORNER_INNER].frameEnd) // I don't like this either but it's better than adding 4 new 1 frame anims?
{
SetCornerAnimFeet(item, coll, ANGLE(90.0f),
item->animNumber = LA_SHIMMY_FEET_RIGHT_CORNER_INNER);
}
}
void lara_as_hang_feet_inLcorner(ITEM_INFO* item, COLL_INFO* coll)
// State 143
// Collision: lara_default_col()
void lara_as_hang_feet_left_corner_inner(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 143*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
if (item->frameNumber == g_Level.Anims[LA_SHIMMY_FEET_LEFT_CORNER_INNER].frameEnd)
{
SetCornerAnimFeet(item, coll, -ANGLE(90.0f),
item->animNumber = LA_SHIMMY_FEET_LEFT_CORNER_INNER);
}
}
void lara_as_hang_feet_outRcorner(ITEM_INFO* item, COLL_INFO* coll)
// State 144
// Collision: lara_default_col()
void lara_as_hang_feet_right_corner_outer(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 144*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
if (item->frameNumber == g_Level.Anims[LA_SHIMMY_FEET_RIGHT_CORNER_OUTER].frameEnd)
{
SetCornerAnimFeet(item, coll, -ANGLE(90.0f),
item->animNumber = LA_SHIMMY_FEET_RIGHT_CORNER_OUTER);
}
}
void lara_as_hang_feet_outLcorner(ITEM_INFO* item, COLL_INFO* coll)
// State 145
// Collision: lara_default_col()
void lara_as_hang_feet_left_corner_outer(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 145*/
/*collision: lara_default_col*/
Camera.laraNode = 8;
Camera.targetElevation = ANGLE(33.0f);
if (item->frameNumber == g_Level.Anims[LA_SHIMMY_FEET_LEFT_CORNER_OUTER].frameEnd)
{
SetCornerAnimFeet(item, coll, ANGLE(90.0f),
item->animNumber = LA_SHIMMY_FEET_LEFT_CORNER_OUTER);
}
}

View file

@ -1,27 +1,30 @@
#pragma once
#include "lara_struct.h"
/*normal hanging and shimmying*/
// Hanging and shimmying control & collision functions.
void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll);
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);
/*go around corners*/
void lara_as_shimmy_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_shimmy_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_shimmy_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_shimmy_right(ITEM_INFO* item, COLL_INFO* coll);
// Shimmying around corners control & collision functions.
void lara_as_extcornerl(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_extcornerr(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_intcornerl(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_intcornerr(ITEM_INFO* item, COLL_INFO* coll);
/*feet hanging and shimmying*/
// Hanging and shimmying by feet control & collision functions.
void lara_as_hang_feet(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll);
/*go around corners feet*/
void lara_as_hang_feet_inRcorner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_inLcorner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_outRcorner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_outLcorner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_shimmy_feet_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_shimmy_feet_right(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_shimmy_feet_left(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_shimmy_feet_left(ITEM_INFO* item, COLL_INFO* coll);
// Shimmying by feet around corners control & collision functions.
void lara_as_hang_feet_right_corner_inner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_left_corner_inner(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_right_corner_outer(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_hang_feet_left_corner_outer(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -149,7 +149,7 @@ void InitialiseLaraAnims(ITEM_INFO* item) // (F) (D)
Lara.waterStatus = LW_ABOVE_WATER;
item->goalAnimState = LS_STOP;
item->currentAnimState = LS_STOP;
item->animNumber = LA_STAND_SOLID;
item->animNumber = LA_STAND_IDLE;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,61 +1,50 @@
#pragma once
#include "lara_struct.h"
/*pickups*/
// Pickup control functions.
void lara_as_pickup(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pickupflare(ITEM_INFO* item, COLL_INFO* coll);
/*end pickups*/
/*-*/
/*switches*/
void lara_as_switchon(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_switchoff(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pickup_flare(ITEM_INFO* item, COLL_INFO* coll);
// Switch control & collision functions.
void lara_as_switch(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_turnswitch(ITEM_INFO* item, COLL_INFO* coll);
/*end switches*/
/*-*/
/*puzzles and keys*/
void lara_as_usekey(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_usepuzzle(ITEM_INFO* item, COLL_INFO* coll);
/*end puzzles and keys*/
/*-*/
/*pushables*/
void lara_as_pushblock(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pullblock(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_ppready(ITEM_INFO* item, COLL_INFO* coll);
/*end pushables*/
/*-*/
/*pulley*/
// Puzzle & key control functions.
void lara_as_use_key(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_use_puzzle(ITEM_INFO* item, COLL_INFO* coll);
// Pushable state functions.
void lara_as_pushable_push(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pushable_pull(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pushable_ready(ITEM_INFO* item, COLL_INFO* coll);
// Pulley control function.
void lara_as_pulley(ITEM_INFO* item, COLL_INFO* coll);
/*end pulley*/
/*-*/
/*parallel bars*/
void lara_as_parallelbars(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pbleapoff(ITEM_INFO* item, COLL_INFO* coll);
/*end parallel bars*/
/*-*/
/*tightropes*/
void lara_as_trpose(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_trwalk(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_trfall(ITEM_INFO* item, COLL_INFO* coll);
/*end tightropes*/
/*-*/
/*ropes*/
void lara_as_ropel(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_roper(ITEM_INFO* item, COLL_INFO* coll);
// Swingbar control functions.
void lara_as_swing_bar(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_swing_bar_leap(ITEM_INFO* item, COLL_INFO* coll);
// Tightrope control functions.
void lara_as_tightrope_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_tightrope_walk(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_tightrope_fall(ITEM_INFO* item, COLL_INFO* coll);
// Rope control & collision functions.
void lara_as_rope_turn_clockwise(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rope_turn_counter_clockwise(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rope(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_rope(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_ropefwd(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_climbrope(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_climbroped(ITEM_INFO* item, COLL_INFO* coll);
/*end ropes*/
/*-*/
/*poles*/
void lara_col_polestat(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_poleup(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_poledown(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_poleleft(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_poleright(ITEM_INFO* item, COLL_INFO* coll);
/*end poles*/
/*-*/
/*deathslide*/
void lara_as_deathslide(ITEM_INFO* item, COLL_INFO* coll);
/*end deathslide*/
void lara_col_rope_swing(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rope_up(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_rope_down(ITEM_INFO* item, COLL_INFO* coll);
// Pole control & collision functions.
void lara_col_pole_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_pole_up(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_pole_down(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pole_turn_clockwise(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_pole_turn_counter_clockwise(ITEM_INFO* item, COLL_INFO* coll);
// Zipline control functions.
void lara_as_zipline(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -1,15 +1,113 @@
#include "framework.h"
#include "lara.h"
#include "lara_collide.h"
#include "lara_tests.h"
#include "input.h"
#include "sound.h"
//#include "lara_slide.h"
short OldAngle = 1;
int OldAngle = 1; // Don't care. To be deleted.
/*this file has all the related functions to sliding*/
// For later.
bool EnableAugmentedSlide; // Adds steep sliding, slope hugging, 180 turn.
bool EnableNonCardinalSlide; // Slides Lara in true slope direction.
bool EnableSlideInterpolation; // Adapts Lara angles to slope.
bool EnableSlideSteering; // Allows player influence on slide trajectory.
/*tests and others*/
int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
// SLOPE SLIDING
// ------------------------------
// Auxiliary functions
// ------------------------------
bool TestLaraSlide(COLL_INFO* coll)
{
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
{
return false;
}
return true;
}
short GetLaraSlideDirection(COLL_INFO* coll)
{
short laraAngle = ANGLE(0.0f);
//if (EnableNonCardinalSlide)
//{
// // TODO: Get true slope direction.
//}
//else
//{
if (coll->tiltX > 2)
{
laraAngle = -ANGLE(90.0f);
}
else if (coll->tiltX < -2)
{
laraAngle = ANGLE(90.0f);
}
if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX))
{
laraAngle = ANGLE(180.0f);
}
else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX))
{
laraAngle = ANGLE(0.0f);
}
//}
return laraAngle;
}
int GetSlopeAngle(COLL_INFO* coll)
{
return 1;
}
void SetLaraSlide(ITEM_INFO* item, COLL_INFO* coll)
{
short dir = GetLaraSlideDirection(coll);
short polarity = dir - item->pos.yRot;
ShiftItem(item, coll);
// Slide back.
if (polarity < ANGLE(-90.0f) || polarity > ANGLE(90.0f))
{
if (GetSlopeAngle(coll) < ANGLE(60.0f))//SLOPE_ANGLE_STEEP)
{
Lara.moveAngle = ANGLE(180);
item->goalAnimState = LS_SLIDE_BACK;
item->pos.yRot = dir + ANGLE(180.0f);
}
else
{
item->goalAnimState = LS_SLIDE_STEEP_BACK;
item->pos.yRot = dir + ANGLE(180.0f);
}
}
// Slide forward.
else
{
if (GetSlopeAngle(coll) < ANGLE(60.0f))//SLOPE_ANGLE_STEEP)
{
Lara.moveAngle = 0;
item->goalAnimState = LS_SLIDE_FORWARD;
item->pos.yRot = dir;
}
else
{
item->goalAnimState = LS_SLIDE_STEEP_FORWARD;
item->pos.yRot = dir;
}
}
}
// LEGACY. Staying until everything is done.
int Old_TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
return 0;
@ -59,64 +157,12 @@ int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
return 1;
}
void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll)//127BC, 1286C (F)
void PerformLaraSlide(ITEM_INFO* item, COLL_INFO* coll)//127BC, 1286C (F)
{
coll->badPos = NO_BAD_POS;
coll->badNeg = -512;
coll->badCeiling = 0;
coll->facing = Lara.moveAngle;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
if (!LaraHitCeiling(item, coll))
{
LaraDeflectEdge(item, coll);
if (coll->midFloor <= 200)
{
TestLaraSlide(item, coll);
item->pos.yPos += coll->midFloor;
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
{
if (TrInput & IN_FORWARD && item->currentAnimState != LS_SLIDE_BACK)
{
item->goalAnimState = LS_RUN_FORWARD;
}
else
item->goalAnimState = LS_STOP;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
else
{
if (item->currentAnimState == LS_SLIDE_FORWARD)
{
item->animNumber = LA_FALL_START;
item->frameNumber = g_Level.Anims[LA_FALL_START].frameBase;
item->currentAnimState = LS_JUMP_FORWARD;
item->goalAnimState = LS_JUMP_FORWARD;
}
else
{
item->animNumber = LA_FALL_BACK;
item->frameNumber = g_Level.Anims[LA_FALL_BACK].frameBase;
item->currentAnimState = LS_FALL_BACK;
item->goalAnimState = LS_FALL_BACK;
}
StopSoundEffect(SFX_LARA_SLIPPING);
item->gravityStatus = true;
item->fallspeed = 0;
}
}
}
void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F)
void PerformLaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F)
{
ShiftItem(item, coll);
@ -150,41 +196,245 @@ void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F)
break;
}
}
/*end tests and others*/
/*-*/
/*Lara state code*/
void lara_as_slide(ITEM_INFO* item, COLL_INFO* coll)//1A824(<), 1A958(<) (F)
// ------------------------------
// SLOPE SLIDING
// Control & Collision Functions
// ------------------------------
// State: 24
// Collision: lara_col_Slide()
void lara_as_slide(ITEM_INFO* player, COLL_INFO* coll)//1A824(<), 1A958(<) (F)
{
/*state 24*/
/*collision: lara_col_slide*/
Camera.targetElevation = -ANGLE(45.0f); // FIXED
if ((TrInput & IN_JUMP) && !(TrInput & IN_BACK))
item->goalAnimState = LS_JUMP_FORWARD;
Camera.targetElevation = player->pos.xRot - ANGLE(45.0f);
/*if (TrInput & IN_LEFT)
{
player->pos.yRot -= ANGLE(2.0f);
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_FAST_TURN)
{
Lara.turnRate = -LARA_FAST_TURN;
}
if (TestLaraLean(coll) & EnableSlideSteering)
{
player->pos.zRot -= LARA_LEAN_RATE;
if (player->pos.zRot < -LARA_LEAN_MAX)
{
player->pos.zRot = -LARA_LEAN_MAX;
}
}
}
else if (TrInput & IN_RIGHT)
{
player->pos.yRot += ANGLE(2.0f);
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_FAST_TURN)
{
Lara.turnRate = LARA_FAST_TURN;
}
if (TestLaraLean(coll) && EnableSlideSteering)
{
player->pos.zRot += LARA_LEAN_RATE;
if (player->pos.zRot > LARA_LEAN_MAX)
{
player->pos.zRot = LARA_LEAN_MAX;
}
}
}*/
if ((TrInput & IN_BACK) || (TrInput & IN_DUCK))
{
player->goalAnimState = LS_SLIDE_STEEP_FORWARD;
}
if (TrInput & IN_JUMP)
{
player->goalAnimState = LS_JUMP_FORWARD;
}
if (TrInput & IN_ROLL)
{
player->goalAnimState = LS_SLIDE_TURN_180;
//SetLaraSlide(item, coll); // Temp: Lara slides up the slope otherwise.
}
}
void lara_col_slide(ITEM_INFO* item, COLL_INFO* coll)//1C108(<), 1C23C(<) (F)
{
/*state 24*/
/*state code: lara_as_slide*/
Lara.moveAngle = 0;
lara_slide_slope(item, coll);
Lara.moveAngle = ANGLE(0.0f);
coll->badPos = NO_BAD_POS;
coll->badNeg = -512;
coll->badCeiling = 0;
coll->facing = Lara.moveAngle;
if (TestLaraHitCeiling(coll))
{
SetLaraHitCeiling(item, coll);
return;
}
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
LaraDeflectEdge(item, coll);
if (coll->midFloor <= 200)
{
item->pos.yPos += coll->midFloor;
if (!TestLaraSlide(coll))
{
item->goalAnimState = (TrInput & IN_FORWARD) ? LS_RUN_FORWARD : LS_STOP;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
else
{
if (TrInput & IN_ACTION && coll->midFloor >= 1024 && EnableSafetyDrop)
{
item->goalAnimState = LS_SAFE_DROP;
}
else
{
item->goalAnimState = LS_FALL;
}
item->gravityStatus = true;
item->fallspeed = 0;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
void lara_as_slideback(ITEM_INFO* item, COLL_INFO* coll)//1A9E0(<), 1AB14(<) (F)
// State: 32
// Collision: lara_col_SlideBack()
void lara_as_slide_back(ITEM_INFO* item, COLL_INFO* coll)//1A9E0(<), 1AB14(<) (F)
{
/*state 32*/
/*collision: lara_col_slideback*/
if ((TrInput & IN_JUMP) && !(TrInput & IN_FORWARD))
Camera.targetElevation = item->pos.xRot;
//if (TrInput & IN_FORWARD)
// item->goalAnimState = LS_SLIDE_STEEP_BACK;
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_JUMP_BACK;
}
/*if (TrInput & IN_ROLL)
{
item->pos.yRot += ANGLE(180.0f);
item->goalAnimState = LS_SLIDE_FORWARD;
SetLaraSlide(item, coll);
}*/
}
void lara_col_slide_back(ITEM_INFO* item, COLL_INFO* coll)//1C284(<), 1C3B8(<) (F)
{
Lara.moveAngle = ANGLE(180.0f);
coll->badPos = NO_BAD_POS;
coll->badNeg = -512;
coll->badCeiling = 0;
coll->facing = Lara.moveAngle;
if (TestLaraHitCeiling(coll))
{
SetLaraHitCeiling(item, coll);
return;
}
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
LaraDeflectEdge(item, coll);
if (coll->midFloor <= 200)
{
item->pos.yPos += coll->midFloor;
if (!TestLaraSlide(coll))
{
item->goalAnimState = LS_STOP;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
else
{
if (TrInput & IN_ACTION && coll->midFloor >= 1024 && EnableSafetyDrop)
{
item->goalAnimState = LS_SAFE_DROP;
}
else
{
item->goalAnimState = LS_FALL_BACK;
}
item->gravityStatus = true;
item->fallspeed = 0;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
// TODO: Unique handling for steep slopes. Anims on the way.
void lara_as_steep_slide(ITEM_INFO* item, COLL_INFO* coll)
{
if (item->pos.xRot >= ANGLE(60))
{
Camera.targetElevation = ANGLE(-60.0f);
}
else
{
Camera.targetElevation = ANGLE(-45.0f);
}
if (TrInput & IN_FORWARD)
{
item->goalAnimState = LS_SLIDE_FORWARD;
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_JUMP_FORWARD;
}
}
void lara_col_steep_slide(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.moveAngle = ANGLE(0.0f);
PerformLaraSlide(item, coll);
}
void lara_as_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.targetElevation = ANGLE(-60.0f);
if (TrInput & IN_BACK)
{
item->goalAnimState = LS_SLIDE_BACK;
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_JUMP_BACK;
}
}
void lara_col_slideback(ITEM_INFO* item, COLL_INFO* coll)//1C284(<), 1C3B8(<) (F)
void lara_col_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll)
{
/*state 32*/
/*state code: lara_as_slideback*/
Lara.moveAngle = ANGLE(180);
lara_slide_slope(item, coll);
Lara.moveAngle = ANGLE(180.0f);
PerformLaraSlide(item, coll);
}
/*end Lara state code*/
void lara_as_slide_turn_180(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.moveAngle = ANGLE(0.0f);
}
// TODO: Straddling illegal slopes.
// TODO: Grabbing edge of plateau leading to steep slope.

View file

@ -1,15 +1,25 @@
#pragma once
#include "lara_struct.h"
/*Tests and others*/
int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll);
void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll);
/*end tests and others*/
/*-*/
/*Lara state code*/
#define SLOPE_ANGLE_NORMAL ANGLE(30.0f)
#define SLOPE_ANGLE_STEEP ANGLE(60.0f)
// Auxiliary functions.
bool TestLaraSlide(COLL_INFO* coll);
float GetLaraSlideDirection(COLL_INFO* coll);
void SetLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
void PerformLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
void PerformLaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll);
int Old_TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll);
// Sliding control & collision functions.
void lara_as_slide(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_slide(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_slideback(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_slideback(ITEM_INFO* item, COLL_INFO* coll);
/*end Lara state code*/
void lara_as_slide_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_slide_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_steep_slide(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_steep_slide(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_steep_slide_back(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_slide_turn_180(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -35,7 +35,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,
@ -178,6 +178,15 @@ enum LARA_STATE
LS_LADDER_DISMOUNT_LEFT = 150,
LS_LADDER_DISMOUNT_RIGHT = 151,
LS_SLIDE_STEEP_FORWARD = 152,
LS_SLIDE_STEEP_BACK = 153,
LS_SLIDE_TURN_180 = 154,
LS_FALL = 155, // This is needed if we are to have a fall anim dispatch from slide states, as LS_JUMP_FORWARD is already used to leap off.
LS_TURN_LEFT_FAST = 156,
LS_SAFE_DROP = 157,
/*LS_POLE_UP = 158,
LS_POLE_DOWN = 159,*/ // I broke poles, sorry. :/ I'll get to it later. -Sezz
NUM_LARA_STATES
};
@ -721,6 +730,34 @@ enum LARA_ANIM
LA_LADDER_DISMOUNT_RIGHT_END = 500, // Ladder dismount right (2/2)
LA_ONWATER_TO_LADDER = 501, // Tread water > climb to ladder idle
// RESERVED.
LA_SLIDE_FORWARD_JUMP = 502, // Slide forward > jump forwad
LA_SLIDE_FORWARD_TURN_180 = 503, // Slide forward > slide back
LA_SLIDE_BACK_JUMP = 504, // Slide back > jump back
LA_SLIDE_BACK_TURN_180 = 505, // Slide back > slide forward
LA_SLIDE_FORWARD_TO_STEEP = 506, // Slide forward, normal > slide forward, steep
LA_SLIDE_STEEP_FORWARD_TO_NORMAL = 507, // Slide forward, steep > slide forward, normal
LA_SLIDE_STEEP_FORWARD_START = 508, // Land on slope > slide forward, steep
LA_SLIDE_STEEP_FORWARD = 509, // Slide forward, steep (looped)
LA_SLIDE_STEEP_FORWARD_END = 510, // Slide forward, steep > stand
LA_SLIDE_STEEP_FORWARD_JUMP = 511, // Slide forward > jump forward
LA_SLIDE_BACK_TO_STEEP = 512, // Slide back, normal > slide back, steep
LA_SLIDE_STEEP_BACK_TO_NORMAL = 513, // Slide back, steep > slide back, normal
LA_SLIDE_STEEP_BACK_START = 514, // Land on slope > slide forward, steep
LA_SLIDE_STEEP_BACK = 515, // Slide back, steep (looped)
LA_SLIDE_STEEP_BACK_END = 516, // Slide back, steep > stand
LA_SLIDE_STEEP_BACK_JUMP = 517, // Slide back, steep > jump forward
LA_SLIDE_FORWARD_LEDGE = 518, // Slide forward > grab ledge
LA_SLIDE_BACK_LEDGE = 519, // Slide back > grab ledge
LA_STAND_CROSS_ARMS_AFK_START = 520, // Stand idle > cross arms AFK
LA_STAND_CROSS_ARMS_AFK = 521, // Cross arms AKF (looped)
LA_STAND_CROSS_ARMS_AFK_END = 522, // Cross arms AFK > stand idle
LA_ROLL_180_ALTERNATE = 523, // Standing mid-air roll 180
LA_SPRINT_TO_SPRINT_DIVE_LEFT = 524, // Sprint > sprint dive, left foot first
LA_SPRINT_TO_SPRINT_DIVE_RIGHT = 525, // Sprint > sprint dive, right foot first
LA_SPRINT_DIVE_TO_RUN = 526, // Sprint dive > run
LA_SPRINT_DIVE = 527, // Sprint dive, leading to swandive freefall
NUM_LARA_ANIMS
};
#pragma endregion

View file

@ -25,32 +25,34 @@ void lara_col_surftread(ITEM_INFO* item, COLL_INFO* coll)
item->fallspeed = 80;
Lara.waterStatus = LW_UNDERWATER;
}
Lara.moveAngle = 0;
LaraSurfaceCollision(item, coll);
}
void lara_col_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DD90(<), 4E1F4(<) (F)
{
Lara.moveAngle = ANGLE(90);
Lara.moveAngle = ANGLE(90.0f);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DD64(<), 4E1C8(<) (F)
{
Lara.moveAngle = -ANGLE(90);
Lara.moveAngle = ANGLE(-90.0f);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfback(ITEM_INFO* item, COLL_INFO* coll)//4DD38(<), 4E19C(<) (F)
{
Lara.moveAngle = ANGLE(180);
Lara.moveAngle = ANGLE(180.0f);
LaraSurfaceCollision(item, coll);
}
void lara_col_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4DCE8(<), 4E14C(<) (F)
{
coll->badNeg = -384;
Lara.moveAngle = 0;
coll->badNeg = -384;
LaraSurfaceCollision(item, coll);
LaraTestWaterClimbOut(item, coll);
LaraTestLadderClimbOut(item, coll);
@ -60,7 +62,9 @@ void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
{
item->fallspeed -= 4;
if (item->fallspeed < 0)
{
item->fallspeed = 0;
}
if (item->hitPoints <= 0)
{
@ -76,11 +80,11 @@ void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(4);
item->pos.yRot -= ANGLE(4.0f);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(4);
item->pos.yRot += ANGLE(4.0f);
}
if (TrInput & IN_FORWARD)
@ -105,8 +109,10 @@ void lara_as_surftread(ITEM_INFO* item, COLL_INFO* coll)//4DBA0, 4E004 (F)
{
Lara.diveCount++;
if (Lara.diveCount == 10)
{
item->goalAnimState = LS_UNDERWATER_FORWARD;
}
}
else
{
Lara.diveCount = 0;
@ -125,11 +131,11 @@ void lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DAF8, 4DF5C (F)
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
item->pos.yRot -= ANGLE(2.0f);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
item->pos.yRot += ANGLE(2.0f);
}
if (!(TrInput & IN_RSTEP))
@ -139,7 +145,9 @@ void lara_as_surfright(ITEM_INFO* item, COLL_INFO* coll)//4DAF8, 4DF5C (F)
item->fallspeed += 8;
if (item->fallspeed > 60)
{
item->fallspeed = 60;
}
}
void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
@ -154,11 +162,11 @@ void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
item->pos.yRot -= ANGLE(2.0f);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
item->pos.yRot += ANGLE(2.0f);
}
if (!(TrInput & IN_LSTEP))
@ -168,7 +176,9 @@ void lara_as_surfleft(ITEM_INFO* item, COLL_INFO* coll)//4DA50(<), 4DEB4(<) (F)
item->fallspeed += 8;
if (item->fallspeed > 60)
{
item->fallspeed = 60;
}
}
void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
@ -183,11 +193,11 @@ void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
if (TrInput & IN_LEFT)
{
item->pos.yRot -= ANGLE(2);
item->pos.yRot -= ANGLE(2.0f);
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot += ANGLE(2);
item->pos.yRot += ANGLE(2.0f);
}
if (!(TrInput & IN_BACK))
@ -197,7 +207,9 @@ void lara_as_surfback(ITEM_INFO* item, COLL_INFO* coll)//4D9A8(<), 4DE0C(<) (F)
item->fallspeed += 8;
if (item->fallspeed > 60)
{
item->fallspeed = 60;
}
}
void lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4D8E4(<), 4DD48(<) (F)
@ -220,13 +232,19 @@ void lara_as_surfswim(ITEM_INFO* item, COLL_INFO* coll)//4D8E4(<), 4DD48(<) (F)
}
if (!(TrInput & IN_FORWARD))
{
item->goalAnimState = LS_ONWATER_STOP;
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_ONWATER_STOP;
}
item->fallspeed += 8;
if (item->fallspeed > 60)
{
item->fallspeed = 60;
}
}
void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)//4D4F0(<), 4D954(<) (F)
@ -246,11 +264,11 @@ void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)//4D4F0(<), 4D954(<)
}
else if (coll->collType == CT_LEFT)
{
item->pos.yRot += ANGLE(5);
item->pos.yRot += ANGLE(5.0f);
}
else if (coll->collType == CT_RIGHT)
{
item->pos.yRot -= ANGLE(5);
item->pos.yRot -= ANGLE(5.0f);
}
if (GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber) - item->pos.yPos > -100)
@ -272,7 +290,9 @@ void LaraSurfaceCollision(ITEM_INFO* item, COLL_INFO* coll)//4D4F0(<), 4D954(<)
int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
{
if (coll->collType != CT_FRONT || !(TrInput & IN_ACTION))
{
return 0;
}
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS READY-
EnableCrawlFlexWaterPullUp = false;
@ -280,18 +300,26 @@ int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
if (Lara.gunStatus && (Lara.gunStatus != LG_READY || Lara.gunType != WEAPON_FLARE))
{
return 0;
}
if (coll->frontCeiling > 0)
{
return 0;
}
if (coll->midCeiling > -384)
{
return 0;
}
int frontFloor = coll->frontFloor + 700;
int frontCeiling = coll->frontCeiling + 700;
if (frontFloor <= -512 || frontFloor > 316)
{
return 0;
}
short rot = item->pos.yRot;
int slope = 0;
@ -304,13 +332,17 @@ int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
else
{
if (abs(coll->rightFloor2 - coll->leftFloor2) >= 60)
{
return 0;
}
result = SnapToQuadrant(rot, 35);
}
if (!result)
{
return 0;
}
item->pos.yPos += frontFloor - 5;
@ -353,9 +385,11 @@ int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
item->goalAnimState = LA_CROUCH_IDLE;
}
else
{
item->animNumber = LA_ONWATER_TO_STAND_M1CLICK;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
}
else
{
@ -371,19 +405,17 @@ int LaraTestWaterClimbOut(ITEM_INFO* item, COLL_INFO* coll)//4D22C, 4D690
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->goalAnimState = LS_STOP;
}
}
Lara.gunStatus = LG_HANDS_BUSY;
Lara.waterStatus = LW_ABOVE_WATER;
item->currentAnimState = LS_ONWATER_EXIT;
item->pos.yRot = rot;
Lara.gunStatus = LG_HANDS_BUSY;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.waterStatus = LW_ABOVE_WATER;
return 1;
}
@ -442,27 +474,33 @@ int LaraTestWaterStepOut(ITEM_INFO* item, COLL_INFO* coll)//4D100, 4D564 (F)
int LaraTestLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll) // NEW function for water to ladder move
{
if (!Lara.climbStatus || coll->collType != CT_FRONT || !(TrInput & IN_ACTION))
{
return 0;
}
if (Lara.gunStatus && (Lara.gunStatus != LG_READY || Lara.gunType != WEAPON_FLARE))
{
return 0;
}
if (!LaraTestClimbStance(item, coll))
return 0;
short rot = item->pos.yRot;
if (rot >= -ANGLE(35.0f) && rot <= ANGLE(35.0f))
if (rot >= ANGLE(-35.0f) && rot <= ANGLE(35.0f))
rot = 0;
else if (rot >= ANGLE(55.0f) && rot <= ANGLE(125.0f))
rot = ANGLE(90.0f);
else if (rot >= ANGLE(145.0f) || rot <= -ANGLE(145.0f))
else if (rot >= ANGLE(145.0f) || rot <= ANGLE(-145.0f))
rot = ANGLE(180.0f);
else if (rot >= -ANGLE(125.0f) && rot <= -ANGLE(55.0f))
else if (rot >= ANGLE(-125.0f) && rot <= ANGLE(-55.0f))
rot = -ANGLE(90.0f);
if (rot & 0x3FFF)
{
return 0;
}
switch ((unsigned short)rot / ANGLE(90.0f))
{
@ -489,22 +527,23 @@ int LaraTestLadderClimbOut(ITEM_INFO* item, COLL_INFO* coll) // NEW function for
item->goalAnimState = LS_LADDER_IDLE;
AnimateLara(item);
item->pos.yRot = rot;
Lara.gunStatus = LG_HANDS_BUSY;
Lara.waterStatus = LW_ABOVE_WATER;
item->pos.yRot = rot;
item->pos.zRot = 0;
item->pos.xRot = 0;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.waterStatus = LW_ABOVE_WATER;
return 1;
}
void lara_as_waterout(ITEM_INFO* item, COLL_INFO* coll)//1AEE4(<), 1B018(<) (F)
{
Camera.flags = CF_FOLLOW_CENTER;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.flags = CF_FOLLOW_CENTER;
}

View file

@ -1,7 +1,5 @@
#pragma once
#include "Lara.h"
#include "lara.h"
void _cdecl lara_col_surftread(ITEM_INFO* item, COLL_INFO* coll);
void _cdecl lara_col_surfright(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -15,17 +15,15 @@
#include "sound.h"
#include "GameFlowScript.h"
typedef struct SUBSUIT_INFO
{
short XRot;
short dXRot;
short XRotVel;
short Vel[2];
short YVel;
};
SUBSUIT_INFO Subsuit;
SubsuitInfo Subsuit;
byte SubHitCount = 0;
// SWIMMING
// ------------------------------
// Auxillary functions
// ------------------------------
void LaraWaterCurrent(COLL_INFO* coll) // (F) (D)
{
if (Lara.currentActive)
@ -43,26 +41,42 @@ void LaraWaterCurrent(COLL_INFO* coll) // (F) (D)
int shift = 0;
if (abs(Lara.currentXvel) <= 16)
{
shift = (abs(Lara.currentXvel) > 8) + 2;
}
else
{
shift = 4;
}
Lara.currentXvel -= Lara.currentXvel >> shift;
if (abs(Lara.currentXvel) < 4)
{
Lara.currentXvel = 0;
}
if (abs(Lara.currentZvel) <= 16)
{
shift = (abs(Lara.currentZvel) > 8) + 2;
}
else
{
shift = 4;
}
Lara.currentZvel -= Lara.currentZvel >> shift;
if (abs(Lara.currentZvel) < 4)
{
Lara.currentZvel = 0;
}
if (!Lara.currentXvel && !Lara.currentZvel)
{
return;
}
}
LaraItem->pos.xPos += Lara.currentXvel >> 8;
LaraItem->pos.zPos += Lara.currentZvel >> 8;
@ -75,12 +89,18 @@ void LaraWaterCurrent(COLL_INFO* coll) // (F) (D)
if (coll->collType == CT_FRONT)
{
if (LaraItem->pos.xRot > ANGLE(35))
{
LaraItem->pos.xRot += ANGLE(1);
}
else if (LaraItem->pos.xRot < -ANGLE(35))
{
LaraItem->pos.xRot -= ANGLE(1);
}
else
{
LaraItem->fallspeed = 0;
}
}
else if (coll->collType == CT_TOP)
{
LaraItem->pos.xRot -= ANGLE(1);
@ -181,190 +201,6 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)//4CA38, 4CE9C
}
}
void lara_col_waterroll(ITEM_INFO* item, COLL_INFO* coll)//4CA18(<), 4CE7C(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_col_uwdeath(ITEM_INFO* item, COLL_INFO* coll)//4C980(<), 4CDE4(<) (F)
{
item->hitPoints = -1;
Lara.air = -1;
Lara.gunStatus = LG_HANDS_BUSY;
int wh = GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
if (wh != NO_HEIGHT)
{
if (wh < item->pos.yPos - 100)
item->pos.yPos -= 5;
}
LaraSwimCollision(item, coll);
}
void lara_col_dive(ITEM_INFO* item, COLL_INFO* coll)//4C960(<), 4CDC4(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_col_tread(ITEM_INFO* item, COLL_INFO* coll)//4C940(<), 4CDA4(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_col_glide(ITEM_INFO* item, COLL_INFO* coll)//4C920(<), 4CD84(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_col_swim(ITEM_INFO* item, COLL_INFO* coll)//4C900(<), 4CD64(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_as_waterroll(ITEM_INFO* item, COLL_INFO* coll)//4C8F8(<), 4CD5C(<) (F)
{
item->fallspeed = 0;
}
void lara_as_uwdeath(ITEM_INFO* item, COLL_INFO* coll)//4C884(<), 4CCE8(<) (F)
{
Lara.look = 0;
item->fallspeed -= 8;
if (item->fallspeed <= 0)
item->fallspeed = 0;
if (item->pos.xRot < -ANGLE(2) || item->pos.xRot > ANGLE(2))
{
if (item->pos.xRot >= 0)
item->pos.xRot -= ANGLE(2);
else
item->pos.xRot += ANGLE(2);
}
else
{
item->pos.xRot = 0;
}
}
void lara_as_dive(ITEM_INFO* item, COLL_INFO* coll)//4C854, 4CCB8 (F)
{
if (TrInput & IN_FORWARD)
{
item->pos.xRot -= ANGLE(1);
}
}
void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll)//4C730, 4CB94 (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL && LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
}
else
{
if (TrInput & IN_LOOK)
LookUpDown();
if (LaraDrawType == LARA_DIVESUIT)
SwimTurnSubsuit(item);
else
SwimTurn(item);
if (TrInput & IN_JUMP)
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed -= 6;
if (item->fallspeed < 0)
item->fallspeed = 0;
if (Lara.gunStatus == LG_HANDS_BUSY)
Lara.gunStatus = LG_NO_ARMS;
}
}
void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)//4C634(<), 4CA98(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL)
{
if (LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
return;
}
}
else if (LaraDrawType != LARA_DIVESUIT)
{
SwimTurn(item);
}
else
{
SwimTurnSubsuit(item);
}
if (TrInput & IN_JUMP)
item->goalAnimState = LS_UNDERWATER_FORWARD;
item->fallspeed -= 6;
if (item->fallspeed < 0)
item->fallspeed = 0;
if (item->fallspeed <= 133)
item->goalAnimState = LS_UNDERWATER_STOP;
}
void lara_as_swim(ITEM_INFO* item, COLL_INFO* coll)//4C548(<), 4C9AC(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL)
{
if (LaraDrawType != LARA_DIVESUIT)
{
item->currentAnimState = LS_UNDERWATER_ROLL;
item->animNumber = LA_UNDERWATER_ROLL_180_START;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
return;
}
}
else if (LaraDrawType != LARA_DIVESUIT)
{
SwimTurn(item);
}
else
{
SwimTurnSubsuit(item);
}
item->fallspeed += 8;
if (item->fallspeed > 200)
item->fallspeed = 200;
if (!(TrInput & IN_JUMP))
item->goalAnimState = LS_UNDERWATER_INERTIA;
}
void UpdateSubsuitAngles()//4BD20, 4C184 (F)
{
if (Subsuit.YVel != 0)
@ -437,7 +273,7 @@ void UpdateSubsuitAngles()//4BD20, 4C184 (F)
}
}
void SwimTurnSubsuit(ITEM_INFO* item)//4BBDC, 4C040 (F)
void DoLaraSubsuitSwimTurn(ITEM_INFO* item)//4BBDC, 4C040 (F)
{
if (item->pos.yPos < 14080)
Subsuit.YVel += (14080 - item->pos.yPos) >> 4;
@ -475,30 +311,36 @@ void SwimTurnSubsuit(ITEM_INFO* item)//4BBDC, 4C040 (F)
}
}
void SwimTurn(ITEM_INFO* item)//4BAF4(<), 4BF58(<) (F)
void DoLaraSwimTurn(ITEM_INFO* item)//4BAF4(<), 4BF58(<) (F)
{
if (TrInput & IN_FORWARD)
{
item->pos.xRot -= ANGLE(2);
item->pos.xRot -= ANGLE(3.5f);
}
else if (TrInput & IN_BACK)
{
item->pos.xRot += ANGLE(2);
item->pos.xRot += ANGLE(3.0f);
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= 409;
if (Lara.turnRate < -ANGLE(6))
Lara.turnRate = -ANGLE(6);
item->pos.zRot -= ANGLE(3);
Lara.turnRate -= ANGLE(3.0f);
if (Lara.turnRate < ANGLE(-6.0f))
{
Lara.turnRate = ANGLE(-6.0f);
}
item->pos.zRot -= ANGLE(3.0f);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += 409;
if (Lara.turnRate > ANGLE(6))
Lara.turnRate = ANGLE(6);
item->pos.zRot += ANGLE(3);
Lara.turnRate += ANGLE(3.0f);
if (Lara.turnRate > ANGLE(6.0f))
{
Lara.turnRate = ANGLE(6.0f);
}
item->pos.zRot += ANGLE(3.0f);
}
}
@ -511,10 +353,10 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
short oldYrot = item->pos.yRot;
short oldZrot = item->pos.zRot;
if (item->pos.xRot < -ANGLE(90) || item->pos.xRot > ANGLE(90))
if (item->pos.xRot < ANGLE(-90.0f) || item->pos.xRot > ANGLE(90.0f))
{
Lara.moveAngle = ANGLE(180);
coll->facing = item->pos.yRot - ANGLE(180);
Lara.moveAngle = ANGLE(180.0f);
coll->facing = item->pos.yRot - ANGLE(180.0f);
}
else
{
@ -526,7 +368,9 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
height = abs(height);
if (height < ((LaraDrawType == LARA_DIVESUIT) << 6) + 200)
{
height = ((LaraDrawType == LARA_DIVESUIT) << 6) + 200;
}
coll->badNeg = -64;
@ -537,10 +381,10 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
GetCollisionInfo(coll, item->pos.xPos, height / 2 + item->pos.yPos, item->pos.zPos, item->roomNumber, height);
c1.facing += ANGLE(45);
c1.facing += ANGLE(45.0f);
GetCollisionInfo(&c1, item->pos.xPos, height / 2 + item->pos.yPos, item->pos.zPos, item->roomNumber, height);
c2.facing -= ANGLE(45);
c2.facing -= ANGLE(45.0f);
GetCollisionInfo(&c2, item->pos.xPos, height / 2 + item->pos.yPos, item->pos.zPos, item->roomNumber, height);
ShiftItem(item, coll);
@ -550,14 +394,14 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
switch (coll->collType)
{
case CT_FRONT:
if (item->pos.xRot <= ANGLE(25))
if (item->pos.xRot <= ANGLE(25.0f))
{
if (item->pos.xRot >= -ANGLE(25))
if (item->pos.xRot >= ANGLE(-25.0f))
{
if (item->pos.xRot > ANGLE(5))
item->pos.xRot += ANGLE(0.5);
else if (item->pos.xRot < -ANGLE(5))
item->pos.xRot -= ANGLE(0.5);
if (item->pos.xRot > ANGLE(5.0f))
item->pos.xRot += ANGLE(0.5f);
else if (item->pos.xRot < ANGLE(-5.0f))
item->pos.xRot -= ANGLE(0.5f);
else if (item->pos.xRot > 0)
item->pos.xRot += 45;
else if (item->pos.xRot < 0)
@ -602,7 +446,7 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
if (item->pos.xRot >= -8190)
{
flag = 1;
item->pos.xRot -= ANGLE(1);
item->pos.xRot -= ANGLE(1.0f);
}
break;
@ -612,12 +456,12 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
break;
case CT_LEFT:
item->pos.yRot += ANGLE(2);
item->pos.yRot += ANGLE(2.0f);
flag = 1;
break;
case CT_RIGHT:
item->pos.yRot -= ANGLE(2);
item->pos.yRot -= ANGLE(2.0f);
flag = 1;
break;
@ -633,7 +477,7 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
if (coll->midFloor < 0 && coll->midFloor != NO_HEIGHT)
{
flag = 1;
item->pos.xRot += ANGLE(1);
item->pos.xRot += ANGLE(1.0f);
item->pos.yPos += coll->midFloor;
}
@ -661,23 +505,26 @@ void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll)//4B608, 4BA6C
}
if (Lara.waterStatus != LW_FLYCHEAT && Lara.ExtraAnim == NO_ITEM)
LaraTestWaterDepth(item, coll);
{
TestLaraWaterDepth(item, coll);
}
}
void LaraTestWaterDepth(ITEM_INFO* item, COLL_INFO* coll)//4B4F8(<), 4B95C(<) (F)
// This is a setter.
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll)//4B4F8(<), 4B95C(<) (F)
{
short roomNumber = item->roomNumber;
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
int wd = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, roomNumber);
int depth = GetWaterDepth(item->pos.xPos, item->pos.yPos, item->pos.zPos, roomNumber);
if (wd == NO_HEIGHT)
if (depth == NO_HEIGHT)
{
item->fallspeed = 0;
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
}
else if (wd <= 512)
else if (depth <= 512)
{
item->animNumber = LA_UNDERWATER_TO_STAND;
item->currentAnimState = LS_ONWATER_EXIT;
@ -692,3 +539,186 @@ void LaraTestWaterDepth(ITEM_INFO* item, COLL_INFO* coll)//4B4F8(<), 4B95C(<) (F
item->pos.yPos = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
}
}
// ------------------------------
// SWIMMING
// State & Collision Functions
// ------------------------------
void lara_as_underwater_stop(ITEM_INFO* item, COLL_INFO* coll)//4C730, 4CB94 (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL && LaraDrawType != LARA_DIVESUIT)
{
//item->currentAnimState = LS_UNDERWATER_ROLL;
//item->animNumber = LA_UNDERWATER_ROLL_180_START;
//item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
// BUG: Doesn't work when idle???
item->goalAnimState = LS_UNDERWATER_ROLL;
return;
}
if (TrInput & IN_LOOK)
{
LookUpDown();
}
if (LaraDrawType == LARA_DIVESUIT)
{
DoLaraSubsuitSwimTurn(item);
}
else
{
DoLaraSwimTurn(item);
}
if (TrInput & IN_JUMP)
{
item->goalAnimState = LS_UNDERWATER_FORWARD;
}
item->fallspeed -= 6;
if (item->fallspeed < 0)
{
item->fallspeed = 0;
}
if (Lara.gunStatus == LG_HANDS_BUSY)
{
Lara.gunStatus = LG_NO_ARMS;
}
}
void lara_col_underwater_stop(ITEM_INFO* item, COLL_INFO* coll)//4C940(<), 4CDA4(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_as_underwater_swim(ITEM_INFO* item, COLL_INFO* coll)//4C548(<), 4C9AC(<) (F)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_ROLL && LaraDrawType != LARA_DIVESUIT)
{
item->goalAnimState = LS_UNDERWATER_ROLL;
return;
}
if (LaraDrawType == LARA_DIVESUIT)
{
DoLaraSubsuitSwimTurn(item);
}
else
{
DoLaraSwimTurn(item);
}
item->fallspeed += 8;
if (item->fallspeed > 200)
{
item->fallspeed = 200;
}
if (!(TrInput & IN_JUMP))
{
item->goalAnimState = LS_UNDERWATER_INERTIA;
}
}
void lara_col_underwater_swim(ITEM_INFO* item, COLL_INFO* coll)//4C900(<), 4CD64(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll)//4C634(<), 4CA98(<) (F)
{
lara_as_underwater_stop(item, coll); // This one has the HANDS_BUSY check which wasn't in the current function.
if (item->fallspeed <= 133)
{
item->goalAnimState = LS_UNDERWATER_STOP;
}
}
void lara_col_glide(ITEM_INFO* item, COLL_INFO* coll)//4C920(<), 4CD84(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_as_dive(ITEM_INFO* item, COLL_INFO* coll)//4C854, 4CCB8 (F)
{
if (TrInput & IN_FORWARD)
{
item->pos.xRot -= ANGLE(1.0f);
}
}
void lara_col_dive(ITEM_INFO* item, COLL_INFO* coll)//4C960(<), 4CDC4(<) (F)
{
LaraSwimCollision(item, coll);
}
void lara_as_underwater_death(ITEM_INFO* item, COLL_INFO* coll)//4C884(<), 4CCE8(<) (F)
{
Lara.look = 0;
item->fallspeed -= 8;
if (item->fallspeed <= 0)
{
item->fallspeed = 0;
}
if (item->pos.xRot < -ANGLE(2.0f) || item->pos.xRot > ANGLE(2.0f))
{
if (item->pos.xRot >= 0)
{
item->pos.xRot -= ANGLE(2.0f);
}
else
{
item->pos.xRot += ANGLE(2.0f);
}
}
else
{
item->pos.xRot = 0;
}
}
void lara_col_underwater_death(ITEM_INFO* item, COLL_INFO* coll)//4C980(<), 4CDE4(<) (F)
{
Lara.gunStatus = LG_HANDS_BUSY;
Lara.air = -1;
item->hitPoints = -1;
int wh = GetWaterHeight(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber);
if (wh != NO_HEIGHT)
{
if (wh < item->pos.yPos - 100)
{
item->pos.yPos -= 5;
}
}
LaraSwimCollision(item, coll);
}
void lara_as_underwater_roll_180(ITEM_INFO* item, COLL_INFO* coll)//4C8F8(<), 4CD5C(<) (F)
{
item->fallspeed = 0;
}
void lara_col_underwater_roll_180(ITEM_INFO* item, COLL_INFO* coll)//4CA18(<), 4CE7C(<) (F)
{
LaraSwimCollision(item, coll);
}

View file

@ -1,23 +1,34 @@
#pragma once
#include "collide.h"
typedef struct SubsuitInfo
{
short XRot;
short dXRot;
short XRotVel;
short Vel[2];
short YVel;
};
// Auxillary Functions
void LaraWaterCurrent(COLL_INFO* coll);
int GetWaterDepth(int x, int y, int z, short roomNumber);
void lara_col_waterroll(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_uwdeath(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_dive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_tread(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_glide(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_swim(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_waterroll(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_uwdeath(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_dive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_tread(ITEM_INFO* item, COLL_INFO* coll);
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 DoLaraSubsuitSwimTurn(ITEM_INFO* item);
void DoLaraSwimTurn(ITEM_INFO* item);
void LaraSwimCollision(ITEM_INFO* item, COLL_INFO* coll);
void LaraTestWaterDepth(ITEM_INFO* item, COLL_INFO* coll);
void TestLaraWaterDepth(ITEM_INFO* item, COLL_INFO* coll);
// State & Collision Functions
void lara_as_underwater_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_underwater_stop(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_underwater_swim(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_underwater_swim(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_glide(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_glide(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_dive(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_dive(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_underwater_death(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_underwater_death(ITEM_INFO* item, COLL_INFO* coll);
void lara_as_underwater_roll_180(ITEM_INFO* item, COLL_INFO* coll);
void lara_col_underwater_roll_180(ITEM_INFO* item, COLL_INFO* coll);

View file

@ -21,15 +21,18 @@ static short RightClimbTab[4] = // offset 0xA0640
/*this file has all the generic test functions called in lara's state code*/
// This function is disgusting.
int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_NO_ARMS)
{
return 0;
}
// EnableCrawlFlex1click = true;
// EnableCrawlFlex2click = true;
// EnableCrawlFlex3click = true;
// EnableMonkeyVault = true;
// EnableCrawlFlex1click = true;
// EnableCrawlFlex2click = true;
// EnableCrawlFlex3click = true;
// EnableMonkeyVault = true;
if (coll->collType == CT_FRONT)
{
@ -219,7 +222,7 @@ int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
return 1;
}
}
// else
// else
return 0;
}
@ -286,6 +289,34 @@ int TestWall(ITEM_INFO* item, int front, int right, int down)//12550, 12600 (F)
return 0;
}
bool TestLaraHang(ITEM_INFO* player, COLL_INFO* coll)
{
if (TrInput & IN_ACTION &&
Lara.climbStatus &&
player->hitPoints > 0)
{
if (!LaraTestHangOnClimbWall(player, coll))
{
int r;
}
return true;
}
else if (TrInput & IN_ACTION && player->hitPoints > 0 && coll->frontFloor <= 0)
{
int t;
// some other garbage.
return true;
}
return false;
}
void SetLaraHang(ITEM_INFO* player, COLL_INFO* coll)
{
}
int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
int delta, flag, flag2, front, dfront, x, z, result;
@ -617,13 +648,28 @@ int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
return result;
}
bool TestLaraHangRightCorner(ITEM_INFO* item, COLL_INFO* coll)
{
if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE ||
coll->hitStatic)
{
return false;
}
return true;
}
int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (item->animNumber != LA_REACH_TO_HANG && item->animNumber != LA_HANG_FEET_IDLE)
{
return 0;
}
if (coll->hitStatic)
{
return 0;
}
int x;
int z;
@ -873,7 +919,6 @@ int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
break;
}
bounds = GetBoundsAccurate(item);
if (Lara.moveAngle)
@ -902,7 +947,6 @@ int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge) // (F) (D)
{
BOUNDING_BOX* bounds = GetBoundsAccurate(item);
int hdif = coll->frontFloor - bounds->Y1;
@ -967,7 +1011,7 @@ int TestHangSwingIn(ITEM_INFO* item, short angle)//14104, 141B4 (F)
if (h != NO_HEIGHT)
{
/* if (TR12_OSCILLATE_HANG == true)
/* if (TR12_OSCILLATE_HANG == true)
{
if (((h - y) > 0)
&& ((c - y) < -400))
@ -979,7 +1023,7 @@ int TestHangSwingIn(ITEM_INFO* item, short angle)//14104, 141B4 (F)
&& ((c - y) < -400)
&& ((y - 819 - c) > -72))
return(1);
// }
// }
}
return(0);
}
@ -1205,20 +1249,26 @@ short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h) // (F) (D)
return height;
}
int LaraFallen(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
bool TestLaraFall(COLL_INFO* coll)
{
if (Lara.waterStatus == LW_WADE || coll->midFloor <= STEPUP_HEIGHT)
if (coll->midFloor <= STEPUP_HEIGHT/* ||
Lara.waterStatus == LW_WADE*/) // TEST: This may have been causing a floor snap bug!
{
return 0;
return false;
}
return true;
}
// TODO: This should eventually become obsolete. Set goal states to LS_FALL. In WAD2, make links to LA_FALL_START.
void SetLaraFall(ITEM_INFO* item)
{
item->animNumber = LA_FALL_START;
item->currentAnimState = LS_JUMP_FORWARD;
item->goalAnimState = LS_JUMP_FORWARD;
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
item->fallspeed = 0;
item->gravityStatus = true;
return 1;
}
int LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
@ -1242,7 +1292,7 @@ int LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
return 0;
}
void GetTighRopeFallOff(int regularity)
void GetTighropeFallOff(int regularity)
{
if (LaraItem->hitPoints <= 0 || LaraItem->hitStatus)
{
@ -1253,20 +1303,32 @@ void GetTighRopeFallOff(int regularity)
}
if (!Lara.tightRopeFall && !(GetRandomControl() & regularity))
{
Lara.tightRopeFall = 2 - ((GetRandomControl() & 0xF) != 0);
}
}
bool TestLaraLean(ITEM_INFO* item, COLL_INFO* coll)
bool TestLaraLean(COLL_INFO* coll)
{
// TODO: make it more fine-tuned when new collision is done.
// TODO: fine-tune this when new collision is done.
switch (coll->collType)
{
case CT_RIGHT:
{
if (TrInput & IN_RIGHT)
return false;
case CT_LEFT:
if (TrInput & IN_LEFT)
{
return false;
}
}
case CT_LEFT:
{
if (TrInput & IN_LEFT)
{
return false;
}
}
}
return true;
}

View file

@ -17,7 +17,10 @@ void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip);
void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip);
short LaraFloorFront(ITEM_INFO* item, short ang, int dist);
short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h);
int LaraFallen(ITEM_INFO* item, COLL_INFO* coll);
int LaraLandedBad(ITEM_INFO* l, COLL_INFO* coll);
void GetTighRopeFallOff(int Regularity);
bool TestLaraLean(ITEM_INFO* item, COLL_INFO* coll);
void GetTighropeFallOff(int Regularity);
bool TestLaraFall(COLL_INFO* coll);
void SetLaraFall(ITEM_INFO* item);
bool TestLaraLean(COLL_INFO* coll);

View file

@ -11,6 +11,7 @@
#include "input.h"
#include "sound.h"
#include "savegame.h"
struct PISTOL_DEF
{
short objectNum;
@ -19,6 +20,7 @@ struct PISTOL_DEF
char draw2Anim;
char recoilAnim;
};
PISTOL_DEF PistolsTable[4] =
{
{ ID_LARA, 0, 0, 0, 0 },

View file

@ -2924,7 +2924,7 @@ void AnimateItem(ITEM_INFO *item)
if (item->gravityStatus)
{
item->fallspeed += (item->fallspeed >= 128 ? 1 : 6);
item->fallspeed += (item->fallspeed >= 128 ? 1 : 6) / 2;
item->pos.yPos += item->fallspeed;
}
else

View file

@ -94,19 +94,29 @@ extern Inventory g_Inventory;
static bool SilencerIsEquiped()
{
return Lara.Weapons[WEAPON_UZI].HasSilencer
|| Lara.Weapons[WEAPON_PISTOLS].HasSilencer
|| Lara.Weapons[WEAPON_SHOTGUN].HasSilencer
|| Lara.Weapons[WEAPON_REVOLVER].HasSilencer
|| Lara.Weapons[WEAPON_CROSSBOW].HasSilencer
|| Lara.Weapons[WEAPON_HK].HasSilencer;
if (Lara.Weapons[WEAPON_UZI].HasSilencer ||
Lara.Weapons[WEAPON_PISTOLS].HasSilencer ||
Lara.Weapons[WEAPON_SHOTGUN].HasSilencer ||
Lara.Weapons[WEAPON_REVOLVER].HasSilencer ||
Lara.Weapons[WEAPON_CROSSBOW].HasSilencer ||
Lara.Weapons[WEAPON_HK].HasSilencer)
{
return true;
}
return false;
}
static bool LaserSightIsEquiped()
{
return Lara.Weapons[WEAPON_REVOLVER].HasLasersight
|| Lara.Weapons[WEAPON_CROSSBOW].HasLasersight
|| Lara.Weapons[WEAPON_HK].HasLasersight;
if (Lara.Weapons[WEAPON_REVOLVER].HasLasersight ||
Lara.Weapons[WEAPON_CROSSBOW].HasLasersight ||
Lara.Weapons[WEAPON_HK].HasLasersight)
{
return true;
}
return false;
}
void PickedUpObject(short objectNumber)
@ -502,7 +512,9 @@ void do_pickup()
for (int i = 0; i < g_Level.NumItems; i++)
{
if (g_Level.Items[i].objectNumber == item->objectNumber)
{
KillItem(i);
}
}
}
if (item->triggerFlags & 0xC0)
@ -533,10 +545,14 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
short triggerFlags = item->triggerFlags & 0x3F;
if (triggerFlags == 5 || triggerFlags == 10)
{
return;
}
if (item->objectNumber == ID_FLARE_ITEM && Lara.gunType == WEAPON_FLARE)
{
return;
}
item->pos.yRot = l->pos.yRot;
item->pos.zRot = 0;
@ -835,7 +851,10 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (l->currentAnimState == LS_CROUCH_IDLE)
{
if (item->objectNumber == ID_BURNING_TORCH_ITEM)
{
break;
}
AlignLaraPosition(&PickUpPosition, item, l);
if (item->objectNumber == ID_FLARE_ITEM)
{
@ -852,7 +871,10 @@ void PickupCollision(short itemNum, ITEM_INFO* l, COLL_INFO* coll)
if (l->currentAnimState == LS_CRAWL_IDLE)
{
if (item->objectNumber == ID_BURNING_TORCH_ITEM)
{
break;
}
l->goalAnimState = LS_CROUCH_IDLE;
Lara.generalPtr = (void*)itemNum;
break;
@ -955,13 +977,20 @@ void PickupControl(short itemNum)
{
item->pos.yPos = item->itemFlags[0];
if (item->fallspeed <= 64)
{
item->triggerFlags &= 0xC0;
}
else
{
item->fallspeed = -item->fallspeed >> 2;
}
}
if (item->roomNumber != roomNumber)
{
ItemNewRoom(itemNum, roomNumber);
}
break;
case 2:
@ -1007,10 +1036,14 @@ BOUNDING_BOX* FindPlinth(ITEM_INFO* item)
}
if (found != -1)
{
return &StaticObjects[found].collisionBox;
}
if (room->itemNumber == NO_ITEM)
{
return NULL;
}
short itemNumber = room->itemNumber;
for (itemNumber = room->itemNumber; itemNumber != NO_ITEM; itemNumber = g_Level.Items[itemNumber].nextItem)
@ -1029,9 +1062,13 @@ BOUNDING_BOX* FindPlinth(ITEM_INFO* item)
}
if (itemNumber == NO_ITEM)
{
return NULL;
}
else
{
return (BOUNDING_BOX*)GetBestFrame(&g_Level.Items[itemNumber]);
}
}
void InitialisePickup(short itemNumber)
@ -1047,7 +1084,9 @@ void InitialisePickup(short itemNumber)
else
{
if (triggerFlags == 0 || triggerFlags == 3 || triggerFlags == 4 || triggerFlags == 7 || triggerFlags == 8 || triggerFlags == 11)
{
item->pos.yPos -= bounds->Y2;
}
if ((item->triggerFlags & 0x80) != 0)
{
@ -1056,11 +1095,15 @@ void InitialisePickup(short itemNumber)
}
if (item->triggerFlags & 0x100)
{
item->meshBits = 0;
}
if (item->status == ITEM_INVISIBLE)
{
item->flags |= 0x20;
}
}
}
void InitialiseSearchObject(short itemNumber)
@ -1198,7 +1241,9 @@ void SearchObjectControl(short itemNumber)
objNumber = (item->objectNumber - ID_SEARCH_OBJECT1) / 2;
if (item->objectNumber != ID_SEARCH_OBJECT4 || item->itemFlags[0] == 1)
{
AnimateItem(item);
}
frameNumber = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
if (item->objectNumber == ID_SEARCH_OBJECT1)
@ -1217,16 +1262,22 @@ void SearchObjectControl(short itemNumber)
else if (item->objectNumber == ID_SEARCH_OBJECT2)
{
if (frameNumber == 18)
{
item->meshBits = 1;
}
else if (frameNumber == 172)
{
item->meshBits = 2;
}
}
else if (item->objectNumber == ID_SEARCH_OBJECT4)
{
item->meshBits = FlipStats[0] != 0 ? 48 : 9;
if (frameNumber >= 45 && frameNumber <= 131)
{
item->meshBits |= FlipStats[0] != 0 ? 4 : 2;
}
if (item->itemFlags[1] != -1)
{
@ -1234,12 +1285,16 @@ void SearchObjectControl(short itemNumber)
if (Objects[item2->objectNumber].isPickup)
{
if (FlipStats[0])
{
item2->status = ITEM_NOT_ACTIVE;
}
else
{
item2->status = ITEM_INVISIBLE;
}
}
}
}
if (frameNumber == SearchCollectFrames[objNumber])
{
@ -1287,11 +1342,12 @@ void SearchObjectControl(short itemNumber)
int UseSpecialItem(ITEM_INFO* item) // to pickup.cpp?
{
short selectedObject = g_Inventory.GetSelectedObject();
if (item->animNumber != LA_STAND_IDLE || Lara.gunStatus || selectedObject == NO_ITEM)
{
return false;
}
if (selectedObject >= ID_WATERSKIN1_EMPTY && selectedObject <= ID_WATERSKIN2_5)
{
@ -1300,9 +1356,13 @@ int UseSpecialItem(ITEM_INFO* item) // to pickup.cpp?
if (selectedObject != ID_WATERSKIN1_3 && selectedObject != ID_WATERSKIN2_5)
{
if (selectedObject >= ID_WATERSKIN2_EMPTY)
{
Lara.Waterskin2.Quantity = 5;
}
else
{
Lara.Waterskin1.Quantity = 3;
}
item->animNumber = LA_WATERSKIN_FILL;
}

View file

@ -1306,6 +1306,11 @@ unsigned short atanTab[] = {
0x2000, 0x2000
};
int GetSign(int num)
{
return (num >= 0) ? 1 : -1;
}
// fix "improperly terminated macro invocation"
// fix "expression must have integral or unscoped enum type"
short ANGLE(float angle)

View file

@ -45,6 +45,9 @@ template<typename T>
constexpr auto MESH_BITS(T x) {
return (1 << x);
}
int GetSign(int num);
short ANGLE(float angle);
float TO_DEGREES(short angle);
float TO_RAD(short angle);

View file

@ -24,7 +24,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_STOP || 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:
{
@ -33,7 +33,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_STOP || 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: