lara: add jump-twist animations

Resolves #88.
This commit is contained in:
lahm86 2023-04-15 14:32:23 +01:00 committed by GitHub
parent fbe0014b1a
commit 05934efe6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 156 additions and 146 deletions

View file

@ -1,4 +1,5 @@
## [Unreleased](https://github.com/rr-/Tomb1Main/compare/stable...develop) - ××××-××-××
- added an option to enable TR2+ jump-twist and somersault animations (#88)
## [2.14](https://github.com/rr-/Tomb1Main/compare/2.13.2...2.14) - 2023-04-05
- added Spanish localization to the config tool

View file

@ -239,6 +239,7 @@ Not all options are turned on by default. Refer to `Tomb1Main_ConfigTool.exe` fo
- added ability to select weapons / using items with numeric keys
- added ability to look around while running
- added ability to sidestep like in TR3
- added ability to jump-twist and somersault like in TR2+
- added ability to automatically walk to items when nearby
- added a pause screen
- added a choice whether to play NG or NG+ without having to play the entire game

View file

@ -40,6 +40,7 @@
"injections": [
"data/backpack.bin",
"data/braid.bin",
"data/lara_animations.bin",
"data/uzi_sfx.bin",
],
@ -69,7 +70,8 @@
// specific injection data paths
"injections": [
"data/braid.bin"
"data/braid.bin",
"data/lara_animations.bin",
],
// list of actions to execute when this level is played

View file

@ -13,6 +13,7 @@
"injections": [
"data/backpack.bin",
"data/braid.bin",
"data/lara_animations.bin",
"data/uzi_sfx.bin",
],

Binary file not shown.

View file

@ -228,6 +228,7 @@ bool Config_ReadFromJSON(const char *cfg_data)
READ_BOOL(enable_enhanced_saves, true);
READ_BOOL(enable_pitched_sounds, true);
READ_BOOL(enable_ps_uzi_sfx, false);
READ_BOOL(enable_jump_twists, true);
CLAMP(g_Config.start_lara_hitpoints, 1, LARA_HITPOINTS);
CLAMP(g_Config.fov_value, 30, 255);
@ -424,6 +425,7 @@ bool Config_Write(void)
WRITE_BOOL(enable_enhanced_saves);
WRITE_BOOL(enable_pitched_sounds);
WRITE_BOOL(enable_ps_uzi_sfx);
WRITE_BOOL(enable_jump_twists);
// User settings
WRITE_BOOL(rendering.enable_bilinear_filter);

View file

@ -105,6 +105,7 @@ typedef struct {
bool enable_enhanced_saves;
bool enable_pitched_sounds;
bool enable_ps_uzi_sfx;
bool enable_jump_twists;
struct {
int32_t layout;

View file

@ -1,6 +1,7 @@
#include "game/effect_routines/lara_effects.h"
#include "config.h"
#include "game/items.h"
#include "game/viewport.h"
#include "global/const.h"
#include "global/vars.h"
@ -12,8 +13,7 @@ void FX_LaraNormal(ITEM_INFO *item)
{
item->current_anim_state = LS_STOP;
item->goal_anim_state = LS_STOP;
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
g_Camera.type = CAM_CHASE;
Viewport_AlterFOV(g_Config.fov_value * PHD_DEGREE);
}

View file

@ -21,6 +21,7 @@ typedef enum INJECTION_TYPE {
INJ_TEXTURE_FIX = 2,
INJ_UZI_SFX = 3,
INJ_FLOOR_DATA = 4,
INJ_LARA_ANIMS = 5,
} INJECTION_TYPE;
typedef struct INJECTION {
@ -143,6 +144,7 @@ static bool Inject_LoadFromFile(INJECTION *injection, const char *filename)
switch (injection->type) {
case INJ_GENERAL:
case INJ_TEXTURE_FIX:
case INJ_LARA_ANIMS:
injection->relevant = true;
break;
case INJ_BRAID:
@ -423,11 +425,21 @@ static void Inject_ObjectData(
File_Read(&tmp, sizeof(int32_t), 1, fp);
OBJECT_INFO *object = &g_Objects[tmp];
File_Read(&object->nmeshes, sizeof(int16_t), 1, fp);
File_Read(&object->mesh_index, sizeof(int16_t), 1, fp);
object->mesh_index += level_info->mesh_ptr_count;
File_Read(&object->bone_index, sizeof(int32_t), 1, fp);
object->bone_index += level_info->anim_bone_count;
int16_t num_meshes;
int16_t mesh_index;
int32_t bone_index;
File_Read(&num_meshes, sizeof(int16_t), 1, fp);
File_Read(&mesh_index, sizeof(int16_t), 1, fp);
File_Read(&bone_index, sizeof(int32_t), 1, fp);
// When mesh data has been omitted from the injection, this indicates
// that we wish to retain what's already defined so to avoid duplicate
// packing.
if (!object->loaded || num_meshes) {
object->nmeshes = num_meshes;
object->mesh_index = mesh_index + level_info->mesh_ptr_count;
object->bone_index = bone_index + level_info->anim_bone_count;
}
File_Read(&tmp, sizeof(int32_t), 1, fp);
object->frame_base =
@ -436,8 +448,10 @@ static void Inject_ObjectData(
object->anim_index += level_info->anim_count;
object->loaded = 1;
Inject_AlignTextureReferences(
object, palette_map, level_info->texture_count);
if (num_meshes) {
Inject_AlignTextureReferences(
object, palette_map, level_info->texture_count);
}
}
}

View file

@ -460,6 +460,13 @@ void Item_Translate(ITEM_INFO *item, int32_t x, int32_t y, int32_t z)
item->pos.z += (c * z - s * x) >> W2V_SHIFT;
}
void Item_SwitchToAnim(ITEM_INFO *item, int16_t anim_index, int16_t frame)
{
item->anim_number = g_Objects[item->object_number].anim_index + anim_index;
item->frame_number =
frame < 0 ? g_Anims[item->anim_number].frame_base : frame;
}
void Item_Animate(ITEM_INFO *item)
{
item->touch_bits = 0;

View file

@ -34,6 +34,7 @@ bool Item_MovePosition(
void Item_ShiftCol(ITEM_INFO *item, COLL_INFO *coll);
void Item_Translate(ITEM_INFO *item, int32_t x, int32_t y, int32_t z);
void Item_SwitchToAnim(ITEM_INFO *item, int16_t anim_index, int16_t frame);
void Item_Animate(ITEM_INFO *item);
bool Item_GetAnimChange(ITEM_INFO *item, ANIM_STRUCT *anim);

View file

@ -59,8 +59,7 @@ void Lara_Control(void)
item->pos.y -= 0x80;
item->current_anim_state = LS_SWIM;
item->goal_anim_state = LS_SWIM;
item->anim_number = LA_SWIM_GLIDE;
item->frame_number = g_Anims[item->anim_number].frame_base;
Item_SwitchToAnim(item, LA_SWIM_GLIDE, -1);
item->gravity_status = 0;
item->pos.x_rot = 30 * PHD_DEGREE;
item->fall_speed = 30;
@ -100,8 +99,7 @@ void Lara_Control(void)
} else {
item->current_anim_state = LS_DIVE;
item->goal_anim_state = LS_SWIM;
item->anim_number = LA_JUMP_IN;
item->frame_number = AF_JUMPIN;
Item_SwitchToAnim(item, LA_JUMP_IN, AF_JUMPIN);
item->pos.x_rot = -45 * PHD_DEGREE;
item->fall_speed = (item->fall_speed * 3) / 2;
}
@ -118,8 +116,7 @@ void Lara_Control(void)
g_Lara.dive_timer = DIVE_WAIT + 1;
item->current_anim_state = LS_SURF_TREAD;
item->goal_anim_state = LS_SURF_TREAD;
item->anim_number = LA_SURF_TREAD;
item->frame_number = AF_SURFTREAD;
Item_SwitchToAnim(item, LA_SURF_TREAD, AF_SURFTREAD);
item->fall_speed = 0;
item->pos.y = wh + 1;
item->pos.x_rot = 0;
@ -135,8 +132,7 @@ void Lara_Control(void)
g_Lara.gun_status = LGS_ARMLESS;
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
item->speed = item->fall_speed / 4;
item->fall_speed = 0;
item->gravity_status = 1;
@ -152,8 +148,7 @@ void Lara_Control(void)
g_Lara.gun_status = LGS_ARMLESS;
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
item->speed = item->fall_speed / 4;
item->fall_speed = 0;
item->gravity_status = 1;
@ -235,8 +230,7 @@ void Lara_Control(void)
g_Lara.water_status = LWS_UNDERWATER;
} else {
g_Lara.water_status = LWS_ABOVE_WATER;
item->anim_number = LA_STOP;
item->frame_number = g_Anims[item->anim_number].frame_base;
Item_SwitchToAnim(item, LA_STOP, -1);
item->pos.x_rot = item->pos.z_rot = 0;
g_Lara.head_x_rot = 0;
g_Lara.head_y_rot = 0;
@ -489,14 +483,12 @@ void Lara_Initialise(int32_t level_num)
g_LaraItem->fall_speed = 0;
g_LaraItem->goal_anim_state = LS_TREAD;
g_LaraItem->current_anim_state = LS_TREAD;
g_LaraItem->anim_number = LA_TREAD;
g_LaraItem->frame_number = AF_TREAD;
Item_SwitchToAnim(g_LaraItem, LA_TREAD, AF_TREAD);
} else {
g_Lara.water_status = LWS_ABOVE_WATER;
g_LaraItem->goal_anim_state = LS_STOP;
g_LaraItem->current_anim_state = LS_STOP;
g_LaraItem->anim_number = LA_STOP;
g_LaraItem->frame_number = AF_STOP;
Item_SwitchToAnim(g_LaraItem, LA_STOP, AF_STOP);
}
g_Lara.current_active = 0;
@ -719,8 +711,7 @@ bool Lara_MovePosition(ITEM_INFO *item, PHD_VECTOR *vec)
- ((uint16_t)(item->pos.y_rot + PHD_45) >> W2V_SHIFT))
& 0x3);
g_LaraItem->anim_number = step_to_anim_num[quadrant];
g_LaraItem->frame_number = g_Anims[g_LaraItem->anim_number].frame_base;
Item_SwitchToAnim(g_LaraItem, step_to_anim_num[quadrant], -1);
g_LaraItem->goal_anim_state = step_to_anim_state[quadrant];
g_LaraItem->current_anim_state = step_to_anim_state[quadrant];

View file

@ -93,16 +93,13 @@ void Lara_Col_Walk(ITEM_INFO *item, COLL_INFO *coll)
if (Lara_DeflectEdge(item, coll)) {
if (item->frame_number >= 29 && item->frame_number <= 47) {
item->anim_number = LA_STOP_RIGHT;
item->frame_number = AF_STOP_RIGHT;
Item_SwitchToAnim(item, LA_STOP_RIGHT, AF_STOP_RIGHT);
} else if (
(item->frame_number >= 22 && item->frame_number <= 28)
|| (item->frame_number >= 48 && item->frame_number <= 57)) {
item->anim_number = LA_STOP_LEFT;
item->frame_number = AF_STOP_LEFT;
Item_SwitchToAnim(item, LA_STOP_LEFT, AF_STOP_LEFT);
} else {
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
}
@ -112,21 +109,18 @@ void Lara_Col_Walk(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > STEP_L / 2) {
if (item->frame_number >= 28 && item->frame_number <= 45) {
item->anim_number = LA_WALK_STEP_DOWN_RIGHT;
item->frame_number = AF_WALKSTEPD_RIGHT;
Item_SwitchToAnim(
item, LA_WALK_STEP_DOWN_RIGHT, AF_WALKSTEPD_RIGHT);
} else {
item->anim_number = LA_WALK_STEP_DOWN_LEFT;
item->frame_number = AF_WALKSTEPD_LEFT;
Item_SwitchToAnim(item, LA_WALK_STEP_DOWN_LEFT, AF_WALKSTEPD_LEFT);
}
}
if (coll->mid_floor >= -STEPUP_HEIGHT && coll->mid_floor < -STEP_L / 2) {
if (item->frame_number >= 27 && item->frame_number <= 44) {
item->anim_number = LA_WALK_STEP_UP_RIGHT;
item->frame_number = AF_WALKSTEPUP_RIGHT;
Item_SwitchToAnim(item, LA_WALK_STEP_UP_RIGHT, AF_WALKSTEPUP_RIGHT);
} else {
item->anim_number = LA_WALK_STEP_UP_LEFT;
item->frame_number = AF_WALKSTEPUP_LEFT;
Item_SwitchToAnim(item, LA_WALK_STEP_UP_LEFT, AF_WALKSTEPUP_LEFT);
}
}
@ -165,18 +159,15 @@ void Lara_Col_Run(ITEM_INFO *item, COLL_INFO *coll)
&& coll->front_floor < -(STEP_L * 5) / 2) {
item->current_anim_state = LS_SPLAT;
if (item->frame_number >= 0 && item->frame_number <= 9) {
item->anim_number = LA_HIT_WALL_LEFT;
item->frame_number = AF_HITWALLLEFT;
Item_SwitchToAnim(item, LA_HIT_WALL_LEFT, AF_HITWALLLEFT);
return;
}
if (item->frame_number >= 10 && item->frame_number <= 21) {
item->anim_number = LA_HIT_WALL_RIGHT;
item->frame_number = AF_HITWALLRIGHT;
Item_SwitchToAnim(item, LA_HIT_WALL_RIGHT, AF_HITWALLRIGHT);
return;
}
}
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
if (Lara_Fallen(item, coll)) {
@ -185,11 +176,9 @@ void Lara_Col_Run(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor >= -STEPUP_HEIGHT && coll->mid_floor < -STEP_L / 2) {
if (item->frame_number >= 3 && item->frame_number <= 14) {
item->anim_number = LA_RUN_STEP_UP_LEFT;
item->frame_number = AF_RUNSTEPUP_LEFT;
Item_SwitchToAnim(item, LA_RUN_STEP_UP_LEFT, AF_RUNSTEPUP_LEFT);
} else {
item->anim_number = LA_RUN_STEP_UP_RIGHT;
item->frame_number = AF_RUNSTEPUP_RIGHT;
Item_SwitchToAnim(item, LA_RUN_STEP_UP_RIGHT, AF_RUNSTEPUP_RIGHT);
}
}
@ -227,8 +216,7 @@ void Lara_Col_Stop(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > 100) {
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
item->gravity_status = 1;
item->fall_speed = 0;
return;
@ -295,16 +283,14 @@ void Lara_Col_FastBack(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > 200) {
item->current_anim_state = LS_FALL_BACK;
item->goal_anim_state = LS_FALL_BACK;
item->anim_number = LA_FALL_BACK;
item->frame_number = AF_FALLBACK;
Item_SwitchToAnim(item, LA_FALL_BACK, AF_FALLBACK);
item->gravity_status = 1;
item->fall_speed = 0;
return;
}
if (Lara_DeflectEdge(item, coll)) {
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
item->pos.y += coll->mid_floor;
@ -325,8 +311,7 @@ void Lara_Col_TurnR(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > 100) {
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
item->gravity_status = 1;
item->fall_speed = 0;
return;
@ -374,8 +359,7 @@ void Lara_Col_FastFall(ITEM_INFO *item, COLL_INFO *coll)
} else {
item->goal_anim_state = LS_STOP;
item->current_anim_state = LS_STOP;
item->anim_number = LA_LAND_FAR;
item->frame_number = AF_LANDFAR;
Item_SwitchToAnim(item, LA_LAND_FAR, AF_LANDFAR);
}
Sound_StopEffect(SFX_LARA_FALL, NULL);
item->pos.y += coll->mid_floor;
@ -457,8 +441,7 @@ void Lara_Col_Compress(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_ceiling > -100) {
item->goal_anim_state = LS_STOP;
item->current_anim_state = LS_STOP;
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
item->gravity_status = 0;
item->fall_speed = 0;
item->speed = 0;
@ -485,8 +468,7 @@ void Lara_Col_Back(ITEM_INFO *item, COLL_INFO *coll)
}
if (Lara_DeflectEdge(item, coll)) {
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
if (g_Config.fix_descending_glitch && Lara_Fallen(item, coll)) {
@ -495,11 +477,10 @@ void Lara_Col_Back(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > STEP_L / 2 && coll->mid_floor < (STEP_L * 3) / 2) {
if (item->frame_number >= 964 && item->frame_number <= 993) {
item->anim_number = LA_BACK_STEP_DOWN_RIGHT;
item->frame_number = AF_BACKSTEPD_RIGHT;
Item_SwitchToAnim(
item, LA_BACK_STEP_DOWN_RIGHT, AF_BACKSTEPD_RIGHT);
} else {
item->anim_number = LA_BACK_STEP_DOWN_LEFT;
item->frame_number = AF_BACKSTEPD_LEFT;
Item_SwitchToAnim(item, LA_BACK_STEP_DOWN_LEFT, AF_BACKSTEPD_LEFT);
}
}
@ -537,8 +518,7 @@ void Lara_Col_StepRight(ITEM_INFO *item, COLL_INFO *coll)
}
if (Lara_DeflectEdge(item, coll)) {
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
if (g_Config.fix_descending_glitch && Lara_Fallen(item, coll)) {
@ -569,8 +549,7 @@ void Lara_Col_StepLeft(ITEM_INFO *item, COLL_INFO *coll)
}
if (Lara_DeflectEdge(item, coll)) {
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
}
if (g_Config.fix_descending_glitch && Lara_Fallen(item, coll)) {
@ -745,8 +724,7 @@ void Lara_Col_Roll(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > 200) {
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
item->gravity_status = 1;
item->fall_speed = 0;
return;
@ -778,8 +756,7 @@ void Lara_Col_Roll2(ITEM_INFO *item, COLL_INFO *coll)
if (coll->mid_floor > 200) {
item->current_anim_state = LS_FALL_BACK;
item->goal_anim_state = LS_FALL_BACK;
item->anim_number = LA_FALL_BACK;
item->frame_number = AF_FALLBACK;
Item_SwitchToAnim(item, LA_FALL_BACK, AF_FALLBACK);
item->gravity_status = 1;
item->fall_speed = 0;
return;

View file

@ -44,16 +44,16 @@ void Lara_Draw(ITEM_INFO *item)
switch (g_Lara.hit_direction) {
default:
case DIR_NORTH:
frame = g_Anims[LA_SPAZ_FORWARD].frame_ptr;
frame = g_Anims[object->anim_index + LA_SPAZ_FORWARD].frame_ptr;
break;
case DIR_EAST:
frame = g_Anims[LA_SPAZ_RIGHT].frame_ptr;
frame = g_Anims[object->anim_index + LA_SPAZ_RIGHT].frame_ptr;
break;
case DIR_SOUTH:
frame = g_Anims[LA_SPAZ_BACK].frame_ptr;
frame = g_Anims[object->anim_index + LA_SPAZ_BACK].frame_ptr;
break;
case DIR_WEST:
frame = g_Anims[LA_SPAZ_LEFT].frame_ptr;
frame = g_Anims[object->anim_index + LA_SPAZ_LEFT].frame_ptr;
break;
}

View file

@ -77,23 +77,23 @@ void Lara_Hair_Control(void)
mesh_base = &g_Meshes[object->mesh_index];
if (!in_cutscene && g_Lara.hit_direction >= 0) {
int16_t spaz;
int16_t spaz = object->anim_index;
switch (g_Lara.hit_direction) {
case DIR_NORTH:
spaz = LA_SPAZ_FORWARD;
spaz += LA_SPAZ_FORWARD;
break;
case DIR_SOUTH:
spaz = LA_SPAZ_BACK;
spaz += LA_SPAZ_BACK;
break;
case DIR_EAST:
spaz = LA_SPAZ_RIGHT;
spaz += LA_SPAZ_RIGHT;
break;
default:
spaz = LA_SPAZ_LEFT;
spaz += LA_SPAZ_LEFT;
break;
}

View file

@ -64,8 +64,7 @@ void Lara_HangTest(ITEM_INFO *item, COLL_INFO *coll)
if (!g_Input.action || item->hit_points <= 0) {
item->goal_anim_state = LS_JUMP_UP;
item->current_anim_state = LS_JUMP_UP;
item->anim_number = LA_STOP_HANG;
item->frame_number = AF_STOPHANG;
Item_SwitchToAnim(item, LA_STOP_HANG, AF_STOPHANG);
bounds = Item_GetBoundsAccurate(item);
item->pos.y += coll->front_floor - bounds[FRAME_BOUND_MIN_Y] + 2;
item->pos.x += coll->shift.x;
@ -90,8 +89,7 @@ void Lara_HangTest(ITEM_INFO *item, COLL_INFO *coll)
|| item->current_anim_state == LS_HANG_RIGHT) {
item->goal_anim_state = LS_HANG;
item->current_anim_state = LS_HANG;
item->anim_number = LA_HANG;
item->frame_number = AF_HANG;
Item_SwitchToAnim(item, LA_HANG, AF_HANG);
}
return;
}
@ -130,13 +128,11 @@ void Lara_SlideSlope(ITEM_INFO *item, COLL_INFO *coll)
if (item->current_anim_state == LS_SLIDE) {
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = AF_FALLDOWN;
Item_SwitchToAnim(item, LA_FALL_DOWN, AF_FALLDOWN);
} else {
item->current_anim_state = LS_FALL_BACK;
item->goal_anim_state = LS_FALL_BACK;
item->anim_number = LA_FALL_BACK;
item->frame_number = AF_FALLBACK;
Item_SwitchToAnim(item, LA_FALL_BACK, AF_FALLBACK);
}
item->gravity_status = 1;
item->fall_speed = 0;
@ -158,8 +154,7 @@ bool Lara_Fallen(ITEM_INFO *item, COLL_INFO *coll)
}
item->current_anim_state = LS_JUMP_FORWARD;
item->goal_anim_state = LS_JUMP_FORWARD;
item->anim_number = LA_FALL_DOWN;
item->frame_number = g_Anims[item->anim_number].frame_base;
Item_SwitchToAnim(item, LA_FALL_DOWN, -1);
item->gravity_status = 1;
item->fall_speed = 0;
return true;
@ -176,8 +171,7 @@ bool Lara_HitCeiling(ITEM_INFO *item, COLL_INFO *coll)
item->pos.z = coll->old.z;
item->goal_anim_state = LS_STOP;
item->current_anim_state = LS_STOP;
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
item->gravity_status = 0;
item->fall_speed = 0;
item->speed = 0;
@ -220,8 +214,7 @@ void Lara_DeflectEdgeJump(ITEM_INFO *item, COLL_INFO *coll)
case COLL_TOPFRONT:
item->goal_anim_state = LS_FAST_FALL;
item->current_anim_state = LS_FAST_FALL;
item->anim_number = LA_FAST_FALL;
item->frame_number = AF_FASTFALL;
Item_SwitchToAnim(item, LA_FAST_FALL, AF_FASTFALL);
item->speed /= 4;
g_Lara.move_angle -= PHD_180;
if (item->fall_speed <= 0) {
@ -313,8 +306,7 @@ bool Lara_TestVault(ITEM_INFO *item, COLL_INFO *coll)
}
item->current_anim_state = LS_NULL;
item->goal_anim_state = LS_STOP;
item->anim_number = LA_VAULT_12;
item->frame_number = AF_VAULT12;
Item_SwitchToAnim(item, LA_VAULT_12, AF_VAULT12);
item->pos.y += STEP_L * 2 + hdif;
g_Lara.gun_status = LGS_HANDS_BUSY;
item->pos.y_rot = angle;
@ -329,8 +321,7 @@ bool Lara_TestVault(ITEM_INFO *item, COLL_INFO *coll)
}
item->current_anim_state = LS_NULL;
item->goal_anim_state = LS_STOP;
item->anim_number = LA_VAULT_34;
item->frame_number = AF_VAULT34;
Item_SwitchToAnim(item, LA_VAULT_34, AF_VAULT34);
item->pos.y += STEP_L * 3 + hdif;
g_Lara.gun_status = LGS_HANDS_BUSY;
item->pos.y_rot = angle;
@ -340,8 +331,7 @@ bool Lara_TestVault(ITEM_INFO *item, COLL_INFO *coll)
hdif >= -STEP_L * 7 - STEP_L / 2 && hdif <= -STEP_L * 4 + STEP_L / 2) {
item->goal_anim_state = LS_JUMP_UP;
item->current_anim_state = LS_STOP;
item->anim_number = LA_STOP;
item->frame_number = AF_STOP;
Item_SwitchToAnim(item, LA_STOP, AF_STOP);
g_Lara.calc_fall_speed =
-(int16_t)(Math_Sqrt((int)(-2 * GRAVITY * (hdif + 800))) + 3);
Lara_Animate(item);
@ -396,11 +386,9 @@ bool Lara_TestHangJump(ITEM_INFO *item, COLL_INFO *coll)
}
if (Lara_TestHangSwingIn(item, angle)) {
item->anim_number = LA_GRAB_LEDGE_IN;
item->frame_number = AF_GRABLEDGEIN;
Item_SwitchToAnim(item, LA_GRAB_LEDGE_IN, AF_GRABLEDGEIN);
} else {
item->anim_number = LA_GRAB_LEDGE;
item->frame_number = AF_GRABLEDGE;
Item_SwitchToAnim(item, LA_GRAB_LEDGE, AF_GRABLEDGE);
}
item->current_anim_state = LS_HANG;
item->goal_anim_state = LS_HANG;
@ -493,8 +481,7 @@ bool Lara_TestHangJumpUp(ITEM_INFO *item, COLL_INFO *coll)
item->goal_anim_state = LS_HANG;
item->current_anim_state = LS_HANG;
item->anim_number = LA_HANG;
item->frame_number = AF_STARTHANG;
Item_SwitchToAnim(item, LA_HANG, AF_STARTHANG);
bounds = Item_GetBoundsAccurate(item);
item->pos.y += coll->front_floor - bounds[FRAME_BOUND_MIN_Y];
item->pos.x += coll->shift.x;
@ -533,8 +520,7 @@ bool Lara_TestSlide(ITEM_INFO *item, COLL_INFO *coll)
if (item->current_anim_state != LS_SLIDE || old_angle != ang) {
item->goal_anim_state = LS_SLIDE;
item->current_anim_state = LS_SLIDE;
item->anim_number = LA_SLIDE;
item->frame_number = AF_SLIDE;
Item_SwitchToAnim(item, LA_SLIDE, AF_SLIDE);
item->pos.y_rot = ang;
g_Lara.move_angle = ang;
old_angle = ang;
@ -543,8 +529,7 @@ bool Lara_TestSlide(ITEM_INFO *item, COLL_INFO *coll)
if (item->current_anim_state != LS_SLIDE_BACK || old_angle != ang) {
item->goal_anim_state = LS_SLIDE_BACK;
item->current_anim_state = LS_SLIDE_BACK;
item->anim_number = LA_SLIDE_BACK;
item->frame_number = AF_SLIDEBACK;
Item_SwitchToAnim(item, LA_SLIDE_BACK, AF_SLIDEBACK);
item->pos.y_rot = ang - PHD_180;
g_Lara.move_angle = ang;
old_angle = ang;
@ -614,8 +599,7 @@ void Lara_SurfaceCollision(ITEM_INFO *item, COLL_INFO *coll)
if (wh - item->pos.y <= -100) {
item->goal_anim_state = LS_SWIM;
item->current_anim_state = LS_DIVE;
item->anim_number = LA_SURF_DIVE;
item->frame_number = AF_SURFDIVE;
Item_SwitchToAnim(item, LA_SURF_DIVE, AF_SURFDIVE);
item->pos.x_rot = -45 * PHD_DEGREE;
item->fall_speed = 80;
g_Lara.water_status = LWS_UNDERWATER;
@ -679,8 +663,7 @@ bool Lara_TestWaterClimbOut(ITEM_INFO *item, COLL_INFO *coll)
break;
}
item->anim_number = LA_SURF_CLIMB;
item->frame_number = AF_SURFCLIMB;
Item_SwitchToAnim(item, LA_SURF_CLIMB, AF_SURFCLIMB);
item->current_anim_state = LS_WATER_OUT;
item->goal_anim_state = LS_STOP;
item->pos.x_rot = 0;

View file

@ -2,6 +2,7 @@
#include "config.h"
#include "game/input.h"
#include "game/items.h"
#include "game/lara/lara_look.h"
#include "game/objects/effects/twinkle.h"
#include "game/room.h"
@ -32,6 +33,7 @@ void (*g_LaraStateRoutines[])(ITEM_INFO *item, COLL_INFO *coll) = {
Lara_State_SurfLeft, Lara_State_SurfRight, Lara_State_UseMidas,
Lara_State_DieMidas, Lara_State_SwanDive, Lara_State_FastDive,
Lara_State_Gymnast, Lara_State_WaterOut, Lara_State_Controlled,
Lara_State_Twist,
};
static int16_t Lara_FloorFront(ITEM_INFO *item, PHD_ANGLE ang, int32_t dist);
@ -86,8 +88,7 @@ void Lara_State_Run(ITEM_INFO *item, COLL_INFO *coll)
if (g_Input.roll) {
item->current_anim_state = LS_ROLL;
item->goal_anim_state = LS_STOP;
item->anim_number = LA_ROLL;
item->frame_number = AF_ROLL;
Item_SwitchToAnim(item, LA_ROLL, AF_ROLL);
return;
}
@ -130,8 +131,7 @@ void Lara_State_Stop(ITEM_INFO *item, COLL_INFO *coll)
if (g_Input.roll) {
item->current_anim_state = LS_ROLL;
item->goal_anim_state = LS_STOP;
item->anim_number = LA_ROLL;
item->frame_number = AF_ROLL;
Item_SwitchToAnim(item, LA_ROLL, AF_ROLL);
return;
}
@ -196,6 +196,10 @@ void Lara_State_ForwardJump(ITEM_INFO *item, COLL_INFO *coll)
if (g_Input.action && g_Lara.gun_status == LGS_ARMLESS) {
item->goal_anim_state = LS_REACH;
}
if (g_Config.enable_jump_twists && g_Input.roll
&& item->goal_anim_state != LS_RUN) {
item->goal_anim_state = LS_TWIST;
}
if (g_Input.slow && g_Lara.gun_status == LGS_ARMLESS) {
item->goal_anim_state = LS_SWAN_DIVE;
}
@ -481,6 +485,11 @@ void Lara_State_BackJump(ITEM_INFO *item, COLL_INFO *coll)
if (item->fall_speed > LARA_FASTFALL_SPEED) {
item->goal_anim_state = LS_FAST_FALL;
}
if (g_Config.enable_jump_twists && g_Input.roll
&& item->goal_anim_state != LS_STOP) {
item->goal_anim_state = LS_TWIST;
}
}
void Lara_State_RightJump(ITEM_INFO *item, COLL_INFO *coll)
@ -748,18 +757,28 @@ void Lara_State_SwanDive(ITEM_INFO *item, COLL_INFO *coll)
{
coll->enable_spaz = 0;
coll->enable_baddie_push = 1;
if (item->fall_speed > LARA_FASTFALL_SPEED) {
if (item->fall_speed > LARA_FASTFALL_SPEED
&& item->goal_anim_state != LS_DIVE) {
item->goal_anim_state = LS_FAST_DIVE;
}
}
void Lara_State_FastDive(ITEM_INFO *item, COLL_INFO *coll)
{
if (g_Config.enable_jump_twists && g_Input.roll
&& item->goal_anim_state == LS_FAST_DIVE) {
item->goal_anim_state = LS_TWIST;
}
coll->enable_spaz = 0;
coll->enable_baddie_push = 1;
item->speed = (item->speed * 95) / 100;
}
void Lara_State_Twist(ITEM_INFO *item, COLL_INFO *coll)
{
}
void Lara_State_Null(ITEM_INFO *item, COLL_INFO *coll)
{
coll->enable_spaz = 0;
@ -962,8 +981,7 @@ void Lara_State_SurfTread(ITEM_INFO *item, COLL_INFO *coll)
if (g_Lara.dive_timer == DIVE_WAIT) {
item->goal_anim_state = LS_SWIM;
item->current_anim_state = LS_DIVE;
item->anim_number = LA_SURF_DIVE;
item->frame_number = AF_SURFDIVE;
Item_SwitchToAnim(item, LA_SURF_DIVE, AF_SURFDIVE);
item->pos.x_rot = -45 * PHD_DEGREE;
item->fall_speed = 80;
g_Lara.water_status = LWS_UNDERWATER;

View file

@ -63,3 +63,4 @@ void Lara_State_SwanDive(ITEM_INFO *item, COLL_INFO *coll);
void Lara_State_FastDive(ITEM_INFO *item, COLL_INFO *coll);
void Lara_State_Gymnast(ITEM_INFO *item, COLL_INFO *coll);
void Lara_State_WaterOut(ITEM_INFO *item, COLL_INFO *coll);
void Lara_State_Twist(ITEM_INFO *item, COLL_INFO *coll);

View file

@ -25,6 +25,7 @@ void BaconLara_Setup(OBJECT_INFO *obj)
void BaconLara_Initialise(int16_t item_num)
{
g_Objects[O_BACON_LARA].anim_index = g_Objects[O_LARA].anim_index;
g_Objects[O_BACON_LARA].frame_base = g_Objects[O_LARA].frame_base;
g_Items[item_num].data = NULL;
}
@ -67,8 +68,7 @@ void BaconLara_Control(int16_t item_num)
if (h >= lh + WALL_L && !g_LaraItem->gravity_status) {
item->current_anim_state = LS_FAST_FALL;
item->goal_anim_state = LS_FAST_FALL;
item->anim_number = LA_FAST_FALL;
item->frame_number = AF_FASTFALL;
Item_SwitchToAnim(item, LA_FAST_FALL, AF_FASTFALL);
item->speed = 0;
item->fall_speed = 0;
item->gravity_status = 1;

View file

@ -166,7 +166,7 @@ void Pickup_CollisionControlled(
if (Lara_TestPosition(item, m_PickUpBoundsControlled)) {
m_PickUpPosition.y = lara_item->pos.y - item->pos.y;
if (Lara_MovePosition(item, &m_PickUpPosition)) {
lara_item->anim_number = LA_PICKUP;
Item_SwitchToAnim(lara_item, LA_PICKUP, -1);
lara_item->current_anim_state = LS_PICKUP;
have_item = true;
}
@ -182,8 +182,6 @@ void Pickup_CollisionControlled(
g_Lara.head_x_rot = 0;
g_Lara.torso_y_rot = 0;
g_Lara.torso_x_rot = 0;
lara_item->frame_number =
g_Anims[lara_item->anim_number].frame_base;
g_Lara.interact_target.is_moving = false;
g_Lara.gun_status = LGS_HANDS_BUSY;
}
@ -205,12 +203,10 @@ void Pickup_CollisionControlled(
if (Lara_TestPosition(item, m_PickUpBoundsUW)) {
if (Lara_MovePosition(item, &m_PickUpPositionUW)) {
lara_item->anim_number = LA_PICKUP_UW;
Item_SwitchToAnim(lara_item, LA_PICKUP_UW, -1);
lara_item->current_anim_state = LS_PICKUP;
lara_item->goal_anim_state = LS_TREAD;
lara_item->frame_number =
g_Anims[lara_item->anim_number].frame_base;
g_Lara.interact_target.is_moving = false;
g_Lara.gun_status = LGS_HANDS_BUSY;
}

View file

@ -136,11 +136,11 @@ void Switch_CollisionControlled(
if (Lara_TestPosition(item, m_Switch_BoundsControlled)) {
if (Lara_MovePosition(item, &move_vector)) {
if (item->current_anim_state == SWITCH_STATE_ON) {
lara_item->anim_number = LA_WALL_SWITCH_DOWN;
Item_SwitchToAnim(lara_item, LA_WALL_SWITCH_DOWN, -1);
lara_item->current_anim_state = LS_SWITCH_OFF;
item->goal_anim_state = SWITCH_STATE_OFF;
} else {
lara_item->anim_number = LA_WALL_SWITCH_UP;
Item_SwitchToAnim(lara_item, LA_WALL_SWITCH_UP, -1);
lara_item->current_anim_state = LS_SWITCH_ON;
item->goal_anim_state = SWITCH_STATE_ON;
}
@ -148,8 +148,6 @@ void Switch_CollisionControlled(
g_Lara.head_y_rot = 0;
g_Lara.torso_x_rot = 0;
g_Lara.torso_y_rot = 0;
lara_item->frame_number =
g_Anims[lara_item->anim_number].frame_base;
g_Lara.interact_target.is_moving = false;
g_Lara.gun_status = LGS_HANDS_BUSY;
Item_AddActive(item_num);

View file

@ -162,8 +162,7 @@ void RollingBall_Collision(
lara_item->current_anim_state = LS_SPECIAL;
lara_item->goal_anim_state = LS_SPECIAL;
lara_item->anim_number = LA_ROLLING_BALL_DEATH;
lara_item->frame_number = AF_RBALL_DEATH;
Item_SwitchToAnim(lara_item, LA_ROLLING_BALL_DEATH, AF_RBALL_DEATH);
g_Camera.flags = FOLLOW_CENTRE;
g_Camera.target_angle = 170 * PHD_DEGREE;

View file

@ -49,8 +49,7 @@ void Spikes_Collision(int16_t item_num, ITEM_INFO *lara_item, COLL_INFO *coll)
if (lara_item->hit_points <= 0) {
lara_item->current_anim_state = LS_DEATH;
lara_item->goal_anim_state = LS_DEATH;
lara_item->anim_number = LA_SPIKE_DEATH;
lara_item->frame_number = AF_SPIKE_DEATH;
Item_SwitchToAnim(lara_item, LA_SPIKE_DEATH, AF_SPIKE_DEATH);
lara_item->pos.y = item->pos.y;
lara_item->gravity_status = 0;
}

View file

@ -100,8 +100,8 @@ void ThorsHandle_Control(int16_t item_num)
g_LaraItem->gravity_status = 0;
g_LaraItem->current_anim_state = LS_SPECIAL;
g_LaraItem->goal_anim_state = LS_SPECIAL;
g_LaraItem->anim_number = LA_ROLLING_BALL_DEATH;
g_LaraItem->frame_number = AF_RBALL_DEATH;
Item_SwitchToAnim(
g_LaraItem, LA_ROLLING_BALL_DEATH, AF_RBALL_DEATH);
}
}
break;

View file

@ -726,6 +726,7 @@ typedef enum LARA_STATE {
LS_GYMNAST = 54,
LS_WATER_OUT = 55,
LS_CONTROLLED = 56,
LS_TWIST = 57,
} LARA_STATE;
typedef enum LARA_GUN_STATE {

View file

@ -91,6 +91,10 @@
"Title": "Look while running",
"Description": "Allows Lara to look while running, jumping etc. - similar to TR2 style."
},
"enable_jump_twists": {
"Title": "Jump twists",
"Description": "Enables TR2+ style jump twists and somersaults i.e. press roll during jump and swan dive animations."
},
"enable_numeric_keys": {
"Title": "Numeric key quick item use",
"Description": "Enables quick weapon draws and medipack usage.\n- 1: Draw pistols\n- 2: Draw shotgun\n- 3: Draw magnums\n- 4: Draw Uzis\n- 8: Use small medipack\n- 9: Use large medipack"

View file

@ -179,6 +179,10 @@
"Description": "Habilita la reproducción de FMV.",
"Title": "Habilitar FMV"
},
"enable_jump_twists": {
"Title": "Giros al saltar",
"Description": "Habilita los giros al saltar y saltos mortales al estilo TR2+, es decir, presione rodar durante las animaciones del salto y salto del cisne."
},
"enable_music_in_inventory": {
"Description": "Permite que los sonidos del juego continúen sonando en la pantalla de inventario.",
"Title": "Habilitar sonidos de juegos en el inventario"

View file

@ -91,6 +91,10 @@
"Title": "Observer en mouvement",
"Description": "Permet à Lara de regarder autour d'elle, lorsqu'elle court, saute etc. - Similaire à TR2."
},
"enable_jump_twists": {
"Title": "Sauts retournés",
"Description": "Activer les sauts retournés qui permettent à Lara de faire un demi-tour en l'air pendant un saut, et le saut de l'ange alternatif avec saut périlleux avant. Comme depuis TR2. Appuyer sur la touche roulade pendant un saut classique ou un saut de l'ange."
},
"enable_numeric_keys": {
"Title": "Touches rapide numériques",
"Description": "Active les touches rapides numériques en haut du clavier, en raccourci d'équipement d'armes ou d'utilisation de soins.\n- 1: Pistolets\n- 2: Fusil à pompe\n- 3: Magnums\n- 4: Uzis\n- 8: Utiliser une petite trousse de soin\n- 9: Utiliser une grande trousse de soin"

View file

@ -57,6 +57,11 @@
"DataType": "Bool",
"DefaultValue": true
},
{
"Field": "enable_jump_twists",
"DataType": "Bool",
"DefaultValue": true
},
{
"Field": "enable_numeric_keys",
"DataType": "Bool",