TombEngine/TR5Main/Game/lara.cpp

7340 lines
176 KiB
C++
Raw Normal View History

#include "framework.h"
2019-11-21 07:43:34 +01:00
#include "Lara.h"
2018-08-19 09:46:58 +02:00
#include "control.h"
#include "items.h"
#include "inventory.h"
#include "larafire.h"
#include "misc.h"
2019-11-21 07:43:34 +01:00
#include "draw.h"
#include "sphere.h"
#include "camera.h"
2019-11-21 07:43:34 +01:00
#include "larasurf.h"
#include "laraswim.h"
#include "lara1gun.h"
#include "lara2gun.h"
#include "laraflar.h"
#include "laramisc.h"
#include "laraclmb.h"
#include "rope.h"
#include "health.h"
#include "level.h"
#include "input.h"
2020-04-24 19:15:05 +02:00
#include "sound.h"
#include "setup.h"
2018-08-19 09:46:58 +02:00
#include "motorbike.h"
#include "cannon.h"
#include "quad.h"
#include "snowmobile.h"
#include "jeep.h"
#include "boat.h"
#include "upv.h"
#include "kayak.h"
#include "minecart.h"
2018-08-19 09:46:58 +02:00
2019-12-02 09:11:21 +01:00
static short LeftClimbTab[4] = // offset 0xA0638
2019-11-21 07:43:34 +01:00
{
0x0200, 0x0400, 0x0800, 0x0100
};
2019-12-02 09:11:21 +01:00
static short RightClimbTab[4] = // offset 0xA0640
2019-11-21 07:43:34 +01:00
{
0x0800, 0x0100, 0x0200, 0x0400
};
extern Inventory* g_Inventory;
2019-12-02 09:11:21 +01:00
short elevation = 57346;
2019-11-21 07:43:34 +01:00
bool doJump = false;
short OldAngle = 1;
int RopeSwing = 0;
LaraInfo Lara;
2020-04-23 19:22:01 +02:00
ITEM_INFO* LaraItem;
byte LaraNodeUnderwater[NUM_LARA_MESHES];
bool EnableCrouchRoll, EnableFeetHang, EnableMonkeyVault, EnableMonkeyRoll, EnableCrawlFlex1click, EnableCrawlFlex2click, EnableCrawlFlex3click;
bool EnableCrawlFlex1clickE, EnableCrawlFlex2clickE, EnableCrawlFlex1clickup, EnableCrawlFlex1clickdown;
2019-12-02 06:39:51 +01:00
function<LaraRoutineFunction> lara_control_routines[NUM_LARA_STATES + 1] = {
2019-12-02 06:39:51 +01:00
lara_as_walk,
lara_as_run,
lara_as_stop,
lara_as_forwardjump,
lara_void_func,
lara_as_fastback,
lara_as_turn_r,
lara_as_turn_l,
lara_as_death,
lara_as_fastfall,
lara_as_hang,
lara_as_reach,
lara_as_splat,
lara_as_tread,
lara_void_func,
lara_as_compress,
lara_as_back,
lara_as_swim,
lara_as_glide,
lara_as_null,
lara_as_fastturn,
lara_as_stepright,
lara_as_stepleft,
lara_void_func,
lara_as_slide,
lara_as_backjump,
lara_as_rightjump,
lara_as_leftjump,
lara_as_upjump,
lara_as_fallback,
lara_as_hangleft,
lara_as_hangright,
lara_as_slideback,
lara_as_surftread,
lara_as_surfswim,
lara_as_dive,
lara_as_pushblock,
lara_as_pullblock,
lara_as_ppready,
lara_as_pickup,
lara_as_switchon,
lara_as_switchoff,
lara_as_usekey,
lara_as_usepuzzle,
lara_as_uwdeath,
lara_void_func,
lara_as_special,
lara_as_surfback,
lara_as_surfleft,
lara_as_surfright,
lara_void_func,
lara_void_func,
lara_as_swandive,
lara_as_fastdive,
lara_as_gymnast,
lara_as_waterout,
lara_as_climbstnc,
lara_as_climbing,
lara_as_climbleft,
lara_as_climbend,
lara_as_climbright,
lara_as_climbdown,
lara_void_func,
lara_void_func,
lara_void_func,
lara_as_wade,
lara_as_waterroll,
lara_as_pickupflare,
lara_void_func,
lara_void_func,
lara_as_deathslide,
lara_as_duck,
2020-05-01 21:19:03 -05:00
lara_as_crouch_roll,
2019-12-02 06:39:51 +01:00
lara_as_dash,
lara_as_dashdive,
lara_as_hang2,
lara_as_monkeyswing,
lara_as_monkeyl,
lara_as_monkeyr,
lara_as_monkey180,
lara_as_all4s,
lara_as_crawl,
lara_as_hangturnl,
lara_as_hangturnr,
lara_as_all4turnl,
lara_as_all4turnr,
lara_as_crawlb,
lara_as_null,
lara_as_null,
lara_as_controlled,
lara_as_ropel,
lara_as_roper,
lara_as_controlled,
lara_as_controlled,
lara_as_controlled,
lara_as_controlledl,
lara_as_controlledl,
lara_as_controlled,
lara_as_pickup,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_poleleft,
lara_as_poleright,
lara_as_pulley,
lara_as_duckl,
lara_as_duckr,
lara_as_extcornerl,
lara_as_extcornerr,
lara_as_intcornerl,
lara_as_intcornerr,
lara_as_rope,
lara_as_climbrope,
lara_as_climbroped,
lara_as_rope,
lara_as_rope,
lara_void_func,
lara_as_controlled,
lara_as_swimcheat,
lara_as_trpose,
lara_as_null,
lara_as_trwalk,
lara_as_trfall,
lara_as_trfall,
lara_as_null,
lara_as_null,
lara_as_switchon,
lara_as_null,
lara_as_parallelbars,
lara_as_pbleapoff,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_null,
lara_as_null,
2020-05-23 15:59:18 -05:00
lara_as_null,
lara_as_hang_feet,
lara_as_hang_feet_shimmyr,
lara_as_hang_feet_shimmyl,
lara_as_hang_feet_inRcorner,
lara_as_hang_feet_inLcorner,
lara_as_hang_feet_outRcorner,
lara_as_hang_feet_outLcorner,
2019-12-02 06:39:51 +01:00
};
function<LaraRoutineFunction> lara_collision_routines[NUM_LARA_STATES + 1] = {
2019-12-02 06:39:51 +01:00
lara_col_walk,
lara_col_run,
lara_col_stop,
lara_col_forwardjump,
lara_col_pose,
lara_col_fastback,
lara_col_turn_r,
lara_col_turn_l,
lara_col_death,
lara_col_fastfall,
lara_col_hang,
lara_col_reach,
lara_col_splat,
lara_col_tread,
lara_col_land,
lara_col_compress,
lara_col_back,
lara_col_swim,
lara_col_glide,
lara_default_col,
lara_col_fastturn,
lara_col_stepright,
lara_col_stepleft,
lara_col_roll2,
lara_col_slide,
lara_col_backjump,
lara_col_rightjump,
lara_col_leftjump,
lara_col_upjump,
lara_col_fallback,
lara_col_hangleft,
lara_col_hangright,
lara_col_slideback,
lara_col_surftread,
lara_col_surfswim,
lara_col_dive,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_uwdeath,
lara_col_roll,
lara_void_func,
lara_col_surfback,
lara_col_surfleft,
lara_col_surfright,
lara_void_func,
lara_void_func,
lara_col_swandive,
lara_col_fastdive,
lara_default_col,
lara_default_col,
lara_col_climbstnc,
lara_col_climbing,
lara_col_climbleft,
lara_col_climbend,
lara_col_climbright,
lara_col_climbdown,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_wade,
lara_col_waterroll,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_col_duck,
lara_col_duck,
lara_col_dash,
lara_col_dashdive,
lara_col_hang2,
lara_col_monkeyswing,
lara_col_monkeyl,
lara_col_monkeyr,
lara_col_monkey180,
lara_col_all4s,
lara_col_crawl,
lara_col_hangturnlr,
lara_col_hangturnlr,
lara_col_all4turnlr,
lara_col_all4turnlr,
lara_col_crawlb,
lara_void_func,
lara_col_crawl2hang,
lara_default_col,
lara_void_func,
lara_void_func,
lara_default_col,
lara_void_func,
lara_void_func,
lara_col_turnswitch,
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_polestat,
lara_col_poleup,
lara_col_poledown,
lara_void_func,
lara_void_func,
lara_default_col,
lara_col_ducklr,
lara_col_ducklr,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_col_rope,
lara_void_func,
lara_void_func,
lara_col_ropefwd,
lara_col_ropefwd,
lara_void_func,
lara_void_func,
lara_col_swim,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
lara_void_func,
2020-05-23 15:59:18 -05:00
lara_void_func,
lara_col_hang_feet,
lara_col_hang_feet_shimmyr,
lara_col_hang_feet_shimmyl,
lara_default_col,
lara_default_col,
lara_default_col,
lara_default_col,
2019-12-02 06:39:51 +01:00
};
/*function<LaraRoutineFunction> lara_camera_routines[NUM_LARA_STATES + 1] = {
};*/
2019-12-02 06:39:51 +01:00
void LaraAboveWater(ITEM_INFO* item, COLL_INFO* coll)
2018-09-16 15:05:16 +02:00
{
coll->old.x = item->pos.xPos;
coll->old.y = item->pos.yPos;
coll->old.z = item->pos.zPos;
coll->oldAnimState = item->currentAnimState;
coll->enableBaddiePush = true;
coll->enableSpaz = true;
coll->slopesAreWalls = false;
coll->slopesArePits = false;
coll->lavaIsPit = false;
coll->oldAnimNumber = item->animNumber;
coll->oldFrameNumber = item->frameNumber;
coll->radius = LARA_RAD;
coll->trigger = NULL;
2018-09-16 15:05:16 +02:00
if ((TrInput & IN_LOOK) && Lara.ExtraAnim == NO_ITEM && Lara.look)
LookLeftRight();
2018-09-16 15:05:16 +02:00
else
ResetLook();
Lara.look = true;
// Process Vehicles
if (Lara.Vehicle != NO_ITEM)
2018-09-16 15:05:16 +02:00
{
switch (Items[Lara.Vehicle].objectNumber)
2018-09-16 15:05:16 +02:00
{
case ID_QUAD:
if (QuadBikeControl())
return;
break;
case ID_JEEP:
if (JeepControl())
return;
break;
case ID_MOTORBIKE:
if (MotorbikeControl())
return;
break;
case ID_KAYAK:
if (KayakControl())
return;
break;
case ID_SNOWMOBILE:
if (SkidooControl())
return;
break;
//case ID_SPEEDBOAT:
// if (BoatControl())
// return;
// break;
//case ID_RUBBERBOAT:
// if (RubberBoatControl())
// return;
// break;
//case ID_UPV:
// if (SubControl())
// return;
// break;
//case ID_MINECART:
// if (MineCartControl())
// return;
// break;
default:
break;
2018-09-16 15:05:16 +02:00
}
}
// Handle current Lara status
lara_control_routines[item->currentAnimState](item, coll);
2018-09-16 15:05:16 +02:00
if (item->pos.zRot >= -ANGLE(1.0f) && item->pos.zRot <= ANGLE(1.0f))
2018-09-16 15:05:16 +02:00
item->pos.zRot = 0;
else if (item->pos.zRot < -ANGLE(1.0f))
item->pos.zRot += ANGLE(1.0f);
2018-09-16 15:05:16 +02:00
else
item->pos.zRot -= ANGLE(1.0f);
2018-09-16 15:05:16 +02:00
if (Lara.turnRate >= -ANGLE(2.0f) && Lara.turnRate <= ANGLE(2.0f))
2018-09-16 15:05:16 +02:00
Lara.turnRate = 0;
else if (Lara.turnRate < -ANGLE(2.0f))
Lara.turnRate += ANGLE(2.0f);
2018-09-16 15:05:16 +02:00
else
Lara.turnRate -= ANGLE(2.0f);
2018-09-16 15:05:16 +02:00
item->pos.yRot += Lara.turnRate;
// Animate Lara
AnimateLara(item);
if (Lara.ExtraAnim == NO_ITEM)
{
// Check for collision with items
LaraBaddieCollision(item, coll);
2018-09-16 15:05:16 +02:00
// Handle Lara collision
if (Lara.Vehicle == NO_ITEM)
lara_collision_routines[item->currentAnimState](item, coll);
}
2018-09-16 15:05:16 +02:00
UpdateLaraRoom(item, -LARA_HITE/2);
2018-09-16 15:05:16 +02:00
//if (Lara.gunType == WEAPON_CROSSBOW && !LaserSight)
// TrInput &= ~IN_ACTION;
2018-09-16 15:05:16 +02:00
// Handle weapons
LaraGun();
// Test if there's a trigger
TestTriggers(coll->trigger, FALSE, 0);
2018-09-16 15:05:16 +02:00
}
int UseSpecialItem(ITEM_INFO* item)
2018-11-28 13:19:01 +01:00
{
2019-12-02 09:11:21 +01:00
short selectedObject = g_Inventory->GetSelectedObject();
if (item->animNumber != ANIMATION_LARA_STAY_IDLE || Lara.gunStatus || selectedObject == NO_ITEM)
return FALSE;
2018-11-28 13:19:01 +01:00
if (selectedObject >= ID_WATERSKIN1_EMPTY && selectedObject <= ID_WATERSKIN2_5)
2018-11-28 13:19:01 +01:00
{
item->itemFlags[2] = 25;
if (selectedObject != ID_WATERSKIN1_3 && selectedObject != ID_WATERSKIN2_5)
2018-11-28 13:19:01 +01:00
{
if (selectedObject >= ID_WATERSKIN2_EMPTY)
Lara.Waterskin2.Quantity = 5;
2018-11-28 13:19:01 +01:00
else
Lara.Waterskin1.Quantity = 3;
2018-11-28 13:19:01 +01:00
item->animNumber = ANIMATION_LARA_WATERSKIN_FILL;
2018-11-28 13:19:01 +01:00
}
else
{
if (selectedObject >= ID_WATERSKIN2_EMPTY)
2018-11-28 13:19:01 +01:00
{
item->itemFlags[3] = Lara.Waterskin2.Quantity;
Lara.Waterskin2.Quantity = 1;
2018-11-28 13:19:01 +01:00
}
else
{
item->itemFlags[3] = Lara.Waterskin1.Quantity;
Lara.Waterskin1.Quantity = 1;
2018-11-28 13:19:01 +01:00
}
item->animNumber = ANIMATION_LARA_WATERSKIN_EMPTY;
2018-11-28 13:19:01 +01:00
}
}
else if (selectedObject == ID_CLOCKWORK_BEETLE)
2018-11-28 13:19:01 +01:00
{
item->animNumber = ANIMATION_LARA_BEETLE_PUT;
2018-11-28 13:19:01 +01:00
//UseClockworkBeetle(1);
}
else
{
return FALSE;
2018-11-28 13:19:01 +01:00
}
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
2018-11-28 13:19:01 +01:00
Lara.gunStatus = LG_HANDS_BUSY;
g_Inventory->SetSelectedObject(NO_ITEM);
2018-11-28 13:19:01 +01:00
return TRUE;
2018-11-28 13:19:01 +01:00
}
void lara_as_stop(ITEM_INFO* item, COLL_INFO* coll)
2018-11-28 13:19:01 +01:00
{
2019-12-02 09:11:21 +01:00
short fheight = NO_HEIGHT;
short rheight = NO_HEIGHT;
2018-11-28 13:19:01 +01:00
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_DEATH;
return;
}
if (item->animNumber != ANIMATION_LARA_SPRINT_SLIDE_STAND_RIGHT && item->animNumber != ANIMATION_LARA_SPRINT_SLIDE_STAND_LEFT)
2018-11-28 13:19:01 +01:00
StopSoundEffect(SFX_LARA_SLIPPING);
// Handles waterskin and clockwork beetle
if (UseSpecialItem(item))
return;
if (TrInput & IN_ROLL && Lara.waterStatus != LW_WADE)
2018-11-28 13:19:01 +01:00
{
item->animNumber = ANIMATION_LARA_ROLL_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase + 2;
2018-11-28 13:19:01 +01:00
item->currentAnimState = STATE_LARA_ROLL_FORWARD;
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (TrInput & IN_DUCK
&& Lara.waterStatus != LW_WADE
&& item->currentAnimState == STATE_LARA_STOP
&& (Lara.gunStatus == LG_NO_ARMS
|| Lara.gunType == WEAPON_NONE
|| Lara.gunType == WEAPON_PISTOLS
|| Lara.gunType == WEAPON_REVOLVER
|| Lara.gunType == WEAPON_UZI
|| Lara.gunType == WEAPON_FLARE))
2018-11-28 13:19:01 +01:00
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
return;
}
item->goalAnimState = STATE_LARA_STOP;
if (TrInput & IN_LOOK)
LookUpDown();
if (TrInput & IN_FORWARD)
fheight = LaraFloorFront(item, item->pos.yRot, LARA_RAD + 4);
2018-11-28 13:19:01 +01:00
else if (TrInput & IN_BACK)
2020-05-31 04:20:52 -05:00
rheight = LaraFloorFront(item, item->pos.yRot - ANGLE(180.0f), LARA_RAD + 4); // TR3: item->pos.yRot + ANGLE(180) ?
2018-11-28 13:19:01 +01:00
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
2018-11-28 13:19:01 +01:00
{
if (TrInput & IN_LEFT)
item->goalAnimState = STATE_LARA_TURN_LEFT_SLOW;
else if (TrInput & IN_RIGHT)
item->goalAnimState = STATE_LARA_TURN_RIGHT_SLOW;
2018-11-28 13:19:01 +01:00
}
else
2018-11-28 13:19:01 +01:00
{
if (TrInput & IN_LSTEP)
{
short height, ceiling;
2020-05-31 04:20:52 -05:00
height = LaraFloorFront(item, item->pos.yRot - ANGLE(90.0f), LARA_RAD + 48);
ceiling = LaraCeilingFront(item, item->pos.yRot - ANGLE(90.0f), LARA_RAD + 48, LARA_HITE);
if ((height < 128 && height > -128) && HeightType != BIG_SLOPE && ceiling <= 0)
item->goalAnimState = STATE_LARA_WALK_LEFT;
}
else if (TrInput & IN_RSTEP)
{
short height, ceiling;
2020-05-31 04:20:52 -05:00
height = LaraFloorFront(item, item->pos.yRot + ANGLE(90.0f), LARA_RAD + 48);
ceiling = LaraCeilingFront(item, item->pos.yRot + ANGLE(90.0f), LARA_RAD + 48, LARA_HITE);
if ((height < 128 && height > -128) && HeightType != BIG_SLOPE && ceiling <= 0)
item->goalAnimState = STATE_LARA_WALK_RIGHT;
}
else if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_TURN_LEFT_SLOW;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_TURN_RIGHT_SLOW;
}
2018-11-28 13:19:01 +01:00
}
if (Lara.waterStatus == LW_WADE)
2018-11-28 13:19:01 +01:00
{
if (TrInput & IN_JUMP && !(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
2018-11-28 13:19:01 +01:00
item->goalAnimState = STATE_LARA_JUMP_PREPARE;
if (TrInput & IN_FORWARD)
{
bool wade = false;
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
{
if (fheight > -(STEPUP_HEIGHT - 1))
{
lara_as_wade(item, coll);
wade = true;
}
}
else
{
if ((fheight < (STEPUP_HEIGHT - 1)) && (fheight > -(STEPUP_HEIGHT - 1)))
{
lara_as_wade(item, coll);
wade = true;
}
}
if (!wade)
2018-11-28 13:19:01 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2018-11-28 13:19:01 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
coll->radius = LARA_RAD + 2;
2018-11-28 13:19:01 +01:00
GetLaraCollisionInfo(item, coll);
if (TestLaraVault(item, coll))
return;
coll->radius = LARA_RAD;
2018-11-28 13:19:01 +01:00
}
}
else if (TrInput & IN_BACK)
2018-11-28 13:19:01 +01:00
{
if ((rheight < (STEPUP_HEIGHT-1)) && (rheight > -(STEPUP_HEIGHT-1)))
lara_as_back(item, coll);
2018-11-28 13:19:01 +01:00
}
}
else
2018-11-28 13:19:01 +01:00
{
if (TrInput & IN_JUMP)
2018-11-28 13:19:01 +01:00
{
item->goalAnimState = STATE_LARA_JUMP_PREPARE;
2018-11-28 13:19:01 +01:00
}
else if (TrInput & IN_FORWARD)
2018-11-28 13:19:01 +01:00
{
short height, ceiling;
2018-11-28 13:19:01 +01:00
height = LaraFloorFront(item, item->pos.yRot, LARA_RAD+4);
ceiling = LaraCeilingFront(item, item->pos.yRot, LARA_RAD+4, LARA_HITE);
2019-11-21 07:43:34 +01:00
if ((HeightType == BIG_SLOPE || HeightType == DIAGONAL) && (height < 0 || ceiling > 0))
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
2019-12-02 06:39:51 +01:00
if (height >= -STEP_SIZE || fheight >= -STEP_SIZE)
{
if (TrInput & IN_WALK)
lara_as_walk(item, coll);
else
lara_as_run(item, coll);
}
else
2019-12-02 06:39:51 +01:00
{
Lara.moveAngle = item->pos.yRot;
2019-12-02 06:39:51 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = 0;
coll->radius = LARA_RAD + 2;
coll->slopesAreWalls = true;
GetLaraCollisionInfo(item, coll);
if (!TestLaraVault(item, coll))
{
coll->radius = LARA_RAD;
item->goalAnimState = STATE_LARA_STOP;
}
2019-12-02 06:39:51 +01:00
}
}
else if (TrInput & IN_BACK)
2019-12-02 06:39:51 +01:00
{
if (TrInput & IN_WALK)
{
if ((rheight < (STEPUP_HEIGHT-1)) && (rheight > -(STEPUP_HEIGHT-1)) && HeightType != BIG_SLOPE)
lara_as_back(item, coll);
}
else if (rheight > -(STEPUP_HEIGHT-1))
{
item->goalAnimState = STATE_LARA_RUN_BACK;
}
2019-12-02 06:39:51 +01:00
}
}
}
2019-11-21 07:43:34 +01:00
void lara_as_pbleapoff(ITEM_INFO* item, COLL_INFO* coll)//1D244, 1D3D8 (F)
2019-11-21 07:43:34 +01:00
{
ITEM_INFO* pitem = (ITEM_INFO*)Lara.generalPtr;
item->gravityStatus = true;
if (item->frameNumber == Anims[item->animNumber].frameBase)
{
2019-12-02 09:11:21 +01:00
int dist;
2019-11-21 07:43:34 +01:00
if (item->pos.yRot == pitem->pos.yRot)
{
dist = pitem->triggerFlags / 100 - 2;
}
else
{
dist = pitem->triggerFlags % 100 - 2;
}
item->fallspeed = -(20 * dist + 64);
item->speed = 20 * dist + 58;
}
if (item->frameNumber == Anims[item->animNumber].frameEnd)
{
2020-04-25 16:23:53 +02:00
item->pos.xPos += 700 * phd_sin(item->pos.yRot) >> W2V_SHIFT;
2019-12-26 07:24:39 +01:00
item->pos.yPos -= 361;
2020-04-25 16:23:53 +02:00
item->pos.zPos += 700 * phd_cos(item->pos.yRot) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
item->animNumber = ANIMATION_LARA_TRY_HANG_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_REACH;
item->currentAnimState = STATE_LARA_REACH;
}
}
void lara_as_parallelbars(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
if (!(TrInput & IN_ACTION))
{
item->goalAnimState = STATE_LARA_BARS_JUMP;
}
}
void lara_as_trfall(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
if (item->animNumber == ANIMATION_LARA_TIGHTROPE_FALL_LEFT || item->animNumber == ANIMATION_LARA_TIGHTROPE_FALL_RIGHT)
{
if (item->frameNumber == Anims[item->animNumber].frameEnd)
{
PHD_VECTOR pos;
pos.x = 0;
pos.y = 0;
pos.z = 0;
GetLaraJointPosition(&pos, LM_RFOOT);
2019-11-21 07:43:34 +01:00
item->pos.xPos = pos.x;
item->pos.yPos = pos.y + 75;
item->pos.zPos = pos.z;
item->goalAnimState = STATE_LARA_FREEFALL;
item->currentAnimState = STATE_LARA_FREEFALL;
2019-12-01 08:13:19 +01:00
item->animNumber = ANIMATION_LARA_FREE_FALL_LONG;
2019-11-21 07:43:34 +01:00
item->frameNumber = Anims[item->animNumber].frameBase;
item->fallspeed = 81;
Camera.targetspeed = 16;
}
}
else
{
2019-12-02 09:11:21 +01:00
int undoInp, wrongInput;
int undoAnim, undoFrame;
2019-11-21 07:43:34 +01:00
if (Lara.tightRopeOnCount > 0)
Lara.tightRopeOnCount--;
if (item->animNumber == ANIMATION_LARA_TIGHTROPE_LOOSE_LEFT)
{
undoInp = IN_RIGHT;
wrongInput = IN_LEFT;
undoAnim = ANIMATION_LARA_TIGHTROPE_RECOVER_LEFT;
}
else if (item->animNumber == ANIMATION_LARA_TIGHTROPE_LOOSE_RIGHT)
{
undoInp = IN_LEFT;
wrongInput = IN_RIGHT;
undoAnim = ANIMATION_LARA_TIGHTROPE_RECOVER_RIGHT;
}
else
{
return;
}
undoFrame = Anims[item->animNumber].frameEnd + Anims[undoAnim].frameBase - item->frameNumber;
if (TrInput & undoInp && Lara.tightRopeOnCount == 0)
{
item->currentAnimState = STATE_LARA_TIGHTROPE_RESTORE_BALANCE;
item->goalAnimState = STATE_LARA_TIGHTROPE_IDLE;
item->animNumber = undoAnim;
item->frameNumber = undoFrame;
Lara.tightRopeFall--;
}
else
{
if (TrInput & wrongInput)
{
if (Lara.tightRopeOnCount < 10)
Lara.tightRopeOnCount += (GetRandomControl() & 3) + 2;
}
}
}
}
void lara_as_trwalk(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
if (Lara.tightRopeOnCount)
{
Lara.tightRopeOnCount--;
}
else if (Lara.tightRopeOff)
{
2019-12-02 09:11:21 +01:00
short roomNumber = item->roomNumber;
2019-11-21 07:43:34 +01:00
if (GetFloorHeight(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos) == item->pos.yPos)
{
Lara.tightRopeOff = 0;
item->goalAnimState = STATE_LARA_TIGHTROPE_EXIT;
}
}
else
{
GetTighRopeFallOff(127);
}
if (LaraItem->currentAnimState != STATE_LARA_TIGHTROPE_BALANCING_LEFT)
{
if (TrInput & IN_LOOK)
{
LookUpDown();
}
if (item->goalAnimState != STATE_LARA_TIGHTROPE_EXIT &&
(Lara.tightRopeFall
|| (TrInput & IN_BACK || TrInput & IN_ROLL || !(TrInput & IN_FORWARD)) && !Lara.tightRopeOnCount && !Lara.tightRopeOff))
{
item->goalAnimState = STATE_LARA_TIGHTROPE_IDLE;
}
}
}
void lara_as_trpose(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_LOOK)
LookUpDown();
GetTighRopeFallOff(127);
if (LaraItem->currentAnimState != STATE_LARA_TIGHTROPE_BALANCING_LEFT)
{
if (Lara.tightRopeFall)
{
if (GetRandomControl() & 1)
item->goalAnimState = STATE_LARA_TIGHTROPE_BALANCING_RIGHT;
else
item->goalAnimState = STATE_LARA_TIGHTROPE_BALANCING_LEFT;
}
else
{
if (TrInput & IN_FORWARD)
{
item->goalAnimState = STATE_LARA_TIGHTROPE_FORWARD;
}
else if ((TrInput & IN_ROLL) || (TrInput & IN_BACK))
{
if (item->animNumber == ANIMATION_LARA_TIGHTROPE_STAND)
{
item->currentAnimState = STATE_LARA_TIGHTROPE_TURNAROUND;
item->animNumber = ANIMATION_LARA_TIGHTROPE_TURN;
item->frameNumber = Anims[item->animNumber].frameBase;
GetTighRopeFallOff(1);
}
}
}
}
}
void GetTighRopeFallOff(int regularity)
2019-11-21 07:43:34 +01:00
{
if (LaraItem->hitPoints <= 0 || LaraItem->hitStatus)
{
LaraItem->goalAnimState = STATE_LARA_TIGHTROPE_BALANCING_LEFT;
LaraItem->currentAnimState = STATE_LARA_TIGHTROPE_BALANCING_LEFT;
LaraItem->animNumber = ANIMATION_LARA_TIGHTROPE_FALL_LEFT;
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
}
if (!Lara.tightRopeFall && !(GetRandomControl() & regularity))
Lara.tightRopeFall = 2 - ((GetRandomControl() & 0xF) != 0);
}
void LookLeftRight()
2019-11-21 07:43:34 +01:00
{
Camera.type = LOOK_CAMERA;
if (TrInput & IN_LEFT)
{
TrInput &= ~IN_LEFT;
2020-05-31 04:20:52 -05:00
if (Lara.headYrot > -ANGLE(44.0f))
2019-11-21 07:43:34 +01:00
{
if (BinocularRange)
2020-05-31 04:20:52 -05:00
Lara.headYrot += ANGLE(2.0f) * (BinocularRange - 1792) / 1536;
2019-11-21 07:43:34 +01:00
else
2020-05-31 04:20:52 -05:00
Lara.headYrot -= ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
}
else if (TrInput & IN_RIGHT)
{
TrInput &= ~IN_RIGHT;
2020-05-31 04:20:52 -05:00
if (Lara.headYrot < ANGLE(44.0f))
2019-11-21 07:43:34 +01:00
{
if (BinocularRange)
2020-05-31 04:20:52 -05:00
Lara.headYrot += ANGLE(2.0f) * (1792 - BinocularRange) / 1536;
2019-11-21 07:43:34 +01:00
else
2020-05-31 04:20:52 -05:00
Lara.headYrot += ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
}
if (Lara.gunStatus != LG_HANDS_BUSY && !Lara.leftArm.lock && !Lara.rightArm.lock)
Lara.torsoYrot = Lara.headYrot;
}
void LookUpDown()
2019-11-21 07:43:34 +01:00
{
Camera.type = LOOK_CAMERA;
if (TrInput & IN_FORWARD)
{
TrInput &= ~IN_FORWARD;
2020-05-31 04:20:52 -05:00
if (Lara.headXrot > -ANGLE(35.0f))
2019-11-21 07:43:34 +01:00
{
if (BinocularRange)
2020-05-31 04:20:52 -05:00
Lara.headXrot += ANGLE(2.0f) * (BinocularRange - 1792) / 3072;
2019-11-21 07:43:34 +01:00
else
2020-05-31 04:20:52 -05:00
Lara.headXrot -= ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
}
else if (TrInput & IN_BACK)
{
TrInput &= ~IN_BACK;
2020-05-31 04:20:52 -05:00
if (Lara.headXrot < ANGLE(30.0f))
2019-11-21 07:43:34 +01:00
{
if (BinocularRange)
2020-05-31 04:20:52 -05:00
Lara.headXrot += ANGLE(2.0f) * (1792 - BinocularRange) / 3072;
2019-11-21 07:43:34 +01:00
else
2020-05-31 04:20:52 -05:00
Lara.headXrot += ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
}
if (Lara.gunStatus != LG_HANDS_BUSY && !Lara.leftArm.lock && !Lara.rightArm.lock)
Lara.torsoXrot = Lara.headXrot;
}
void ResetLook()
2019-11-21 07:43:34 +01:00
{
if (Camera.type != 2)
{
2020-05-31 04:20:52 -05:00
if (Lara.headXrot <= -ANGLE(2.0f) || Lara.headXrot >= ANGLE(2.0f))
2019-11-21 07:43:34 +01:00
Lara.headXrot = Lara.headXrot / -8 + Lara.headXrot;
else
Lara.headXrot = 0;
2020-05-31 04:20:52 -05:00
if (Lara.headYrot <= -ANGLE(2.0f) || Lara.headYrot >= ANGLE(2.0f))
2019-11-21 07:43:34 +01:00
Lara.headYrot = Lara.headYrot / -8 + Lara.headYrot;
else
Lara.headYrot = 0;
if (Lara.gunStatus == LG_HANDS_BUSY || Lara.leftArm.lock || Lara.rightArm.lock)
{
if (!Lara.headXrot)
Lara.torsoXrot = 0;
if (!Lara.headYrot)
Lara.torsoYrot = 0;
}
else
{
Lara.torsoYrot = Lara.headYrot;
Lara.torsoXrot = Lara.headXrot;
}
}
}
void lara_col_jumper(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (item->fallspeed > 0 && coll->midFloor <= 0)
{
if (LaraLandedBad(item, coll))
item->goalAnimState = STATE_LARA_DEATH;
else
item->goalAnimState = STATE_LARA_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_default_col(ITEM_INFO* item, COLL_INFO* coll)//1C80C(<), 1C940(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesArePits = true;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
}
void lara_col_wade(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
2019-11-21 07:43:34 +01:00
if (LaraHitCeiling(item, coll))
return;
if (TestLaraVault(item, coll))
return;
2019-12-16 17:11:24 +01:00
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
if ((coll->frontType == WALL || coll->frontType == SPLIT_TRI) && coll->frontFloor < -((STEP_SIZE*5)/2) && !(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
item->currentAnimState = STATE_LARA_SPLAT;
if (item->frameNumber >= 0 && item->frameNumber <= 9)
2019-11-21 07:43:34 +01:00
{
item->animNumber = ANIMATION_LARA_WALL_SMASH_LEFT;
item->frameNumber = Anims[ANIMATION_LARA_WALL_SMASH_LEFT].frameBase;
return;
}
if (item->frameNumber >= 10 && item->frameNumber <= 21)
{
item->animNumber = ANIMATION_LARA_WALL_SMASH_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
return;
2019-11-21 07:43:34 +01:00
}
}
LaraCollideStop(item, coll);
}
if (coll->midFloor >= -STEPUP_HEIGHT && coll->midFloor < -STEP_SIZE/2 && !(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
if (item->frameNumber >= 3 && item->frameNumber <= 14)
2019-11-21 07:43:34 +01:00
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
}
else
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
if (coll->midFloor >= 50 && !(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
{
item->pos.yPos += 50;
return;
2019-11-21 07:43:34 +01:00
}
if (!(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->midFloor < 0)
item->pos.yPos += coll->midFloor; // Enforce to floor height.. if not a swamp room.
else if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->midFloor)
item->pos.yPos += SWAMP_GRAVITY;
2019-11-21 07:43:34 +01:00
}
void lara_col_fastdive(ITEM_INFO* item, COLL_INFO* coll)//1C558(<), 1C68C(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (coll->midFloor <= 0 && item->fallspeed > 0)
{
if (item->fallspeed <= 133)
item->goalAnimState = STATE_LARA_STOP;
else
item->goalAnimState = STATE_LARA_DEATH;
item->fallspeed = 0;
item->gravityStatus = 0;
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_col_swandive(ITEM_INFO* item, COLL_INFO* coll)//1C4A0(<), 1C5D4(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (coll->midFloor <= 0 && item->fallspeed > 0)
{
item->goalAnimState = STATE_LARA_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_col_roll2(ITEM_INFO* item, COLL_INFO* coll)//1C384, 1C4B8 (F)
2019-11-21 07:43:34 +01:00
{
Camera.laraNode = 0;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
item->gravityStatus = false;
item->fallspeed = 0;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (LaraHitCeiling(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
2019-11-21 07:43:34 +01:00
if (coll->midFloor > 200)
{
item->animNumber = ANIMATION_LARA_FREE_FALL_BACK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_FALL_BACKWARD;
item->goalAnimState = STATE_LARA_FALL_BACKWARD;
item->fallspeed = 0;
item->gravityStatus = true;
return;
}
2019-11-21 07:43:34 +01:00
ShiftItem(item, coll);
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
2019-11-21 07:43:34 +01:00
}
void lara_col_roll(ITEM_INFO* item, COLL_INFO* coll)//1C2B0, 1C3E4 (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesArePits = false;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
item->gravityStatus = false;
item->fallspeed = 0;
GetLaraCollisionInfo(item, coll);
if (LaraHitCeiling(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
if (LaraFallen(item, coll))
return;
if (TrInput & IN_FORWARD && item->animNumber == ANIMATION_LARA_LANDING_ROLL)
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
ShiftItem(item, coll);
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
2019-11-21 07:43:34 +01:00
}
void lara_col_slideback(ITEM_INFO* item, COLL_INFO* coll)//1C284(<), 1C3B8(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
lara_slide_slope(item, coll);
}
void lara_col_fallback(ITEM_INFO* item, COLL_INFO* coll)//1C1B4(<), 1C2E8(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (item->fallspeed > 0 && coll->midFloor <= 0)
{
if (LaraLandedBad(item, coll))
item->goalAnimState = STATE_LARA_DEATH;
else
item->goalAnimState = STATE_LARA_STOP;
item->fallspeed = 0;
item->gravityStatus = 0;
2019-11-21 07:43:34 +01:00
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_col_leftjump(ITEM_INFO* item, COLL_INFO* coll)//1C188(<), 1C2BC(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
lara_col_jumper(item, coll);
}
void lara_col_rightjump(ITEM_INFO* item, COLL_INFO* coll)//1C15C(<), 1C290(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
lara_col_jumper(item, coll);
}
void lara_col_backjump(ITEM_INFO* item, COLL_INFO* coll)//1C130(<), 1C264(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
lara_col_jumper(item, coll);
}
void lara_col_slide(ITEM_INFO* item, COLL_INFO* coll)//1C108(<), 1C23C(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
lara_slide_slope(item, coll);
}
void lara_col_stepleft(ITEM_INFO* item, COLL_INFO* coll)//1C0E8(<), 1C21C(<) (F)
2019-11-21 07:43:34 +01:00
{
lara_col_stepright(item, coll);
}
void lara_col_stepright(ITEM_INFO* item, COLL_INFO* coll)//1BFB0, 1C0E4 (F)
2019-11-21 07:43:34 +01:00
{
if (item->currentAnimState == STATE_LARA_WALK_RIGHT)
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
else
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
item->gravityStatus = false;
item->fallspeed = 0;
if (Lara.waterStatus == LW_WADE)
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
else
coll->badPos = 128;
coll->slopesAreWalls = true;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
coll->badNeg = -128;
coll->badCeiling = 0;
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll))
{
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
if (!LaraFallen(item, coll) && !TestLaraSlide(item, coll) && coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
2020-03-31 21:03:28 -03:00
void lara_col_back(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = false;
item->fallspeed = 0;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
if (Lara.waterStatus == LW_WADE)
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
else
coll->badPos = STEPUP_HEIGHT;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesArePits = true;
2020-03-31 21:03:28 -03:00
coll->slopesAreWalls = 1;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (LaraHitCeiling(item, coll))
return;
2019-11-21 07:43:34 +01:00
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
2019-11-21 07:43:34 +01:00
if (LaraFallen(item, coll))
return;
2020-03-31 21:03:28 -03:00
if (coll->midFloor > STEP_SIZE / 2 && coll->midFloor < STEPUP_HEIGHT)
{
if (item->frameNumber >= 964 && item->frameNumber <= 993)
{
item->animNumber = ANIMATION_LARA_WALK_DOWN_BACK_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_WALK_DOWN_BACK_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
}
}
if (TestLaraSlide(item, coll))
return;
2020-03-31 21:03:28 -03:00
#if 0
if (!(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->midFloor < 0)
item->pos.yPos += coll->midFloor;
else if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->midFloor)
item->pos.yPos += SWAMP_GRAVITY;
2020-03-31 21:03:28 -03:00
#else
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
#endif
2019-11-21 07:43:34 +01:00
}
void lara_col_compress(ITEM_INFO* item, COLL_INFO* coll)//1BD30, 1BE64 (F)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = NO_HEIGHT;
coll->badCeiling = 0;
GetLaraCollisionInfo(item, coll);
if (!LaraFallen(item, coll))
{
if (coll->midCeiling > -100)
{
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->currentAnimState = STATE_LARA_STOP;
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
}
if (coll->midFloor > -256 && coll->midFloor < 256)
item->pos.yPos += coll->midFloor;
}
}
void lara_col_land(ITEM_INFO* item, COLL_INFO* coll)//1BD10(<), 1BE44(<) (F)
2019-11-21 07:43:34 +01:00
{
lara_col_stop(item, coll);
}
void lara_col_splat(ITEM_INFO* item, COLL_INFO* coll)//1BC74(<), 1BDA8(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->slopesAreWalls = true;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
GetLaraCollisionInfo(item, coll);
ShiftItem(item, coll);
if (coll->midFloor >= -256 && coll->midFloor <= 256)
item->pos.yPos += coll->midFloor;
}
void lara_col_fastfall(ITEM_INFO* item, COLL_INFO* coll)//1BB88, 1BCBC (F)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = true;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraSlideEdgeJump(item, coll);
if (coll->midFloor <= 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = STATE_LARA_DEATH;
}
else
{
item->goalAnimState = STATE_LARA_STOP;
item->currentAnimState = STATE_LARA_STOP;
item->animNumber = ANIMATION_LARA_LANDING_HARD;
item->frameNumber = Anims[item->animNumber].frameBase;
}
StopSoundEffect(SFX_LARA_FALL);
item->fallspeed = 0;
item->gravityStatus = false;
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_col_death(ITEM_INFO* item, COLL_INFO* coll)//1BADC(<), 1BC10(<) (F)
2019-11-21 07:43:34 +01:00
{
StopSoundEffect(SFX_LARA_FALL);
Lara.moveAngle = item->pos.yRot;
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->radius = 400;
GetLaraCollisionInfo(item, coll);
ShiftItem(item, coll);
item->hitPoints = -1;
Lara.air = -1;
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
void lara_col_turn_l(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
lara_col_turn_r(item, coll);
}
void lara_col_turn_r(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
Lara.moveAngle = item->pos.yRot;
coll->badPos = STEPUP_HEIGHT;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = 1;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
2020-01-29 08:29:15 +01:00
#if 1
if (coll->midFloor > 100)
2020-01-29 08:29:15 +01:00
#else
if (coll->midFloor > 100 && !(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP))
2020-01-29 08:29:15 +01:00
#endif
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->gravityStatus = true;
return;
2019-11-21 07:43:34 +01:00
}
if (TestLaraSlide(item, coll))
return;
2020-01-29 08:29:15 +01:00
#if 1
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
#else
if (!(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->midFloor < 0)
item->pos.yPos += coll->midFloor;
else if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->midFloor)
item->pos.yPos += SWAMP_GRAVITY;
2020-01-29 08:29:15 +01:00
#endif
2019-11-21 07:43:34 +01:00
}
void lara_col_fastback(ITEM_INFO* item, COLL_INFO* coll)//1B89C, 1B9D0 (F)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
coll->slopesAreWalls = 0;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll))
{
if (coll->midFloor <= 200)
{
if (LaraDeflectEdge(item, coll))
LaraCollideStop(item, coll);
if (!TestLaraSlide(item, coll) && coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
else
{
item->fallspeed = 0;
item->animNumber = ANIMATION_LARA_FREE_FALL_BACK;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_FALL_BACKWARD;
item->goalAnimState = STATE_LARA_FALL_BACKWARD;
item->gravityStatus = true;
}
}
}
void lara_col_pose(ITEM_INFO* item, COLL_INFO* coll)//1B87C(<), 1B9B0(<) (F)
2019-11-21 07:43:34 +01:00
{
lara_col_stop(item, coll);
}
void lara_col_run(ITEM_INFO* item, COLL_INFO* coll)//1B64C, 1B780 (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
if (item->animNumber != ANIMATION_LARA_STAY_TO_RUN && TestWall(item, 256, 0, -640))
{
item->currentAnimState = STATE_LARA_SPLAT;
if (item->frameNumber >= 0 && item->frameNumber <= 9)
{
item->animNumber = ANIMATION_LARA_WALL_SMASH_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
return;
}
if (item->frameNumber >= 10 && item->frameNumber <= 21)
{
item->animNumber = ANIMATION_LARA_WALL_SMASH_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
return;
}
}
LaraCollideStop(item, coll);
}
if (!LaraFallen(item, coll))
{
if (coll->midFloor >= -384 && coll->midFloor < -128)
{
if (coll->frontFloor == NO_HEIGHT || coll->frontFloor < -384 || coll->frontFloor >= -128)
{
coll->midFloor = 0;
}
else
{
if (item->frameNumber >= 3 && item->frameNumber <= 14)
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
}
if (!TestLaraSlide(item, coll))
{
if (coll->midFloor < 50)
{
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
else
{
item->pos.yPos += 50;
}
}
}
}
}
void lara_col_walk(ITEM_INFO* item, COLL_INFO* coll)//1B3E8, 1B51C (F)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot;
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
coll->lavaIsPit = 1;
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
if (item->frameNumber >= 29 && item->frameNumber <= 47)
{
item->animNumber = ANIMATION_LARA_END_WALK_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
if (item->frameNumber >= 22 && item->frameNumber <= 28 ||
item->frameNumber >= 48 && item->frameNumber <= 57)
{
item->animNumber = ANIMATION_LARA_END_WALK_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
LaraCollideStop(item, coll);
}
}
}
if (!LaraFallen(item, coll))
{
if (coll->midFloor > 128)
{
if (coll->frontFloor == NO_HEIGHT || coll->frontFloor <= 128)
{
coll->midFloor = 0;
}
else
{
if (item->frameNumber >= 28 && item->frameNumber <= 45)
{
item->animNumber = ANIMATION_LARA_WALK_DOWN_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_WALK_DOWN_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
}
if (coll->midFloor >= -384 && coll->midFloor < -128)
{
if (coll->frontFloor == NO_HEIGHT ||
coll->frontFloor < -384 ||
coll->frontFloor >= -128)
{
coll->midFloor = 0;
}
else
{
if (item->frameNumber >= 27 && item->frameNumber <= 44)
{
item->animNumber = ANIMATION_LARA_WALK_UP_STEP_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_WALK_UP_STEP_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
}
if (!TestLaraSlide(item, coll) && coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
}
void lara_as_pulley(ITEM_INFO* item, COLL_INFO* coll)//1B288, 1B3BC (F)
2019-11-21 07:43:34 +01:00
{
ITEM_INFO* p = (ITEM_INFO*) Lara.generalPtr;
Lara.look = false;
coll->enableSpaz = false;
coll->enableBaddiePush = false;
if (TrInput & IN_ACTION && p->triggerFlags)
{
item->goalAnimState = STATE_LARA_PULLEY;
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
if (item->animNumber == ANIMATION_LARA_PULLEY_PULL && item->frameNumber == Anims[ANIMATION_LARA_PULLEY_PULL].frameBase + 44)
{
if (p->triggerFlags)
{
p->triggerFlags--;
if (p->triggerFlags)
{
if (p->itemFlags[2])
{
p->itemFlags[2] = 0;
p->status = ITEM_DESACTIVATED;
2019-11-21 07:43:34 +01:00
}
}
else
{
if (!p->itemFlags[1])
p->status = ITEM_DESACTIVATED;
2019-11-21 07:43:34 +01:00
p->itemFlags[2] = 1;
if (p->itemFlags[3] >= 0)
p->triggerFlags = abs(p->itemFlags[3]);
else
p->itemFlags[0] = 1;
}
}
}
if (item->animNumber == ANIMATION_LARA_PULLEY_UNGRAB && item->frameNumber == Anims[item->animNumber].frameEnd - 1)
Lara.gunStatus = LG_NO_ARMS;
}
void lara_col_turnswitch(ITEM_INFO* item, COLL_INFO* coll)//1B1B4(<), 1B2E8(<) (F)
2019-11-21 07:43:34 +01:00
{
if (coll->old.x != item->pos.xPos || coll->old.z != item->pos.zPos)
{
if (item->animNumber == ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_CONTINUE)
{
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
item->animNumber = ANIMATION_LARA_ROUND_HANDLE_PUSH_LEFT_END;
item->frameNumber = Anims[item->animNumber].frameBase;
}
if (item->animNumber == ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_CONTINUE)
{
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
item->animNumber = ANIMATION_LARA_ROUND_HANDLE_PUSH_RIGHT_END;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
}
void lara_as_controlledl(ITEM_INFO* item, COLL_INFO* coll)//1B180(<), 1B2B4(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
}
void lara_as_controlled(ITEM_INFO* item, COLL_INFO* coll)//1B0FC(<), 1B230(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (item->frameNumber == Anims[item->animNumber].frameEnd - 1)
{
Lara.gunStatus = LG_NO_ARMS;
if (UseForcedFixedCamera)
UseForcedFixedCamera = 0;
}
}
void lara_as_deathslide(ITEM_INFO* item, COLL_INFO* coll)//1B038, 1B16C (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short roomNumber = item->roomNumber;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(70.0f);
2019-11-21 07:43:34 +01:00
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->goalAnimState = STATE_LARA_JUMP_FORWARD;
AnimateLara(item);
LaraItem->gravityStatus = true;
LaraItem->speed = 100;
LaraItem->fallspeed = 40;
Lara.moveAngle = item->pos.yRot;
}
}
void lara_as_wade(ITEM_INFO* item, COLL_INFO* coll)//1AF10, 1B044 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(22.0f);
2019-11-21 07:43:34 +01:00
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -(LARA_FAST_TURN >> 1))
Lara.turnRate = -(LARA_FAST_TURN >> 1);
2019-11-21 07:43:34 +01:00
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -(LARA_LEAN_MAX >> 1))
item->pos.zRot = -(LARA_LEAN_MAX >> 1);
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > (LARA_FAST_TURN >> 1))
Lara.turnRate = (LARA_FAST_TURN >> 1);
2019-11-21 07:43:34 +01:00
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > (LARA_LEAN_MAX >> 1))
item->pos.zRot = (LARA_LEAN_MAX >> 1);
}
2019-11-21 07:43:34 +01:00
if (TrInput & IN_FORWARD)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_WADE_FORWARD;
else
item->goalAnimState = STATE_LARA_STOP;
2019-11-21 07:43:34 +01:00
}
else
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_FAST_TURN)
Lara.turnRate = -LARA_FAST_TURN;
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX)
item->pos.zRot = -LARA_LEAN_MAX;
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_FAST_TURN)
Lara.turnRate = LARA_FAST_TURN;
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX)
item->pos.zRot = LARA_LEAN_MAX;
}
if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_ABOVE_WATER)
item->goalAnimState = STATE_LARA_RUN_FORWARD;
else
item->goalAnimState = STATE_LARA_WADE_FORWARD;
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
2019-11-21 07:43:34 +01:00
}
}
void lara_as_waterout(ITEM_INFO* item, COLL_INFO* coll)//1AEE4(<), 1B018(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.flags = CF_FOLLOW_CENTER;
}
void lara_as_gymnast(ITEM_INFO* item, COLL_INFO* coll)//1AEC8(<), 1AFFC(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
}
void lara_as_fastdive(ITEM_INFO* item, COLL_INFO* coll)//1AE4C(<), 1AF80(<) (F)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ROLL && item->goalAnimState == STATE_LARA_SWANDIVE_END)
item->goalAnimState = STATE_LARA_JUMP_ROLL;
coll->enableBaddiePush = true;
coll->enableSpaz = false;
item->speed = (item->speed * 95) / 100;
}
void lara_as_swandive(ITEM_INFO* item, COLL_INFO* coll)//1AE08(<), 1AF3C(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = true;
coll->enableSpaz = false;
if (item->fallspeed > LARA_FREEFALL_SPEED && item->goalAnimState != STATE_LARA_UNDERWATER_DIVING)
item->goalAnimState = STATE_LARA_SWANDIVE_END;
}
void lara_as_special(ITEM_INFO* item, COLL_INFO* coll)//1ADDC(<), 1AF10(<) (F)
2019-11-21 07:43:34 +01:00
{
Camera.flags = CF_FOLLOW_CENTER;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(170.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
}
void lara_as_usepuzzle(ITEM_INFO* item, COLL_INFO* coll)//1AD18(<), 1AE4C(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = -ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
if (item->frameNumber == Anims[item->animNumber].frameEnd)
{
if (item->itemFlags[0])
{
item->animNumber = item->itemFlags[0];
item->currentAnimState = STATE_LARA_MISC_CONTROL;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
}
}
}
void lara_as_usekey(ITEM_INFO* item, COLL_INFO* coll)//1ACBC(<), 1ADF0(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = -ANGLE(80.0f);
Camera.targetElevation = -4550;
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
}
void lara_as_switchoff(ITEM_INFO* item, COLL_INFO* coll)//1AC54(<), 1AD88(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
Camera.speed = 6;
}
void lara_as_switchon(ITEM_INFO* item, COLL_INFO* coll)//1ABEC(<), 1AD20(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(80.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
Camera.speed = 6;
}
void lara_as_pickupflare(ITEM_INFO* item, COLL_INFO* coll)//1AB5C(<), 1AC90(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(130.0f);
Camera.targetElevation = -ANGLE(15.0f);
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
if (item->frameNumber == Anims[item->animNumber].frameEnd - 1)
2019-11-21 07:43:34 +01:00
Lara.gunStatus = LG_NO_ARMS;
}
void lara_as_pickup(ITEM_INFO* item, COLL_INFO* coll)//1AB00(<), 1AC34(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = -ANGLE(130.0f);
Camera.targetElevation = -ANGLE(15.0f);
2019-11-21 07:43:34 +01:00
Camera.targetDistance = SECTOR(1);
}
void lara_as_ppready(ITEM_INFO* item, COLL_INFO* coll)//1AABC(<), 1ABF0(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(75.0f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_ACTION))
item->goalAnimState = STATE_LARA_STOP;
}
void lara_as_pullblock(ITEM_INFO* item, COLL_INFO* coll)//1AA60(<), 1AB94(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.flags = CF_FOLLOW_CENTER;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(35.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
}
void lara_as_pushblock(ITEM_INFO* item, COLL_INFO* coll)//1AA04(<), 1AB38(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.flags = CF_FOLLOW_CENTER;
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(90.0f);
Camera.targetElevation = -ANGLE(25.0f);
2019-11-21 07:43:34 +01:00
}
void lara_as_slideback(ITEM_INFO* item, COLL_INFO* coll)//1A9E0(<), 1AB14(<) (F)
2019-11-21 07:43:34 +01:00
{
if ((TrInput & IN_JUMP) && !(TrInput & IN_FORWARD))
{
item->goalAnimState = STATE_LARA_JUMP_BACK;
}
}
void lara_as_fallback(ITEM_INFO* item, COLL_INFO* coll)//1959C(<), 196D0(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = STATE_LARA_FREEFALL;
if (TrInput & IN_ACTION)
if (Lara.gunStatus == LG_NO_ARMS)
item->goalAnimState = STATE_LARA_REACH;
}
void lara_as_leftjump(ITEM_INFO* item, COLL_INFO* coll)//1A92C(<), 1AA60(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_FREEFALL;
else if (TrInput & IN_RIGHT && item->goalAnimState != STATE_LARA_STOP)
item->goalAnimState = STATE_LARA_JUMP_ROLL;
2019-11-21 07:43:34 +01:00
}
void lara_as_rightjump(ITEM_INFO* item, COLL_INFO* coll)//1A8C4(<), 1A9F8(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
if (item->fallspeed > LARA_FREEFALL_SPEED)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_FREEFALL;
else if (TrInput & IN_LEFT && item->goalAnimState != STATE_LARA_STOP)
item->goalAnimState = STATE_LARA_JUMP_ROLL;
2019-11-21 07:43:34 +01:00
}
void lara_as_backjump(ITEM_INFO* item, COLL_INFO* coll)//1A854(<), 1A988(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(135.0f);
2019-11-21 07:43:34 +01:00
if (item->fallspeed <= LARA_FREEFALL_SPEED)
{
if (item->goalAnimState == STATE_LARA_RUN_FORWARD)
{
item->goalAnimState = STATE_LARA_STOP;
}
else if ((TrInput & IN_FORWARD || TrInput & IN_ROLL) && item->goalAnimState != STATE_LARA_STOP)
{
item->goalAnimState = STATE_LARA_JUMP_ROLL;
}
}
else
{
item->goalAnimState = STATE_LARA_FREEFALL;
}
}
void lara_as_slide(ITEM_INFO* item, COLL_INFO* coll)//1A824(<), 1A958(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f); // FIXED
2019-11-21 07:43:34 +01:00
if ((TrInput & IN_JUMP) && !(TrInput & IN_BACK))
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
}
void lara_as_stepleft(ITEM_INFO* item, COLL_INFO* coll)//1A750(<), 1A884(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (!Lara.isMoving)
{
if (!(TrInput & IN_LSTEP))
{
item->goalAnimState = STATE_LARA_STOP;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_SLOW_TURN)
Lara.turnRate = -LARA_SLOW_TURN;
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_SLOW_TURN)
Lara.turnRate = LARA_SLOW_TURN;
2019-11-21 07:43:34 +01:00
}
}
}
void lara_as_stepright(ITEM_INFO* item, COLL_INFO* coll)//1A67C(<), 1A7B0(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
2019-11-21 07:43:34 +01:00
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (!Lara.isMoving)
{
if (!(TrInput & IN_RSTEP))
{
item->goalAnimState = STATE_LARA_STOP;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
}
}
void lara_col_fastturn(ITEM_INFO* item, COLL_INFO* coll)//1A65C(<), 1A790(<) (F)
2019-11-21 07:43:34 +01:00
{
lara_col_stop(item, coll);
}
void lara_as_fastturn(ITEM_INFO* item, COLL_INFO* coll)//1A5F8(<), 1A72C(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (Lara.turnRate < 0)
2019-11-21 07:43:34 +01:00
{
Lara.turnRate = -LARA_FAST_TURN;
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_LEFT))
item->goalAnimState = STATE_LARA_STOP;
2019-11-21 07:43:34 +01:00
}
else
{
Lara.turnRate = LARA_FAST_TURN;
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_RIGHT))
item->goalAnimState = STATE_LARA_STOP;
2019-11-21 07:43:34 +01:00
}
}
void lara_as_null(ITEM_INFO* item, COLL_INFO* coll)//1A5DC(<), 1A710(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
}
void lara_as_back(ITEM_INFO* item, COLL_INFO* coll)//1A4F0(<), 1A624(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (!Lara.isMoving)
{
if ((TrInput & IN_BACK) && ((TrInput & IN_WALK) || Lara.waterStatus == LW_WADE))
item->goalAnimState = STATE_LARA_WALK_BACK;
else
item->goalAnimState = STATE_LARA_STOP;
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
}
}
void lara_as_compress(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
if (Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_FORWARD && LaraFloorFront(item, item->pos.yRot, 256) >= -384)
{
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
Lara.moveAngle = item->pos.yRot;
}
2020-05-31 04:20:52 -05:00
else if (TrInput & IN_LEFT && LaraFloorFront(item, item->pos.yRot - ANGLE(90.0f), 256) >= -384)
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_JUMP_RIGHT;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
2020-05-31 04:20:52 -05:00
else if (TrInput & IN_RIGHT && LaraFloorFront(item, item->pos.yRot + ANGLE(90.0f), 256) >= -384)
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_JUMP_LEFT;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
2020-05-31 04:20:52 -05:00
else if (TrInput & IN_BACK && LaraFloorFront(item, item->pos.yRot - ANGLE(180.0f), 256) >= -384)
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_JUMP_BACK;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
}
}
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = STATE_LARA_FREEFALL;
}
void lara_as_splat(ITEM_INFO* item, COLL_INFO* coll)//1A340(<), 1A474(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
}
void lara_as_intcornerr(ITEM_INFO* item, COLL_INFO* coll)//1A2EC(<), 1A420(<) (F)
2019-11-21 07:43:34 +01:00
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, ANGLE(90.0f),
2019-11-21 07:43:34 +01:00
item->animNumber == ANIMATION_LARA_HANG_AROUND_RIGHT_INNER_END ||
item->animNumber == ANIMATION_LARA_LADDER_AROUND_RIGHT_INNER_END);
}
void lara_as_intcornerl(ITEM_INFO* item, COLL_INFO* coll)//1A298(<), 1A3CC(<) (F)
2019-11-21 07:43:34 +01:00
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, -ANGLE(90.0f),
2019-11-21 07:43:34 +01:00
item->animNumber == ANIMATION_LARA_HANG_AROUND_LEFT_INNER_END ||
item->animNumber == ANIMATION_LARA_LADDER_AROUND_LEFT_INNER_END);
}
void lara_as_extcornerr(ITEM_INFO* item, COLL_INFO* coll)//1A244(<), 1A378(<) (F)
2019-11-21 07:43:34 +01:00
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, -ANGLE(90.0f),
2019-11-21 07:43:34 +01:00
item->animNumber == ANIMATION_LARA_HANG_AROUND_RIGHT_OUTER_END ||
item->animNumber == ANIMATION_LARA_LADDER_AROUND_RIGHT_OUTER_END);
}
void lara_as_extcornerl(ITEM_INFO* item, COLL_INFO* coll)//1A1F0(<), 1A324(<) (F)
2019-11-21 07:43:34 +01:00
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnim(item, coll, ANGLE(90.0f),
2019-11-21 07:43:34 +01:00
item->animNumber == ANIMATION_LARA_HANG_AROUND_LEFT_OUTER_END ||
item->animNumber == ANIMATION_LARA_LADDER_AROUND_LEFT_OUTER_END);
}
void SetCornerAnim(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip)//1A090, 1A1C4 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->gravityStatus = true;
item->speed = 2;
item->pos.yPos += 256;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
item->pos.yRot += rot / 2;
}
else if (flip)
{
if (Lara.isClimbing)
{
item->animNumber = ANIMATION_LARA_LADDER_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->currentAnimState = STATE_LARA_LADDER_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase + 21;
item->goalAnimState = STATE_LARA_HANG;
item->currentAnimState = STATE_LARA_HANG;
}
coll->old.x = Lara.cornerX;
item->pos.xPos = Lara.cornerX;
coll->old.z = Lara.cornerZ;
item->pos.zPos = Lara.cornerZ;
item->pos.yRot += rot;
}
}
void lara_col_hangright(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
coll->radius = 102; /* @ORIGINAL_BUG: this value (instead of LARA_RAD) can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
2019-11-21 07:43:34 +01:00
LaraHangTest(item, coll);
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
void lara_as_hangright(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
item->goalAnimState = STATE_LARA_HANG;
}
void lara_col_hangleft(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
coll->radius = 102; /* @ORIGINAL_BUG: this value (instead of LARA_RAD) can make Lara glitch if coll->frontType is DIAGONAL or SPLIT_TRI */
2019-11-21 07:43:34 +01:00
LaraHangTest(item, coll);
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
void lara_as_hangleft(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
item->goalAnimState = STATE_LARA_HANG;
}
void lara_col_hang(ITEM_INFO* item, COLL_INFO* coll)//19AC8, 19BFC (F)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
if (item->animNumber == ANIMATION_LARA_HANG_IDLE && item->frameNumber == Anims[item->animNumber].frameBase + 21)
{
2019-12-02 09:11:21 +01:00
int flag;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
2020-05-31 04:20:52 -05:00
if (CanLaraHangSideways(item, coll, -ANGLE(90.0f)))
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_SHIMMY_LEFT;
return;
}
flag = LaraHangLeftCornerTest(item, coll);
if (flag != 0)
{
if (flag <= 0)
item->goalAnimState = STATE_LARA_CLIMB_CORNER_LEFT_INNER;
else
item->goalAnimState = STATE_LARA_CLIMB_CORNER_LEFT_OUTER;
return;
}
}
if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
2020-05-31 04:20:52 -05:00
if (CanLaraHangSideways(item, coll, ANGLE(90.0f)))
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_SHIMMY_RIGHT;
return;
}
flag = LaraHangRightCornerTest(item, coll);
if (flag != 0)
{
if (flag <= 0)
item->goalAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_INNER;
else
item->goalAnimState = STATE_LARA_CLIMB_CORNER_RIGHT_OUTER;
return;
}
}
}
Lara.moveAngle = item->pos.yRot;
LaraHangTest(item, coll);
if (item->animNumber == ANIMATION_LARA_HANG_IDLE && item->frameNumber == Anims[item->animNumber].frameBase + 21)
{
TestForObjectOnLedge(item, coll);
if (TrInput & IN_FORWARD)
{
if (coll->frontFloor > -850)
{
if (coll->frontFloor < -650 &&
coll->frontFloor >= coll->frontCeiling &&
coll->frontFloor >= coll->leftCeiling2 &&
coll->frontFloor >= coll->rightCeiling2)
{
if (abs(coll->leftFloor2 - coll->rightFloor2) < 60 && !coll->hitStatic)
{
if (TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_HANDSTAND;
}
else if (TrInput & IN_DUCK)
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
}
else
{
item->goalAnimState = STATE_LARA_GRABBING;
}
return;
}
}
if (coll->frontFloor < -650 &&
coll->frontFloor - coll->frontCeiling >= -256 &&
coll->frontFloor - coll->leftCeiling2 >= -256 &&
coll->frontFloor - coll->rightCeiling2 >= -256)
{
if (abs(coll->leftFloor2 - coll->rightFloor2) < 60 && !coll->hitStatic)
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
return;
}
}
}
if (Lara.climbStatus != 0 &&
coll->midCeiling <= -256 &&
abs(coll->leftCeiling2 - coll->rightCeiling2) < 60)
{
if (LaraTestClimbStance(item, coll))
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_LADDER_UP_HANDS;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_HANG;
item->currentAnimState = STATE_LARA_HANG;
}
}
return;
}
if (TrInput & IN_BACK &&
Lara.climbStatus &&
coll->midFloor > 344 &&
item->animNumber == ANIMATION_LARA_HANG_IDLE)
{
if (item->frameNumber == Anims[item->animNumber].frameBase + 21)
{
if (LaraTestClimbStance(item, coll))
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_LADDER_DOWN_HANDS;
item->goalAnimState = STATE_LARA_HANG;
item->currentAnimState = STATE_LARA_HANG;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
}
}
}
void lara_as_hang(ITEM_INFO* item, COLL_INFO* coll)//19A28, 19B5C (F)
2019-11-21 07:43:34 +01:00
{
Lara.isClimbing = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2019-11-21 07:43:34 +01:00
}
2019-12-02 09:11:21 +01:00
int CanLaraHangSideways(ITEM_INFO* item, COLL_INFO* coll, short angle)//19930, 19A64 (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
int oldx = item->pos.xPos;
int oldz = item->pos.zPos;
int x = item->pos.xPos;
int z = item->pos.zPos;
int res;
2019-11-21 07:43:34 +01:00
Lara.moveAngle = angle + item->pos.yRot;
2020-05-31 04:20:52 -05:00
short ang = (unsigned short) (Lara.moveAngle + ANGLE(45.0f)) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
2020-05-23 15:59:18 -05:00
switch (ang)
{
case 0:
z += 16;
break;
case 1:
x += 16;
break;
case 2:
z -= 16;
break;
case 3:
x -= 16;
break;
}
2019-11-21 07:43:34 +01:00
item->pos.xPos = x;
item->pos.zPos = z;
coll->old.y = item->pos.yPos;
res = LaraHangTest(item, coll);
item->pos.xPos = oldx;
item->pos.zPos = oldz;
Lara.moveAngle = angle + item->pos.yRot;
return !res;
}
void lara_void_func(ITEM_INFO* item, COLL_INFO* coll)//19928(<), 19A5C(<) (F)
2019-11-21 07:43:34 +01:00
{
return;
}
void lara_as_fastfall(ITEM_INFO* item, COLL_INFO* coll)//198BC(<), 199F0(<) (F)
2019-11-21 07:43:34 +01:00
{
item->speed = (item->speed * 95) / 100;
if (item->fallspeed == 154)
SoundEffect(SFX_LARA_FALL, &item->pos, 0);
}
void lara_as_death(ITEM_INFO* item, COLL_INFO* coll)//19830(<), 19964(<) (F)
2019-11-21 07:43:34 +01:00
{
Lara.look = false;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (BinocularRange)
{
BinocularRange = 0;
LaserSight = 0;
2020-05-31 04:20:52 -05:00
AlterFOV(ANGLE(80.0f));
2019-11-21 07:43:34 +01:00
LaraItem->meshBits = -1;
Lara.busy = false;
}
}
void lara_as_turn_l(ITEM_INFO* item, COLL_INFO* coll)//1972C(<), 19860(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
Lara.turnRate -= LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
if (Lara.gunStatus != LG_READY || Lara.waterStatus == LW_WADE)
{
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(4.0f))
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_WALK)
2020-05-31 04:20:52 -05:00
Lara.turnRate = -ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
else
item->goalAnimState = STATE_LARA_TURN_FAST;
}
}
else
{
item->goalAnimState = STATE_LARA_TURN_FAST;
}
if (!(TrInput & IN_FORWARD))
{
if (!(TrInput & IN_LEFT))
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_WALK_FORWARD;
}
else
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
}
void lara_as_turn_r(ITEM_INFO* item, COLL_INFO* coll)//19628(<), 1975C(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
Lara.turnRate += LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
if (Lara.gunStatus != LG_READY || Lara.waterStatus == LW_WADE)
{
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(4.0f))
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_WALK)
2020-05-31 04:20:52 -05:00
Lara.turnRate = ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
else
item->goalAnimState = STATE_LARA_TURN_FAST;
}
}
else
{
item->goalAnimState = STATE_LARA_TURN_FAST;
}
if (!(TrInput & IN_FORWARD))
{
if (!(TrInput & IN_RIGHT))
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_WALK_FORWARD;
}
else
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
}
void lara_as_fastback(ITEM_INFO* item, COLL_INFO* coll)//1959C(<), 196D0(<) (F)
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_STOP;
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(6.0f))
Lara.turnRate = -ANGLE(6.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(6.0f))
Lara.turnRate = ANGLE(6.0f);
2019-11-21 07:43:34 +01:00
}
}
void lara_as_run(ITEM_INFO* item, COLL_INFO* coll)//192EC, 19420 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_DEATH;
return;
}
if (TrInput & IN_ROLL)
{
item->animNumber = ANIMATION_LARA_ROLL_BEGIN;
item->frameNumber = Anims[item->animNumber].frameBase + 2;
item->currentAnimState = STATE_LARA_ROLL_FORWARD;
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (TrInput & IN_SPRINT && DashTimer)
{
item->goalAnimState = STATE_LARA_SPRINT;
return;
}
if (TrInput & IN_DUCK &&
Lara.waterStatus != LW_WADE &&
(Lara.gunStatus == LG_NO_ARMS ||
Lara.gunType == WEAPON_NONE ||
Lara.gunType == WEAPON_PISTOLS ||
Lara.gunType == WEAPON_REVOLVER ||
Lara.gunType == WEAPON_UZI ||
Lara.gunType == WEAPON_FLARE))
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
if (Lara.turnRate < -LARA_FAST_TURN)
Lara.turnRate = -LARA_FAST_TURN;
2019-11-21 07:43:34 +01:00
item->pos.zRot -= LARA_LEAN_RATE;
if (item->pos.zRot < -LARA_LEAN_MAX)
item->pos.zRot = -LARA_LEAN_MAX;
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
if (Lara.turnRate > LARA_FAST_TURN)
Lara.turnRate = LARA_FAST_TURN;
2019-11-21 07:43:34 +01:00
item->pos.zRot += LARA_LEAN_RATE;
if (item->pos.zRot > LARA_LEAN_MAX)
item->pos.zRot = LARA_LEAN_MAX;
2019-11-21 07:43:34 +01:00
}
if (item->animNumber == ANIMATION_LARA_STAY_TO_RUN)
{
doJump = false;
}
else if (item->animNumber == ANIMATION_LARA_RUN)
{
if (item->frameNumber == 4)
doJump = true;
}
else
2019-11-21 07:43:34 +01:00
{
doJump = true;
}
if (TrInput & IN_JUMP && doJump && !item->gravityStatus)
{
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
}
else if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_WADE_FORWARD;
}
else
{
if (TrInput & IN_WALK)
item->goalAnimState = STATE_LARA_WALK_FORWARD;
else
item->goalAnimState = STATE_LARA_RUN_FORWARD;
2019-11-21 07:43:34 +01:00
}
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
}
void lara_as_walk(ITEM_INFO* item, COLL_INFO* coll)//191B8(<), 192EC(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (!Lara.isMoving)
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
}
if (TrInput & IN_FORWARD)
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_WADE_FORWARD;
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_WALK_FORWARD;
}
else
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
}
}
// FIXED
void lara_col_reach(ITEM_INFO* item, COLL_INFO* coll)//18D0C, 18E40 (F)
2019-11-21 07:43:34 +01:00
{
if (Lara.ropePtr == -1)
item->gravityStatus = true;
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = 0;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
2019-12-02 09:11:21 +01:00
short angle = 1;
int edge = 0;
int edgeCatch = 0;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && !coll->hitStatic)
{
if (Lara.canMonkeySwing && coll->collType == CT_TOP)
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
Lara.gunStatus = LG_HANDS_BUSY;
item->animNumber = ANIMATION_LARA_OSCILLATE_HANG_ON;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
return;
}
if (coll->midCeiling <= -384 &&
coll->midFloor >= 200 &&
coll->collType == CT_FRONT)
{
edgeCatch = LaraTestEdgeCatch(item, coll, &edge);
if (!(!edgeCatch || edgeCatch < 0 && !LaraTestHangOnClimbWall(item, coll)))
{
angle = item->pos.yRot;
2020-05-31 04:20:52 -05:00
if (abs(angle) > ANGLE(35.0f))
2019-11-21 07:43:34 +01:00
{
if (angle < 10014 || angle > 22754)
{
if (angle >= 26397 || angle <= -26397)
{
2020-05-31 04:20:52 -05:00
angle = -ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
}
else if (angle >= -22754 && angle <= -10014)
{
2020-05-31 04:20:52 -05:00
angle = -ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
}
else
{
2020-05-31 04:20:52 -05:00
angle = ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
}
else
{
angle = 0;
}
}
}
}
if (angle & 0x3FFF)
{
LaraSlideEdgeJump(item, coll);
GetLaraCollisionInfo(item, coll);
ShiftItem(item, coll);
if (item->fallspeed > 0 && coll->midFloor <= 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = STATE_LARA_DEATH;
}
else
{
item->goalAnimState = STATE_LARA_STOP;
item->fallspeed = 0;
item->gravityStatus = false;
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
}
else
{
if (TestHangSwingIn(item, angle))
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
item->animNumber = ANIMATION_LARA_OSCILLATE_HANG_ON;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
else
{
if (TestHangFeet(item, angle))
2020-05-23 15:59:18 -05:00
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG_FEET;
2020-05-23 15:59:18 -05:00
}
else
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG;
2020-05-23 15:59:18 -05:00
}
2019-11-21 07:43:34 +01:00
}
2019-12-02 09:11:21 +01:00
short* bounds = GetBoundsAccurate(item);
2019-11-21 07:43:34 +01:00
if (edgeCatch <= 0)
{
item->pos.yPos = edge - bounds[2] - 22;
}
else
{
item->pos.yPos += coll->frontFloor - bounds[2];
2020-05-31 04:20:52 -05:00
short dir = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
2019-12-01 09:59:31 +01:00
switch (dir)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
case NORTH:
2019-11-21 07:43:34 +01:00
item->pos.zPos = (item->pos.zPos | 0x3FF) - 100;
item->pos.xPos += coll->shift.x;
break;
2019-12-01 08:13:19 +01:00
case SOUTH:
2019-11-21 07:43:34 +01:00
item->pos.zPos = (item->pos.zPos & 0xFFFFFC00) + 100;
item->pos.xPos += coll->shift.x;
break;
2019-12-01 08:13:19 +01:00
case EAST:
2019-11-21 07:43:34 +01:00
item->pos.xPos = (item->pos.xPos | 0x3FF) - 100;
item->pos.zPos += coll->shift.z;
break;
2019-12-01 08:13:19 +01:00
case WEST:
2019-11-21 07:43:34 +01:00
item->pos.xPos = (item->pos.xPos & 0xFFFFFC00) + 100;
item->pos.zPos += coll->shift.z;
break;
default:
break;
}
}
item->pos.yRot = angle;
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
Lara.gunStatus = LG_HANDS_BUSY;
}
}
void lara_as_reach(ITEM_INFO* item, COLL_INFO* coll)//18CE0(<), 18E14(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(85.0f);
2019-11-21 07:43:34 +01:00
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = STATE_LARA_FREEFALL;
}
void lara_col_forwardjump(ITEM_INFO* item, COLL_INFO* coll)//18B88, 18CBC (F)
2019-11-21 07:43:34 +01:00
{
if (item->speed < 0)
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
else
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot;
if (coll->midFloor <= 0 && item->fallspeed > 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = STATE_LARA_DEATH;
}
else
{
if (Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_STOP;
}
else
{
if (TrInput & IN_FORWARD && !(TrInput & IN_STEPSHIFT))
item->goalAnimState = STATE_LARA_RUN_FORWARD;
else
item->goalAnimState = STATE_LARA_STOP;
}
2019-11-21 07:43:34 +01:00
}
item->gravityStatus = false;
item->fallspeed = 0;
item->speed = 0;
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
AnimateLara(item);
2019-11-21 07:43:34 +01:00
}
}
void lara_as_forwardjump(ITEM_INFO* item, COLL_INFO* coll)//18A34, 18B68 (F)
2019-11-21 07:43:34 +01:00
{
if (item->goalAnimState == STATE_LARA_SWANDIVE_BEGIN ||
item->goalAnimState == STATE_LARA_REACH)
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
if (item->goalAnimState != STATE_LARA_DEATH &&
item->goalAnimState != STATE_LARA_STOP &&
item->goalAnimState != STATE_LARA_RUN_FORWARD)
{
if (Lara.gunStatus == LG_NO_ARMS && TrInput & IN_ACTION)
item->goalAnimState = STATE_LARA_REACH;
if (TrInput & IN_BACK || TrInput & IN_ROLL)
item->goalAnimState = STATE_LARA_JUMP_ROLL;
if (Lara.gunStatus == LG_NO_ARMS && TrInput & IN_WALK)
item->goalAnimState = STATE_LARA_SWANDIVE_BEGIN;
if (item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = STATE_LARA_FREEFALL;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(3.0f))
Lara.turnRate = -ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(3.0f))
Lara.turnRate = ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
}
void lara_col_upjump(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
coll->hitCeiling = false;
2020-05-31 04:20:52 -05:00
coll->facing = item->speed < 0 ? Lara.moveAngle + ANGLE(180.0f) : Lara.moveAngle;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 870);
if (TrInput & IN_ACTION && Lara.gunStatus == LG_NO_ARMS && !coll->hitStatic)
{
if (Lara.canMonkeySwing && coll->collType == CT_TOP)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->animNumber = ANIMATION_LARA_MONKEY_GRAB;
item->frameNumber = Anims[item->animNumber].frameBase;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.gunStatus = LG_HANDS_BUSY;
MonkeySwingSnap(item, coll);
return;
}
if (coll->collType == CT_FRONT && coll->midCeiling <= -STEPUP_HEIGHT)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
int edge;
int edgeCatch = LaraTestEdgeCatch(item, coll, &edge);
2019-11-21 07:43:34 +01:00
if (edgeCatch)
{
if (edgeCatch >= 0 || LaraTestHangOnClimbWall(item, coll))
{
2019-12-02 09:11:21 +01:00
short angle = item->pos.yRot;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (abs(angle) <= ANGLE(35.0f))
2019-11-21 07:43:34 +01:00
{
angle = 0;
2019-11-21 07:43:34 +01:00
}
2020-05-31 04:20:52 -05:00
else if (angle >= ANGLE(55.0f) && angle <= ANGLE(125.0f))
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
angle = ANGLE(90.0f);
}
2020-05-31 04:20:52 -05:00
else if (angle >= ANGLE(145.0f) || angle <= -ANGLE(145.0f))
{
angle = ANGLE(180);
}
2020-05-31 04:20:52 -05:00
else if (angle >= -ANGLE(125.0f) && angle <= -ANGLE(55.0f))
{
2020-05-31 04:20:52 -05:00
angle = -ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
}
if ((angle & 0x3FFF) == 0)
{
ANIM_FRAME* bounds;
2019-11-21 07:43:34 +01:00
if (TestHangSwingIn(item, angle))
{
item->animNumber = ANIMATION_LARA_MONKEY_GRAB;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
else
{
if (TestHangFeet(item, angle))
2020-05-23 15:59:18 -05:00
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase + 12;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG_FEET;
2020-05-23 15:59:18 -05:00
}
else
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase + 12;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG;
2020-05-23 15:59:18 -05:00
}
2019-11-21 07:43:34 +01:00
}
bounds = (ANIM_FRAME*) GetBoundsAccurate(item);
2019-11-21 07:43:34 +01:00
if (edgeCatch <= 0)
item->pos.yPos = edge - bounds->MinY + 4;
2019-11-21 07:43:34 +01:00
else
item->pos.yPos += coll->frontFloor - bounds->MinY;
2019-11-21 07:43:34 +01:00
item->pos.xPos += coll->shift.x;
item->pos.zPos += coll->shift.z;
item->pos.yRot = angle;
item->gravityStatus = false;
item->speed = 0;
item->fallspeed = 0;
Lara.gunStatus = LG_HANDS_BUSY;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
return;
}
}
}
}
}
ShiftItem(item, coll);
if (coll->collType == CT_CLAMP ||
coll->collType == CT_TOP ||
coll->collType == CT_TOP_FRONT ||
coll->hitCeiling)
item->fallspeed = 1;
if (coll->collType == CT_NONE)
{
if (item->fallspeed < -70)
{
if (TrInput & IN_FORWARD && item->speed < 5)
{
item->speed++;
}
else if (TrInput & IN_BACK && item->speed > -5)
{
item->speed -= 2;
}
}
}
else
{
item->speed = item->speed <= 0 ? -2 : 2;
}
if (item->fallspeed > 0 && coll->midFloor <= 0)
{
item->goalAnimState = LaraLandedBad(item, coll) ? STATE_LARA_DEATH : STATE_LARA_STOP;
item->gravityStatus = false;
item->fallspeed = 0;
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_as_upjump(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (item->fallspeed > LARA_FREEFALL_SPEED)
{
item->goalAnimState = STATE_LARA_FREEFALL;
}
}
void lara_col_stop(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = STEPUP_HEIGHT;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
item->gravityStatus = false;
item->fallspeed = 0;
coll->slopesArePits = true;
coll->slopesAreWalls = 1;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (LaraHitCeiling(item, coll))
return;
2019-11-21 07:43:34 +01:00
if (LaraFallen(item, coll))
return;
if (TestLaraSlide(item, coll))
return;
ShiftItem(item, coll);
2020-01-29 08:29:15 +01:00
#if 1
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
#else
if (!(Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP) || coll->midFloor < 0)
item->pos.yPos += coll->midFloor;
else if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && coll->midFloor)
item->pos.yPos += SWAMP_GRAVITY;
2020-01-29 08:29:15 +01:00
#endif
2019-11-21 07:43:34 +01:00
}
void lara_as_climbroped(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
LaraClimbRope(item, coll);
2019-11-21 07:43:34 +01:00
}
void lara_as_climbrope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ROLL)
{
FallFromRope(item);
}
else
{
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(30.0f);
2019-11-21 07:43:34 +01:00
if (Anims[item->animNumber].frameEnd == item->frameNumber)
{
item->frameNumber = Anims[item->animNumber].frameBase;
Lara.ropeSegment -= 2;
}
2020-01-15 22:26:49 -03:00
if (!(TrInput & IN_FORWARD) || Lara.ropeSegment <= 4)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_ROPE_IDLE;
}
}
void lara_col_ropefwd(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
Camera.targetDistance = SECTOR(2);
2019-11-21 07:43:34 +01:00
UpdateRopeSwing(item);
if (item->animNumber == ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD)
{
if (TrInput & IN_SPRINT)
{
2019-12-02 09:11:21 +01:00
int vel;
2019-11-21 07:43:34 +01:00
if (abs(Lara.ropeLastX) < 9000)
2020-01-15 22:26:49 -03:00
vel = 192 * (9000 - abs(Lara.ropeLastX)) / 9000;
2019-11-21 07:43:34 +01:00
else
vel = 0;
ApplyVelocityToRope(Lara.ropeSegment - 2,
2020-05-31 04:20:52 -05:00
item->pos.yRot + (Lara.ropeDirection ? ANGLE(0.0f) : ANGLE(180.0f)),
2020-01-15 22:26:49 -03:00
vel >> 5);
2019-11-21 07:43:34 +01:00
}
if (Lara.ropeFrame > Lara.ropeDFrame)
{
2020-01-15 22:26:49 -03:00
Lara.ropeFrame -= (unsigned short) Lara.ropeFrameRate;
2019-11-21 07:43:34 +01:00
if (Lara.ropeFrame < Lara.ropeDFrame)
Lara.ropeFrame = Lara.ropeDFrame;
}
else if (Lara.ropeFrame < Lara.ropeDFrame)
{
2020-01-15 22:26:49 -03:00
Lara.ropeFrame += (unsigned short) Lara.ropeFrameRate;
2019-11-21 07:43:34 +01:00
if (Lara.ropeFrame > Lara.ropeDFrame)
Lara.ropeFrame = Lara.ropeDFrame;
}
2020-01-15 22:26:49 -03:00
item->frameNumber = Lara.ropeFrame >> 8;
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_SPRINT) &&
2020-01-15 22:26:49 -03:00
item->frameNumber == Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 32 &&
2019-11-21 07:43:34 +01:00
Lara.ropeMaxXBackward < 6750 &&
Lara.ropeMaxXForward < 6750)
{
item->animNumber = ANIMATION_LARA_MONKEY_TO_ROPE_END;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
item->currentAnimState = STATE_LARA_ROPE_IDLE;
item->goalAnimState = STATE_LARA_ROPE_IDLE;
}
if (TrInput & IN_JUMP)
JumpOffRope(item);
}
else if (item->frameNumber == Anims[ANIMATION_LARA_ROPE_IDLE_TO_SWING].frameBase + 15)
{
ApplyVelocityToRope(Lara.ropeSegment, item->pos.yRot, 128);
}
2019-11-21 07:43:34 +01:00
}
void lara_as_roper(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ACTION)
{
2020-01-15 22:26:49 -03:00
if (TrInput & IN_RIGHT)
2019-11-21 07:43:34 +01:00
{
Lara.ropeY -= 256;
}
else
{
item->goalAnimState = STATE_LARA_ROPE_IDLE;
}
}
else
{
FallFromRope(item);
}
}
void lara_as_ropel(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ACTION)
{
if (TrInput & IN_LEFT)
{
Lara.ropeY += 256;
}
else
{
item->goalAnimState = STATE_LARA_ROPE_IDLE;
}
}
else
{
FallFromRope(item);
}
}
void lara_col_rope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ACTION)
{
UpdateRopeSwing(item);
if (TrInput & IN_SPRINT)
{
Lara.ropeDFrame = (Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 32) << 8;
Lara.ropeFrame = Lara.ropeDFrame;
item->goalAnimState = STATE_LARA_ROPE_SWING;
}
else if (TrInput & IN_FORWARD && Lara.ropeSegment > 4)
{
item->goalAnimState = STATE_LARA_ROPE_CLIMB_UP;
}
else if (TrInput & IN_BACK && Lara.ropeSegment < 21)
{
item->goalAnimState = STATE_LARA_ROPE_CLIMB_DOWN;
Lara.ropeFlag = 0;
Lara.ropeCount = 0;
}
else if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_ROPE_TURN_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_ROPE_TURN_RIGHT;
}
}
else
{
FallFromRope(item);
}
}
void lara_as_rope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (!(TrInput & IN_ACTION))
FallFromRope(item);
if (TrInput & IN_LOOK)
LookUpDown();
}
void UpdateRopeSwing(ITEM_INFO* item) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (Lara.ropeMaxXForward > 9000)
{
Lara.ropeMaxXForward = 9000;
}
if (Lara.ropeMaxXBackward > 9000)
{
Lara.ropeMaxXBackward = 9000;
}
if (Lara.ropeDirection)
{
2020-01-15 22:26:49 -03:00
if (item->pos.xRot > 0 && item->pos.xRot - Lara.ropeLastX < -100)
{
Lara.ropeArcFront = Lara.ropeLastX;
Lara.ropeDirection = 0;
Lara.ropeMaxXBackward = 0;
2020-01-15 22:26:49 -03:00
int frame = 15 * Lara.ropeMaxXForward / 18000 + Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 47 << 8;
if (frame > Lara.ropeDFrame)
{
2020-01-15 22:26:49 -03:00
Lara.ropeDFrame = frame;
RopeSwing = 1;
}
else
{
RopeSwing = 0;
}
SoundEffect(SFX_LARA_ROPE_CREAK, &item->pos, 0);
}
else if (Lara.ropeLastX < 0 && Lara.ropeFrame == Lara.ropeDFrame)
{
RopeSwing = 0;
2020-01-15 22:26:49 -03:00
Lara.ropeDFrame = 15 * Lara.ropeMaxXBackward / 18000 + Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase + 47 << 8;
Lara.ropeFrameRate = 15 * Lara.ropeMaxXBackward / 9000 + 1;
}
else if (Lara.ropeFrameRate < 512)
{
2020-01-15 22:26:49 -03:00
int num = RopeSwing ? 31 : 7;
2020-01-15 22:26:49 -03:00
Lara.ropeFrameRate += num * Lara.ropeMaxXBackward / 9000 + 1;
}
}
else
{
2020-01-15 22:26:49 -03:00
if (item->pos.xRot < 0 && item->pos.xRot - Lara.ropeLastX > 100)
{
Lara.ropeArcBack = Lara.ropeLastX;
Lara.ropeDirection = 1;
Lara.ropeMaxXForward = 0;
2020-01-15 22:26:49 -03:00
int frame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase - 15 * Lara.ropeMaxXBackward / 18000 + 17 << 8;
if (frame < Lara.ropeDFrame)
{
2020-01-15 22:26:49 -03:00
Lara.ropeDFrame = frame;
RopeSwing = 1;
}
else
{
RopeSwing = 0;
}
SoundEffect(SFX_LARA_ROPE_CREAK, &item->pos, 0);
}
else if (Lara.ropeLastX > 0 && Lara.ropeFrame == Lara.ropeDFrame)
{
RopeSwing = 0;
2020-01-15 22:26:49 -03:00
Lara.ropeDFrame = Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase - 15 * Lara.ropeMaxXForward / 18000 + 17 << 8;
Lara.ropeFrameRate = 15 * Lara.ropeMaxXForward / 9000 + 1;
}
else if (Lara.ropeFrameRate < 512)
{
2020-01-15 22:26:49 -03:00
int num = RopeSwing ? 31 : 7;
2020-01-15 22:26:49 -03:00
Lara.ropeFrameRate += num * Lara.ropeMaxXForward / 9000 + 1;
}
}
2020-01-15 22:26:49 -03:00
Lara.ropeLastX = item->pos.xRot;
if (Lara.ropeDirection)
{
2020-01-15 22:26:49 -03:00
if (item->pos.xRot > Lara.ropeMaxXForward)
Lara.ropeMaxXForward = item->pos.xRot;
}
else
{
2020-01-15 22:26:49 -03:00
if (item->pos.xRot < -Lara.ropeMaxXBackward)
Lara.ropeMaxXBackward = abs(item->pos.xRot);
}
2019-11-21 07:43:34 +01:00
}
void JumpOffRope(ITEM_INFO* item) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (Lara.ropePtr != -1)
{
if (item->pos.xRot >= 0)
{
item->fallspeed = -112;
item->speed = item->pos.xRot / 128;
}
else
{
item->speed = 0;
item->fallspeed = -20;
}
item->pos.xRot = 0;
item->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
if (item->frameNumber - Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase > 42)
{
item->animNumber = ANIMATION_LARA_ROPE_SWING_TO_TRY_HANG_FRONT2;
}
else if (item->frameNumber - Anims[ANIMATION_LARA_ROPE_SWING_FORWARD_SEMIHARD].frameBase > 21)
{
item->animNumber = ANIMATION_LARA_ROPE_SWING_TO_TRY_HANG_MIDDLE;
}
else
{
item->animNumber = ANIMATION_LARA_ROPE_SWING_TO_TRY_HANG_BACK;
}
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_REACH;
item->goalAnimState = STATE_LARA_REACH;
Lara.ropePtr = -1;
}
}
void FallFromRope(ITEM_INFO* item) // (F) (D)
2019-11-21 07:43:34 +01:00
{
2020-01-15 22:26:49 -03:00
item->speed = abs(CurrentPendulum.Velocity.x >> 16) + abs(CurrentPendulum.Velocity.z >> 16) >> 1;
2019-11-21 07:43:34 +01:00
item->pos.xRot = 0;
item->pos.yPos += 320;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[ANIMATION_LARA_FREE_FALL_FORWARD].frameBase;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->fallspeed = 0;
item->gravityStatus = true;
Lara.gunStatus = LG_NO_ARMS;
2020-01-15 22:26:49 -03:00
Lara.ropePtr = -1;
2019-11-21 07:43:34 +01:00
}
void lara_col_poledown(ITEM_INFO* item, COLL_INFO* coll)//171A0, 172D4 (F)
2019-11-21 07:43:34 +01:00
{
coll->enableSpaz = false;
coll->enableBaddiePush = false;
if (TrInput & IN_LOOK)
LookUpDown();
2019-12-22 17:06:25 -03:00
if ((TrInput & (IN_BACK | IN_ACTION)) != (IN_BACK | IN_ACTION) || item->hitPoints <= 0)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_POLE_IDLE;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
Lara.moveAngle = item->pos.yRot;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
coll->facing = Lara.moveAngle;
coll->radius = 100;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (coll->midFloor < 0)
{
2019-12-02 09:11:21 +01:00
short roomNumber = item->roomNumber;
2019-11-21 07:43:34 +01:00
item->floor = GetFloorHeight(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber),
item->pos.xPos, item->pos.yPos - 762, item->pos.zPos);
item->goalAnimState = STATE_LARA_POLE_IDLE;
item->itemFlags[2] = 0;
}
if (TrInput & IN_LEFT)
{
item->pos.yRot += 256;
}
else if (TrInput & IN_RIGHT)
{
item->pos.yRot -= 256;
}
if (item->animNumber == ANIMATION_LARA_POLE_CLIMB_DOWN_TO_IDLE)
{
item->itemFlags[2] -= SECTOR(1);
}
else
{
item->itemFlags[2] += 256;
}
// CHECK
SoundEffect(SFX_LARA_ROPEDOWN_LOOP, &item->pos, 0);
2020-05-31 04:20:52 -05:00
item->itemFlags[2] = CLAMP(item->itemFlags[2], 0, ANGLE(90.0f));
2019-11-21 07:43:34 +01:00
item->pos.yPos += item->itemFlags[2] >> 8;
}
void lara_col_poleup(ITEM_INFO* item, COLL_INFO* coll)//170D8(<), 1720C(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (TrInput & IN_LOOK)
LookUpDown();
if (!(TrInput & IN_ACTION) || !(TrInput & IN_FORWARD) || item->hitPoints <= 0)
item->goalAnimState = STATE_LARA_POLE_IDLE;
2019-12-02 09:11:21 +01:00
short roomNumber = item->roomNumber;
2019-11-21 07:43:34 +01:00
if (item->pos.yPos -
GetCeiling(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber),
item->pos.xPos, item->pos.yPos, item->pos.zPos) < SECTOR(1))
item->goalAnimState = STATE_LARA_POLE_IDLE;
}
void lara_as_poleright(ITEM_INFO* item, COLL_INFO* coll)//1707C(<), 171B0(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (!(TrInput & IN_RIGHT) || !(TrInput & IN_ACTION) || (TrInput & (IN_FORWARD | IN_BACK)) || item->hitPoints <= 0)
item->goalAnimState = STATE_LARA_POLE_IDLE;
else
item->pos.yRot -= 256;
}
void lara_as_poleleft(ITEM_INFO* item, COLL_INFO* coll)//17020(<), 17154(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
if (!(TrInput & IN_LEFT) || !(TrInput & IN_ACTION) || (TrInput & (IN_FORWARD | IN_BACK)) || item->hitPoints <= 0)
item->goalAnimState = STATE_LARA_POLE_IDLE;
else
item->pos.yRot += 256;
}
void lara_col_polestat(ITEM_INFO* item, COLL_INFO* coll)//16DFC, 16F30 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_FREEFALL;
return;
}
coll->enableSpaz = false;
coll->enableBaddiePush = false;
if (item->animNumber == ANIMATION_LARA_POLE_IDLE)
{
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
Lara.moveAngle = item->pos.yRot;
coll->facing = Lara.moveAngle;
coll->radius = 100;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (TrInput & IN_ACTION)
{
item->goalAnimState = STATE_LARA_POLE_IDLE;
if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_POLE_TURN_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_POLE_TURN_RIGHT;
}
if (TrInput & IN_LOOK)
LookUpDown();
if (TrInput & IN_FORWARD)
{
2019-12-02 09:11:21 +01:00
short roomNum = item->roomNumber;
2019-11-21 07:43:34 +01:00
if (item->pos.yPos - GetCeiling(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNum),
item->pos.xPos, item->pos.yPos, item->pos.zPos) > SECTOR(1))
{
item->goalAnimState = STATE_LARA_POLE_UP;
}
}
else if (TrInput & IN_BACK && coll->midFloor > 0)
{
item->goalAnimState = STATE_LARA_POLE_DOWN;
item->itemFlags[2] = 0;
}
if (TrInput & IN_JUMP)
item->goalAnimState = STATE_LARA_JUMP_BACK;
}
else if (coll->midFloor <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
}
else
{
2020-04-25 16:23:53 +02:00
item->pos.xPos -= (phd_sin(item->pos.yRot)) << 6 >> W2V_SHIFT;
item->pos.zPos -= (phd_cos(item->pos.yRot)) << 6 >> W2V_SHIFT;
2019-12-22 17:06:25 -03:00
item->goalAnimState = STATE_LARA_FREEFALL;
2019-11-21 07:43:34 +01:00
}
}
}
void lara_col_monkey180(ITEM_INFO* item, COLL_INFO* coll)//16DDC, 16F10 (F)
2019-11-21 07:43:34 +01:00
{
lara_col_monkeyswing(item, coll);
}
void lara_as_monkey180(ITEM_INFO* item, COLL_INFO* coll)//16DB8(<), 16EEC(<) (F)
2019-11-21 07:43:34 +01:00
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
item->goalAnimState = STATE_LARA_MONKEYSWING_TURNAROUND;
2019-11-21 07:43:34 +01:00
}
void lara_as_hangturnr(ITEM_INFO* item, COLL_INFO* coll)//16D64(<), 16E98(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
return;
}
Camera.targetElevation = 1820;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_RIGHT))
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
void lara_col_hangturnlr(ITEM_INFO* item, COLL_INFO* coll)//16C94(<), 16DC8(<) (F)
2019-11-21 07:43:34 +01:00
{
if ((TrInput & IN_ACTION) && Lara.canMonkeySwing)
{
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
Lara.moveAngle = item->pos.yRot;
coll->facing = item->pos.yRot;
coll->radius = 100;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600);
MonkeySwingSnap(item, coll);
}
else
{
MonkeySwingFall(item);
}
}
void lara_as_hangturnl(ITEM_INFO* item, COLL_INFO* coll)//16C40(<), 16D74(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
return;
}
Camera.targetElevation = 1820;
2019-11-21 07:43:34 +01:00
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_LEFT))
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
void lara_col_monkeyr(ITEM_INFO* item, COLL_INFO* coll)//16B9C(<), 16CD0(<) (F)
2019-11-21 07:43:34 +01:00
{
if ((TrInput & IN_ACTION) && Lara.canMonkeySwing)
{
if (TestMonkeyRight(item, coll))
{
MonkeySwingSnap(item, coll);
}
else
{
item->animNumber = ANIMATION_LARA_MONKEY_IDLE;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
}
}
else
{
MonkeySwingFall(item);
}
}
void lara_as_monkeyr(ITEM_INFO* item, COLL_INFO* coll)//16B24(<), 16C58(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
return;
}
2019-12-16 17:11:24 +01:00
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_RSTEP)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_RIGHT;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(10.0f);
2019-11-21 07:43:34 +01:00
}
else
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(10.0f);
2019-11-21 07:43:34 +01:00
}
}
void lara_col_monkeyl(ITEM_INFO* item, COLL_INFO* coll)//16A80(<), 16BB4(<) (F)
2019-11-21 07:43:34 +01:00
{
if ((TrInput & IN_ACTION) && Lara.canMonkeySwing)
{
if (TestMonkeyLeft(item, coll))
{
MonkeySwingSnap(item, coll);
}
else
{
item->animNumber = ANIMATION_LARA_MONKEY_IDLE;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
}
}
else
{
MonkeySwingFall(item);
}
}
void lara_as_monkeyl(ITEM_INFO* item, COLL_INFO* coll)//16A0C(<), 16B40(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
return;
}
2019-12-16 17:11:24 +01:00
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
coll->enableBaddiePush = false;
coll->enableSpaz = false;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_LSTEP)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_LEFT;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(10.0f);
2019-11-21 07:43:34 +01:00
}
else
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(10.0f);
2019-11-21 07:43:34 +01:00
}
}
void lara_col_monkeyswing(ITEM_INFO* item, COLL_INFO* coll)//16828, 1695C (F)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_ACTION && Lara.canMonkeySwing)
{
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = NO_HEIGHT;
coll->badCeiling = 0;
Lara.moveAngle = item->pos.yRot;
coll->enableSpaz = false;
coll->enableBaddiePush = false;
coll->facing = Lara.moveAngle;
coll->radius = 100;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600);
if (coll->collType == CT_FRONT
|| abs(coll->midCeiling - coll->frontCeiling) > 50)
2019-11-21 07:43:34 +01:00
{
item->animNumber = ANIMATION_LARA_MONKEY_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
else
{
if (abs(coll->midCeiling - coll->leftCeiling2) <= 50)
2019-11-21 07:43:34 +01:00
{
if (abs(coll->midCeiling - coll->rightCeiling2) > 50)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
}
}
else
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
}
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(10.0f);
2019-11-21 07:43:34 +01:00
MonkeySwingSnap(item, coll);
}
}
else
{
MonkeySwingFall(item);
}
}
void lara_as_monkeyswing(ITEM_INFO* item, COLL_INFO* coll)//1670C, 16840 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
return;
}
coll->enableSpaz = false;
coll->enableBaddiePush = false;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
if (TrInput & IN_LOOK)
LookUpDown();
if (TrInput & IN_FORWARD)
item->goalAnimState = STATE_LARA_MONKEYSWING_FORWARD;
else
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(3.0f))
Lara.turnRate = -ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(3.0f))
Lara.turnRate = ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
}
void lara_col_hang2(ITEM_INFO* item, COLL_INFO* coll)//163DC, 16510 (F)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
if (Lara.canMonkeySwing)
{
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = NO_HEIGHT;
coll->badCeiling = 0;
coll->slopesAreWalls = 0;
coll->facing = Lara.moveAngle;
coll->radius = 100;
2019-11-21 07:43:34 +01:00
Lara.moveAngle = item->pos.yRot;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600);
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS READY-
EnableMonkeyRoll = true;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_FORWARD && coll->collType != CT_FRONT && abs(coll->midCeiling - coll->frontCeiling) < 50)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_FORWARD;
}
else if (TrInput & IN_LSTEP && TestMonkeyLeft(item, coll))
{
item->goalAnimState = STATE_LARA_MONKEYSWING_LEFT;
}
else if (TrInput & IN_RSTEP && TestMonkeyRight(item, coll))
{
item->goalAnimState = STATE_LARA_MONKEYSWING_RIGHT;
}
else if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_TURN_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_MONKEYSWING_TURN_RIGHT;
}
else if ((TrInput & IN_ROLL) && EnableMonkeyRoll == true)
{
item->currentAnimState = STATE_LARA_MONKEYSWING_TURNAROUND;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->animNumber = ANIMATION_LARA_MONKEY_TURN_AROUND;
item->frameNumber = Anims[ANIMATION_LARA_MONKEY_TURN_AROUND].frameBase;
}
2019-11-21 07:43:34 +01:00
MonkeySwingSnap(item, coll);
}
else
{
LaraHangTest(item, coll);
if (item->goalAnimState == STATE_LARA_MONKEYSWING_IDLE)
{
TestForObjectOnLedge(item, coll);
if (!(TrInput & IN_FORWARD) ||
coll->frontFloor <= -850 ||
coll->frontFloor >= -650 ||
coll->frontFloor < coll->frontCeiling ||
coll->leftFloor2 < coll->leftCeiling2 ||
coll->rightFloor2 < coll->rightCeiling2 ||
coll->hitStatic)
{
if (!(TrInput & IN_FORWARD) ||
coll->frontFloor <= -850 ||
coll->frontFloor >= -650 ||
coll->frontFloor - coll->frontCeiling < -256 ||
coll->leftFloor2 - coll->leftCeiling2 < -256 ||
coll->rightFloor2 - coll->rightCeiling2 < -256 ||
coll->hitStatic)
{
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
item->goalAnimState = STATE_LARA_SHIMMY_LEFT;
}
else if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
item->goalAnimState = STATE_LARA_SHIMMY_RIGHT;
}
}
else
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
}
}
else if (TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_HANDSTAND;
}
else if (TrInput & IN_DUCK)
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
}
else
{
item->goalAnimState = STATE_LARA_GRABBING;
}
}
}
}
void lara_as_hang2(ITEM_INFO* item, COLL_INFO* coll)//1630C(<), 16440(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
if (Lara.canMonkeySwing)
{
if (!(TrInput & IN_ACTION) || item->hitPoints <= 0)
MonkeySwingFall(item);
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2019-11-21 07:43:34 +01:00
}
if (TrInput & IN_LOOK)
LookUpDown();
}
2019-12-02 09:11:21 +01:00
short TestMonkeyRight(ITEM_INFO* item, COLL_INFO* coll)//161EC(<), 16320(<) (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short oct;
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
coll->slopesAreWalls = 0;
coll->facing = Lara.moveAngle;
coll->radius = 100;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600);
if (abs(coll->midCeiling - coll->frontCeiling) > 50)
return 0;
if (!coll->collType)
return 1;
oct = GetDirOctant(item->pos.yRot);
if (oct)
{
if (oct != 1)
return 1;
if (coll->collType != CT_FRONT && coll->collType != CT_RIGHT && coll->collType != CT_LEFT)
return 1;
}
else if (coll->collType != CT_FRONT)
{
return 1;
}
return 0;
}
2019-12-02 09:11:21 +01:00
short TestMonkeyLeft(ITEM_INFO* item, COLL_INFO* coll)//160CC(<), 16200(<) (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short oct;
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = NO_HEIGHT;
coll->badCeiling = 0;
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
coll->slopesAreWalls = 0;
coll->facing = Lara.moveAngle;
coll->radius = 100;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 600);
if (abs(coll->midCeiling - coll->frontCeiling) > 50)
return 0;
if (!coll->collType)
return 1;
oct = GetDirOctant(item->pos.yRot);
if (oct)
{
if (oct != 1)
return 1;
if (coll->collType != CT_RIGHT && coll->collType != CT_LEFT)
return 1;
}
else
{
if (coll->collType != CT_FRONT && coll->collType != CT_LEFT)
return 1;
}
return 0;
}
2019-12-02 09:11:21 +01:00
short GetDirOctant(int rot)//160B4(<), 161E8(<) (F)
2019-11-21 07:43:34 +01:00
{
2020-05-31 04:20:52 -05:00
return abs(rot) >= ANGLE(45) && abs(rot) <= ANGLE(135.0f);
2019-11-21 07:43:34 +01:00
}
void MonkeySwingSnap(ITEM_INFO* item, COLL_INFO* coll)//1605C(<), 16190(<) (F)
2019-11-21 07:43:34 +01:00
{
short roomNum = item->roomNumber;
item->pos.yPos = GetCeiling(GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNum),
item->pos.xPos, item->pos.yPos, item->pos.zPos) + 704;
2019-11-21 07:43:34 +01:00
}
void MonkeySwingFall(ITEM_INFO* item)//16004(<), 16138(<) (F)
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_JUMP_UP;
item->currentAnimState = STATE_LARA_JUMP_UP;
item->animNumber = ANIMATION_LARA_TRY_HANG_VERTICAL;
item->frameNumber = Anims[item->animNumber].frameBase + 9;
2019-11-21 07:43:34 +01:00
item->speed = 2;
item->gravityStatus = true;
item->fallspeed = 1;
item->pos.yPos += 256;
2019-11-21 07:43:34 +01:00
Lara.gunStatus = LG_NO_ARMS;
}
void lara_col_dashdive(ITEM_INFO* item, COLL_INFO* coll)//15E5C, 15F90 (F)
2019-11-21 07:43:34 +01:00
{
if (item->speed < 0)
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
else
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = -256;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
LaraDeflectEdgeJump(item, coll);
if (!LaraFallen(item, coll))
{
if (item->speed < 0)
Lara.moveAngle = item->pos.yRot;
if (coll->midFloor <= 0 && item->fallspeed > 0)
{
if (LaraLandedBad(item, coll))
{
item->goalAnimState = STATE_LARA_DEATH;
}
else if (Lara.waterStatus == LW_WADE || !(TrInput & IN_FORWARD) || TrInput & IN_WALK)
{
item->goalAnimState = STATE_LARA_STOP;
}
else
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
item->gravityStatus = false;
item->fallspeed = 0;
item->pos.yPos += coll->midFloor;
item->speed = 0;
AnimateLara(item);
}
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_as_dashdive(ITEM_INFO* item, COLL_INFO* coll)//15E1C(<), 15F50(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->goalAnimState != STATE_LARA_DEATH &&
item->goalAnimState != STATE_LARA_STOP &&
item->goalAnimState != STATE_LARA_RUN_FORWARD &&
item->fallspeed > LARA_FREEFALL_SPEED)
item->goalAnimState = STATE_LARA_FREEFALL;
}
void lara_col_dash(ITEM_INFO* item, COLL_INFO* coll)//15C50, 15D84 (F)
2019-11-21 07:43:34 +01:00
{
Lara.moveAngle = item->pos.yRot;
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll) && !TestLaraVault(item, coll))
{
if (LaraDeflectEdge(item, coll))
{
item->pos.zRot = 0;
if (TestWall(item, 256, 0, -640))
{
item->currentAnimState = STATE_LARA_SPLAT;
item->animNumber = ANIMATION_LARA_WALL_SMASH_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
return;
}
LaraCollideStop(item, coll);
}
if (!LaraFallen(item, coll))
{
if (coll->midFloor >= -384 && coll->midFloor < -128)
{
if (item->frameNumber >= 3 && item->frameNumber <= 14)
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
else
{
item->animNumber = ANIMATION_LARA_RUN_UP_STEP_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
if (!TestLaraSlide(item, coll))
{
if (coll->midFloor < 50)
{
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
else
{
item->pos.yPos += 50;
}
}
}
}
}
void lara_as_dash(ITEM_INFO* item, COLL_INFO* coll)//15A28, 15B5C (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0 || !DashTimer || !(TrInput & IN_SPRINT) || Lara.waterStatus == LW_WADE)
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
return;
}
DashTimer--;
if (TrInput & IN_DUCK
&& (Lara.gunStatus == LG_NO_ARMS
|| Lara.gunType == WEAPON_NONE
|| Lara.gunType == WEAPON_PISTOLS
|| Lara.gunType == WEAPON_REVOLVER
|| Lara.gunType == WEAPON_UZI
|| Lara.gunType == WEAPON_FLARE))
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
return;
}
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(4.0f))
Lara.turnRate = -ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
item->pos.zRot -= ANGLE(1.5f);
if (item->pos.zRot < -ANGLE(16.0f))
item->pos.zRot = -ANGLE(16.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(4.0f))
Lara.turnRate = ANGLE(4.0f);
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
item->pos.zRot += ANGLE(1.5f);
if (item->pos.zRot > ANGLE(16.0f))
item->pos.zRot = ANGLE(16.0f);
2019-11-21 07:43:34 +01:00
}
if (!(TrInput & IN_JUMP) || item->gravityStatus)
{
if (TrInput & IN_FORWARD)
{
if (TrInput & IN_WALK)
item->goalAnimState = STATE_LARA_WALK_FORWARD;
else
item->goalAnimState = STATE_LARA_SPRINT;
}
else if (!(TrInput & IN_LEFT) && !(TrInput & IN_RIGHT))
2019-11-21 07:43:34 +01:00
{
item->goalAnimState = STATE_LARA_STOP;
}
}
else
{
item->goalAnimState = STATE_LARA_SPRINT_ROLL;
}
}
void lara_col_crawl2hang(ITEM_INFO* item, COLL_INFO* coll)//15770, 158A4 (F)
2019-11-21 07:43:34 +01:00
{
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2019-11-21 07:43:34 +01:00
coll->enableSpaz = false;
coll->enableBaddiePush = false;
if (item->animNumber == ANIMATION_LARA_CRAWL_TO_HANG_END)
{
int edgeCatch;
2019-12-02 09:11:21 +01:00
int edge;
2019-11-21 07:43:34 +01:00
item->fallspeed = 512;
item->pos.yPos += 255;
2019-11-21 07:43:34 +01:00
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = BAD_JUMP_CEILING;
2019-11-21 07:43:34 +01:00
Lara.moveAngle = item->pos.yRot;
coll->facing = Lara.moveAngle;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 870);
2019-12-16 17:11:24 +01:00
edgeCatch = LaraTestEdgeCatch(item, coll, &edge);
2019-11-21 07:43:34 +01:00
if (edgeCatch)
2019-12-16 17:11:24 +01:00
{
if (edgeCatch >= 0 || LaraTestHangOnClimbWall(item, coll))
{
short angle = item->pos.yRot;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (abs(angle) > ANGLE(35.0f))
{
if (angle >= 10014 && angle <= 22754)
{
2020-05-31 04:20:52 -05:00
angle = ANGLE(90.0f);
}
else
{
if (abs(angle) >= 26397)
{
2020-05-31 04:20:52 -05:00
angle = -ANGLE(180.0f);
}
else if (angle >= -22754 && angle <= -10014)
{
2020-05-31 04:20:52 -05:00
angle = -ANGLE(90.0f);
}
}
}
else
{
angle = 0;
}
2019-11-21 07:43:34 +01:00
if ((angle & 0x3FFF) == 0)
{
short* bounds;
2019-11-21 07:43:34 +01:00
if (TestHangSwingIn(item, angle))
{
Lara.headYrot = 0;
Lara.headXrot = 0;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2019-11-21 07:43:34 +01:00
item->animNumber = ANIMATION_LARA_OSCILLATE_HANG_ON;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_MONKEYSWING_IDLE;
item->goalAnimState = STATE_LARA_MONKEYSWING_IDLE;
}
else
{
if (TestHangFeet(item, angle))
2020-05-23 15:59:18 -05:00
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG_FEET;
2020-05-23 15:59:18 -05:00
}
else
{
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG;
2020-05-23 15:59:18 -05:00
}
}
2019-11-21 07:43:34 +01:00
bounds = GetBoundsAccurate(item);
2019-11-21 07:43:34 +01:00
if (edgeCatch <= 0)
{
item->pos.yPos = edge - bounds[2];
}
else
{
item->pos.yPos += coll->frontFloor - bounds[2];
item->pos.xPos += coll->shift.x;
item->pos.zPos += coll->shift.z;
}
item->pos.yRot = angle;
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
Lara.gunStatus = LG_HANDS_BUSY;
}
}
}
2019-11-21 07:43:34 +01:00
}
}
void lara_col_crawlb(ITEM_INFO* item, COLL_INFO* coll)//15614, 15748 (F)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = false;
item->fallspeed = 0;
coll->radius = 250;
coll->badPos = 255;
coll->badNeg = -255;
coll->badCeiling = 400;
coll->slopesArePits = true;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
coll->facing = Lara.moveAngle;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
if (LaraDeflectEdgeDuck(item, coll))
{
item->currentAnimState = STATE_LARA_CRAWL_IDLE;
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
if (item->animNumber != ANIMATION_LARA_CRAWL_IDLE)
{
item->animNumber = ANIMATION_LARA_CRAWL_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
else if (LaraFallen(item, coll))
{
Lara.gunStatus = LG_NO_ARMS;
}
else if (!TestLaraSlide(item, coll))
{
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
item->pos.yPos += coll->midFloor;
Lara.moveAngle = item->pos.yRot;
}
}
void lara_as_crawlb(ITEM_INFO* item, COLL_INFO* coll)//154F0, 15624 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0 || Lara.waterStatus == 4)
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
coll->enableSpaz = false;
coll->enableBaddiePush = true;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(23.0f);
2019-11-21 07:43:34 +01:00
if (TrInput & IN_BACK)
{
if (TrInput & IN_RIGHT)
{
Lara.turnRate -= LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(3.0f))
Lara.turnRate = -ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_LEFT)
{
Lara.turnRate += LARA_TURN_RATE;
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(3.0f))
Lara.turnRate = ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
}
else
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
}
}
void lara_as_all4turnr(ITEM_INFO* item, COLL_INFO* coll)//15484(<), 155B8(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
return;
}
coll->enableSpaz = 0;
coll->enableBaddiePush = 1;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(23.0f);
item->pos.yRot += ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_RIGHT))
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
}
void lara_col_all4turnlr(ITEM_INFO* item, COLL_INFO* coll)//153FC, 15530 (F)
2019-11-21 07:43:34 +01:00
{
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
if (!TestLaraSlide(item, coll))
{
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
item->pos.yPos += coll->midFloor;
}
}
void lara_as_all4turnl(ITEM_INFO* item, COLL_INFO* coll)//15390(<), 154C4(<) (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
return;
}
coll->enableSpaz = 0;
coll->enableBaddiePush = 1;
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(23.0f);
item->pos.yRot -= ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
if (!(TrInput & IN_LEFT))
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
}
void lara_col_crawl(ITEM_INFO* item, COLL_INFO* coll)//1523C, 15370 (F)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot;
coll->radius = 200;
coll->badPos = 255;
coll->badNeg = -255;
coll->badCeiling = 400;
coll->slopesArePits = true;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
coll->facing = Lara.moveAngle;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, -400);
if (LaraDeflectEdgeDuck(item, coll))
{
item->currentAnimState = STATE_LARA_CRAWL_IDLE;
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
if (item->animNumber != ANIMATION_LARA_CRAWL_IDLE)
{
item->animNumber = ANIMATION_LARA_CRAWL_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase;
}
}
else if (LaraFallen(item, coll))
{
Lara.gunStatus = LG_NO_ARMS;
}
else if (!TestLaraSlide(item, coll))
{
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
item->pos.yPos += coll->midFloor;
}
}
void lara_as_crawl(ITEM_INFO* item, COLL_INFO* coll)//150F4, 15228 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0 || TrInput & IN_JUMP)
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
Lara.torsoXrot = 0;
Lara.torsoYrot = 0;
coll->enableSpaz = false;
coll->enableBaddiePush = true;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(23.0f);
2019-11-21 07:43:34 +01:00
if (TrInput & IN_FORWARD
&& (TrInput & IN_DUCK || Lara.keepDucked)
&& Lara.waterStatus != LW_WADE)
{
if (TrInput & IN_LEFT)
{
Lara.turnRate -= LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (Lara.turnRate < -ANGLE(3.0f))
Lara.turnRate = -ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
else if (TrInput & IN_RIGHT)
{
Lara.turnRate += LARA_TURN_RATE;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
if (Lara.turnRate > ANGLE(3.0f))
Lara.turnRate = ANGLE(3.0f);
2019-11-21 07:43:34 +01:00
}
}
else
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
}
}
void lara_col_all4s(ITEM_INFO* item, COLL_INFO* coll)//14B40, 14C74 (F)
2019-11-21 07:43:34 +01:00
{
item->fallspeed = 0;
item->gravityStatus = false;
if (item->goalAnimState != STATE_LARA_CRAWL_TO_CLIMB)
{
Lara.moveAngle = item->pos.yRot;
coll->facing = Lara.moveAngle;
coll->radius = 200;
coll->badPos = 255;
coll->badNeg = -255;
coll->badCeiling = 400;
coll->slopesAreWalls = true;
coll->slopesArePits = true;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
if (LaraFallen(item, coll))
{
Lara.gunStatus = LG_NO_ARMS;
}
else if (!TestLaraSlide(item, coll))
{
2019-12-02 09:11:21 +01:00
int slope = abs(coll->leftFloor2 - coll->rightFloor2);
2019-11-21 07:43:34 +01:00
Lara.keepDucked = coll->midCeiling >= -362;
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT && coll->midFloor > -256)
item->pos.yPos += coll->midFloor;
if (TrInput & IN_DUCK || Lara.keepDucked &&
(!(TrInput & IN_FLARE) && !(TrInput & IN_DRAW) || TrInput & IN_FORWARD) &&
Lara.waterStatus != LW_WADE)
{
if (item->animNumber == ANIMATION_LARA_CRAWL_IDLE ||
2020-05-08 12:17:35 -05:00
item->animNumber == ANIMATION_LARA_CROUCH_TO_CRAWL_END ||
item->animNumber == ANIMATION_LARA_CRAWL_FORWARD_TO_IDLE_END_RIGHT ||
item->animNumber == ANIMATION_LARA_CRAWL_FORWARD_TO_IDLE_END_LEFT)
2019-11-21 07:43:34 +01:00
{
if (TrInput & IN_FORWARD)
{
if (abs(LaraFloorFront(item, item->pos.yRot, 256)) < 255 && HeightType != BIG_SLOPE)
item->goalAnimState = STATE_LARA_CRAWL_FORWARD;
}
else if (TrInput & IN_BACK)
{
2019-12-02 09:11:21 +01:00
short height = LaraCeilingFront(item, item->pos.yRot, -300, 128);
short heightl = 0;
short heightr = 0;
2019-11-21 07:43:34 +01:00
if (height != NO_HEIGHT && height <= 256)
{
if (TrInput & IN_ACTION)
{
2019-12-02 09:11:21 +01:00
int x = item->pos.xPos;
int z = item->pos.zPos;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
item->pos.xPos += 128 * phd_sin(item->pos.yRot - ANGLE(90.0f)) >> W2V_SHIFT;
item->pos.zPos += 128 * phd_cos(item->pos.yRot - ANGLE(90.0f)) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
heightl = LaraFloorFront(item, item->pos.yRot, -300);
2020-05-31 04:20:52 -05:00
item->pos.xPos += 256 * phd_sin(item->pos.yRot + ANGLE(90.0f)) >> W2V_SHIFT;
item->pos.zPos += 256 * phd_cos(item->pos.yRot + ANGLE(90.0f)) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
heightr = LaraFloorFront(item, item->pos.yRot, -300);
item->pos.xPos = x;
item->pos.zPos = z;
}
height = LaraFloorFront(item, item->pos.yRot, -300);
if (abs(height) >= 255 || HeightType == BIG_SLOPE)
{
if (TrInput & IN_ACTION)
{
if (height > 768 &&
heightl > 768 &&
heightr > 768 &&
slope < 120)
{
2019-12-02 09:11:21 +01:00
int tmp;
2019-11-21 07:43:34 +01:00
ITEM_INFO* tmp1;
MESH_INFO* tmp2;
2019-12-02 09:11:21 +01:00
int x = item->pos.xPos;
int z = item->pos.zPos;
2019-11-21 07:43:34 +01:00
2020-04-25 16:23:53 +02:00
item->pos.xPos -= 100 * phd_sin(coll->facing) >> W2V_SHIFT;
item->pos.zPos -= 100 * phd_cos(coll->facing) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
//tmp = GetCollidedObjects(item, 100, 1, wat, wat, 0);
//S_Warn("[lara_col_all4s] - Warning: Core Design function call shittery\n");
tmp = GetCollidedObjects(item, 100, 1, &tmp1, &tmp2, 0);
item->pos.xPos = x;
item->pos.zPos = z;
if (!tmp)
{
2020-05-31 04:20:52 -05:00
switch ((unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f))
2019-11-21 07:43:34 +01:00
{
case 0:
item->pos.yRot = 0;
item->pos.zPos = (item->pos.zPos & 0xFFFFFC00) + 225;
break;
case 1:
2020-05-31 04:20:52 -05:00
item->pos.yRot = ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
item->pos.xPos = (item->pos.xPos & 0xFFFFFC00) + 225;
break;
case 2:
2020-05-31 04:20:52 -05:00
item->pos.yRot = -ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
item->pos.zPos = (item->pos.zPos | 0x3FF) - 225;
break;
case 3:
2020-05-31 04:20:52 -05:00
item->pos.yRot = -ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
item->pos.xPos = (item->pos.xPos | 0x3FF) - 225;
break;
}
item->goalAnimState = STATE_LARA_CRAWL_TO_CLIMB;
}
}
}
}
else
{
item->goalAnimState = STATE_LARA_CRAWL_BACK;
}
}
}
else if (TrInput & IN_LEFT)
{
item->animNumber = ANIMATION_LARA_CRAWL_TURN_LEFT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_CRAWL_TURN_LEFT;
item->goalAnimState = STATE_LARA_CRAWL_TURN_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->animNumber = ANIMATION_LARA_CRAWL_TURN_RIGHT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_CRAWL_TURN_RIGHT;
item->goalAnimState = STATE_LARA_CRAWL_TURN_RIGHT;
}
}
}
else
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
}
}
}
}
void lara_as_all4s(ITEM_INFO* item, COLL_INFO* coll)//14970, 14A78 (F)
2019-11-21 07:43:34 +01:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_DEATH;
return;
}
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED
EnableCrawlFlex1clickdown = true;
EnableCrawlFlex1clickup = true;
EnableCrawlFlex2clickE = true;
EnableCrawlFlex1clickE = true;
2020-05-30 13:02:24 -05:00
2019-11-21 07:43:34 +01:00
if (TrInput & IN_JUMP)
{
GAME_VECTOR s, d;
MESH_INFO* StaticMesh;
PHD_VECTOR v;
if (LaraFloorFront(item, item->pos.yRot, 512) > 512 &&
2019-11-21 07:43:34 +01:00
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
{
s.x = LaraItem->pos.xPos;
s.y = LaraItem->pos.yPos - 96;
s.z = LaraItem->pos.zPos;
s.roomNumber = LaraItem->roomNumber;
2020-04-25 16:23:53 +02:00
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
2019-11-21 07:43:34 +01:00
d.y = s.y + 160;
2020-04-25 16:23:53 +02:00
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
2019-11-21 07:43:34 +01:00
if (LOS(&s, &d) && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_BEGIN && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_CONTINUE)
2019-11-21 07:43:34 +01:00
{
2019-12-14 08:51:28 +01:00
// TODO: fix ObjectOnLOS2
2019-12-01 08:13:19 +01:00
/*if (ObjectOnLOS2(&s, &d, &v, (PHD_VECTOR*)&StaticMesh) == 999)
2019-12-14 08:51:28 +01:00
{*/
2019-11-21 07:43:34 +01:00
item->animNumber = ANIMATION_LARA_CRAWL_JUMP_DOWN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
Lara.gunStatus = LG_HANDS_BUSY;
2019-12-14 08:51:28 +01:00
/*}*/
2019-11-21 07:43:34 +01:00
}
}
else if (LaraFloorFront(item, item->pos.yRot, 256) == 512 &&
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
{
s.x = LaraItem->pos.xPos;
s.y = LaraItem->pos.yPos - 96;
s.z = LaraItem->pos.zPos;
s.roomNumber = LaraItem->roomNumber;
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
d.y = s.y + 160;
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
if (LOS(&s, &d) && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_BEGIN && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_CONTINUE && EnableCrawlFlex2clickE == true)
{
item->animNumber = ANIMATION_LARA_2CLICK_CRAWL_EXIT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
Lara.gunStatus = LG_HANDS_BUSY;
}
}
else if (LaraFloorFront(item, item->pos.yRot, 256) == 256 &&
LaraCeilingFront(item, item->pos.yRot, 768, 512) != NO_HEIGHT &&
LaraCeilingFront(item, item->pos.yRot, 768, 512) <= 0)
{
s.x = LaraItem->pos.xPos;
s.y = LaraItem->pos.yPos - 96;
s.z = LaraItem->pos.zPos;
s.roomNumber = LaraItem->roomNumber;
d.x = s.x + (768 * phd_sin(LaraItem->pos.yRot) >> W2V_SHIFT);
d.y = s.y + 160;
d.z = s.z + (768 * phd_cos(LaraItem->pos.yRot) >> W2V_SHIFT);
if (LOS(&s, &d) && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_BEGIN && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_CONTINUE && EnableCrawlFlex1clickE == true)
{
item->animNumber = ANIMATION_LARA_1CLICK_CRAWL_EXIT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
Lara.gunStatus = LG_HANDS_BUSY;
}
}
}
if ((TrInput & IN_ACTION) && (TrInput & IN_FORWARD) && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_BEGIN && item->animNumber != ANIMATION_LARA_CROUCH_TO_CRAWL_CONTINUE)
{
if (LaraFloorFront(item, item->pos.yRot, 256) == -256 &&
LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT &&
LaraCeilingFront(item, item->pos.yRot, 256, 256) <= -512 &&
EnableCrawlFlex1clickup == true)
{
item->animNumber = ANIMATION_LARA_1CLICK_CRAWL_TO_CRAWL_UP;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
Lara.gunStatus = LG_HANDS_BUSY;
}
else
if (LaraFloorFront(item, item->pos.yRot, 256) == 256 &&
LaraCeilingFront(item, item->pos.yRot, 256, 256) != NO_HEIGHT &&
LaraCeilingFront(item, item->pos.yRot, 256, -256) <= -512 &&
EnableCrawlFlex1clickdown == true)
{
item->animNumber = ANIMATION_LARA_1CLICK_CRAWL_TO_CRAWL_DOWN;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_MISC_CONTROL;
item->currentAnimState = STATE_LARA_MISC_CONTROL;
Lara.gunStatus = LG_HANDS_BUSY;
}
2019-11-21 07:43:34 +01:00
}
if (TrInput & IN_LOOK)
LookUpDown();
Lara.torsoXrot = 0;
Lara.torsoYrot = 0;
coll->enableSpaz = false;
coll->enableBaddiePush = true;
if (item->animNumber == ANIMATION_LARA_CROUCH_TO_CRAWL_BEGIN)
Lara.gunStatus = LG_HANDS_BUSY;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(23.0f);
2020-05-20 22:07:27 -05:00
if (Rooms[LaraItem->roomNumber].flags & ENV_FLAG_WATER)
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
item->requiredAnimState = STATE_LARA_STOP;
}
2019-11-21 07:43:34 +01:00
}
void lara_col_duck(ITEM_INFO* item, COLL_INFO* coll)//147C4, 148CC (F)
2019-11-21 07:43:34 +01:00
{
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot;
coll->facing = item->pos.yRot;
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
if (LaraFallen(item, coll))
{
Lara.gunStatus = LG_NO_ARMS;
}
else if (!TestLaraSlide(item, coll))
{
2019-12-02 18:19:05 +01:00
Lara.keepDucked = coll->midCeiling >= -362;
2019-11-21 07:43:34 +01:00
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
if (TrInput & IN_DUCK && Lara.waterStatus != LW_WADE ||
Lara.keepDucked ||
item->animNumber != ANIMATION_LARA_CROUCH_IDLE)
{
if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_CROUCH_TURN_LEFT;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_CROUCH_TURN_RIGHT;
}
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
}
}
void lara_as_duck(ITEM_INFO* item, COLL_INFO* coll)//14688, 14738 (F)
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
short roomNum;
2019-11-21 07:43:34 +01:00
coll->enableSpaz = false;
coll->enableBaddiePush = true;
Lara.isDucked = true;
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
return;
}
roomNum = LaraItem->roomNumber;
if (TrInput & IN_LOOK)
LookUpDown();
GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &roomNum);
// FOR DEBUG PURPOSES UNTIL SCRIPTING IS FINISHED-
EnableCrouchRoll = true;
2019-11-21 07:43:34 +01:00
if ((TrInput & IN_FORWARD || TrInput & IN_BACK)
&& (TrInput & IN_DUCK || Lara.keepDucked)
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.waterStatus != LW_WADE
2020-05-20 22:07:27 -05:00
|| Lara.waterSurfaceDist == 256
&& !(Lara.waterSurfaceDist > 256)
/*&& !(Rooms[roomNum].flags & ENV_FLAG_WATER)*/)
2019-11-21 07:43:34 +01:00
{
2020-05-01 21:19:03 -05:00
if ((item->animNumber == ANIMATION_LARA_CROUCH_IDLE
2019-12-02 18:19:05 +01:00
|| item->animNumber == ANIMATION_LARA_CROUCH_PREPARE)
2019-11-21 07:43:34 +01:00
&& !(TrInput & IN_FLARE || TrInput & IN_DRAW)
&& (Lara.gunType != WEAPON_FLARE || Lara.flareAge < 900 && Lara.flareAge != 0))
{
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
item->goalAnimState = STATE_LARA_CRAWL_IDLE;
}
2020-05-01 21:19:03 -05:00
}
else
/*crouch roll*/
if ((TrInput & IN_SPRINT) //maybe change this roll? or jump?
&& (TrInput & IN_DUCK || Lara.keepDucked)
&& Lara.gunStatus == LG_NO_ARMS
&& Lara.waterStatus != LW_WADE
2020-05-20 22:07:27 -05:00
|| Lara.waterSurfaceDist == 256
&& !(Lara.waterSurfaceDist > 256)
&& EnableCrouchRoll == true)
2020-05-20 22:07:27 -05:00
//&& !(Rooms[roomNum].flags & ENV_FLAG_WATER)) //is this necessary?- update: nope, it's not
2020-05-01 21:19:03 -05:00
{
lara_as_crouch_roll(item, coll);
}
}
2020-05-01 21:47:35 -05:00
void lara_as_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
2020-05-01 21:19:03 -05:00
{
2020-05-02 12:05:42 -05:00
/*stop Lara from doing it in these conditions to avoid trouble*/
if (LaraFloorFront(item, item->pos.yRot, 1024) >= 384 || //4 clicks away from holes in the floor
2020-05-20 22:07:27 -05:00
TestWall(item, 1024, 0, -256)) //4 clicks away from walls
2020-05-01 21:19:03 -05:00
{
return;
}
/*do actual anim*/
if ((item->animNumber == ANIMATION_LARA_CROUCH_IDLE //)
|| item->animNumber == ANIMATION_LARA_CROUCH_PREPARE) // not exactly necessary but makes gameplay much faster, make optional in the future.
&& !(TrInput & IN_FLARE || TrInput & IN_DRAW) //avoids some flare spawning/wep stuff
&& (Lara.gunType != WEAPON_FLARE || Lara.flareAge < 900 && Lara.flareAge != 0))
{
Lara.torsoYrot = 0;
Lara.torsoXrot = 0;
lara_col_crouch_roll(item, coll);
item->currentAnimState = STATE_LARA_CROUCH_ROLL;
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
item->animNumber = ANIMATION_LARA_CROUCH_ROLL_FORWARD_BEGIN;
2020-05-02 12:05:42 -05:00
item->frameNumber = Anims[ANIMATION_LARA_CROUCH_ROLL_FORWARD_BEGIN].frameBase; //fix it being slow
2020-05-01 21:19:03 -05:00
}
}
2020-05-02 12:05:42 -05:00
2020-05-01 21:47:35 -05:00
void lara_col_crouch_roll(ITEM_INFO* item, COLL_INFO* coll)
2020-05-01 21:19:03 -05:00
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
return;
2019-11-21 07:43:34 +01:00
}
2020-05-01 21:19:03 -05:00
2020-05-02 12:05:42 -05:00
Lara.isDucked = true;
item->gravityStatus = false;
item->fallspeed = 0;
2020-05-01 21:19:03 -05:00
Lara.moveAngle = item->pos.yRot;
coll->facing = item->pos.yRot;
coll->badPos = STEPUP_HEIGHT;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = 0;
2020-05-02 12:05:42 -05:00
coll->slopesAreWalls = true;
2020-05-01 21:19:03 -05:00
GetLaraCollisionInfo(item, coll);
ShiftItem(item, coll);
2020-05-02 12:05:42 -05:00
item->pos.yPos += coll->midFloor;
2019-11-21 07:43:34 +01:00
}
2020-05-01 21:19:03 -05:00
void lara_col_ducklr(ITEM_INFO* item, COLL_INFO* coll)//14534, 145E4 (F)
2019-11-21 07:43:34 +01:00
{
// FIXED
Lara.isDucked = true;
if (TrInput & IN_LOOK)
LookUpDown();
item->gravityStatus = false;
item->fallspeed = 0;
Lara.moveAngle = item->pos.yRot;
coll->facing = item->pos.yRot;
coll->badPos = 384;
coll->badNeg = -STEPUP_HEIGHT;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
coll->slopesAreWalls = true;
2019-11-21 07:43:34 +01:00
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 400);
if (LaraFallen(item, coll))
{
Lara.gunStatus = LG_NO_ARMS;
}
else if (!TestLaraSlide(item, coll))
{
if (coll->midCeiling < -362)
Lara.keepDucked = false;
else
Lara.keepDucked = true;
ShiftItem(item, coll);
if (coll->midFloor != NO_HEIGHT)
item->pos.yPos += coll->midFloor;
}
}
void lara_as_duckr(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
coll->enableSpaz = false;
if ((TrInput & (IN_DUCK | IN_LEFT)) != (IN_DUCK | IN_LEFT) || item->hitPoints <= 0) /* @ORIGINAL_BUG: the condition checks for IN_LEFT instead of IN_RIGHT */
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
}
void lara_as_duckl(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
coll->enableSpaz = false;
2019-12-22 17:06:25 -03:00
if ((TrInput & (IN_DUCK | IN_LEFT)) != (IN_DUCK | IN_LEFT) || item->hitPoints <= 0)
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(1.5f);
2019-11-21 07:43:34 +01:00
}
2019-12-02 09:11:21 +01:00
int TestHangSwingIn(ITEM_INFO* item, short angle)//14104, 141B4 (F)
2019-11-21 07:43:34 +01:00
{
int x = item->pos.xPos;
int y = item->pos.yPos;
int z = item->pos.zPos;
2019-12-02 09:11:21 +01:00
short roomNum = item->roomNumber;
2019-11-21 07:43:34 +01:00
FLOOR_INFO* floor;
int h, c;
2020-05-31 04:20:52 -05:00
if (angle == ANGLE(180.0f))
2019-11-21 07:43:34 +01:00
{
z -= 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == -ANGLE(90.0f))
2019-11-21 07:43:34 +01:00
{
x -= 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == ANGLE(90.0f))
2019-11-21 07:43:34 +01:00
{
x += 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == ANGLE(0.0f))
2019-11-21 07:43:34 +01:00
{
z += 256;
}
floor = GetFloor(x, y, z, &roomNum);
h = GetFloorHeight(floor, x, y, z);
c = GetCeiling(floor, x, y, z);
return h != NO_HEIGHT && h - y > 0 && c - y < -400 && y - c - 819 > -72;
}
int LaraHangLeftCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
2020-05-30 13:02:24 -05:00
if (item->animNumber != ANIMATION_LARA_HANG_IDLE && item->animNumber != ANIMATION_LARA_HANG_FEET)
2019-11-21 07:43:34 +01:00
return 0;
if (coll->hitStatic)
return 0;
2019-12-02 09:11:21 +01:00
int x;
int z;
2019-11-21 07:43:34 +01:00
2019-12-02 09:11:21 +01:00
int oldXpos = item->pos.xPos;
int oldZpos = item->pos.zPos;
short oldYrot = item->pos.yRot;
int oldFrontFloor = coll->frontFloor;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
short angle = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
if (angle != NORTH && angle != SOUTH)
2019-11-21 07:43:34 +01:00
{
x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF;
z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF;
}
else
{
x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1);
z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1);
}
item->pos.xPos = x;
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
2019-12-02 09:11:21 +01:00
int result = -IsValidHangPos(item, coll);
2019-11-21 07:43:34 +01:00
if (result)
{
if (Lara.climbStatus)
{
if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle])
2019-11-21 07:43:34 +01:00
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
}
}
else
{
if (abs(oldFrontFloor - coll->frontFloor) <= 60)
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
}
}
}
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
2020-05-31 04:20:52 -05:00
if (LaraFloorFront(item, oldYrot - ANGLE(90.0f), 116) < 0)
2019-11-21 07:43:34 +01:00
return 0;
switch (angle)
{
case NORTH:
x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.xPos - SECTOR(1);
z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ item->pos.zPos + SECTOR(1);
break;
case SOUTH:
x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1));
z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1));
break;
case WEST:
x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF);
z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF);
break;
default:
x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1);
z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1);
break;
}
item->pos.xPos = x;
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
result = IsValidHangPos(item, coll);
if (!result)
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
2019-11-21 07:43:34 +01:00
}
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
if (!Lara.climbStatus)
{
if (abs(oldFrontFloor - coll->frontFloor) <= 60)
{
switch (angle)
{
case NORTH:
if ((oldXpos & 0x3FF) > 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case EAST:
if ((oldZpos & 0x3FF) < 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case SOUTH:
if ((oldXpos & 0x3FF) < 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case WEST:
if ((oldZpos & 0x3FF) > 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
}
return result;
}
return 0;
}
if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle])
2019-11-21 07:43:34 +01:00
return result;
2019-12-02 09:11:21 +01:00
short front = LaraFloorFront(item, item->pos.yRot, 116);
2019-11-21 07:43:34 +01:00
if (abs(front - coll->frontFloor) > 60)
return 0;
if (front < -768)
return 0;
return result;
}
int LaraHangRightCornerTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
2020-05-30 13:02:24 -05:00
if (item->animNumber != ANIMATION_LARA_HANG_IDLE && item->animNumber != ANIMATION_LARA_HANG_FEET)
2019-11-21 07:43:34 +01:00
return 0;
if (coll->hitStatic)
return 0;
2019-12-02 09:11:21 +01:00
int x;
int z;
2019-11-21 07:43:34 +01:00
2019-12-02 09:11:21 +01:00
int oldXpos = item->pos.xPos;
int oldZpos = item->pos.zPos;
short oldYrot = item->pos.yRot;
int oldFrontFloor = coll->frontFloor;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
short angle = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
if (angle != NORTH && angle != SOUTH)
2019-11-21 07:43:34 +01:00
{
x = (item->pos.xPos & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1);
z = (item->pos.zPos & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1);
}
else
{
x = item->pos.xPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF;
z = item->pos.zPos ^ (item->pos.xPos ^ item->pos.zPos) & 0x3FF;
}
item->pos.xPos = x;
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
2019-12-02 09:11:21 +01:00
int result = -IsValidHangPos(item, coll);
2019-11-21 07:43:34 +01:00
if (result)
{
if (Lara.climbStatus)
{
if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & LeftClimbTab[angle])
2019-11-21 07:43:34 +01:00
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
}
}
else
{
if (abs(oldFrontFloor - coll->frontFloor) <= 60)
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
}
}
}
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
2020-05-31 04:20:52 -05:00
if (LaraFloorFront(item, oldYrot + ANGLE(90.0f), 116) < 0)
2019-11-21 07:43:34 +01:00
return 0;
switch (angle)
{
case NORTH:
x = ((item->pos.xPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1);
z = ((item->pos.zPos + SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1);
2019-11-21 07:43:34 +01:00
break;
case SOUTH:
x = ((item->pos.xPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.zPos & 0x3FF) + SECTOR(1);
z = ((item->pos.zPos - SECTOR(1)) & 0xFFFFFC00) - (item->pos.xPos & 0x3FF) + SECTOR(1);
2019-11-21 07:43:34 +01:00
break;
case WEST:
x = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.xPos - SECTOR(1));
z = (item->pos.xPos ^ item->pos.zPos) & 0x3FF ^ (item->pos.zPos + SECTOR(1));
2019-11-21 07:43:34 +01:00
break;
default:
x = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.xPos + SECTOR(1));
z = ((item->pos.xPos ^ item->pos.zPos) & 0x3FF) ^ (item->pos.zPos - SECTOR(1));
2019-11-21 07:43:34 +01:00
break;
}
item->pos.xPos = x;
Lara.cornerX = x;
item->pos.zPos = z;
Lara.cornerZ = z;
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
result = IsValidHangPos(item, coll);
if (!result)
{
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
return result;
2019-11-21 07:43:34 +01:00
}
item->pos.xPos = oldXpos;
item->pos.zPos = oldZpos;
item->pos.yRot = oldYrot;
Lara.moveAngle = oldYrot;
if (!Lara.climbStatus)
{
if (abs(oldFrontFloor - coll->frontFloor) <= 60)
{
switch (angle)
{
case NORTH:
if ((oldXpos & 0x3FF) < 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case EAST:
if ((oldZpos & 0x3FF) > 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case SOUTH:
if ((oldXpos & 0x3FF) > 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
case WEST:
if ((oldZpos & 0x3FF) < 512)
result = 0;
break;
2019-11-21 07:43:34 +01:00
}
return result;
}
return 0;
}
if (GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber) & RightClimbTab[angle])
2019-11-21 07:43:34 +01:00
return result;
2019-12-02 09:11:21 +01:00
short front = LaraFloorFront(item, item->pos.yRot, 116);
2019-11-21 07:43:34 +01:00
if (abs(front - coll->frontFloor) > 60)
return 0;
if (front < -768)
return 0;
return result;
2019-12-01 08:13:19 +01:00
}
2019-11-21 07:43:34 +01:00
int IsValidHangPos(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (LaraFloorFront(item, Lara.moveAngle, 100) < 200)
return 0;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
short angle = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
2019-11-21 07:43:34 +01:00
switch (angle)
{
case NORTH:
item->pos.zPos += 4;
break;
case EAST:
item->pos.xPos += 4;
break;
case SOUTH:
item->pos.zPos -= 4;
break;
case WEST:
item->pos.xPos -= 4;
break;
default:
break;
}
coll->badPos = NO_BAD_POS;
2019-11-21 07:43:34 +01:00
coll->badNeg = -512;
coll->badCeiling = 0;
Lara.moveAngle = item->pos.yRot;
GetLaraCollisionInfo(item, coll);
if (coll->midCeiling >= 0 || coll->collType != CT_FRONT || coll->hitStatic)
return 0;
2019-11-21 07:43:34 +01:00
return abs(coll->frontFloor - coll->rightFloor2) < 60;
}
void SnapLaraToEdgeOfBlock(ITEM_INFO* item, COLL_INFO* coll, short angle) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (item->currentAnimState == STATE_LARA_SHIMMY_RIGHT)
{
switch (angle)
{
2019-12-01 08:13:19 +01:00
case NORTH:
2019-11-21 07:43:34 +01:00
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x390;
return;
2019-12-01 08:13:19 +01:00
case EAST:
2019-11-21 07:43:34 +01:00
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0x70;
return;
2019-12-01 08:13:19 +01:00
case SOUTH:
2019-11-21 07:43:34 +01:00
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0x70;
return;
2019-12-01 08:13:19 +01:00
case WEST:
2019-11-21 07:43:34 +01:00
default:
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x390;
return;
}
}
if (item->currentAnimState == STATE_LARA_SHIMMY_LEFT)
{
switch (angle)
{
2019-12-01 08:13:19 +01:00
case NORTH:
2019-11-21 07:43:34 +01:00
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0x70;
return;
2019-12-01 08:13:19 +01:00
case EAST:
2019-11-21 07:43:34 +01:00
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x390;
return;
2019-12-01 08:13:19 +01:00
case SOUTH:
2019-11-21 07:43:34 +01:00
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x390;
return;
2019-12-01 08:13:19 +01:00
case WEST:
2019-11-21 07:43:34 +01:00
default:
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0x70;
return;
}
}
2020-05-23 15:59:18 -05:00
if (item->currentAnimState == STATE_LARA_HANG_FEET_SHIMMYR)
{
switch (angle)
{
case NORTH:
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x720;
return;
case EAST:
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0xE0;
return;
case SOUTH:
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0xE0;
return;
case WEST:
default:
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x720;
return;
}
}
if (item->currentAnimState == STATE_LARA_HANG_FEET_SHIMMYL)
{
switch (angle)
{
case NORTH:
item->pos.xPos = coll->old.x & 0xFFFFFC70 | 0xE0;
return;
case EAST:
item->pos.zPos = coll->old.z & 0xFFFFFF90 | 0x720;
return;
case SOUTH:
item->pos.xPos = coll->old.x & 0xFFFFFF90 | 0x720;
return;
case WEST:
default:
item->pos.zPos = coll->old.z & 0xFFFFFC70 | 0xE0;
return;
}
}
2019-11-21 07:43:34 +01:00
}
int LaraTestHangOnClimbWall(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
ANIM_FRAME* bounds;
2019-11-21 07:43:34 +01:00
int shift, result;
if (Lara.climbStatus == 0)
return 0;
2019-11-21 07:43:34 +01:00
if (item->fallspeed < 0)
return 0;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
switch ((unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f))
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
case NORTH:
case SOUTH:
2019-11-21 07:43:34 +01:00
item->pos.zPos += coll->shift.z;
break;
2019-12-01 08:13:19 +01:00
case EAST:
case WEST:
2019-11-21 07:43:34 +01:00
item->pos.xPos += coll->shift.x;
break;
default:
break;
}
bounds = (ANIM_FRAME*) GetBoundsAccurate(item);
2019-11-21 07:43:34 +01:00
if (Lara.moveAngle != item->pos.yRot)
{
2019-12-02 09:11:21 +01:00
short l = LaraCeilingFront(item, item->pos.yRot, 0, 0);
short r = LaraCeilingFront(item, Lara.moveAngle, 128, 0);
2019-11-21 07:43:34 +01:00
if (abs(l - r) > 60)
return 0;
2019-11-21 07:43:34 +01:00
}
if (LaraTestClimbPos(item, coll->radius, coll->radius, bounds->MinY, bounds->MaxY - bounds->MinY, &shift) &&
LaraTestClimbPos(item, coll->radius, -coll->radius, bounds->MinY, bounds->MaxY - bounds->MinY, &shift))
2019-11-21 07:43:34 +01:00
{
result = LaraTestClimbPos(item, coll->radius, 0, bounds->MinY, bounds->MaxY - bounds->MinY, &shift);
if (result)
{
if (result != 1)
item->pos.yPos += shift;
return 1;
}
2019-11-21 07:43:34 +01:00
}
return 0;
2019-11-21 07:43:34 +01:00
}
void LaraSlideEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12B18, 12BC8 (F)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
switch (coll->collType)
{
case CT_LEFT:
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
break;
case CT_RIGHT:
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
break;
case CT_TOP:
case CT_TOP_FRONT:
if (item->fallspeed <= 0)
item->fallspeed = 1;
break;
case CT_CLAMP:
2020-04-25 16:23:53 +02:00
item->pos.zPos -= (400 * phd_cos(coll->facing)) >> W2V_SHIFT;
item->pos.xPos -= (400 * phd_sin(coll->facing)) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
item->speed = 0;
2019-11-21 07:43:34 +01:00
coll->midFloor = 0;
if (item->fallspeed <= 0)
item->fallspeed = 16;
2019-12-16 17:11:24 +01:00
break;
2019-11-21 07:43:34 +01:00
}
}
void LaraDeflectEdgeJump(ITEM_INFO* item, COLL_INFO* coll)//12904, 129B4 (F)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
switch (coll->collType)
{
case CT_FRONT:
case CT_TOP_FRONT:
if (!Lara.climbStatus || item->speed != 2)
{
if (coll->midFloor <= 512)
{
if (coll->midFloor <= 128)
{
item->goalAnimState = STATE_LARA_GRAB_TO_FALL;
item->currentAnimState = STATE_LARA_GRAB_TO_FALL;
item->animNumber = ANIMATION_LARA_LANDING_LIGHT;
item->frameNumber = Anims[ANIMATION_LARA_LANDING_LIGHT].frameBase;
2019-11-21 07:43:34 +01:00
}
}
else
{
item->goalAnimState = STATE_LARA_FREEFALL;
item->currentAnimState = STATE_LARA_FREEFALL;
item->animNumber = ANIMATION_LARA_SMASH_JUMP;
item->frameNumber = Anims[ANIMATION_LARA_SMASH_JUMP].frameBase + 1;
2019-11-21 07:43:34 +01:00
}
item->speed /= 4;
2020-05-31 04:20:52 -05:00
Lara.moveAngle -= ANGLE(180.0f);
2019-11-21 07:43:34 +01:00
if (item->fallspeed <= 0)
item->fallspeed = 1;
}
2019-11-21 07:43:34 +01:00
break;
case CT_TOP:
if (item->fallspeed <= 0)
item->fallspeed = 1;
2019-11-21 07:43:34 +01:00
break;
case CT_LEFT:
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
break;
case CT_RIGHT:
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
break;
case CT_CLAMP:
2020-04-25 16:23:53 +02:00
item->pos.xPos -= (100 * 4 * phd_sin(coll->facing)) >> W2V_SHIFT;
item->pos.zPos -= (100 * 4 * phd_cos(coll->facing)) >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
item->speed = 0;
coll->midFloor = 0;
if (item->fallspeed <= 0)
item->fallspeed = 16;
2019-11-21 07:43:34 +01:00
break;
}
}
void lara_slide_slope(ITEM_INFO* item, COLL_INFO* coll)//127BC, 1286C (F)
2019-11-21 07:43:34 +01:00
{
coll->badPos = NO_BAD_POS;
coll->badNeg = -512;
2019-11-21 07:43:34 +01:00
coll->badCeiling = 0;
GetLaraCollisionInfo(item, coll);
if (!LaraHitCeiling(item, coll))
{
LaraDeflectEdge(item, coll);
if (coll->midFloor <= 200)
{
TestLaraSlide(item, coll);
item->pos.yPos += coll->midFloor;
2019-12-01 08:13:19 +01:00
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
2019-11-21 07:43:34 +01:00
{
2020-05-19 20:42:06 -05:00
if (TrInput & IN_FORWARD && item->currentAnimState != STATE_LARA_SLIDE_BACK)
{
item->goalAnimState = STATE_LARA_RUN_FORWARD;
}
else
2019-11-21 07:43:34 +01:00
item->goalAnimState = STATE_LARA_STOP;
StopSoundEffect(SFX_LARA_SLIPPING);
}
}
else
{
if (item->currentAnimState == STATE_LARA_SLIDE_FORWARD)
{
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[ANIMATION_LARA_FREE_FALL_FORWARD].frameBase;
2019-12-16 17:11:24 +01:00
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
2019-11-21 07:43:34 +01:00
}
else
{
item->animNumber = ANIMATION_LARA_FREE_FALL_BACK;
item->frameNumber = Anims[ANIMATION_LARA_FREE_FALL_BACK].frameBase;
2019-12-16 17:11:24 +01:00
item->currentAnimState = STATE_LARA_FALL_BACKWARD;
item->goalAnimState = STATE_LARA_FALL_BACKWARD;
2019-11-21 07:43:34 +01:00
}
StopSoundEffect(SFX_LARA_SLIPPING);
2019-11-21 07:43:34 +01:00
item->gravityStatus = true;
item->fallspeed = 0;
}
}
}
void LaraCollideStop(ITEM_INFO* item, COLL_INFO* coll)//126F0(<), 127A0(<) (F)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
switch (coll->oldAnimState)
2019-11-21 07:43:34 +01:00
{
case STATE_LARA_STOP:
case STATE_LARA_TURN_RIGHT_SLOW:
case STATE_LARA_TURN_LEFT_SLOW:
case STATE_LARA_TURN_FAST:
2019-12-01 08:13:19 +01:00
item->currentAnimState = coll->oldAnimState;
item->animNumber = coll->oldAnimNumber;
item->frameNumber = coll->oldFrameNumber;
2019-11-21 07:43:34 +01:00
if (TrInput & IN_LEFT)
{
item->goalAnimState = STATE_LARA_TURN_LEFT_SLOW;
}
else if (TrInput & IN_RIGHT)
{
item->goalAnimState = STATE_LARA_TURN_RIGHT_SLOW;
}
else
{
item->goalAnimState = STATE_LARA_STOP;
}
AnimateLara(item);
break;
default:
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[ANIMATION_LARA_STAY_SOLID].frameBase;
2019-11-21 07:43:34 +01:00
break;
}
}
int TestWall(ITEM_INFO* item, int front, int right, int down)//12550, 12600 (F)
2019-11-21 07:43:34 +01:00
{
int x = item->pos.xPos;
int y = item->pos.yPos + down;
int z = item->pos.zPos;
2019-11-21 07:43:34 +01:00
2020-05-31 04:20:52 -05:00
short angle = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
short roomNum = item->roomNumber;
2019-11-21 07:43:34 +01:00
FLOOR_INFO* floor;
int h, c;
2019-11-21 07:43:34 +01:00
switch (angle)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
case NORTH:
2019-11-21 07:43:34 +01:00
x -= right;
break;
2019-12-01 08:13:19 +01:00
case EAST:
2019-11-21 07:43:34 +01:00
z -= right;
break;
2019-12-01 08:13:19 +01:00
case SOUTH:
2019-11-21 07:43:34 +01:00
x += right;
break;
2019-12-01 08:13:19 +01:00
case WEST:
2019-11-21 07:43:34 +01:00
z += right;
break;
default:
break;
}
GetFloor(x, y, z, &roomNum);
switch (angle)
2019-11-21 07:43:34 +01:00
{
2019-12-01 08:13:19 +01:00
case NORTH:
2019-11-21 07:43:34 +01:00
z += front;
break;
2019-12-01 08:13:19 +01:00
case EAST:
2019-11-21 07:43:34 +01:00
x += front;
break;
2019-12-01 08:13:19 +01:00
case SOUTH:
2019-11-21 07:43:34 +01:00
z -= front;
break;
2019-12-01 08:13:19 +01:00
case WEST:
2019-11-21 07:43:34 +01:00
x -= front;
break;
default:
break;
}
floor = GetFloor(x, y, z, &roomNum);
h = GetFloorHeight(floor, x, y, z);
c = GetCeiling(floor, x, y, z);
if (h == NO_HEIGHT)
return 1;
if (y >= h || y <= c)
2019-11-21 07:43:34 +01:00
return 2;
return 0;
}
int LaraTestClimbStance(ITEM_INFO* item, COLL_INFO* coll)//11F78, 12028
2019-11-21 07:43:34 +01:00
{
2019-12-02 09:11:21 +01:00
int shift_r, shift_l;
2019-11-21 07:43:34 +01:00
if (LaraTestClimbPos(item, coll->radius, coll->radius + 120, -700, 512, &shift_r) != 1)
return false;
2019-11-21 07:43:34 +01:00
if (LaraTestClimbPos(item, coll->radius, -(coll->radius + 120), -700, 512, &shift_l) != 1)
return false;
2019-11-21 07:43:34 +01:00
if (shift_r)
{
if (shift_l)
{
if (shift_r < 0 != shift_l < 0)
return false;
2019-11-21 07:43:34 +01:00
if ((shift_r < 0 && shift_l < shift_r) ||
(shift_r > 0 && shift_l > shift_r))
/*if (SIGN(shift_r) == SIGN(shift_l) &&
abs(shift_l) > abs(shift_r))*/
{
item->pos.yPos += shift_l;
return true;
}
2019-11-21 07:43:34 +01:00
}
item->pos.yPos += shift_r;
}
else if (shift_l)
{
item->pos.yPos += shift_l;
}
return true;
2019-11-21 07:43:34 +01:00
}
int LaraTestEdgeCatch(ITEM_INFO* item, COLL_INFO* coll, int* edge) // (F) (D)
2019-11-21 07:43:34 +01:00
{
ANIM_FRAME* bounds = (ANIM_FRAME*) GetBoundsAccurate(item);
int hdif = coll->frontFloor - bounds->MinY;
2019-11-21 07:43:34 +01:00
if (hdif < 0 == hdif + item->fallspeed < 0)
2019-11-21 07:43:34 +01:00
{
hdif = item->pos.yPos + bounds->MinY;
2019-11-21 07:43:34 +01:00
if ((hdif + item->fallspeed & 0xFFFFFF00) != (hdif & 0xFFFFFF00))
2019-11-21 07:43:34 +01:00
{
if (item->fallspeed > 0)
*edge = (hdif + item->fallspeed) & 0xFFFFFF00;
2019-11-21 07:43:34 +01:00
else
*edge = hdif & 0xFFFFFF00;
2019-11-21 07:43:34 +01:00
return -1;
}
return 0;
}
if (abs(coll->leftFloor2 - coll->rightFloor2) >= SLOPE_DIF)
return 0;
return 1;
}
int LaraDeflectEdgeDuck(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
{
ShiftItem(item, coll);
item->gravityStatus = false;
item->speed = 0;
return 1;
}
if (coll->collType == CT_LEFT)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
else if (coll->collType == CT_RIGHT)
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(2.0f);
2019-11-21 07:43:34 +01:00
}
return 0;
}
int LaraDeflectEdge(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (coll->collType == CT_FRONT || coll->collType == CT_TOP_FRONT)
{
ShiftItem(item, coll);
item->goalAnimState = STATE_LARA_STOP;
2019-11-21 07:43:34 +01:00
item->speed = 0;
item->gravityStatus = false;
2019-11-21 07:43:34 +01:00
return 1;
}
if (coll->collType == CT_LEFT)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot += ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
}
else if (coll->collType == CT_RIGHT)
2019-11-21 07:43:34 +01:00
{
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
item->pos.yRot -= ANGLE(5.0f);
2019-11-21 07:43:34 +01:00
}
return 0;
2019-11-21 07:43:34 +01:00
}
int LaraHitCeiling(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (coll->collType == CT_TOP || coll->collType == CT_CLAMP)
{
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
item->goalAnimState = STATE_LARA_STOP;
item->currentAnimState = STATE_LARA_STOP;
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
2019-11-21 07:43:34 +01:00
item->speed = 0;
item->fallspeed = 0;
item->gravityStatus = false;
2019-11-21 07:43:34 +01:00
return 1;
2019-11-21 07:43:34 +01:00
}
return 0;
2019-11-21 07:43:34 +01:00
}
int LaraLandedBad(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
int landspeed = item->fallspeed - 140;
2019-11-21 07:43:34 +01:00
if (landspeed > 0)
{
if (landspeed <= 14)
{
item->hitPoints -= 1000 * SQUARE(landspeed) / 196;
return item->hitPoints <= 0;
}
else
{
item->hitPoints = -1;
return 1;
}
}
2019-11-21 07:43:34 +01:00
return 0;
2019-11-21 07:43:34 +01:00
}
int LaraFallen(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
if (Lara.waterStatus == LW_WADE || coll->midFloor <= STEPUP_HEIGHT)
{
return 0;
2019-11-21 07:43:34 +01:00
}
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->fallspeed = 0;
item->gravityStatus = true;
return 1;
2019-12-16 17:11:24 +01:00
}
2019-11-21 07:43:34 +01:00
short LaraCeilingFront(ITEM_INFO* item, short ang, int dist, int h) // (F) (D)
2019-11-21 07:43:34 +01:00
{
short room = item->roomNumber;
2020-04-25 16:23:53 +02:00
int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT);
int y = item->pos.yPos - h;
2020-04-25 16:23:53 +02:00
int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT);
2019-11-21 07:43:34 +01:00
int height = GetCeiling(GetFloor(x, y, z, &room), x, y, z);
2019-11-21 07:43:34 +01:00
if (height != NO_HEIGHT)
height += h - item->pos.yPos;
2019-11-21 07:43:34 +01:00
return height;
}
short LaraFloorFront(ITEM_INFO* item, short ang, int dist) // (F) (D)
2019-11-21 07:43:34 +01:00
{
short room = item->roomNumber;
2019-11-21 07:43:34 +01:00
2020-04-25 16:23:53 +02:00
int x = item->pos.xPos + ((dist * phd_sin(ang)) >> W2V_SHIFT);
int y = item->pos.yPos - 762;
2020-04-25 16:23:53 +02:00
int z = item->pos.zPos + ((dist * phd_cos(ang)) >> W2V_SHIFT);
int height = GetFloorHeight(GetFloor(x, y, z, &room), x, y, z);
2019-11-21 07:43:34 +01:00
if (height != NO_HEIGHT)
height -= item->pos.yPos;
return height;
}
void GetLaraCollisionInfo(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-11-21 07:43:34 +01:00
{
coll->facing = Lara.moveAngle;
GetCollisionInfo(coll, item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, LARA_HITE);
2019-11-21 07:43:34 +01:00
}
int TestLaraVault(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
2019-12-02 06:39:51 +01:00
{
if (!(TrInput & IN_ACTION) || Lara.gunStatus != LG_NO_ARMS)
return 0;
2019-12-02 06:39:51 +01:00
// FOR DEBUG PURPOSES UNTIL SCRPTING IS FINISHED-
EnableCrawlFlex1click = true;
EnableCrawlFlex2click = true;
EnableCrawlFlex3click = true;
EnableMonkeyVault = true;
if (coll->collType == CT_FRONT)
{
short angle = item->pos.yRot;
2020-05-31 04:20:52 -05:00
if (angle >= -ANGLE(30.0f) && angle <= ANGLE(30.0f))
angle = 0;
2020-05-31 04:20:52 -05:00
else if (angle >= ANGLE(60.0f) && angle <= ANGLE(120.0f))
angle = ANGLE(90.0f);
else if (angle >= ANGLE(150.0f) || angle <= -ANGLE(150.0f))
angle = ANGLE(180.0f);
else if (angle >= -ANGLE(120.0f) && angle <= -ANGLE(60.0f))
angle = -ANGLE(90.0f);
2019-12-02 06:39:51 +01:00
if (angle & 0x3FFF)
return 0;
2019-12-02 06:39:51 +01:00
int slope = abs(coll->leftFloor2 - coll->rightFloor2) >= 60;
/*
if (coll->frontFloor >= 0 && coll->frontFloor <= -256)
{
if (!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256) && EnableCrawlFlex1click == true)
{
item->animNumber = ANIMATION_LARA_1CLICK_CRAWL_VAULT;
item->currentAnimState = STATE_LARA_GRABBING;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->pos.yPos += coll->frontFloor + 256;
Lara.gunStatus = LG_HANDS_BUSY;
}
2019-12-02 06:39:51 +01:00
else
{
return 0;
}
}
*/
if (coll->frontFloor >= -640 && coll->frontFloor <= -384)
2019-12-02 06:39:51 +01:00
{
if (!slope &&
coll->frontFloor - coll->frontCeiling >= 0 &&
coll->leftFloor2 - coll->leftCeiling2 >= 0 &&
coll->rightFloor2 - coll->rightCeiling2 >= 0)
{
#if 0
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768)
return 0;
#endif
item->animNumber = ANIMATION_LARA_CLIMB_2CLICK;
item->currentAnimState = STATE_LARA_GRABBING;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->pos.yPos += coll->frontFloor + 512;
Lara.gunStatus = LG_HANDS_BUSY;
}
else if((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256)) && EnableCrawlFlex2click == true)
{
item->animNumber = ANIMATION_LARA_2CLICK_CRAWL_VAULT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_GRABBING;
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
item->pos.yPos += coll->frontFloor + 512;
Lara.gunStatus = LG_HANDS_BUSY;
}
else
{
return 0;
}
}
else if (coll->frontFloor >= -896 && coll->frontFloor <= -640)
2019-12-02 06:39:51 +01:00
{
if (!slope &&
coll->frontFloor - coll->frontCeiling >= 0 &&
coll->leftFloor2 - coll->leftCeiling2 >= 0 &&
coll->rightFloor2 - coll->rightCeiling2 >= 0)
{
#if 0
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP && Lara.waterSurfaceDist < -768)
return 0;
#endif
item->animNumber = ANIMATION_LARA_CLIMB_3CLICK;
item->currentAnimState = STATE_LARA_GRABBING;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_STOP;
item->pos.yPos += coll->frontFloor + 768;
Lara.gunStatus = LG_HANDS_BUSY;
}
else if ((!slope && (abs(coll->frontCeiling - coll->frontFloor) < 256) && EnableCrawlFlex3click == true ))
{
item->animNumber = ANIMATION_LARA_3CLICK_CRAWL_VAULT;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_GRABBING;
item->goalAnimState = STATE_LARA_CROUCH_IDLE;
item->pos.yPos += coll->frontFloor + 768;
Lara.gunStatus = LG_HANDS_BUSY;
}
else
{
return 0;
}
2019-12-02 06:39:51 +01:00
}
else if (!slope && coll->frontFloor >= -1920 && coll->frontFloor <= -896)
{
#if 0
if (Rooms[item->roomNumber].flags & ENV_FLAG_SWAMP)
return 0;
#endif
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_JUMP_UP;
item->currentAnimState = STATE_LARA_STOP;
2020-04-20 14:17:01 +02:00
Lara.calcFallSpeed = -3 - sqrt(-9600 - 12 * coll->frontFloor);
AnimateLara(item);
}
else
2019-12-02 06:39:51 +01:00
{
if (!Lara.climbStatus)
return 0;
2019-12-02 06:39:51 +01:00
if (coll->frontFloor > -1920 || Lara.waterStatus == LW_WADE || coll->leftFloor2 > -1920 || coll->rightFloor2 > -2048 || coll->midCeiling > -1158)
2019-12-16 17:11:24 +01:00
{
if ((coll->frontFloor < -1024 || coll->frontCeiling >= 506) && coll->midCeiling <= -518)
{
ShiftItem(item, coll);
if (LaraTestClimbStance(item, coll))
{
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_LADDER_IDLE;
item->currentAnimState = STATE_LARA_STOP;
AnimateLara(item);
item->pos.yRot = angle;
Lara.gunStatus = LG_HANDS_BUSY;
return 1;
}
}
return 0;
2019-12-02 06:39:51 +01:00
}
item->animNumber = ANIMATION_LARA_STAY_SOLID;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_JUMP_UP;
item->currentAnimState = STATE_LARA_STOP;
Lara.calcFallSpeed = -116;
AnimateLara(item);
}
2019-12-02 06:39:51 +01:00
item->pos.yRot = angle;
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
short dir = (unsigned short)(item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
switch (dir)
{
case NORTH:
item->pos.zPos = (item->pos.zPos | (WALL_SIZE - 1)) - LARA_RAD;
break;
case EAST:
item->pos.xPos = (item->pos.xPos | (WALL_SIZE - 1)) - LARA_RAD;
break;
case SOUTH:
item->pos.zPos = (item->pos.zPos & -WALL_SIZE) + LARA_RAD;
break;
case WEST:
item->pos.xPos = (item->pos.xPos & -WALL_SIZE) + LARA_RAD;
break;
}
return 1;
}
else if (EnableMonkeyVault == true)
{
if (Lara.canMonkeySwing)
{
FLOOR_INFO* F;
int c, h;
F = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &item->roomNumber);
c = GetCeiling(F, item->pos.xPos, item->pos.yPos, item->pos.zPos);
h = (c) - (item->pos.yPos);
if (h > 1792 ||
h < -1792 ||
abs(h) == 768)
{
return 0;
}
2020-05-02 21:49:44 -05:00
item->animNumber = ANIMATION_LARA_STAY_IDLE;
item->frameNumber = Anims[ANIMATION_LARA_STAY_IDLE].frameBase;
item->goalAnimState = STATE_LARA_JUMP_UP;
item->currentAnimState = STATE_LARA_NULL_62;
AnimateLara(item);
return 1;
}
}
2020-05-02 21:49:44 -05:00
else
return 0;
2019-12-02 06:39:51 +01:00
}
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (!(TrInput & IN_ACTION))
{
FallFromRope(item);
}
2020-01-15 22:26:49 -03:00
else
{
2020-05-31 04:20:52 -05:00
Camera.targetAngle = ANGLE(30.0f);
2020-01-15 22:26:49 -03:00
if (Lara.ropeCount)
{
if (!Lara.ropeFlag)
{
--Lara.ropeCount;
Lara.ropeOffset += Lara.ropeDownVel;
if (!Lara.ropeCount)
Lara.ropeFlag = 1;
return;
}
}
else
{
2020-01-15 22:26:49 -03:00
if (!Lara.ropeFlag)
{
ROPE_STRUCT* rope = &Ropes[Lara.ropePtr];
Lara.ropeOffset = 0;
Lara.ropeDownVel = (unsigned int) (rope->meshSegment[Lara.ropeSegment + 1].y - rope->meshSegment[Lara.ropeSegment].y) >> 17;
Lara.ropeCount = 0;
Lara.ropeOffset += Lara.ropeDownVel;
Lara.ropeFlag = 1;
2020-01-15 22:26:49 -03:00
return;
}
}
2020-01-15 22:26:49 -03:00
if (item->animNumber == ANIMATION_LARA_ROPE_DOWN && item->frameNumber == Anims[item->animNumber].frameEnd)
{
SoundEffect(SFX_LARA_ROPEDOWN_LOOP, &LaraItem->pos, 0);
item->frameNumber = Anims[item->animNumber].frameBase;
Lara.ropeFlag = 0;
++Lara.ropeSegment;
Lara.ropeOffset = 0;
}
if (!(TrInput & IN_BACK) || Lara.ropeSegment >= 21)
item->goalAnimState = STATE_LARA_ROPE_IDLE;
}
}
/*int GetLaraJointPos(PHD_VECTOR* vec, int mat)
2019-11-21 07:43:34 +01:00
{
#if !PSXPC_TEST///@FIXME excuse me but this doesn't work.
MatrixPtr[0] = lara_joint_matrices[mat].m00;
MatrixPtr[1] = lara_joint_matrices[mat].m01;
MatrixPtr[2] = lara_joint_matrices[mat].m02;
MatrixPtr[3] = lara_joint_matrices[mat].m10;
MatrixPtr[4] = lara_joint_matrices[mat].m11;
MatrixPtr[5] = lara_joint_matrices[mat].m12;
MatrixPtr[6] = lara_joint_matrices[mat].m20;
MatrixPtr[7] = lara_joint_matrices[mat].m21;
MatrixPtr[8] = lara_joint_matrices[mat].m22;
MatrixPtr[9] = lara_joint_matrices[mat].tx;
MatrixPtr[10] = lara_joint_matrices[mat].ty;
MatrixPtr[11] = lara_joint_matrices[mat].tz;
2019-11-21 07:43:34 +01:00
mTranslateXYZ(vec->x, vec->y, vec->z);
2019-11-21 07:43:34 +01:00
vec->x = phd_mxptr[3] >> W2V_SHIFT;
vec->y = phd_mxptr[7] >> W2V_SHIFT; // todo this is wrong // todo actually not
vec->z = phd_mxptr[11] >> W2V_SHIFT;
2019-11-21 07:43:34 +01:00
vec->x += LaraItem->pos.xPos;
vec->y += LaraItem->pos.yPos;
vec->z += LaraItem->pos.zPos;
2019-11-21 07:43:34 +01:00
mPopMatrix();
#endif
return 48;
2019-12-01 08:13:19 +01:00
}*/
2019-11-21 07:43:34 +01:00
2019-12-01 08:13:19 +01:00
/*
void SetLaraUnderwaterNodes()//8596C(<), 879B0(<) (F)
2019-11-21 07:43:34 +01:00
{
return;//not used yet
PHD_VECTOR joint;
2019-12-02 09:11:21 +01:00
short roomNumber;//_18
2019-11-21 07:43:34 +01:00
room_info* r;//$a1
2019-12-02 09:11:21 +01:00
int flags;//$s1
int current_joint;//$s0
2019-11-21 07:43:34 +01:00
joint.x = 0;
joint.y = 0;
joint.z = 0;
flags = 0;
//loc_85988
for (current_joint = 14; current_joint >= 0; current_joint--)
{
GetLaraJointPos(&joint, current_joint);
roomNumber = LaraItem->roomNumber;
GetFloor(joint.x, joint.y, joint.z, &roomNumber);
r = &room[roomNumber];
LaraNodeUnderwater[current_joint] = r->flags & RF_FILL_WATER;
if (r->flags & RF_FILL_WATER)
{
Lara.wet[current_joint] = 0xFC;
if (!(flags & 1))
{
flags |= 1;
2019-12-02 09:11:21 +01:00
((int*)SRhandPtr)[3] = ((int*)& r->ambient)[0];
2019-11-21 07:43:34 +01:00
}
}
else
{
//loc_85A1C
if (!(flags & 2))
{
flags |= 2;
2019-12-02 09:11:21 +01:00
((int*)SRhandPtr)[2] = ((int*)& r->ambient)[0];
2019-11-21 07:43:34 +01:00
}
}
}
}
void SetPendulumVelocity(int x, int y, int z)// (F)
2019-11-21 07:43:34 +01:00
{
if ((CurrentPendulum.node & 0xFFFFFFFE) < 24)
{
int val = 4096 / ((12 - (CurrentPendulum.node >> 1)) << 9 >> 8) << 8; // todo make this more beautiful
x = (x * val) >> 16;
y = (y * val) >> 16;
z = (z * val) >> 16;
}
CurrentPendulum.Velocity.x += x;
CurrentPendulum.Velocity.y += y;
CurrentPendulum.Velocity.z += z;
}
void LaraClimbRope(ITEM_INFO* item, COLL_INFO* coll)
2019-11-21 07:43:34 +01:00
{
UNIMPLEMENTED();
}
void FireChaff()
2019-11-21 07:43:34 +01:00
{
UNIMPLEMENTED();
}
void GetLaraJointPosRot(PHD_VECTOR* a1, int a2, int a3, SVECTOR * a4)
2019-11-21 07:43:34 +01:00
{
UNIMPLEMENTED();
}
void DoSubsuitStuff()
2019-11-21 07:43:34 +01:00
{
UNIMPLEMENTED();
2019-12-01 08:13:19 +01:00
}*/
2019-11-21 07:43:34 +01:00
int TestLaraSlide(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
if (abs(coll->tiltX) <= 2 && abs(coll->tiltZ) <= 2)
return 0;
2020-05-31 04:20:52 -05:00
short angle = ANGLE(0.0f);
if (coll->tiltX > 2)
2020-05-31 04:20:52 -05:00
angle = -ANGLE(90.0f);
else if (coll->tiltX < -2)
2020-05-31 04:20:52 -05:00
angle = ANGLE(90.0f);
if (coll->tiltZ > 2 && coll->tiltZ > abs(coll->tiltX))
2020-05-31 04:20:52 -05:00
angle = ANGLE(180.0f);
else if (coll->tiltZ < -2 && -coll->tiltZ > abs(coll->tiltX))
2020-05-31 04:20:52 -05:00
angle = ANGLE(0.0f);
short delta = angle - item->pos.yRot;
ShiftItem(item, coll);
2020-05-31 04:20:52 -05:00
if (delta < -ANGLE(90.0f) || delta > ANGLE(90.0f))
{
if (item->currentAnimState == STATE_LARA_SLIDE_BACK && OldAngle == angle)
return 1;
item->animNumber = ANIMATION_LARA_START_SLIDE_BACKWARD;
item->goalAnimState = STATE_LARA_SLIDE_BACK;
item->currentAnimState = STATE_LARA_SLIDE_BACK;
item->frameNumber = Anims[item->animNumber].frameBase;
2020-05-31 04:20:52 -05:00
item->pos.yRot = angle + ANGLE(180.0f);
}
else
{
if (item->currentAnimState == STATE_LARA_SLIDE_FORWARD && OldAngle == angle)
return 1;
item->animNumber = ANIMATION_LARA_SLIDE_FORWARD;
item->goalAnimState = STATE_LARA_SLIDE_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->currentAnimState = STATE_LARA_SLIDE_FORWARD;
item->pos.yRot = angle;
}
Lara.moveAngle = angle;
OldAngle = angle;
return 1;
}
int LaraHangTest(ITEM_INFO* item, COLL_INFO* coll) // (F) (D)
{
int delta, flag, flag2, front, dfront, x, z, result;
short angle, hdif, cdif, dir;
ANIM_FRAME* frame;
delta = 0;
flag = 0;
angle = Lara.moveAngle;
2020-05-31 04:20:52 -05:00
if (angle == (short) (item->pos.yRot - ANGLE(90.0f)))
{
delta = -100;
}
2020-05-31 04:20:52 -05:00
else if (angle == (short) (item->pos.yRot + ANGLE(90.0f)))
{
delta = 100;
}
hdif = LaraFloorFront(item, angle, 100);
if (hdif < 200)
flag = 1;
cdif = LaraCeilingFront(item, angle, 100, 0);
2020-05-31 04:20:52 -05:00
dir = (unsigned short) (item->pos.yRot + ANGLE(45.0f)) / ANGLE(90.0f);
switch (dir)
{
case NORTH:
item->pos.zPos += 4;
break;
case EAST:
item->pos.xPos += 4;
break;
case SOUTH:
item->pos.zPos -= 4;
break;
case WEST:
item->pos.xPos -= 4;
break;
}
coll->badPos = NO_BAD_POS;
coll->badNeg = -STEPUP_HEIGHT;
coll->badCeiling = 0;
Lara.moveAngle = item->pos.yRot;
GetLaraCollisionInfo(item, coll);
result = 0;
if (Lara.climbStatus)
{
if (TrInput & IN_ACTION && item->hitPoints > 0)
{
Lara.moveAngle = angle;
if (!LaraTestHangOnClimbWall(item, coll))
{
if (item->animNumber != ANIMATION_LARA_LADDER_TO_HANDS_RIGHT && item->animNumber != ANIMATION_LARA_LADDER_TO_HANDS_LEFT)
{
SnapLaraToEdgeOfBlock(item, coll, dir);
item->pos.yPos = coll->old.y;
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG;
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase + 21;
}
result = 1;
}
else
{
if (item->animNumber == ANIMATION_LARA_HANG_IDLE && item->frameNumber == Anims[ANIMATION_LARA_HANG_IDLE].frameBase + 21 && LaraTestClimbStance(item, coll))
item->goalAnimState = STATE_LARA_LADDER_IDLE;
}
}
else
{
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->pos.yPos += 256;
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
}
}
else
{
if (TrInput & IN_ACTION && item->hitPoints > 0 && coll->frontFloor <= 0)
{
if (flag && hdif > 0 && delta > 0 == coll->leftFloor > coll->rightFloor)
flag = 0;
frame = (ANIM_FRAME*) GetBoundsAccurate(item);
front = coll->frontFloor;
dfront = coll->frontFloor - frame->MinY;
flag2 = 0;
x = item->pos.xPos;
z = item->pos.zPos;
switch (dir)
{
case NORTH:
x += delta;
break;
case EAST:
z -= delta;
break;
case SOUTH:
x -= delta;
break;
case WEST:
z += delta;
break;
}
Lara.moveAngle = angle;
if (256 << dir & GetClimbTrigger(x, item->pos.yPos, z, item->roomNumber))
{
if (!LaraTestHangOnClimbWall(item, coll))
dfront = 0;
}
else if (abs(coll->leftFloor2 - coll->rightFloor2) >= 60)
{
if (delta < 0 && coll->leftFloor2 != coll->frontFloor || delta > 0 && coll->rightFloor2 != coll->frontFloor)
flag2 = 1;
}
coll->frontFloor = front;
if (!flag2 && coll->midCeiling < 0 && coll->collType == CT_FRONT && !flag && !coll->hitStatic && cdif <= -950 && dfront >= -60 && dfront <= 60)
{
switch (dir)
{
case NORTH:
case SOUTH:
item->pos.zPos += coll->shift.z;
break;
case EAST:
case WEST:
item->pos.xPos += coll->shift.x;
break;
}
item->pos.yPos += dfront;
}
else
{
item->pos.xPos = coll->old.x;
item->pos.yPos = coll->old.y;
item->pos.zPos = coll->old.z;
if (item->currentAnimState == STATE_LARA_SHIMMY_LEFT || item->currentAnimState == STATE_LARA_SHIMMY_RIGHT)
{
item->currentAnimState = STATE_LARA_HANG;
item->goalAnimState = STATE_LARA_HANG;
item->animNumber = ANIMATION_LARA_HANG_IDLE;
item->frameNumber = Anims[item->animNumber].frameBase + 21;
}
result = 1;
}
}
else
{
item->currentAnimState = STATE_LARA_JUMP_UP;
item->goalAnimState = STATE_LARA_JUMP_UP;
item->animNumber = ANIMATION_LARA_TRY_HANG_VERTICAL;
item->frameNumber = Anims[item->animNumber].frameBase + 9;
frame = (ANIM_FRAME*) GetBoundsAccurate(item);
item->pos.xPos += coll->shift.x;
item->pos.yPos += frame->MaxY;
item->pos.zPos += coll->shift.z;
item->gravityStatus = true;
item->speed = 2;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
}
}
return result;
}
/**********************
Current problems with with the feet hanging:
-holding right/left at block ends makes Lara do the shimmy anim repeatedly
-lara doesn't want to shimmy on uneven surfaces at all
-going around corners isn't working. code is commented for now.
-obviously, not all animations were made yet- we still need crouch pull up (works well, tested with placeholder anim) and corner anims (doesn't work) and handstand (not tested)
-I'm *not* sure how Lara will react will react if the animations don't exist, but probably not good. This will be a problem until scrpting is done to enable/disable the entire system.
2020-05-23 15:59:18 -05:00
***********************/
int TestHangFeet(ITEM_INFO* item, short angle)
2020-05-23 15:59:18 -05:00
{
if (Lara.climbStatus == 1)
return 0;
2020-05-30 13:02:24 -05:00
// EnableFeetHang = true;
if (EnableFeetHang == false)
return 0;
2020-05-23 15:59:18 -05:00
int x = item->pos.xPos;
int y = item->pos.yPos;
int z = item->pos.zPos;
short roomNum = item->roomNumber;
FLOOR_INFO* floor;
int h, c, g, m, j;
2020-05-31 04:20:52 -05:00
if (angle == ANGLE(180.0f))
2020-05-23 15:59:18 -05:00
{
z -= 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == -ANGLE(90.0f))
2020-05-23 15:59:18 -05:00
{
x -= 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == ANGLE(90.0f))
2020-05-23 15:59:18 -05:00
{
x += 256;
}
2020-05-31 04:20:52 -05:00
else if (angle == ANGLE(0.0f))
2020-05-23 15:59:18 -05:00
{
z += 256;
}
floor = GetFloor(x, y, z, &roomNum);
h = GetFloorHeight(floor, x, y, z);
c = GetCeiling(floor, x, y, z);
g = h - y;
m = c - y;
j = y - 128 - c;
if (item->currentAnimState == STATE_LARA_CRAWL_TO_CLIMB)
{
if (h != NO_HEIGHT)
{
if (((g) > 0)
&& ((m) < -128)
&& ((j) > -72))
return(1);
2020-05-23 15:59:18 -05:00
}
return(0);
2020-05-23 15:59:18 -05:00
}
else
{
if (h != NO_HEIGHT)
{
if (((g) > 0)
&& ((m) < -128)
&& ((j) > -72))
return(0);
2020-05-23 15:59:18 -05:00
}
return(1);
2020-05-23 15:59:18 -05:00
}
}
void lara_as_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
{
Lara.isClimbing = false;
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_STOP;
return;
}
if (TrInput & IN_LOOK)
LookUpDown();
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2020-05-23 15:59:18 -05:00
}
void lara_col_hang_feet(ITEM_INFO* item, COLL_INFO* coll)
{
item->fallspeed = 0;
item->gravityStatus = false;
Lara.moveAngle = item->pos.yRot;
LaraHangTest(item, coll);
if (!(TrInput & IN_ACTION))
item->goalAnimState = STATE_LARA_JUMP_UP;
2020-05-23 16:50:53 -05:00
if (item->animNumber == ANIMATION_LARA_HANG_FEET_IDLE)
2020-05-23 15:59:18 -05:00
{
int flag;
if (TrInput & IN_LEFT || TrInput & IN_LSTEP)
{
2020-05-31 04:20:52 -05:00
if (CanLaraHangSideways(item, coll, -ANGLE(90.0f)))
2020-05-23 15:59:18 -05:00
{
item->goalAnimState = STATE_LARA_HANG_FEET_SHIMMYL;
return;
}
2020-05-30 13:02:24 -05:00
/* flag = LaraHangLeftCornerTest(item, coll);
if (flag != 0)
{
if (flag <= 0)
item->goalAnimState = STATE_LARA_HANG_FEET_INCORNERL;
else
item->goalAnimState = STATE_LARA_HANG_FEET_OUTCORNERL;
return;
}*/
2020-05-23 15:59:18 -05:00
}
if (TrInput & IN_RIGHT || TrInput & IN_RSTEP)
{
2020-05-31 04:20:52 -05:00
if (CanLaraHangSideways(item, coll, ANGLE(90.0f)))
2020-05-23 15:59:18 -05:00
{
item->goalAnimState = STATE_LARA_HANG_FEET_SHIMMYR;
return;
}
2020-05-30 13:02:24 -05:00
/* flag = LaraHangRightCornerTest(item, coll);
if (flag != 0)
{
if (flag <= 0)
item->goalAnimState = STATE_LARA_HANG_FEET_INCORNERR;
else
item->goalAnimState = STATE_LARA_HANG_FEET_OUTCORNERR;
return;
}*/
2020-05-23 15:59:18 -05:00
}
TestForObjectOnLedge(item, coll);
if (TrInput & IN_FORWARD)
{
if (coll->frontFloor > -850)
{
if (coll->frontFloor < -650 &&
coll->frontFloor >= coll->frontCeiling &&
coll->frontFloor >= coll->leftCeiling2 &&
coll->frontFloor >= coll->rightCeiling2)
{
if (abs(coll->leftFloor2 - coll->rightFloor2) < 60 && !coll->hitStatic)
{
if (TrInput & IN_WALK)
{
//till anim item->goalAnimState = STATE_LARA_HANDSTAND;
}
else if (TrInput & IN_DUCK)
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
2020-05-23 15:59:18 -05:00
}
else
{
item->goalAnimState = STATE_LARA_GRABBING;
}
return;
}
}
}
if (coll->frontFloor < -650 &&
coll->frontFloor - coll->frontCeiling >= -256 &&
coll->frontFloor - coll->leftCeiling2 >= -256 &&
coll->frontFloor - coll->rightCeiling2 >= -256)
{
if (abs(coll->leftFloor2 - coll->rightFloor2) < 60 && !coll->hitStatic)
2020-05-23 15:59:18 -05:00
{
item->goalAnimState = STATE_LARA_CLIMB_TO_CRAWL;
item->requiredAnimState = STATE_LARA_CROUCH_IDLE;
return;
2020-05-23 15:59:18 -05:00
}
}
}
/*
2020-05-23 15:59:18 -05:00
if (Lara.climbStatus != 0 &&
coll->midCeiling <= -256 &&
abs(coll->leftCeiling2 - coll->rightCeiling2) < 60)
{
if (LaraTestClimbStance(item, coll))
{
item->goalAnimState = STATE_LARA_LADDER_IDLE;
}
else
{
item->animNumber = ANIMATION_LARA_LADDER_UP_HANDS;
item->frameNumber = Anims[item->animNumber].frameBase;
item->goalAnimState = STATE_LARA_HANG;
item->currentAnimState = STATE_LARA_HANG;
}
}
return;
}*///commenting till daniel makes anims
Lara.moveAngle = item->pos.yRot;
LaraHangTest(item, coll);
2020-05-23 15:59:18 -05:00
}
}
void lara_as_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll)
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2020-05-23 15:59:18 -05:00
2020-05-23 16:50:53 -05:00
if (!(TrInput & (IN_RIGHT | IN_RSTEP)))
2020-05-23 15:59:18 -05:00
item->goalAnimState = STATE_LARA_HANG_FEET;
}
void lara_col_hang_feet_shimmyr(ITEM_INFO* item, COLL_INFO* coll)
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2020-05-23 15:59:18 -05:00
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);
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot + ANGLE(90.0f);
2020-05-23 15:59:18 -05:00
}
void lara_as_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll)
{
coll->enableBaddiePush = false;
coll->enableSpaz = false;
Camera.targetAngle = 0;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = -ANGLE(45.0f);
2020-05-23 16:50:53 -05:00
if (!(TrInput & (IN_LEFT | IN_LSTEP)))
2020-05-23 15:59:18 -05:00
item->goalAnimState = STATE_LARA_HANG_FEET;
}
void lara_col_hang_feet_shimmyl(ITEM_INFO* item, COLL_INFO* coll)
{
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
2020-05-23 15:59:18 -05:00
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);
2020-05-31 04:20:52 -05:00
Lara.moveAngle = item->pos.yRot - ANGLE(90.0f);
}
void lara_as_hang_feet_inRcorner(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnimFeet(item, coll, ANGLE(90.0f),
item->animNumber = ANIMATION_LARA_HANG_FEET_IN_RCORNER);
}
void lara_as_hang_feet_inLcorner(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnimFeet(item, coll, -ANGLE(90.0f),
item->animNumber = ANIMATION_LARA_HANG_FEET_IN_LCORNER);
}
void lara_as_hang_feet_outRcorner(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnimFeet(item, coll, -ANGLE(90.0f),
item->animNumber = ANIMATION_LARA_HANG_FEET_OUT_RCORNER);
}
void lara_as_hang_feet_outLcorner(ITEM_INFO* item, COLL_INFO* coll)
{
Camera.laraNode = 8;
2020-05-31 04:20:52 -05:00
Camera.targetElevation = ANGLE(33.0f);
SetCornerAnimFeet(item, coll, ANGLE(90.0f),
item->animNumber = ANIMATION_LARA_HANG_FEET_OUT_LCORNER);
}
void SetCornerAnimFeet(ITEM_INFO* item, COLL_INFO* coll, short rot, short flip)
{
if (item->hitPoints <= 0)
{
item->goalAnimState = STATE_LARA_JUMP_FORWARD;
item->currentAnimState = STATE_LARA_JUMP_FORWARD;
item->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
item->frameNumber = Anims[item->animNumber].frameBase;
item->gravityStatus = true;
item->speed = 2;
item->pos.yPos += 256;
item->fallspeed = 1;
Lara.gunStatus = LG_NO_ARMS;
item->pos.yRot += rot / 2;
}
else if (flip)
{
item->animNumber = ANIMATION_LARA_HANG_FEET;
item->frameNumber = Anims[item->animNumber].frameBase + 24;
item->goalAnimState = STATE_LARA_HANG_FEET;
item->currentAnimState = STATE_LARA_HANG_FEET;
coll->old.x = Lara.cornerX;
item->pos.xPos = Lara.cornerX;
coll->old.z = Lara.cornerZ;
item->pos.zPos = Lara.cornerZ;
item->pos.yRot += rot;
}
2020-05-23 15:59:18 -05:00
}