diff --git a/docs/progress.svg b/docs/progress.svg index 16484890..5ac88c59 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -244,7 +244,7 @@ int32_t __cdecl Misc_Move3DPosTo3DPos(PHD_3DPOS *src_pos, const PHD_3DPOS *dest_pos, int32_t velocity, PHD_ANGLE ang_add); int32_t __cdecl Game_Control(int32_t nframes, int32_t demo_mode); void __cdecl Item_Animate(ITEM_INFO *item); -int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM_STRUCT *anim); +int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM *anim); void __cdecl Item_Translate(ITEM_INFO *item, int32_t x, int32_t y, int32_t z); SECTOR_INFO *__cdecl Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num); int32_t __cdecl Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num); @@ -677,7 +677,7 @@ bool __cdecl LOT_EnableBaddieAI(int16_t item_num, bool always); void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); void __cdecl LOT_CreateZone(ITEM_INFO *item); -void __cdecl LOT_ClearLOT(LOT_INFO *LOT); +void __cdecl LOT_ClearLOT(LOT_INFO *lot); void __cdecl ControlMissile(int16_t fx_num); void __cdecl ShootAtLara(FX_INFO *fx); int32_t __cdecl Effect_ExplodingDeath(int16_t item_num, int32_t mesh_bits, int16_t damage); @@ -1806,7 +1806,7 @@ void __cdecl Requester_AddItem(REQUEST_INFO *req, const char *text1, uint32_t flags1, const char *text2, uint32_t flags2); void __cdecl SpiderLeap(int16_t item_num, int16_t angle); bool __cdecl Matrix_TranslateRel(int32_t x, int32_t y, int32_t z); -int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM_STRUCT *anim); +int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM *anim); int16_t __cdecl DragonFire(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE yrot, int16_t room_num); void __cdecl Overlay_DrawHealthBar(bool flash_state); void __cdecl Lara_SlideEdgeJump(ITEM_INFO *item, COLL_INFO *coll); @@ -2125,7 +2125,7 @@ void __cdecl HWR_FreeTexturePages(void); LONG __cdecl SetRegistryStringValue(LPCTSTR lpValueName, LPCTSTR value, int32_t length); void __cdecl Creature_Head(ITEM_INFO *item, int16_t required); -void __cdecl LOT_ClearLOT(LOT_INFO *LOT); +void __cdecl LOT_ClearLOT(LOT_INFO *lot); void __cdecl Lara_CatchFire(void); BOOL __cdecl ReadFileSync(HANDLE handle, LPVOID lpBuffer, DWORD nBytesToRead, LPDWORD lpnBytesRead, LPOVERLAPPED lpOverlapped); void __cdecl AddDynamicLight(int32_t x, int32_t y, int32_t z, int32_t intensity, int32_t falloff); diff --git a/docs/progress.txt b/docs/progress.txt index 2bb2da69..63e751d8 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -510,7 +510,7 @@ typedef struct __unaligned { // decompiled uint16_t pad: 10; } COLL_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t min_x; int16_t max_x; int16_t min_y; @@ -639,12 +639,12 @@ typedef struct __unaligned { int16_t sample_num; } WEAPON_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled XYZ_32 pos; XYZ_16 rot; int16_t room_num; int16_t object_id; - int16_t next_fx; + int16_t next_free; int16_t next_active; int16_t speed; int16_t fall_speed; @@ -663,14 +663,14 @@ typedef struct __unaligned { int16_t enemy_facing; } AI_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t exit_box; uint16_t search_num; int16_t next_expansion; int16_t box_num; } BOX_NODE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled BOX_NODE *node; int16_t head; int16_t tail; @@ -836,7 +836,7 @@ typedef enum { GFE_REMOVE_AMMO = 22, } GF_EVENTS; -typedef enum { +typedef enum { // decompiled MOOD_BORED = 0, MOOD_ATTACK = 1, MOOD_ESCAPE = 2, @@ -854,7 +854,7 @@ typedef struct __unaligned { int32_t mesh_num; } BITE_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t *frame_ptr; int16_t interpolation; int16_t current_anim_state; @@ -868,15 +868,15 @@ typedef struct __unaligned { int16_t change_idx; int16_t num_commands; int16_t command_idx; -} ANIM_STRUCT; +} ANIM; -typedef struct { +typedef struct { // decompiled int16_t goal_anim_state; int16_t num_ranges; int16_t range_idx; } ANIM_CHANGE; -typedef struct { +typedef struct { // decompiled int16_t start_frame; int16_t end_frame; int16_t link_anim_num; @@ -960,7 +960,7 @@ typedef struct __unaligned { uint16_t flags; } ROOM_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t head_rotation; int16_t neck_rotation; int16_t maximum_turn; @@ -1174,7 +1174,7 @@ typedef struct __unaligned { XYZ_32 mic_pos; } CAMERA_INFO; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t *frame_base; int16_t frame_num; int16_t anim_num; @@ -1187,11 +1187,11 @@ typedef struct __unaligned { int16_t flash_gun; } LARA_ARM; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int32_t ammo; } AMMO_INFO; -typedef enum { +typedef enum { // decompiled LWS_ABOVE_WATER = 0, LWS_UNDERWATER = 1, LWS_SURFACE = 2, @@ -1199,7 +1199,7 @@ typedef enum { LWS_WADE = 4, } LARA_WATER_STATE; -typedef struct __unaligned { +typedef struct __unaligned { // decompiled int16_t item_num; int16_t gun_status; int16_t gun_type; @@ -1637,7 +1637,7 @@ typedef struct __unaligned { int16_t roll; } CINE_FRAME; -typedef enum { +typedef enum { // decompiled IF_ONE_SHOT = 0x0100, IF_CODE_BITS = 0x3E00, IF_REVERSE = 0x4000, @@ -1683,7 +1683,7 @@ typedef enum { // decompiled IN_LOAD = 0x00800000, } INPUT_STATE; -typedef enum { +typedef enum { // decompiled LA_RUN = 0, LA_WALK_FORWARD = 1, LA_WALK_STOP_RIGHT = 2, @@ -1904,7 +1904,7 @@ typedef enum { LA_ZIPLINE_FALL = 217, } LARA_ANIMATION; -typedef enum { +typedef enum { // decompiled LA_EXTRA_BREATH = 0, LA_EXTRA_PLUNGER = 1, LA_EXTRA_YETI_KILL = 2, @@ -1918,7 +1918,7 @@ typedef enum { LA_EXTRA_FINAL_ANIM = 10, } LARA_EXTRA_ANIMATION; -typedef enum { +typedef enum { // decompiled LS_WALK = 0, LS_RUN = 1, LS_STOP = 2, @@ -1999,7 +1999,7 @@ typedef enum { LS_LAST = 77, } LARA_STATE; -typedef enum { +typedef enum { // decompiled LGS_ARMLESS = 0, LGS_HANDS_BUSY = 1, LGS_DRAW = 2, @@ -2008,7 +2008,7 @@ typedef enum { LGS_SPECIAL = 5, } LARA_GUN_STATE; -typedef enum { +typedef enum { // decompiled LGT_UNARMED = 0, LGT_PISTOLS = 1, LGT_MAGNUMS = 2, @@ -2022,7 +2022,7 @@ typedef enum { NUM_WEAPONS = 10, } LARA_GUN_TYPE; -typedef enum { +typedef enum { // decompiled LM_HIPS = 0, LM_THIGH_L = 1, LM_CALF_L = 2, @@ -2407,7 +2407,7 @@ typedef enum { HT_BIG_SLOPE = 2, } HEIGHT_TYPE; -typedef enum { +typedef enum { // decompiled DIR_UNKNOWN = -1, DIR_NORTH = 0, DIR_EAST = 1, @@ -3031,7 +3031,7 @@ typedef enum { # game/control.c 0x00414390 0x0356 + int32_t __cdecl Game_Control(int32_t nframes, int32_t demo_mode); 0x004146F0 0x0338 + void __cdecl Item_Animate(ITEM_INFO *item); -0x00414A60 0x00AB + int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM_STRUCT *anim); +0x00414A60 0x00AB + int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM *anim); 0x00414B10 0x005F + void __cdecl Item_Translate(ITEM_INFO *item, int32_t x, int32_t y, int32_t z); 0x00414B70 0x0198 + SECTOR_INFO *__cdecl Room_GetSector(int32_t x, int32_t y, int32_t z, int16_t *room_num); 0x00414D10 0x0168 + int32_t __cdecl Room_GetWaterHeight(int32_t x, int32_t y, int32_t z, int16_t room_num); @@ -3514,7 +3514,7 @@ typedef enum { 0x00432B10 0x01B0 + bool __cdecl LOT_EnableBaddieAI(int16_t item_num, bool always); 0x00432CC0 0x0106 + void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); 0x00432ED0 0x00B8 + void __cdecl LOT_CreateZone(ITEM_INFO *item); -0x00432F90 0x0049 + void __cdecl LOT_ClearLOT(LOT_INFO *LOT); +0x00432F90 0x0049 + void __cdecl LOT_ClearLOT(LOT_INFO *lot); # game/missile.c 0x00432FE0 0x02D0 -R void __cdecl ControlMissile(int16_t fx_num); @@ -4435,7 +4435,7 @@ typedef enum { 0x005252B0 - int16_t **g_Meshes; 0x005252C0 - MATRIX g_IMMatrixStack[256]; 0x005258F0 - int32_t g_IMFrac; -0x005258F4 - ANIM_STRUCT *g_Anims; +0x005258F4 - ANIM *g_Anims; 0x00525BE8 - int32_t *g_AnimBones; 0x00526180 - int32_t g_RoomCount; 0x00526184 - int32_t g_IMRate; diff --git a/meson.build b/meson.build index 25e950e0..384ced7f 100644 --- a/meson.build +++ b/meson.build @@ -19,6 +19,7 @@ c_compiler = meson.get_compiler('c') build_opts = [ '-Wno-unused', + '-Wno-address-of-packed-member', '-DMESON_BUILD', '-fno-omit-frame-pointer', '-ffile-prefix-map=../../src/=', @@ -90,12 +91,10 @@ dll_sources = [ 'src/game/camera.c', 'src/game/clock.c', 'src/game/collide.c', - 'src/game/console/cmd/die.c', 'src/game/console/cmd/end_level.c', 'src/game/console/cmd/exit_game.c', 'src/game/console/cmd/exit_to_title.c', 'src/game/console/cmd/flipmap.c', - 'src/game/console/cmd/fly.c', 'src/game/console/cmd/load_game.c', 'src/game/console/cmd/play_demo.c', 'src/game/console/cmd/play_level.c', @@ -122,15 +121,14 @@ dll_sources = [ 'src/game/inventory/ring.c', 'src/game/inventory/vars.c', 'src/game/items.c', + 'src/game/lara/cheat.c', + 'src/game/lara/col.c', 'src/game/lara/common.c', - 'src/game/lara/lara_cheat.c', - 'src/game/lara/lara_col.c', - 'src/game/lara/lara_control.c', - 'src/game/lara/lara_draw.c', - 'src/game/lara/lara_look.c', - 'src/game/lara/lara_misc.c', - 'src/game/lara/lara_state.c', + 'src/game/lara/control.c', + 'src/game/lara/draw.c', + 'src/game/lara/look.c', 'src/game/lara/misc.c', + 'src/game/lara/state.c', 'src/game/level.c', 'src/game/los.c', 'src/game/lot.c', diff --git a/src/decomp/decomp.c b/src/decomp/decomp.c index 1b2279fe..26320885 100644 --- a/src/decomp/decomp.c +++ b/src/decomp/decomp.c @@ -12,8 +12,8 @@ #include "game/inventory/backpack.h" #include "game/inventory/common.h" #include "game/items.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_draw.h" +#include "game/lara/control.h" +#include "game/lara/draw.h" #include "game/lot.h" #include "game/math.h" #include "game/music.h" diff --git a/src/game/console/cmd/die.c b/src/game/console/cmd/die.c deleted file mode 100644 index 20c121b6..00000000 --- a/src/game/console/cmd/die.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "game/console/cmd/die.h" - -#include "decomp/effects.h" -#include "game/sound.h" -#include "global/vars.h" - -static COMMAND_RESULT M_Entrypoint(const char *args); - -static COMMAND_RESULT M_Entrypoint(const char *const args) -{ - if (!g_Objects[O_LARA].loaded) { - return CR_UNAVAILABLE; - } - - if (g_LaraItem->hit_points <= 0) { - return CR_UNAVAILABLE; - } - - Sound_Effect(SFX_LARA_FALL, &g_LaraItem->pos, SPM_NORMAL); - Effect_ExplodingDeath(g_Lara.item_num, -1, 1); - - g_LaraItem->hit_points = 0; - g_LaraItem->flags |= IF_INVISIBLE; - return CR_SUCCESS; -} - -CONSOLE_COMMAND g_Console_Cmd_Die = { - .prefix = "abortion|natlastinks", - .proc = M_Entrypoint, -}; diff --git a/src/game/console/cmd/die.h b/src/game/console/cmd/die.h deleted file mode 100644 index bf50d44b..00000000 --- a/src/game/console/cmd/die.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -extern CONSOLE_COMMAND g_Console_Cmd_Die; diff --git a/src/game/console/cmd/end_level.c b/src/game/console/cmd/end_level.c index 94db367a..79d6c185 100644 --- a/src/game/console/cmd/end_level.c +++ b/src/game/console/cmd/end_level.c @@ -1,6 +1,6 @@ #include "game/console/cmd/end_level.h" -#include "game/lara/lara_cheat.h" +#include "game/lara/cheat.h" #include diff --git a/src/game/console/cmd/fly.c b/src/game/console/cmd/fly.c deleted file mode 100644 index 4fe91a84..00000000 --- a/src/game/console/cmd/fly.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "game/console/cmd/fly.h" - -#include "game/game.h" -#include "game/lara/lara_cheat.h" -#include "global/vars.h" - -static COMMAND_RESULT M_Entrypoint(const char *args); - -static COMMAND_RESULT M_Entrypoint(const char *const args) -{ - if (!Game_IsPlayable()) { - return CR_UNAVAILABLE; - } - Lara_Cheat_EnterFlyMode(); - return CR_SUCCESS; -} - -CONSOLE_COMMAND g_Console_Cmd_Fly = { - .prefix = "fly", - .proc = M_Entrypoint, -}; diff --git a/src/game/console/cmd/fly.h b/src/game/console/cmd/fly.h deleted file mode 100644 index 24e195a5..00000000 --- a/src/game/console/cmd/fly.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include - -extern CONSOLE_COMMAND g_Console_Cmd_Fly; diff --git a/src/game/console/cmd/teleport.c b/src/game/console/cmd/teleport.c index 907574f2..affb7575 100644 --- a/src/game/console/cmd/teleport.c +++ b/src/game/console/cmd/teleport.c @@ -3,7 +3,7 @@ #include "game/game_string.h" #include "game/gameflow/gameflow_new.h" #include "game/items.h" -#include "game/lara/lara_cheat.h" +#include "game/lara/cheat.h" #include "game/objects/names.h" #include "game/objects/vars.h" #include "game/random.h" diff --git a/src/game/console/setup.c b/src/game/console/setup.c index 9c962381..f7da151f 100644 --- a/src/game/console/setup.c +++ b/src/game/console/setup.c @@ -1,11 +1,9 @@ #include "game/console/setup.h" -#include "game/console/cmd/die.h" #include "game/console/cmd/end_level.h" #include "game/console/cmd/exit_game.h" #include "game/console/cmd/exit_to_title.h" #include "game/console/cmd/flipmap.h" -#include "game/console/cmd/fly.h" #include "game/console/cmd/load_game.h" #include "game/console/cmd/play_demo.h" #include "game/console/cmd/play_level.h" @@ -13,6 +11,8 @@ #include "game/console/cmd/teleport.h" #include +#include +#include #include #include #include diff --git a/src/game/creature.c b/src/game/creature.c index 390b33aa..4bd0e76e 100644 --- a/src/game/creature.c +++ b/src/game/creature.c @@ -3,7 +3,7 @@ #include "decomp/effects.h" #include "game/box.h" #include "game/items.h" -#include "game/lara/lara_misc.h" +#include "game/lara/misc.h" #include "game/los.h" #include "game/lot.h" #include "game/math.h" diff --git a/src/game/demo.c b/src/game/demo.c index fd56723c..c994d724 100644 --- a/src/game/demo.c +++ b/src/game/demo.c @@ -4,7 +4,7 @@ #include "game/game.h" #include "game/gameflow.h" #include "game/items.h" -#include "game/lara/lara_cheat.h" +#include "game/lara/cheat.h" #include "game/random.h" #include "game/room.h" #include "game/shell.h" diff --git a/src/game/effects.c b/src/game/effects.c index e6fad7fc..685ce612 100644 --- a/src/game/effects.c +++ b/src/game/effects.c @@ -32,16 +32,16 @@ static void M_RemoveDrawn(const int16_t fx_num) FX_INFO *const fx = &g_Effects[fx_num]; int16_t link_num = g_Rooms[fx->room_num].fx_num; if (link_num == fx_num) { - g_Rooms[fx->room_num].fx_num = fx->next_fx; + g_Rooms[fx->room_num].fx_num = fx->next_free; return; } while (link_num != NO_ITEM) { - if (g_Effects[link_num].next_fx == fx_num) { - g_Effects[link_num].next_fx = fx->next_fx; + if (g_Effects[link_num].next_free == fx_num) { + g_Effects[link_num].next_free = fx->next_free; return; } - link_num = g_Effects[link_num].next_fx; + link_num = g_Effects[link_num].next_free; } } @@ -52,9 +52,9 @@ void __cdecl Effect_InitialiseArray(void) for (int32_t i = 0; i < MAX_EFFECTS - 1; i++) { FX_INFO *const fx = &g_Effects[i]; - fx->next_fx = i + 1; + fx->next_free = i + 1; } - g_Effects[MAX_EFFECTS - 1].next_fx = NO_ITEM; + g_Effects[MAX_EFFECTS - 1].next_free = NO_ITEM; } int16_t __cdecl Effect_Create(const int16_t room_num) @@ -65,11 +65,11 @@ int16_t __cdecl Effect_Create(const int16_t room_num) } FX_INFO *const fx = &g_Effects[fx_num]; - g_NextEffectFree = fx->next_fx; + g_NextEffectFree = fx->next_free; ROOM_INFO *const room = &g_Rooms[room_num]; fx->room_num = room_num; - fx->next_fx = room->fx_num; + fx->next_free = room->fx_num; room->fx_num = fx_num; fx->next_active = g_NextEffectActive; @@ -86,7 +86,7 @@ void __cdecl Effect_Kill(const int16_t fx_num) M_RemoveActive(fx_num); M_RemoveDrawn(fx_num); - fx->next_fx = g_NextEffectFree; + fx->next_free = g_NextEffectFree; g_NextEffectFree = fx_num; } @@ -97,20 +97,20 @@ void __cdecl Effect_NewRoom(const int16_t fx_num, const int16_t room_num) int16_t link_num = room->fx_num; if (link_num == fx_num) { - room->fx_num = fx->next_fx; + room->fx_num = fx->next_free; } else { while (link_num != NO_ITEM) { - if (g_Effects[link_num].next_fx == fx_num) { - g_Effects[link_num].next_fx = fx->next_fx; + if (g_Effects[link_num].next_free == fx_num) { + g_Effects[link_num].next_free = fx->next_free; break; } - link_num = g_Effects[link_num].next_fx; + link_num = g_Effects[link_num].next_free; } } fx->room_num = room_num; room = &g_Rooms[room_num]; - fx->next_fx = room->fx_num; + fx->next_free = room->fx_num; room->fx_num = fx_num; } diff --git a/src/game/game.c b/src/game/game.c index ed92b9bf..489b17e6 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -6,7 +6,7 @@ #include "game/gameflow/gameflow_new.h" #include "game/input.h" #include "game/inventory/common.h" -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "game/music.h" #include "game/overlay.h" #include "game/room_draw.h" diff --git a/src/game/gun/gun.c b/src/game/gun/gun.c index fff6de1a..2d23a8e4 100644 --- a/src/game/gun/gun.c +++ b/src/game/gun/gun.c @@ -5,7 +5,7 @@ #include "game/gun/gun_rifle.h" #include "game/input.h" #include "game/inventory/backpack.h" -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "game/sound.h" #include "global/funcs.h" #include "global/vars.h" diff --git a/src/game/gun/gun_rifle.c b/src/game/gun/gun_rifle.c index d4d6181e..4cde241b 100644 --- a/src/game/gun/gun_rifle.c +++ b/src/game/gun/gun_rifle.c @@ -5,7 +5,7 @@ #include "game/gun/gun_misc.h" #include "game/input.h" #include "game/items.h" -#include "game/lara/lara_misc.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/random.h" #include "game/sound.h" diff --git a/src/game/inventory/common.c b/src/game/inventory/common.c index 4c3caa5a..4aa7bd40 100644 --- a/src/game/inventory/common.c +++ b/src/game/inventory/common.c @@ -5,7 +5,7 @@ #include "game/inventory/backpack.h" #include "game/inventory/ring.h" #include "game/inventory/vars.h" -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "game/math_misc.h" #include "game/matrix.h" #include "game/music.h" diff --git a/src/game/items.c b/src/game/items.c index c5119df6..a9cadec7 100644 --- a/src/game/items.c +++ b/src/game/items.c @@ -445,7 +445,7 @@ void __cdecl Item_Animate(ITEM_INFO *const item) item->hit_status = 0; item->touch_bits = 0; - const ANIM_STRUCT *anim = &g_Anims[item->anim_num]; + const ANIM *anim = &g_Anims[item->anim_num]; item->frame_num++; @@ -586,7 +586,7 @@ void __cdecl Item_Animate(ITEM_INFO *const item) } int32_t __cdecl Item_GetAnimChange( - ITEM_INFO *const item, const ANIM_STRUCT *const anim) + ITEM_INFO *const item, const ANIM *const anim) { if (item->current_anim_state == item->goal_anim_state) { return false; @@ -651,7 +651,7 @@ int32_t __cdecl Item_IsTriggerActive(ITEM_INFO *const item) int32_t __cdecl Item_GetFrames( const ITEM_INFO *item, FRAME_INFO *frmptr[], int32_t *rate) { - const ANIM_STRUCT *const anim = &g_Anims[item->anim_num]; + const ANIM *const anim = &g_Anims[item->anim_num]; const int32_t cur_frame_num = item->frame_num - anim->frame_base; const int32_t size = anim->interpolation >> 8; const int32_t key_frame_span = anim->interpolation & 0xFF; diff --git a/src/game/items.h b/src/game/items.h index 564e97c1..8884a2ba 100644 --- a/src/game/items.h +++ b/src/game/items.h @@ -24,7 +24,7 @@ int32_t __cdecl Item_TestPosition( void __cdecl Item_AlignPosition( const XYZ_32 *vec, const ITEM_INFO *src_item, ITEM_INFO *dst_item); void __cdecl Item_Animate(ITEM_INFO *item); -int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM_STRUCT *anim); +int32_t __cdecl Item_GetAnimChange(ITEM_INFO *item, const ANIM *anim); void __cdecl Item_Translate(ITEM_INFO *item, int32_t x, int32_t y, int32_t z); int32_t __cdecl Item_IsTriggerActive(ITEM_INFO *item); int32_t __cdecl Item_GetFrames( diff --git a/src/game/lara/lara_cheat.c b/src/game/lara/cheat.c similarity index 98% rename from src/game/lara/lara_cheat.c rename to src/game/lara/cheat.c index 9317d5af..90765c87 100644 --- a/src/game/lara/lara_cheat.c +++ b/src/game/lara/cheat.c @@ -1,4 +1,4 @@ -#include "game/lara/lara_cheat.h" +#include "game/lara/cheat.h" #include "decomp/effects.h" #include "game/camera.h" @@ -8,7 +8,7 @@ #include "game/gun/gun.h" #include "game/inventory/backpack.h" #include "game/items.h" -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "game/math.h" #include "game/objects/common.h" #include "game/objects/vars.h" @@ -110,7 +110,7 @@ void __cdecl Lara_Cheat_EndLevel(void) Console_Log(GS(OSD_COMPLETE_LEVEL)); } -bool __cdecl Lara_Cheat_EnterFlyMode(void) +bool Lara_Cheat_EnterFlyMode(void) { if (g_LaraItem == NULL) { return false; @@ -157,7 +157,7 @@ bool __cdecl Lara_Cheat_EnterFlyMode(void) return true; } -bool __cdecl Lara_Cheat_ExitFlyMode(void) +bool Lara_Cheat_ExitFlyMode(void) { if (g_LaraItem == NULL) { return false; diff --git a/src/game/lara/lara_cheat.h b/src/game/lara/cheat.h similarity index 81% rename from src/game/lara/lara_cheat.h rename to src/game/lara/cheat.h index 7e004531..4ec8fd76 100644 --- a/src/game/lara/lara_cheat.h +++ b/src/game/lara/cheat.h @@ -4,8 +4,8 @@ #include void __cdecl Lara_Cheat_EndLevel(void); -bool __cdecl Lara_Cheat_EnterFlyMode(void); -bool __cdecl Lara_Cheat_ExitFlyMode(void); +bool Lara_Cheat_EnterFlyMode(void); +bool Lara_Cheat_ExitFlyMode(void); void __cdecl Lara_Cheat_GetStuff(void); bool Lara_Cheat_GiveAllKeys(void); bool Lara_Cheat_GiveAllGuns(void); diff --git a/src/game/lara/lara_col.c b/src/game/lara/col.c similarity index 99% rename from src/game/lara/lara_col.c rename to src/game/lara/col.c index ded1284d..6f694516 100644 --- a/src/game/lara/lara_col.c +++ b/src/game/lara/col.c @@ -1,10 +1,10 @@ -#include "game/lara/lara_col.h" +#include "game/lara/col.h" #include "game/collide.h" #include "game/input.h" #include "game/items.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_misc.h" +#include "game/lara/control.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/room.h" #include "game/sound.h" diff --git a/src/game/lara/lara_col.h b/src/game/lara/col.h similarity index 100% rename from src/game/lara/lara_col.h rename to src/game/lara/col.h diff --git a/src/game/lara/common.c b/src/game/lara/common.c index b28f4d6c..10eafdc6 100644 --- a/src/game/lara/common.c +++ b/src/game/lara/common.c @@ -2,6 +2,11 @@ #include +LARA_INFO *Lara_GetLaraInfo(void) +{ + return &g_Lara; +} + ITEM_INFO *Lara_GetItem(void) { return g_LaraItem; diff --git a/src/game/lara/lara_control.c b/src/game/lara/control.c similarity index 99% rename from src/game/lara/lara_control.c rename to src/game/lara/control.c index 0a189c4e..2444c003 100644 --- a/src/game/lara/lara_control.c +++ b/src/game/lara/control.c @@ -1,13 +1,13 @@ -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "game/creature.h" #include "game/gun/gun.h" #include "game/input.h" #include "game/inventory/backpack.h" #include "game/items.h" -#include "game/lara/lara_cheat.h" -#include "game/lara/lara_look.h" -#include "game/lara/lara_misc.h" +#include "game/lara/cheat.h" +#include "game/lara/look.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/music.h" #include "game/room.h" @@ -498,7 +498,7 @@ void __cdecl Lara_Animate(ITEM_INFO *const item) { item->frame_num++; - const ANIM_STRUCT *anim = &g_Anims[item->anim_num]; + const ANIM *anim = &g_Anims[item->anim_num]; if (anim->num_changes > 0 && Item_GetAnimChange(item, anim)) { anim = &g_Anims[item->anim_num]; item->current_anim_state = anim->current_anim_state; diff --git a/src/game/lara/lara_control.h b/src/game/lara/control.h similarity index 100% rename from src/game/lara/lara_control.h rename to src/game/lara/control.h diff --git a/src/game/lara/lara_draw.c b/src/game/lara/draw.c similarity index 99% rename from src/game/lara/lara_draw.c rename to src/game/lara/draw.c index adf8b66b..db40e696 100644 --- a/src/game/lara/lara_draw.c +++ b/src/game/lara/draw.c @@ -1,4 +1,4 @@ -#include "game/lara/lara_draw.h" +#include "game/lara/draw.h" #include "game/items.h" #include "game/matrix.h" diff --git a/src/game/lara/lara_draw.h b/src/game/lara/draw.h similarity index 100% rename from src/game/lara/lara_draw.h rename to src/game/lara/draw.h diff --git a/src/game/lara/lara_misc.c b/src/game/lara/lara_misc.c deleted file mode 100644 index fc258044..00000000 --- a/src/game/lara/lara_misc.c +++ /dev/null @@ -1,1851 +0,0 @@ -#include "game/lara/lara_misc.h" - -#include "decomp/decomp.h" -#include "game/box.h" -#include "game/collide.h" -#include "game/effects.h" -#include "game/input.h" -#include "game/items.h" -#include "game/lara/lara_control.h" -#include "game/math.h" -#include "game/matrix.h" -#include "game/random.h" -#include "game/room.h" -#include "game/sound.h" -#include "global/const.h" -#include "global/funcs.h" -#include "global/vars.h" - -#include - -#define MAX_BADDIE_COLLISION 20 -#define MOVE_SPEED 16 -#define MOVE_ANGLE (2 * PHD_DEGREE) // = 364 -#define CLIMB_HANG 900 -#define CLIMB_SHIFT 70 - -static void __cdecl M_TakeHit( - ITEM_INFO *const lara_item, const int32_t dx, const int32_t dz); - -static void __cdecl M_TakeHit( - ITEM_INFO *const lara_item, const int32_t dx, const int32_t dz) -{ - const PHD_ANGLE hit_angle = lara_item->rot.y + PHD_180 - Math_Atan(dz, dx); - g_Lara.hit_direction = Math_GetDirection(hit_angle); - if (g_Lara.hit_frame == 0) { - Sound_Effect(SFX_LARA_INJURY, &lara_item->pos, SPM_NORMAL); - } - g_Lara.hit_frame++; - CLAMPG(g_Lara.hit_frame, 34); -} - -void __cdecl Lara_GetCollisionInfo(ITEM_INFO *item, COLL_INFO *coll) -{ - coll->facing = g_Lara.move_angle; - Collide_GetCollisionInfo( - coll, item->pos.x, item->pos.y, item->pos.z, item->room_num, - LARA_HEIGHT); -} - -void __cdecl Lara_SlideSlope(ITEM_INFO *item, COLL_INFO *coll) -{ - coll->bad_pos = NO_BAD_POS; - coll->bad_neg = -STEP_L * 2; - coll->bad_ceiling = 0; - Lara_GetCollisionInfo(item, coll); - - if (Lara_HitCeiling(item, coll)) { - return; - } - - Lara_DeflectEdge(item, coll); - - if (coll->side_mid.floor > 200) { - if (item->current_anim_state == LS_SLIDE) { - item->goal_anim_state = LS_FORWARD_JUMP; - item->current_anim_state = LS_FORWARD_JUMP; - item->anim_num = LS_SURF_SWIM; - item->frame_num = g_Anims[item->anim_num].frame_base; - } else { - item->goal_anim_state = LS_FALL_BACK; - item->current_anim_state = LS_FALL_BACK; - item->anim_num = LA_FALL_BACK; - item->frame_num = g_Anims[item->anim_num].frame_base; - } - item->gravity = 1; - item->fall_speed = 0; - return; - } - - Lara_TestSlide(item, coll); - item->pos.y += coll->side_mid.floor; - if (ABS(coll->x_tilt) <= 2 && ABS(coll->z_tilt) <= 2) { - item->goal_anim_state = LS_STOP; - } -} - -int32_t __cdecl Lara_HitCeiling(ITEM_INFO *item, COLL_INFO *coll) -{ - if (coll->coll_type != COLL_TOP && coll->coll_type != COLL_CLAMP) { - return 0; - } - - item->pos.x = coll->old.x; - item->pos.y = coll->old.y; - item->pos.z = coll->old.z; - item->goal_anim_state = LS_STOP; - item->current_anim_state = LS_STOP; - item->anim_num = LS_REACH; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->speed = 0; - item->gravity = 0; - item->fall_speed = 0; - return 1; -} - -int32_t __cdecl Lara_DeflectEdge(ITEM_INFO *item, COLL_INFO *coll) -{ - switch (coll->coll_type) { - case COLL_FRONT: - case COLL_TOP_FRONT: - Item_ShiftCol(item, coll); - item->goal_anim_state = LS_STOP; - item->current_anim_state = LS_STOP; - item->gravity = 0; - item->speed = 0; - return 1; - - case COLL_LEFT: - Item_ShiftCol(item, coll); - item->rot.y += LARA_DEFLECT_ANGLE; - return 0; - - case COLL_RIGHT: - Item_ShiftCol(item, coll); - item->rot.y -= LARA_DEFLECT_ANGLE; - return 0; - - default: - return 0; - } -} - -void __cdecl Lara_DeflectEdgeJump(ITEM_INFO *item, COLL_INFO *coll) -{ - Item_ShiftCol(item, coll); - switch (coll->coll_type) { - case COLL_FRONT: - case COLL_TOP_FRONT: - if (!g_Lara.climb_status || item->speed != 2) { - if (coll->side_mid.floor > 512) { - item->goal_anim_state = LS_FAST_FALL; - item->current_anim_state = LS_FAST_FALL; - item->anim_num = LA_SMASH_JUMP; - item->frame_num = g_Anims[item->anim_num].frame_base + 1; - } else if (coll->side_mid.floor <= 128) { - item->goal_anim_state = LS_LAND; - item->current_anim_state = LS_LAND; - item->anim_num = LA_JUMP_UP_LAND; - item->frame_num = g_Anims[item->anim_num].frame_base; - } - item->speed /= 4; - g_Lara.move_angle += PHD_180; - CLAMPL(item->fall_speed, 1); - } - break; - - case COLL_LEFT: - item->rot.y += LARA_DEFLECT_ANGLE; - break; - - case COLL_RIGHT: - item->rot.y -= LARA_DEFLECT_ANGLE; - break; - - case COLL_TOP: - CLAMPL(item->fall_speed, 1); - break; - - case COLL_CLAMP: - item->pos.z -= (Math_Cos(coll->facing) * 100) >> W2V_SHIFT; - item->pos.x -= (Math_Sin(coll->facing) * 100) >> W2V_SHIFT; - item->speed = 0; - coll->side_mid.floor = 0; - if (item->fall_speed <= 0) { - item->fall_speed = 16; - } - break; - - default: - break; - } -} - -void __cdecl Lara_SlideEdgeJump(ITEM_INFO *item, COLL_INFO *coll) -{ - Item_ShiftCol(item, coll); - - switch (coll->coll_type) { - case COLL_LEFT: - item->rot.y += LARA_DEFLECT_ANGLE; - break; - - case COLL_RIGHT: - item->rot.y -= LARA_DEFLECT_ANGLE; - break; - - case COLL_TOP: - case COLL_TOP_FRONT: - CLAMPL(item->fall_speed, 1); - break; - - case COLL_CLAMP: - item->pos.z -= (Math_Cos(coll->facing) * 100) >> W2V_SHIFT; - item->pos.x -= (Math_Sin(coll->facing) * 100) >> W2V_SHIFT; - item->speed = 0; - coll->side_mid.floor = 0; - if (item->fall_speed <= 0) { - item->fall_speed = 16; - } - break; - - default: - break; - } -} - -int32_t __cdecl Lara_TestWall( - ITEM_INFO *item, int32_t front, int32_t right, int32_t down) -{ - int32_t x = item->pos.x; - int32_t y = item->pos.y + down; - int32_t z = item->pos.z; - - DIRECTION dir = Math_GetDirection(item->rot.y); - switch (dir) { - case DIR_NORTH: - x -= right; - break; - case DIR_EAST: - z -= right; - break; - case DIR_SOUTH: - x += right; - break; - case DIR_WEST: - z += right; - break; - default: - break; - } - - int16_t room_num = item->room_num; - Room_GetSector(x, y, z, &room_num); - - switch (dir) { - case DIR_NORTH: - z += front; - break; - case DIR_EAST: - x += front; - break; - case DIR_SOUTH: - z -= front; - break; - case DIR_WEST: - x -= front; - break; - default: - break; - } - - const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); - const int32_t height = Room_GetHeight(sector, x, y, z); - const int32_t ceiling = Room_GetCeiling(sector, x, y, z); - if (height == NO_HEIGHT) { - return 1; - } - if (height - y > 0 && ceiling - y < 0) { - return 0; - } - return 2; -} - -int32_t __cdecl Lara_TestHangOnClimbWall(ITEM_INFO *item, COLL_INFO *coll) -{ - if (!g_Lara.climb_status || item->fall_speed < 0) { - return 0; - } - - DIRECTION dir = Math_GetDirection(item->rot.y); - switch (dir) { - case DIR_NORTH: - case DIR_SOUTH: - item->pos.z += coll->shift.z; - break; - - case DIR_EAST: - case DIR_WEST: - item->pos.x += coll->shift.x; - break; - - default: - break; - } - - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - int32_t y = bounds->min_y; - int32_t h = bounds->max_y - y; - - int32_t shift; - if (!Lara_TestClimbPos(item, coll->radius, coll->radius, y, h, &shift)) { - return 0; - } - - if (!Lara_TestClimbPos(item, coll->radius, -coll->radius, y, h, &shift)) { - return 0; - } - - int32_t result = Lara_TestClimbPos(item, coll->radius, 0, y, h, &shift); - switch (result) { - case 0: - case 1: - return result; - - default: - item->pos.y += shift; - return 1; - } -} - -int32_t __cdecl Lara_TestClimbStance(ITEM_INFO *item, COLL_INFO *coll) -{ - int32_t shift_r; - int32_t result_r = Lara_TestClimbPos( - item, coll->radius, coll->radius + LARA_CLIMB_WIDTH_RIGHT, -700, - STEP_L * 2, &shift_r); - if (result_r != 1) { - return 0; - } - - int32_t shift_l; - int32_t result_l = Lara_TestClimbPos( - item, coll->radius, -(coll->radius + LARA_CLIMB_WIDTH_LEFT), -700, - STEP_L * 2, &shift_l); - if (result_l != 1) { - return 0; - } - - int32_t shift = 0; - if (shift_r) { - if (shift_l) { - if ((shift_r < 0) != (shift_l < 0)) { - return 0; - } - if (shift_r < 0 && shift_l < shift_r) { - shift = shift_l; - } else if (shift_r > 0 && shift_l > shift_r) { - shift = shift_l; - } else { - shift = shift_r; - } - } else { - shift = shift_r; - } - } else if (shift_l) { - shift = shift_l; - } - - item->pos.y += shift; - return 1; -} - -void __cdecl Lara_HangTest(ITEM_INFO *item, COLL_INFO *coll) -{ - coll->bad_pos = NO_BAD_POS; - coll->bad_neg = NO_BAD_NEG; - coll->bad_ceiling = 0; - Lara_GetCollisionInfo(item, coll); - bool flag = coll->side_front.floor < 200; - - item->gravity = 0; - item->fall_speed = 0; - g_Lara.move_angle = item->rot.y; - - DIRECTION dir = Math_GetDirection(item->rot.y); - switch (dir) { - case DIR_NORTH: - item->pos.z += 2; - break; - case DIR_EAST: - item->pos.x += 2; - break; - case DIR_SOUTH: - item->pos.z -= 2; - break; - case DIR_WEST: - item->pos.x -= 2; - break; - default: - break; - } - - coll->bad_pos = NO_BAD_POS; - coll->bad_neg = -STEPUP_HEIGHT; - coll->bad_ceiling = 0; - Lara_GetCollisionInfo(item, coll); - - if (g_Lara.climb_status) { - if (!(g_Input & IN_ACTION) || item->hit_points <= 0) { - XYZ_32 pos = { - .x = 0, - .y = 0, - .z = 0, - }; - Collide_GetJointAbsPosition(item, &pos, 0); - if (dir == DIR_NORTH || dir == DIR_SOUTH) { - item->pos.x = pos.x; - } else { - item->pos.z = pos.z; - } - - item->goal_anim_state = LS_FORWARD_JUMP; - item->current_anim_state = LS_FORWARD_JUMP; - item->anim_num = LA_FALL_START; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->pos.y += STEP_L; - item->gravity = 1; - item->speed = 2; - item->fall_speed = 1; - g_Lara.gun_status = LGS_ARMLESS; - return; - } - - if (!Lara_TestHangOnClimbWall(item, coll)) { - item->pos.x = coll->old.x; - item->pos.y = coll->old.y; - item->pos.z = coll->old.z; - item->goal_anim_state = LS_HANG; - item->current_anim_state = LS_HANG; - item->anim_num = LA_REACH_TO_HANG; - item->frame_num = g_Anims[item->anim_num].frame_base + 21; - return; - } - - if (item->anim_num == LA_REACH_TO_HANG - && item->frame_num == g_Anims[item->anim_num].frame_base + 21 - && Lara_TestClimbStance(item, coll)) { - item->goal_anim_state = LS_CLIMB_STANCE; - } - return; - } - - if (!(g_Input & IN_ACTION) || item->hit_points <= 0 - || coll->side_front.floor > 0) { - item->goal_anim_state = LS_UP_JUMP; - item->current_anim_state = LS_UP_JUMP; - item->anim_num = LA_JUMP_UP; - item->frame_num = g_Anims[item->anim_num].frame_base + 9; - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - item->pos.y += bounds->max_y; - item->pos.x += coll->shift.x; - item->pos.z += coll->shift.z; - item->gravity = 1; - item->speed = 2; - item->fall_speed = 1; - g_Lara.gun_status = LGS_ARMLESS; - return; - } - - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - int32_t hdif = coll->side_front.floor - bounds->min_y; - - if (ABS(coll->side_left.floor - coll->side_right.floor) >= SLOPE_DIF - || coll->side_mid.ceiling >= 0 || coll->coll_type != COLL_FRONT || flag - || coll->hit_static || hdif < -SLOPE_DIF || hdif > SLOPE_DIF) { - item->pos.x = coll->old.x; - item->pos.y = coll->old.y; - item->pos.z = coll->old.z; - if (item->current_anim_state == LS_HANG_LEFT - || item->current_anim_state == LS_HANG_RIGHT) { - item->goal_anim_state = LS_HANG; - item->current_anim_state = LS_HANG; - item->anim_num = LA_REACH_TO_HANG; - item->frame_num = g_Anims[item->anim_num].frame_base + 21; - } - return; - } - - switch (dir) { - case DIR_NORTH: - case DIR_SOUTH: - item->pos.z += coll->shift.z; - break; - - case DIR_EAST: - case DIR_WEST: - item->pos.x += coll->shift.x; - break; - - default: - break; - } - - item->pos.y += hdif; -} - -int32_t __cdecl Lara_TestEdgeCatch( - ITEM_INFO *item, COLL_INFO *coll, int32_t *edge) -{ - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - int32_t hdif1 = coll->side_front.floor - bounds->min_y; - int32_t hdif2 = hdif1 + item->fall_speed; - if ((hdif1 < 0 && hdif2 < 0) || (hdif1 > 0 && hdif2 > 0)) { - hdif1 = item->pos.y + bounds->min_y; - hdif2 = hdif1 + item->fall_speed; - if ((hdif1 >> (WALL_SHIFT - 2)) == (hdif2 >> (WALL_SHIFT - 2))) { - return 0; - } - if (item->fall_speed > 0) { - *edge = hdif2 & ~(STEP_L - 1); - } else { - *edge = hdif1 & ~(STEP_L - 1); - } - return -1; - } - - return ABS(coll->side_left.floor - coll->side_right.floor) < SLOPE_DIF; -} - -int32_t __cdecl Lara_TestHangJumpUp(ITEM_INFO *item, COLL_INFO *coll) -{ - if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) - || g_Lara.gun_status != LGS_ARMLESS || coll->hit_static - || coll->side_mid.ceiling > -STEPUP_HEIGHT) { - return 0; - } - - int32_t edge; - int32_t edge_catch = Lara_TestEdgeCatch(item, coll, &edge); - if (!edge_catch - || (edge_catch < 0 && !Lara_TestHangOnClimbWall(item, coll))) { - return 0; - } - - DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_HANG_ANGLE); - if (dir == DIR_UNKNOWN) { - return 0; - } - int16_t angle = Math_DirectionToAngle(dir); - - item->goal_anim_state = LS_HANG; - item->current_anim_state = LS_HANG; - item->anim_num = LA_REACH_TO_HANG; - item->frame_num = g_Anims[item->anim_num].frame_base + 12; - - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - if (edge_catch > 0) { - item->pos.y += coll->side_front.floor - bounds->min_y; - } else { - item->pos.y = edge - bounds->min_y; - } - item->pos.x += coll->shift.x; - item->pos.z += coll->shift.z; - item->rot.y = angle; - item->speed = 0; - item->gravity = 0; - item->fall_speed = 0; - g_Lara.gun_status = LGS_HANDS_BUSY; - return 1; -} - -int32_t __cdecl Lara_TestHangJump(ITEM_INFO *item, COLL_INFO *coll) -{ - if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) - || g_Lara.gun_status != LGS_ARMLESS || coll->hit_static - || coll->side_mid.ceiling > -STEPUP_HEIGHT - || coll->side_mid.floor < 200) { - return 0; - } - - int32_t edge; - int32_t edge_catch = Lara_TestEdgeCatch(item, coll, &edge); - if (!edge_catch - || (edge_catch < 0 && !Lara_TestHangOnClimbWall(item, coll))) { - return 0; - } - - DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_HANG_ANGLE); - if (dir == DIR_UNKNOWN) { - return 0; - } - int16_t angle = Math_DirectionToAngle(dir); - - if (Lara_TestHangSwingIn(item, angle)) { - item->anim_num = LA_REACH_TO_THIN_LEDGE; - item->frame_num = g_Anims[item->anim_num].frame_base; - } else { - item->anim_num = LA_REACH_TO_HANG; - item->frame_num = g_Anims[item->anim_num].frame_base; - } - item->current_anim_state = LS_HANG; - item->goal_anim_state = LS_HANG; - - const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); - if (edge_catch > 0) { - item->pos.y += coll->side_front.floor - bounds->min_y; - item->pos.x += coll->shift.x; - item->pos.z += coll->shift.z; - } else { - item->pos.y = edge - bounds->min_y; - } - - item->rot.y = angle; - item->speed = 2; - item->gravity = 1; - item->fall_speed = 1; - g_Lara.gun_status = LGS_HANDS_BUSY; - return 1; -} - -int32_t __cdecl Lara_TestHangSwingIn(ITEM_INFO *item, PHD_ANGLE angle) -{ - int32_t x = item->pos.x; - int32_t y = item->pos.y; - int32_t z = item->pos.z; - int16_t room_num = item->room_num; - switch (angle) { - case 0: - z += STEP_L; - break; - case PHD_90: - x += STEP_L; - break; - case -PHD_180: - z -= STEP_L; - break; - case -PHD_90: - x -= STEP_L; - break; - } - - const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); - int32_t height = Room_GetHeight(sector, x, y, z); - int32_t ceiling = Room_GetCeiling(sector, x, y, z); - return height != NO_HEIGHT && height - y > 0 && ceiling - y < -400; -} - -int32_t __cdecl Lara_TestVault(ITEM_INFO *item, COLL_INFO *coll) -{ - if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) - || g_Lara.gun_status != LGS_ARMLESS) { - return 0; - } - - DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_VAULT_ANGLE); - if (dir == DIR_UNKNOWN) { - return 0; - } - int16_t angle = Math_DirectionToAngle(dir); - - int32_t left_floor = coll->side_left.floor; - int32_t left_ceiling = coll->side_left.ceiling; - int32_t right_floor = coll->side_right.floor; - int32_t right_ceiling = coll->side_right.ceiling; - int32_t front_floor = coll->side_front.floor; - int32_t front_ceiling = coll->side_front.ceiling; - bool slope = ABS(left_floor - right_floor) >= SLOPE_DIF; - - int32_t mid = STEP_L / 2; - if (front_floor >= -STEP_L * 2 - mid && front_floor <= -STEP_L * 2 + mid) { - if (slope || front_floor - front_ceiling < 0 - || left_floor - left_ceiling < 0 - || right_floor - right_ceiling < 0) { - return 0; - } - item->goal_anim_state = LS_STOP; - item->current_anim_state = LS_NULL; - item->anim_num = LA_CLIMB_2CLICK; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->pos.y += front_floor + STEP_L * 2; - g_Lara.gun_status = LGS_HANDS_BUSY; - } else if ( - front_floor >= -STEP_L * 3 - mid && front_floor <= -STEP_L * 3 + mid) { - if (slope || front_floor - front_ceiling < 0 - || left_floor - left_ceiling < 0 - || right_floor - right_ceiling < 0) { - return 0; - } - item->goal_anim_state = LS_STOP; - item->current_anim_state = LS_NULL; - item->anim_num = LA_CLIMB_3CLICK; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->pos.y += front_floor + STEP_L * 3; - g_Lara.gun_status = LGS_HANDS_BUSY; - } else if ( - !slope && front_floor >= -STEP_L * 7 - mid - && front_floor <= -STEP_L * 4 + mid) { - item->goal_anim_state = LS_UP_JUMP; - item->current_anim_state = LS_STOP; - item->anim_num = LA_STAND_STILL; - item->frame_num = g_Anims[item->anim_num].frame_base; - g_Lara.calc_fallspeed = - -(Math_Sqrt(-2 * GRAVITY * (front_floor + 800)) + 3); - Lara_Animate(item); - } else if ( - g_Lara.climb_status && front_floor <= -1920 - && g_Lara.water_status != LWS_WADE && left_floor <= -STEP_L * 8 + mid - && right_floor <= -STEP_L * 8 - && coll->side_mid.ceiling <= -STEP_L * 8 + mid + LARA_HEIGHT) { - item->goal_anim_state = LS_UP_JUMP; - item->current_anim_state = LS_STOP; - item->anim_num = LA_STAND_STILL; - item->frame_num = g_Anims[item->anim_num].frame_base; - g_Lara.calc_fallspeed = -116; - Lara_Animate(item); - } else if ( - g_Lara.climb_status - && (front_floor < -STEP_L * 4 || front_ceiling >= LARA_HEIGHT - STEP_L) - && coll->side_mid.ceiling <= -STEP_L * 5 + LARA_HEIGHT) { - Item_ShiftCol(item, coll); - if (Lara_TestClimbStance(item, coll)) { - item->goal_anim_state = LS_CLIMB_STANCE; - item->current_anim_state = LS_STOP; - item->anim_num = LA_STAND_STILL; - item->frame_num = g_Anims[item->anim_num].frame_base; - Lara_Animate(item); - item->rot.y = angle; - g_Lara.gun_status = LGS_HANDS_BUSY; - return 1; - } - return 0; - } else { - return 0; - } - - item->rot.y = angle; - Item_ShiftCol(item, coll); - return 1; -} - -int32_t __cdecl Lara_TestSlide(ITEM_INFO *item, COLL_INFO *coll) -{ - if (ABS(coll->x_tilt) <= 2 && ABS(coll->z_tilt) <= 2) { - return 0; - } - - int16_t angle = 0; - if (coll->x_tilt > 2) { - angle = -PHD_90; - } else if (coll->x_tilt < -2) { - angle = PHD_90; - } - - if (coll->z_tilt > 2 && coll->z_tilt > ABS(coll->x_tilt)) { - angle = PHD_180; - } else if (coll->z_tilt < -2 && -coll->z_tilt > ABS(coll->x_tilt)) { - angle = 0; - } - - const int16_t angle_dif = angle - item->rot.y; - Item_ShiftCol(item, coll); - - if (angle_dif >= -PHD_90 && angle_dif <= PHD_90) { - if (item->current_anim_state == LS_SLIDE - && g_LaraOldSlideAngle == angle) { - return 1; - } - item->goal_anim_state = LS_SLIDE; - item->current_anim_state = LS_SLIDE; - item->anim_num = LA_SLIDE_FORWARD; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->rot.y = angle; - } else { - if (item->current_anim_state == LS_SLIDE_BACK - && g_LaraOldSlideAngle == angle) { - return 1; - } - item->goal_anim_state = LS_SLIDE_BACK; - item->current_anim_state = LS_SLIDE_BACK; - item->anim_num = LA_SLIDE_BACKWARD_START; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->rot.y = angle + PHD_180; - } - - g_Lara.move_angle = angle; - g_LaraOldSlideAngle = angle; - return 1; -} - -int16_t __cdecl Lara_FloorFront(ITEM_INFO *item, int16_t ang, int32_t dist) -{ - const int32_t x = item->pos.x + ((dist * Math_Sin(ang)) >> W2V_SHIFT); - const int32_t y = item->pos.y - LARA_HEIGHT; - const int32_t z = item->pos.z + ((dist * Math_Cos(ang)) >> W2V_SHIFT); - int16_t room_num = item->room_num; - const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); - int32_t height = Room_GetHeight(sector, x, y, z); - if (height != NO_HEIGHT) { - height -= item->pos.y; - } - return height; -} - -int32_t __cdecl Lara_LandedBad(ITEM_INFO *item, COLL_INFO *coll) -{ - const int32_t x = item->pos.x; - const int32_t y = item->pos.y; - const int32_t z = item->pos.z; - - int16_t room_num = item->room_num; - const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); - const int32_t height = Room_GetHeight(sector, x, y - LARA_HEIGHT, z); - item->pos.y = height; - item->floor = height; - - Room_TestTriggers(g_TriggerIndex, 0); - int32_t land_speed = item->fall_speed - DAMAGE_START; - item->pos.y = y; - if (land_speed <= 0) { - return 0; - } - if (land_speed <= DAMAGE_LENGTH) { - item->hit_points += -LARA_MAX_HITPOINTS * land_speed * land_speed - / (DAMAGE_LENGTH * DAMAGE_LENGTH); - } else { - item->hit_points = -1; - } - return item->hit_points <= 0; -} - -int32_t __cdecl Lara_CheckForLetGo(ITEM_INFO *item, COLL_INFO *coll) -{ - item->gravity = 0; - item->fall_speed = 0; - - int16_t room_num = item->room_num; - int32_t x = item->pos.x; - int32_t y = item->pos.y; - int32_t z = item->pos.z; - const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); - Room_GetHeight(sector, x, y, z); - coll->trigger = g_TriggerIndex; - if ((g_Input & IN_ACTION) && item->hit_points > 0) { - return 0; - } - - item->goal_anim_state = LS_FORWARD_JUMP; - item->current_anim_state = LS_FORWARD_JUMP; - item->anim_num = LA_FALL_START; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->gravity = 1; - item->speed = 2; - item->fall_speed = 1; - g_Lara.gun_status = LGS_ARMLESS; - return 1; -} - -void __cdecl Lara_GetJointAbsPosition(XYZ_32 *vec, int32_t joint) -{ - FRAME_INFO *frmptr[2] = { NULL, NULL }; - if (g_Lara.hit_direction < 0) { - int32_t rate; - int32_t frac = Item_GetFrames(g_LaraItem, frmptr, &rate); - if (frac) { - Lara_GetJointAbsPosition_I( - g_LaraItem, vec, frmptr[0], frmptr[1], frac, rate); - return; - } - } - - const FRAME_INFO *frame_ptr = NULL; - const OBJECT_INFO *obj = &g_Objects[g_LaraItem->object_id]; - if (g_Lara.hit_direction >= 0) { - LARA_ANIMATION anim_num; - switch (g_Lara.hit_direction) { - case DIR_EAST: - anim_num = LA_HIT_RIGHT; - break; - case DIR_SOUTH: - anim_num = LA_HIT_BACK; - break; - case DIR_WEST: - anim_num = LA_HIT_LEFT; - break; - default: - anim_num = LA_HIT_FRONT; - break; - } - const ANIM_STRUCT *anim = &g_Anims[anim_num]; - int32_t interpolation = anim->interpolation; - frame_ptr = (const FRAME_INFO *)(anim->frame_ptr - + (int32_t)(g_Lara.hit_frame - * (interpolation >> 8))); - } else { - frame_ptr = frmptr[0]; - } - - Matrix_PushUnit(); - g_MatrixPtr->_03 = 0; - g_MatrixPtr->_13 = 0; - g_MatrixPtr->_23 = 0; - Matrix_RotYXZ(g_LaraItem->rot.y, g_LaraItem->rot.x, g_LaraItem->rot.z); - - const int16_t *rot = frame_ptr->mesh_rots; - const int32_t *bone = &g_AnimBones[obj->bone_idx]; - - Matrix_TranslateRel( - frame_ptr->offset.x, frame_ptr->offset.y, frame_ptr->offset.z); - Matrix_RotYXZsuperpack(&rot, 0); - - Matrix_TranslateRel(bone[25], bone[26], bone[27]); - Matrix_RotYXZsuperpack(&rot, 6); - Matrix_RotYXZ(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); - - LARA_GUN_TYPE gun_type = LGT_UNARMED; - if (g_Lara.gun_status == LGS_READY || g_Lara.gun_status == LGS_SPECIAL - || g_Lara.gun_status == LGS_DRAW || g_Lara.gun_status == LGS_UNDRAW) { - gun_type = g_Lara.gun_type; - } - - if (g_Lara.gun_type == LGT_FLARE) { - Matrix_TranslateRel(bone[41], bone[42], bone[43]); - if (g_Lara.flare_control_left) { - const LARA_ARM *arm = &g_Lara.left_arm; - const ANIM_STRUCT *anim = &g_Anims[arm->anim_num]; - rot = &arm->frame_base - [(anim->interpolation >> 8) - * (arm->frame_num - anim->frame_base) - + FBBOX_ROT]; - } else { - rot = frame_ptr->mesh_rots; - } - Matrix_RotYXZsuperpack(&rot, 11); - - Matrix_TranslateRel(bone[45], bone[46], bone[47]); - Matrix_RotYXZsuperpack(&rot, 0); - - Matrix_TranslateRel(bone[49], bone[50], bone[51]); - Matrix_RotYXZsuperpack(&rot, 0); - } else if (gun_type != LGT_UNARMED) { - Matrix_TranslateRel(bone[29], bone[30], bone[31]); - - const LARA_ARM *arm = &g_Lara.right_arm; - const ANIM_STRUCT *anim = &g_Anims[arm->anim_num]; - rot = &arm->frame_base - [arm->frame_num * (anim->interpolation >> 8) + FBBOX_ROT]; - Matrix_RotYXZsuperpack(&rot, 8); - - Matrix_TranslateRel(bone[33], bone[34], bone[35]); - Matrix_RotYXZsuperpack(&rot, 0); - - Matrix_TranslateRel(bone[37], bone[38], bone[39]); - Matrix_RotYXZsuperpack(&rot, 0); - } - - Matrix_TranslateRel(vec->x, vec->y, vec->z); - vec->x = g_LaraItem->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT); - vec->y = g_LaraItem->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT); - vec->z = g_LaraItem->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT); - Matrix_Pop(); -} - -void __cdecl Lara_GetJointAbsPosition_I( - ITEM_INFO *item, XYZ_32 *vec, FRAME_INFO *frame1, FRAME_INFO *frame2, - int32_t frac, int32_t rate) -{ - const OBJECT_INFO *obj = &g_Objects[item->object_id]; - - Matrix_PushUnit(); - g_MatrixPtr->_03 = 0; - g_MatrixPtr->_13 = 0; - g_MatrixPtr->_23 = 0; - Matrix_RotYXZ(item->rot.y, item->rot.x, item->rot.z); - - const int32_t *const bone = &g_AnimBones[obj->bone_idx]; - const int16_t *rot1 = frame1->mesh_rots; - const int16_t *rot2 = frame2->mesh_rots; - Matrix_InitInterpolate(frac, rate); - - Matrix_TranslateRel_ID( - frame1->offset.x, frame1->offset.y, frame1->offset.z, frame2->offset.x, - frame2->offset.y, frame2->offset.z); - Matrix_RotYXZsuperpack_I(&rot1, &rot2, 0); - - Matrix_TranslateRel_I(bone[25], bone[26], bone[27]); - Matrix_RotYXZsuperpack_I(&rot1, &rot2, 6); - Matrix_RotYXZ_I(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); - - LARA_GUN_TYPE gun_type = LGT_UNARMED; - if (g_Lara.gun_status == LGS_READY || g_Lara.gun_status == LGS_SPECIAL - || g_Lara.gun_status == LGS_DRAW || g_Lara.gun_status == LGS_UNDRAW) { - gun_type = g_Lara.gun_type; - } - - if (g_Lara.gun_type == LGT_FLARE) { - Matrix_Interpolate(); - Matrix_TranslateRel(bone[29], bone[30], bone[31]); - if (g_Lara.flare_control_left) { - const LARA_ARM *arm = &g_Lara.left_arm; - const ANIM_STRUCT *anim = &g_Anims[arm->anim_num]; - rot1 = &arm->frame_base - [(anim->interpolation >> 8) - * (arm->frame_num - anim->frame_base) - + FBBOX_ROT]; - } else { - rot1 = frame1->mesh_rots; - } - Matrix_RotYXZsuperpack(&rot1, 11); - - Matrix_TranslateRel(bone[45], bone[46], bone[47]); - Matrix_RotYXZsuperpack(&rot1, 0); - - Matrix_TranslateRel(bone[49], bone[50], bone[51]); - Matrix_RotYXZsuperpack(&rot1, 0); - } else if (gun_type != LGT_UNARMED) { - Matrix_Interpolate(); - Matrix_TranslateRel(bone[29], bone[30], bone[31]); - - const LARA_ARM *arm = &g_Lara.right_arm; - const ANIM_STRUCT *anim = &g_Anims[arm->anim_num]; - rot1 = &arm->frame_base - [arm->frame_num * (anim->interpolation >> 8) + FBBOX_ROT]; - Matrix_RotYXZsuperpack(&rot1, 8); - - Matrix_TranslateRel(bone[33], bone[34], bone[35]); - Matrix_RotYXZsuperpack(&rot1, 0); - - Matrix_TranslateRel(bone[37], bone[38], bone[39]); - Matrix_RotYXZsuperpack(&rot1, 0); - } - - Matrix_TranslateRel(vec->x, vec->y, vec->z); - vec->x = item->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT); - vec->y = item->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT); - vec->z = item->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT); - - Matrix_Pop(); -} - -void __cdecl Lara_TakeHit( - ITEM_INFO *const lara_item, const COLL_INFO *const coll) -{ - const int32_t dx = g_Lara.spaz_effect->pos.x - lara_item->pos.x; - const int32_t dz = g_Lara.spaz_effect->pos.z - lara_item->pos.z; - M_TakeHit(lara_item, dx, dz); - g_Lara.spaz_effect_count--; -} - -void __cdecl Lara_BaddieCollision(ITEM_INFO *lara_item, COLL_INFO *coll) -{ - lara_item->hit_status = 0; - g_Lara.hit_direction = -1; - if (lara_item->hit_points <= 0) { - return; - } - - int16_t roomies[MAX_BADDIE_COLLISION] = { 0 }; - int32_t roomies_count = 0; - - roomies[roomies_count++] = lara_item->room_num; - - DOOR_INFOS *doors = g_Rooms[roomies[0]].doors; - if (doors != NULL) { - for (int32_t i = 0; i < doors->count; i++) { - if (roomies_count >= MAX_BADDIE_COLLISION) { - break; - } - roomies[roomies_count++] = doors->door[i].room; - } - } - - for (int32_t i = 0; i < roomies_count; i++) { - int16_t item_num = g_Rooms[roomies[i]].item_num; - while (item_num != NO_ITEM) { - const ITEM_INFO *const item = &g_Items[item_num]; - - // the collision routine can destroy the item - need to store the - // next item beforehand - const int16_t next_item_num = item->next_item; - - if (item->collidable && item->status != IS_INVISIBLE) { - const OBJECT_INFO *const object = &g_Objects[item->object_id]; - if (object->collision) { - // clang-format off - const XYZ_32 d = { - .x = lara_item->pos.x - item->pos.x, - .y = lara_item->pos.y - item->pos.y, - .z = lara_item->pos.z - item->pos.z, - }; - if (d.x > -TARGET_DIST && d.x < TARGET_DIST && - d.y > -TARGET_DIST && d.y < TARGET_DIST && - d.z > -TARGET_DIST && d.z < TARGET_DIST) { - object->collision(item_num, lara_item, coll); - } - // clang-format on - } - } - - item_num = next_item_num; - } - } - - if (g_Lara.spaz_effect_count) { - Lara_TakeHit(lara_item, coll); - } - - if (g_Lara.hit_direction == -1) { - g_Lara.hit_frame = 0; - } - - g_Inv_Chosen = -1; -} - -void __cdecl Lara_Push( - const ITEM_INFO *const item, ITEM_INFO *const lara_item, - COLL_INFO *const coll, const bool spaz_on, const bool big_push) -{ - int32_t dx = lara_item->pos.x - item->pos.x; - int32_t dz = lara_item->pos.z - item->pos.z; - const int32_t c = Math_Cos(item->rot.y); - const int32_t s = Math_Sin(item->rot.y); - int32_t rx = (c * dx - s * dz) >> W2V_SHIFT; - int32_t rz = (c * dz + s * dx) >> W2V_SHIFT; - - const BOUNDS_16 *const bounds = &Item_GetBestFrame(item)->bounds; - int32_t min_x = bounds->min_x; - int32_t max_x = bounds->max_x; - int32_t min_z = bounds->min_z; - int32_t max_z = bounds->max_z; - - if (big_push) { - max_x += coll->radius; - min_z -= coll->radius; - max_z += coll->radius; - min_x -= coll->radius; - } - - if (rx < min_x || rx > max_x || rz < min_z || rz > max_z) { - return; - } - - int32_t l = rx - min_x; - int32_t r = max_x - rx; - int32_t t = max_z - rz; - int32_t b = rz - min_z; - - if (l <= r && l <= t && l <= b) { - rx -= l; - } else if (r <= l && r <= t && r <= b) { - rx += r; - } else if (t <= l && t <= r && t <= b) { - rz += t; - } else { - rz = min_z; - } - - lara_item->pos.x = item->pos.x + ((rz * s + rx * c) >> W2V_SHIFT); - lara_item->pos.z = item->pos.z + ((rz * c - rx * s) >> W2V_SHIFT); - - rz = (bounds->max_z + bounds->min_z) / 2; - rx = (bounds->max_x + bounds->min_x) / 2; - dx -= (c * rx + s * rz) >> W2V_SHIFT; - dz -= (c * rz - s * rx) >> W2V_SHIFT; - - if (spaz_on && bounds->max_y - bounds->min_y > STEP_L) { - M_TakeHit(lara_item, dx, dz); - } - - int16_t old_facing = coll->facing; - coll->bad_pos = NO_BAD_POS; - coll->bad_neg = -STEPUP_HEIGHT; - coll->bad_ceiling = 0; - coll->facing = Math_Atan( - lara_item->pos.z - coll->old.z, lara_item->pos.x - coll->old.x); - Collide_GetCollisionInfo( - coll, lara_item->pos.x, lara_item->pos.y, lara_item->pos.z, - lara_item->room_num, LARA_HEIGHT); - coll->facing = old_facing; - - if (coll->coll_type != COLL_NONE) { - lara_item->pos.x = coll->old.x; - lara_item->pos.z = coll->old.z; - } else { - coll->old.x = lara_item->pos.x; - coll->old.y = lara_item->pos.y; - coll->old.z = lara_item->pos.z; - Item_UpdateRoom(lara_item, -WALL_SHIFT); - } -} - -int32_t __cdecl Lara_MovePosition( - XYZ_32 *vec, ITEM_INFO *item, ITEM_INFO *lara_item) -{ - const XYZ_16 rot = { - .x = item->rot.x, - .y = item->rot.y, - .z = item->rot.z, - }; - - Matrix_PushUnit(); - Matrix_RotYXZ(rot.y, rot.x, rot.z); - const MATRIX *const m = g_MatrixPtr; - const XYZ_32 shift = { - .x = (vec->y * m->_01 + vec->z * m->_02 + vec->x * m->_00) >> W2V_SHIFT, - .y = (vec->x * m->_10 + vec->z * m->_12 + vec->y * m->_11) >> W2V_SHIFT, - .z = (vec->y * m->_21 + vec->x * m->_20 + vec->z * m->_22) >> W2V_SHIFT, - }; - Matrix_Pop(); - - const XYZ_32 new_pos = { - .x = item->pos.x + shift.x, - .y = item->pos.y + shift.y, - .z = item->pos.z + shift.z, - }; - - if (item->object_id == O_FLARE_ITEM) { - int16_t room_num = lara_item->room_num; - const SECTOR_INFO *const sector = - Room_GetSector(new_pos.x, new_pos.y, new_pos.z, &room_num); - const int32_t height = - Room_GetHeight(sector, new_pos.x, new_pos.y, new_pos.z); - if (ABS(height - lara_item->pos.y) > STEP_L * 2) { - return false; - } - if (XYZ_32_GetDistance(&new_pos, &lara_item->pos) < STEP_L) { - return true; - } - } - - // TODO: get rid of this conversion - const PHD_3DPOS new_pos_full = { - .pos = new_pos, - .rot = rot, - }; - PHD_3DPOS src_pos = { - .pos = lara_item->pos, - .rot = lara_item->rot, - }; - const int32_t result = - Misc_Move3DPosTo3DPos(&src_pos, &new_pos_full, MOVE_SPEED, MOVE_ANGLE); - lara_item->pos = src_pos.pos; - lara_item->rot = src_pos.rot; - return result; -} - -int32_t __cdecl Lara_IsNearItem(const XYZ_32 *const pos, const int32_t distance) -{ - return Item_IsNearItem(g_LaraItem, pos, distance); -} - -int32_t __cdecl Lara_TestClimb( - const int32_t x, const int32_t y, const int32_t z, const int32_t x_front, - const int32_t z_front, const int32_t item_height, const int16_t item_room, - int32_t *const shift) -{ - *shift = 0; - bool hang = true; - if (!g_Lara.climb_status) { - return 0; - } - - const SECTOR_INFO *sector; - int32_t height; - int32_t ceiling; - - int16_t room_num = item_room; - sector = Room_GetSector(x, y - 128, z, &room_num); - height = Room_GetHeight(sector, x, y, z); - if (height == NO_HEIGHT) { - return 0; - } - - height -= y + item_height + STEP_L / 2; - if (height < -CLIMB_SHIFT) { - return 0; - } - if (height < 0) { - *shift = height; - } - - ceiling = Room_GetCeiling(sector, x, y, z) - y; - if (ceiling > CLIMB_SHIFT) { - return 0; - } - if (ceiling > 0) { - if (*shift) { - return 0; - } - *shift = ceiling; - } - - if (item_height + height < CLIMB_HANG) { - hang = false; - } - - const int32_t x2 = x + x_front; - const int32_t z2 = z + z_front; - sector = Room_GetSector(x2, y, z2, &room_num); - height = Room_GetHeight(sector, x2, y, z2); - if (height != NO_HEIGHT) { - height -= y; - } - - if (height > CLIMB_SHIFT) { - ceiling = Room_GetCeiling(sector, x2, y, z2) - y; - if (ceiling >= LARA_CLIMB_HEIGHT) { - return 1; - } - - if (ceiling > LARA_CLIMB_HEIGHT - CLIMB_SHIFT) { - if (*shift > 0) { - return hang ? -1 : 0; - } - *shift = ceiling - LARA_CLIMB_HEIGHT; - return 1; - } - - if (ceiling > 0) { - return hang ? -1 : 0; - } - - if (ceiling > -CLIMB_SHIFT && hang && *shift <= 0) { - if (*shift > ceiling) { - *shift = ceiling; - } - - return -1; - } - - return 0; - } - - if (height > 0) { - if (*shift < 0) { - return 0; - } - if (height > *shift) { - *shift = height; - } - } - - room_num = item_room; - sector = Room_GetSector(x, item_height + y, z, &room_num); - sector = Room_GetSector(x2, item_height + y, z2, &room_num); - ceiling = Room_GetCeiling(sector, x2, item_height + y, z2); - if (ceiling == NO_HEIGHT) { - return 1; - } - - ceiling -= y; - if (ceiling <= height) { - return 1; - } - - if (ceiling >= LARA_CLIMB_HEIGHT) { - return 1; - } - - if (ceiling > LARA_CLIMB_HEIGHT - CLIMB_SHIFT) { - if (*shift > 0) { - return hang ? -1 : 0; - } - *shift = ceiling - LARA_CLIMB_HEIGHT; - return 1; - } - - return hang ? -1 : 0; -} - -int32_t __cdecl Lara_TestClimbPos( - const ITEM_INFO *const item, const int32_t front, const int32_t right, - const int32_t origin, const int32_t height, int32_t *const shift) -{ - const int32_t y = item->pos.y + origin; - int32_t x; - int32_t z; - int32_t x_front = 0; - int32_t z_front = 0; - - switch (Math_GetDirection(item->rot.y)) { - case DIR_NORTH: - x = item->pos.x + right; - z = item->pos.z + front; - z_front = 2; - break; - - case DIR_EAST: - x = item->pos.x + front; - z = item->pos.z - right; - x_front = 2; - break; - - case DIR_SOUTH: - x = item->pos.x - right; - z = item->pos.z - front; - z_front = -2; - break; - - case DIR_WEST: - x = item->pos.x - front; - z = item->pos.z + right; - x_front = -2; - break; - - default: - x = front; - z = front; - break; - } - - return Lara_TestClimb( - x, y, z, x_front, z_front, height, item->room_num, shift); -} - -void __cdecl Lara_DoClimbLeftRight( - ITEM_INFO *const item, const COLL_INFO *const coll, const int32_t result, - const int32_t shift) -{ - if (result == 1) { - if (g_Input & IN_LEFT) { - item->goal_anim_state = LS_CLIMB_LEFT; - } else if (g_Input & IN_RIGHT) { - item->goal_anim_state = LS_CLIMB_RIGHT; - } else { - item->goal_anim_state = LS_CLIMB_STANCE; - } - item->pos.y += shift; - return; - } - - if (result) { - item->goal_anim_state = LS_HANG; - do { - Item_Animate(item); - } while (item->current_anim_state != LS_HANG); - item->pos.x = coll->old.x; - item->pos.z = coll->old.z; - return; - } - - item->pos.x = coll->old.x; - item->pos.z = coll->old.z; - item->goal_anim_state = LS_CLIMB_STANCE; - item->current_anim_state = LS_CLIMB_STANCE; - if (coll->old_anim_state == LS_CLIMB_STANCE) { - item->frame_num = coll->old_frame_num; - item->anim_num = coll->old_anim_num; - Lara_Animate(item); - } else { - item->anim_num = LA_LADDER_IDLE; - item->frame_num = g_Anims[item->anim_num].frame_base; - } -} - -int32_t __cdecl Lara_TestClimbUpPos( - const ITEM_INFO *const item, const int32_t front, const int32_t right, - int32_t *const shift, int32_t *const ledge) -{ - const int32_t y = item->pos.y - LARA_CLIMB_HEIGHT - STEP_L; - int32_t x; - int32_t z; - int32_t x_front = 0; - int32_t z_front = 0; - - switch (Math_GetDirection(item->rot.y)) { - case DIR_NORTH: - x = item->pos.x + right; - z = item->pos.z + front; - z_front = 2; - break; - - case DIR_EAST: - x = item->pos.x + front; - z = item->pos.z - right; - x_front = 2; - break; - - case DIR_SOUTH: - x = item->pos.x - right; - z = item->pos.z - front; - z_front = -2; - break; - - case DIR_WEST: - z = item->pos.z + right; - x = item->pos.x - front; - x_front = -2; - break; - - default: - x = front; - z = front; - break; - } - - *shift = 0; - - const SECTOR_INFO *sector; - int32_t height; - int32_t ceiling; - - int16_t room_num = item->room_num; - sector = Room_GetSector(x, y, z, &room_num); - ceiling = Room_GetCeiling(sector, x, y, z) + STEP_L - y; - if (ceiling > CLIMB_SHIFT) { - return 0; - } - - if (ceiling > 0) { - *shift = ceiling; - } - - const int32_t x2 = x + x_front; - const int32_t z2 = z + z_front; - sector = Room_GetSector(x2, y, z2, &room_num); - height = Room_GetHeight(sector, x2, y, z2); - if (height == NO_HEIGHT) { - *ledge = NO_HEIGHT; - return 1; - } - - height -= y; - *ledge = height; - if (height > STEP_L / 2) { - ceiling = Room_GetCeiling(sector, x2, y, z2) - y; - if (ceiling >= LARA_CLIMB_HEIGHT) { - return 1; - } - - if (height - ceiling > LARA_HEIGHT) { - *shift = height; - return -1; - } - - return 0; - } - - if (height > 0 && height > *shift) { - *shift = height; - } - - room_num = item->room_num; - sector = Room_GetSector(x, y + LARA_CLIMB_HEIGHT, z, &room_num); - sector = Room_GetSector(x2, y + LARA_CLIMB_HEIGHT, z2, &room_num); - ceiling = Room_GetCeiling(sector, x2, y + LARA_CLIMB_HEIGHT, z2) - y; - if (ceiling <= height) { - return 1; - } - - if (ceiling >= LARA_CLIMB_HEIGHT) { - return 1; - } - return 0; -} - -int32_t __cdecl Lara_GetWaterDepth( - const int32_t x, const int32_t y, const int32_t z, int16_t room_num) -{ - const ROOM_INFO *r = &g_Rooms[room_num]; - const SECTOR_INFO *sector; - - while (true) { - int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; - int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; - - if (z_sector <= 0) { - z_sector = 0; - if (x_sector < 1) { - x_sector = 1; - } else if (x_sector > r->x_size - 2) { - x_sector = r->x_size - 2; - } - } else if (z_sector >= r->z_size - 1) { - z_sector = r->z_size - 1; - if (x_sector < 1) { - x_sector = 1; - } else if (x_sector > r->x_size - 2) { - x_sector = r->x_size - 2; - } - } else if (x_sector < 0) { - x_sector = 0; - } else if (x_sector >= r->x_size) { - x_sector = r->x_size - 1; - } - - sector = &r->sector[z_sector + x_sector * r->z_size]; - const int16_t data = Room_GetDoor(sector); - if (data == NO_ROOM) { - break; - } - room_num = data; - r = &g_Rooms[room_num]; - } - - if (r->flags & RF_UNDERWATER) { - while (sector->sky_room != NO_ROOM) { - r = &g_Rooms[sector->sky_room]; - if (!(r->flags & RF_UNDERWATER)) { - const int32_t water_height = sector->ceiling << 8; - sector = Room_GetSector(x, y, z, &room_num); - return Room_GetHeight(sector, x, y, z) - water_height; - } - const int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; - const int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; - sector = &r->sector[z_sector + x_sector * r->z_size]; - } - return 0x7FFF; - } - - while (sector->pit_room != NO_ROOM) { - r = &g_Rooms[sector->pit_room]; - if (r->flags & RF_UNDERWATER) { - const int32_t water_height = sector->floor << 8; - sector = Room_GetSector(x, y, z, &room_num); - return Room_GetHeight(sector, x, y, z) - water_height; - } - const int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; - const int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; - sector = &r->sector[z_sector + x_sector * r->z_size]; - } - return NO_HEIGHT; -} - -void __cdecl Lara_TestWaterDepth( - ITEM_INFO *const item, const COLL_INFO *const coll) -{ - int16_t room_num = item->room_num; - - const SECTOR_INFO *const sector = - Room_GetSector(item->pos.x, item->pos.y, item->pos.z, &room_num); - const int32_t water_depth = - Lara_GetWaterDepth(item->pos.x, item->pos.y, item->pos.z, room_num); - - if (water_depth == NO_HEIGHT) { - item->pos = coll->old; - item->fall_speed = 0; - } else if (water_depth <= STEP_L * 2) { - item->anim_num = LA_UNDERWATER_TO_STAND; - item->frame_num = g_Anims[item->anim_num].frame_base; - item->current_anim_state = LS_WATER_OUT; - item->goal_anim_state = LS_STOP; - item->rot.x = 0; - item->rot.z = 0; - item->gravity = 0; - item->speed = 0; - item->fall_speed = 0; - g_Lara.water_status = LWS_WADE; - item->pos.y = - Room_GetHeight(sector, item->pos.x, item->pos.y, item->pos.z); - } -} - -void __cdecl Lara_SwimCollision(ITEM_INFO *const item, COLL_INFO *const coll) -{ - if (item->rot.x < -PHD_90 || item->rot.x > PHD_90) { - g_Lara.move_angle = item->rot.y + PHD_180; - } else { - g_Lara.move_angle = item->rot.y; - } - - coll->facing = g_Lara.move_angle; - - int32_t height = (LARA_HEIGHT * Math_Sin(item->rot.x)) >> W2V_SHIFT; - if (height < 0) { - height = -height; - } - CLAMPL(height, 200); - - coll->bad_neg = -height; - Collide_GetCollisionInfo( - coll, item->pos.x, item->pos.y + height / 2, item->pos.z, - item->room_num, height); - Item_ShiftCol(item, coll); - - switch (coll->coll_type) { - case COLL_FRONT: - if (item->rot.x > 35 * PHD_DEGREE) { - item->rot.x += LARA_UW_WALL_DEFLECT; - } else if (item->rot.x < -35 * PHD_DEGREE) { - item->rot.x -= LARA_UW_WALL_DEFLECT; - } else { - item->fall_speed = 0; - } - break; - - case COLL_TOP: - if (item->rot.x >= -45 * PHD_DEGREE) { - item->rot.x -= LARA_UW_WALL_DEFLECT; - } - break; - - case COLL_TOP_FRONT: - item->fall_speed = 0; - break; - - case COLL_LEFT: - item->rot.y += 5 * PHD_DEGREE; - break; - - case COLL_RIGHT: - item->rot.y -= 5 * PHD_DEGREE; - break; - - case COLL_CLAMP: - item->pos = coll->old; - item->fall_speed = 0; - return; - } - - if (coll->side_mid.floor < 0) { - item->rot.x += LARA_UW_WALL_DEFLECT; - item->pos.y = coll->side_mid.floor + item->pos.y; - } - - if (g_Lara.water_status != LWS_CHEAT && !g_Lara.extra_anim) { - Lara_TestWaterDepth(item, coll); - } -} - -void __cdecl Lara_WaterCurrent(COLL_INFO *const coll) -{ - ITEM_INFO *const item = g_LaraItem; - - int16_t room_num = g_LaraItem->room_num; - const ROOM_INFO *const r = &g_Rooms[g_LaraItem->room_num]; - const int32_t z_sector = (g_LaraItem->pos.z - r->pos.z) >> WALL_SHIFT; - const int32_t x_sector = (g_LaraItem->pos.x - r->pos.x) >> WALL_SHIFT; - g_LaraItem->box_num = r->sector[z_sector + x_sector * r->z_size].box; - - if (g_Lara.creature == NULL) { - g_Lara.current_active = 0; - return; - } - - XYZ_32 target; - if (Box_CalculateTarget(&target, item, &g_Lara.creature->lot) - == TARGET_NONE) { - return; - } - - target.x -= item->pos.x; - if (target.x > g_Lara.current_active) { - item->pos.x += g_Lara.current_active; - } else if (target.x < -g_Lara.current_active) { - item->pos.x -= g_Lara.current_active; - } else { - item->pos.x += target.x; - } - - target.z -= item->pos.z; - if (target.z > g_Lara.current_active) { - item->pos.z += g_Lara.current_active; - } else if (target.z < -g_Lara.current_active) { - item->pos.z -= g_Lara.current_active; - } else { - item->pos.z += target.z; - } - - target.y = target.y - item->pos.y; - if (target.y > g_Lara.current_active) { - item->pos.y += g_Lara.current_active; - } else if (target.y < -g_Lara.current_active) { - item->pos.y -= g_Lara.current_active; - } else { - item->pos.y += target.y; - } - - g_Lara.current_active = 0; - coll->facing = - Math_Atan(item->pos.z - coll->old.z, item->pos.x - coll->old.x); - Collide_GetCollisionInfo( - coll, item->pos.x, item->pos.y + LARA_HEIGHT_UW / 2, item->pos.z, - room_num, LARA_HEIGHT_UW); - - switch (coll->coll_type) { - case COLL_FRONT: - if (item->rot.x > 35 * PHD_DEGREE) { - item->rot.x = item->rot.x + LARA_UW_WALL_DEFLECT; - } else if (item->rot.x < -35 * PHD_DEGREE) { - item->rot.x = item->rot.x - LARA_UW_WALL_DEFLECT; - } else { - item->fall_speed = 0; - } - break; - - case COLL_TOP: - item->rot.x -= LARA_UW_WALL_DEFLECT; - break; - - case COLL_TOP_FRONT: - item->fall_speed = 0; - break; - - case COLL_LEFT: - item->rot.y += 910; - break; - - case COLL_RIGHT: - item->rot.y -= 910; - break; - - default: - break; - } - - if (coll->side_mid.floor < 0) { - item->pos.y += coll->side_mid.floor; - item->rot.x += LARA_UW_WALL_DEFLECT; - } - Item_ShiftCol(item, coll); - - coll->old = item->pos; -} - -void __cdecl Lara_CatchFire(void) -{ - if (g_Lara.burn || g_Lara.water_status == LWS_CHEAT) { - return; - } - - const int16_t fx_num = Effect_Create(g_LaraItem->room_num); - if (fx_num == NO_ITEM) { - return; - } - - FX_INFO *const fx = &g_Effects[fx_num]; - fx->frame_num = 0; - fx->object_id = O_FLAME; - fx->counter = -1; - g_Lara.burn = 1; -} - -void __cdecl Lara_TouchLava(ITEM_INFO *const item) -{ - if (item->hit_points < 0 || g_Lara.water_status == LWS_CHEAT) { - return; - } - - int16_t room_num = item->room_num; - const SECTOR_INFO *const sector = - Room_GetSector(item->pos.x, MAX_HEIGHT, item->pos.z, &room_num); - const int32_t height = - Room_GetHeight(sector, item->pos.x, MAX_HEIGHT, item->pos.z); - if (item->floor != height) { - return; - } - - item->hit_points = -1; - item->hit_status = 1; - - for (int32_t i = 0; i < 10; i++) { - const int16_t fx_num = Effect_Create(item->room_num); - if (fx_num != NO_ITEM) { - FX_INFO *const fx = &g_Effects[fx_num]; - fx->object_id = O_FLAME; - fx->frame_num = - g_Objects[O_FLAME].mesh_count * Random_GetControl() / 0x7FFF; - fx->counter = -1 - 24 * Random_GetControl() / 0x7FFF; - } - } -} diff --git a/src/game/lara/lara_look.c b/src/game/lara/look.c similarity index 98% rename from src/game/lara/lara_look.c rename to src/game/lara/look.c index 3189a045..8ad48d11 100644 --- a/src/game/lara/lara_look.c +++ b/src/game/lara/look.c @@ -1,4 +1,4 @@ -#include "game/lara/lara_look.h" +#include "game/lara/look.h" #include "game/input.h" #include "global/const.h" diff --git a/src/game/lara/lara_look.h b/src/game/lara/look.h similarity index 100% rename from src/game/lara/lara_look.h rename to src/game/lara/look.h diff --git a/src/game/lara/misc.c b/src/game/lara/misc.c index 4ff1e0c7..677d99d3 100644 --- a/src/game/lara/misc.c +++ b/src/game/lara/misc.c @@ -1,7 +1,1856 @@ +#include "game/lara/misc.h" + +#include "decomp/decomp.h" +#include "game/box.h" +#include "game/collide.h" #include "game/effects.h" +#include "game/input.h" +#include "game/items.h" +#include "game/lara/control.h" +#include "game/math.h" +#include "game/matrix.h" +#include "game/random.h" +#include "game/room.h" +#include "game/sound.h" +#include "global/const.h" +#include "global/funcs.h" #include "global/vars.h" #include +#include +#include + +#define MAX_BADDIE_COLLISION 20 +#define MOVE_SPEED 16 +#define MOVE_ANGLE (2 * PHD_DEGREE) // = 364 +#define CLIMB_HANG 900 +#define CLIMB_SHIFT 70 + +static void __cdecl M_TakeHit( + ITEM_INFO *const lara_item, const int32_t dx, const int32_t dz); + +static void __cdecl M_TakeHit( + ITEM_INFO *const lara_item, const int32_t dx, const int32_t dz) +{ + const PHD_ANGLE hit_angle = lara_item->rot.y + PHD_180 - Math_Atan(dz, dx); + g_Lara.hit_direction = Math_GetDirection(hit_angle); + if (g_Lara.hit_frame == 0) { + Sound_Effect(SFX_LARA_INJURY, &lara_item->pos, SPM_NORMAL); + } + g_Lara.hit_frame++; + CLAMPG(g_Lara.hit_frame, 34); +} + +void __cdecl Lara_GetCollisionInfo(ITEM_INFO *item, COLL_INFO *coll) +{ + coll->facing = g_Lara.move_angle; + Collide_GetCollisionInfo( + coll, item->pos.x, item->pos.y, item->pos.z, item->room_num, + LARA_HEIGHT); +} + +void __cdecl Lara_SlideSlope(ITEM_INFO *item, COLL_INFO *coll) +{ + coll->bad_pos = NO_BAD_POS; + coll->bad_neg = -STEP_L * 2; + coll->bad_ceiling = 0; + Lara_GetCollisionInfo(item, coll); + + if (Lara_HitCeiling(item, coll)) { + return; + } + + Lara_DeflectEdge(item, coll); + + if (coll->side_mid.floor > 200) { + if (item->current_anim_state == LS_SLIDE) { + item->goal_anim_state = LS_FORWARD_JUMP; + item->current_anim_state = LS_FORWARD_JUMP; + item->anim_num = LS_SURF_SWIM; + item->frame_num = g_Anims[item->anim_num].frame_base; + } else { + item->goal_anim_state = LS_FALL_BACK; + item->current_anim_state = LS_FALL_BACK; + item->anim_num = LA_FALL_BACK; + item->frame_num = g_Anims[item->anim_num].frame_base; + } + item->gravity = 1; + item->fall_speed = 0; + return; + } + + Lara_TestSlide(item, coll); + item->pos.y += coll->side_mid.floor; + if (ABS(coll->x_tilt) <= 2 && ABS(coll->z_tilt) <= 2) { + item->goal_anim_state = LS_STOP; + } +} + +int32_t __cdecl Lara_HitCeiling(ITEM_INFO *item, COLL_INFO *coll) +{ + if (coll->coll_type != COLL_TOP && coll->coll_type != COLL_CLAMP) { + return 0; + } + + item->pos.x = coll->old.x; + item->pos.y = coll->old.y; + item->pos.z = coll->old.z; + item->goal_anim_state = LS_STOP; + item->current_anim_state = LS_STOP; + item->anim_num = LS_REACH; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->speed = 0; + item->gravity = 0; + item->fall_speed = 0; + return 1; +} + +int32_t __cdecl Lara_DeflectEdge(ITEM_INFO *item, COLL_INFO *coll) +{ + switch (coll->coll_type) { + case COLL_FRONT: + case COLL_TOP_FRONT: + Item_ShiftCol(item, coll); + item->goal_anim_state = LS_STOP; + item->current_anim_state = LS_STOP; + item->gravity = 0; + item->speed = 0; + return 1; + + case COLL_LEFT: + Item_ShiftCol(item, coll); + item->rot.y += LARA_DEFLECT_ANGLE; + return 0; + + case COLL_RIGHT: + Item_ShiftCol(item, coll); + item->rot.y -= LARA_DEFLECT_ANGLE; + return 0; + + default: + return 0; + } +} + +void __cdecl Lara_DeflectEdgeJump(ITEM_INFO *item, COLL_INFO *coll) +{ + Item_ShiftCol(item, coll); + switch (coll->coll_type) { + case COLL_FRONT: + case COLL_TOP_FRONT: + if (!g_Lara.climb_status || item->speed != 2) { + if (coll->side_mid.floor > 512) { + item->goal_anim_state = LS_FAST_FALL; + item->current_anim_state = LS_FAST_FALL; + item->anim_num = LA_SMASH_JUMP; + item->frame_num = g_Anims[item->anim_num].frame_base + 1; + } else if (coll->side_mid.floor <= 128) { + item->goal_anim_state = LS_LAND; + item->current_anim_state = LS_LAND; + item->anim_num = LA_JUMP_UP_LAND; + item->frame_num = g_Anims[item->anim_num].frame_base; + } + item->speed /= 4; + g_Lara.move_angle += PHD_180; + CLAMPL(item->fall_speed, 1); + } + break; + + case COLL_LEFT: + item->rot.y += LARA_DEFLECT_ANGLE; + break; + + case COLL_RIGHT: + item->rot.y -= LARA_DEFLECT_ANGLE; + break; + + case COLL_TOP: + CLAMPL(item->fall_speed, 1); + break; + + case COLL_CLAMP: + item->pos.z -= (Math_Cos(coll->facing) * 100) >> W2V_SHIFT; + item->pos.x -= (Math_Sin(coll->facing) * 100) >> W2V_SHIFT; + item->speed = 0; + coll->side_mid.floor = 0; + if (item->fall_speed <= 0) { + item->fall_speed = 16; + } + break; + + default: + break; + } +} + +void __cdecl Lara_SlideEdgeJump(ITEM_INFO *item, COLL_INFO *coll) +{ + Item_ShiftCol(item, coll); + + switch (coll->coll_type) { + case COLL_LEFT: + item->rot.y += LARA_DEFLECT_ANGLE; + break; + + case COLL_RIGHT: + item->rot.y -= LARA_DEFLECT_ANGLE; + break; + + case COLL_TOP: + case COLL_TOP_FRONT: + CLAMPL(item->fall_speed, 1); + break; + + case COLL_CLAMP: + item->pos.z -= (Math_Cos(coll->facing) * 100) >> W2V_SHIFT; + item->pos.x -= (Math_Sin(coll->facing) * 100) >> W2V_SHIFT; + item->speed = 0; + coll->side_mid.floor = 0; + if (item->fall_speed <= 0) { + item->fall_speed = 16; + } + break; + + default: + break; + } +} + +int32_t __cdecl Lara_TestWall( + ITEM_INFO *item, int32_t front, int32_t right, int32_t down) +{ + int32_t x = item->pos.x; + int32_t y = item->pos.y + down; + int32_t z = item->pos.z; + + DIRECTION dir = Math_GetDirection(item->rot.y); + switch (dir) { + case DIR_NORTH: + x -= right; + break; + case DIR_EAST: + z -= right; + break; + case DIR_SOUTH: + x += right; + break; + case DIR_WEST: + z += right; + break; + default: + break; + } + + int16_t room_num = item->room_num; + Room_GetSector(x, y, z, &room_num); + + switch (dir) { + case DIR_NORTH: + z += front; + break; + case DIR_EAST: + x += front; + break; + case DIR_SOUTH: + z -= front; + break; + case DIR_WEST: + x -= front; + break; + default: + break; + } + + const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); + const int32_t height = Room_GetHeight(sector, x, y, z); + const int32_t ceiling = Room_GetCeiling(sector, x, y, z); + if (height == NO_HEIGHT) { + return 1; + } + if (height - y > 0 && ceiling - y < 0) { + return 0; + } + return 2; +} + +int32_t __cdecl Lara_TestHangOnClimbWall(ITEM_INFO *item, COLL_INFO *coll) +{ + if (!g_Lara.climb_status || item->fall_speed < 0) { + return 0; + } + + DIRECTION dir = Math_GetDirection(item->rot.y); + switch (dir) { + case DIR_NORTH: + case DIR_SOUTH: + item->pos.z += coll->shift.z; + break; + + case DIR_EAST: + case DIR_WEST: + item->pos.x += coll->shift.x; + break; + + default: + break; + } + + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + int32_t y = bounds->min_y; + int32_t h = bounds->max_y - y; + + int32_t shift; + if (!Lara_TestClimbPos(item, coll->radius, coll->radius, y, h, &shift)) { + return 0; + } + + if (!Lara_TestClimbPos(item, coll->radius, -coll->radius, y, h, &shift)) { + return 0; + } + + int32_t result = Lara_TestClimbPos(item, coll->radius, 0, y, h, &shift); + switch (result) { + case 0: + case 1: + return result; + + default: + item->pos.y += shift; + return 1; + } +} + +int32_t __cdecl Lara_TestClimbStance(ITEM_INFO *item, COLL_INFO *coll) +{ + int32_t shift_r; + int32_t result_r = Lara_TestClimbPos( + item, coll->radius, coll->radius + LARA_CLIMB_WIDTH_RIGHT, -700, + STEP_L * 2, &shift_r); + if (result_r != 1) { + return 0; + } + + int32_t shift_l; + int32_t result_l = Lara_TestClimbPos( + item, coll->radius, -(coll->radius + LARA_CLIMB_WIDTH_LEFT), -700, + STEP_L * 2, &shift_l); + if (result_l != 1) { + return 0; + } + + int32_t shift = 0; + if (shift_r) { + if (shift_l) { + if ((shift_r < 0) != (shift_l < 0)) { + return 0; + } + if (shift_r < 0 && shift_l < shift_r) { + shift = shift_l; + } else if (shift_r > 0 && shift_l > shift_r) { + shift = shift_l; + } else { + shift = shift_r; + } + } else { + shift = shift_r; + } + } else if (shift_l) { + shift = shift_l; + } + + item->pos.y += shift; + return 1; +} + +void __cdecl Lara_HangTest(ITEM_INFO *item, COLL_INFO *coll) +{ + coll->bad_pos = NO_BAD_POS; + coll->bad_neg = NO_BAD_NEG; + coll->bad_ceiling = 0; + Lara_GetCollisionInfo(item, coll); + bool flag = coll->side_front.floor < 200; + + item->gravity = 0; + item->fall_speed = 0; + g_Lara.move_angle = item->rot.y; + + DIRECTION dir = Math_GetDirection(item->rot.y); + switch (dir) { + case DIR_NORTH: + item->pos.z += 2; + break; + case DIR_EAST: + item->pos.x += 2; + break; + case DIR_SOUTH: + item->pos.z -= 2; + break; + case DIR_WEST: + item->pos.x -= 2; + break; + default: + break; + } + + coll->bad_pos = NO_BAD_POS; + coll->bad_neg = -STEPUP_HEIGHT; + coll->bad_ceiling = 0; + Lara_GetCollisionInfo(item, coll); + + if (g_Lara.climb_status) { + if (!(g_Input & IN_ACTION) || item->hit_points <= 0) { + XYZ_32 pos = { + .x = 0, + .y = 0, + .z = 0, + }; + Collide_GetJointAbsPosition(item, &pos, 0); + if (dir == DIR_NORTH || dir == DIR_SOUTH) { + item->pos.x = pos.x; + } else { + item->pos.z = pos.z; + } + + item->goal_anim_state = LS_FORWARD_JUMP; + item->current_anim_state = LS_FORWARD_JUMP; + item->anim_num = LA_FALL_START; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->pos.y += STEP_L; + item->gravity = 1; + item->speed = 2; + item->fall_speed = 1; + g_Lara.gun_status = LGS_ARMLESS; + return; + } + + if (!Lara_TestHangOnClimbWall(item, coll)) { + item->pos.x = coll->old.x; + item->pos.y = coll->old.y; + item->pos.z = coll->old.z; + item->goal_anim_state = LS_HANG; + item->current_anim_state = LS_HANG; + item->anim_num = LA_REACH_TO_HANG; + item->frame_num = g_Anims[item->anim_num].frame_base + 21; + return; + } + + if (item->anim_num == LA_REACH_TO_HANG + && item->frame_num == g_Anims[item->anim_num].frame_base + 21 + && Lara_TestClimbStance(item, coll)) { + item->goal_anim_state = LS_CLIMB_STANCE; + } + return; + } + + if (!(g_Input & IN_ACTION) || item->hit_points <= 0 + || coll->side_front.floor > 0) { + item->goal_anim_state = LS_UP_JUMP; + item->current_anim_state = LS_UP_JUMP; + item->anim_num = LA_JUMP_UP; + item->frame_num = g_Anims[item->anim_num].frame_base + 9; + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + item->pos.y += bounds->max_y; + item->pos.x += coll->shift.x; + item->pos.z += coll->shift.z; + item->gravity = 1; + item->speed = 2; + item->fall_speed = 1; + g_Lara.gun_status = LGS_ARMLESS; + return; + } + + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + int32_t hdif = coll->side_front.floor - bounds->min_y; + + if (ABS(coll->side_left.floor - coll->side_right.floor) >= SLOPE_DIF + || coll->side_mid.ceiling >= 0 || coll->coll_type != COLL_FRONT || flag + || coll->hit_static || hdif < -SLOPE_DIF || hdif > SLOPE_DIF) { + item->pos.x = coll->old.x; + item->pos.y = coll->old.y; + item->pos.z = coll->old.z; + if (item->current_anim_state == LS_HANG_LEFT + || item->current_anim_state == LS_HANG_RIGHT) { + item->goal_anim_state = LS_HANG; + item->current_anim_state = LS_HANG; + item->anim_num = LA_REACH_TO_HANG; + item->frame_num = g_Anims[item->anim_num].frame_base + 21; + } + return; + } + + switch (dir) { + case DIR_NORTH: + case DIR_SOUTH: + item->pos.z += coll->shift.z; + break; + + case DIR_EAST: + case DIR_WEST: + item->pos.x += coll->shift.x; + break; + + default: + break; + } + + item->pos.y += hdif; +} + +int32_t __cdecl Lara_TestEdgeCatch( + ITEM_INFO *item, COLL_INFO *coll, int32_t *edge) +{ + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + int32_t hdif1 = coll->side_front.floor - bounds->min_y; + int32_t hdif2 = hdif1 + item->fall_speed; + if ((hdif1 < 0 && hdif2 < 0) || (hdif1 > 0 && hdif2 > 0)) { + hdif1 = item->pos.y + bounds->min_y; + hdif2 = hdif1 + item->fall_speed; + if ((hdif1 >> (WALL_SHIFT - 2)) == (hdif2 >> (WALL_SHIFT - 2))) { + return 0; + } + if (item->fall_speed > 0) { + *edge = hdif2 & ~(STEP_L - 1); + } else { + *edge = hdif1 & ~(STEP_L - 1); + } + return -1; + } + + return ABS(coll->side_left.floor - coll->side_right.floor) < SLOPE_DIF; +} + +int32_t __cdecl Lara_TestHangJumpUp(ITEM_INFO *item, COLL_INFO *coll) +{ + if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) + || g_Lara.gun_status != LGS_ARMLESS || coll->hit_static + || coll->side_mid.ceiling > -STEPUP_HEIGHT) { + return 0; + } + + int32_t edge; + int32_t edge_catch = Lara_TestEdgeCatch(item, coll, &edge); + if (!edge_catch + || (edge_catch < 0 && !Lara_TestHangOnClimbWall(item, coll))) { + return 0; + } + + DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_HANG_ANGLE); + if (dir == DIR_UNKNOWN) { + return 0; + } + int16_t angle = Math_DirectionToAngle(dir); + + item->goal_anim_state = LS_HANG; + item->current_anim_state = LS_HANG; + item->anim_num = LA_REACH_TO_HANG; + item->frame_num = g_Anims[item->anim_num].frame_base + 12; + + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + if (edge_catch > 0) { + item->pos.y += coll->side_front.floor - bounds->min_y; + } else { + item->pos.y = edge - bounds->min_y; + } + item->pos.x += coll->shift.x; + item->pos.z += coll->shift.z; + item->rot.y = angle; + item->speed = 0; + item->gravity = 0; + item->fall_speed = 0; + g_Lara.gun_status = LGS_HANDS_BUSY; + return 1; +} + +int32_t __cdecl Lara_TestHangJump(ITEM_INFO *item, COLL_INFO *coll) +{ + if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) + || g_Lara.gun_status != LGS_ARMLESS || coll->hit_static + || coll->side_mid.ceiling > -STEPUP_HEIGHT + || coll->side_mid.floor < 200) { + return 0; + } + + int32_t edge; + int32_t edge_catch = Lara_TestEdgeCatch(item, coll, &edge); + if (!edge_catch + || (edge_catch < 0 && !Lara_TestHangOnClimbWall(item, coll))) { + return 0; + } + + DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_HANG_ANGLE); + if (dir == DIR_UNKNOWN) { + return 0; + } + int16_t angle = Math_DirectionToAngle(dir); + + if (Lara_TestHangSwingIn(item, angle)) { + item->anim_num = LA_REACH_TO_THIN_LEDGE; + item->frame_num = g_Anims[item->anim_num].frame_base; + } else { + item->anim_num = LA_REACH_TO_HANG; + item->frame_num = g_Anims[item->anim_num].frame_base; + } + item->current_anim_state = LS_HANG; + item->goal_anim_state = LS_HANG; + + const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item); + if (edge_catch > 0) { + item->pos.y += coll->side_front.floor - bounds->min_y; + item->pos.x += coll->shift.x; + item->pos.z += coll->shift.z; + } else { + item->pos.y = edge - bounds->min_y; + } + + item->rot.y = angle; + item->speed = 2; + item->gravity = 1; + item->fall_speed = 1; + g_Lara.gun_status = LGS_HANDS_BUSY; + return 1; +} + +int32_t __cdecl Lara_TestHangSwingIn(ITEM_INFO *item, PHD_ANGLE angle) +{ + int32_t x = item->pos.x; + int32_t y = item->pos.y; + int32_t z = item->pos.z; + int16_t room_num = item->room_num; + switch (angle) { + case 0: + z += STEP_L; + break; + case PHD_90: + x += STEP_L; + break; + case -PHD_180: + z -= STEP_L; + break; + case -PHD_90: + x -= STEP_L; + break; + } + + const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); + int32_t height = Room_GetHeight(sector, x, y, z); + int32_t ceiling = Room_GetCeiling(sector, x, y, z); + return height != NO_HEIGHT && height - y > 0 && ceiling - y < -400; +} + +int32_t __cdecl Lara_TestVault(ITEM_INFO *item, COLL_INFO *coll) +{ + if (coll->coll_type != COLL_FRONT || !(g_Input & IN_ACTION) + || g_Lara.gun_status != LGS_ARMLESS) { + return 0; + } + + DIRECTION dir = Math_GetDirectionCone(item->rot.y, LARA_VAULT_ANGLE); + if (dir == DIR_UNKNOWN) { + return 0; + } + int16_t angle = Math_DirectionToAngle(dir); + + int32_t left_floor = coll->side_left.floor; + int32_t left_ceiling = coll->side_left.ceiling; + int32_t right_floor = coll->side_right.floor; + int32_t right_ceiling = coll->side_right.ceiling; + int32_t front_floor = coll->side_front.floor; + int32_t front_ceiling = coll->side_front.ceiling; + bool slope = ABS(left_floor - right_floor) >= SLOPE_DIF; + + int32_t mid = STEP_L / 2; + if (front_floor >= -STEP_L * 2 - mid && front_floor <= -STEP_L * 2 + mid) { + if (slope || front_floor - front_ceiling < 0 + || left_floor - left_ceiling < 0 + || right_floor - right_ceiling < 0) { + return 0; + } + item->goal_anim_state = LS_STOP; + item->current_anim_state = LS_NULL; + item->anim_num = LA_CLIMB_2CLICK; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->pos.y += front_floor + STEP_L * 2; + g_Lara.gun_status = LGS_HANDS_BUSY; + } else if ( + front_floor >= -STEP_L * 3 - mid && front_floor <= -STEP_L * 3 + mid) { + if (slope || front_floor - front_ceiling < 0 + || left_floor - left_ceiling < 0 + || right_floor - right_ceiling < 0) { + return 0; + } + item->goal_anim_state = LS_STOP; + item->current_anim_state = LS_NULL; + item->anim_num = LA_CLIMB_3CLICK; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->pos.y += front_floor + STEP_L * 3; + g_Lara.gun_status = LGS_HANDS_BUSY; + } else if ( + !slope && front_floor >= -STEP_L * 7 - mid + && front_floor <= -STEP_L * 4 + mid) { + item->goal_anim_state = LS_UP_JUMP; + item->current_anim_state = LS_STOP; + item->anim_num = LA_STAND_STILL; + item->frame_num = g_Anims[item->anim_num].frame_base; + g_Lara.calc_fallspeed = + -(Math_Sqrt(-2 * GRAVITY * (front_floor + 800)) + 3); + Lara_Animate(item); + } else if ( + g_Lara.climb_status && front_floor <= -1920 + && g_Lara.water_status != LWS_WADE && left_floor <= -STEP_L * 8 + mid + && right_floor <= -STEP_L * 8 + && coll->side_mid.ceiling <= -STEP_L * 8 + mid + LARA_HEIGHT) { + item->goal_anim_state = LS_UP_JUMP; + item->current_anim_state = LS_STOP; + item->anim_num = LA_STAND_STILL; + item->frame_num = g_Anims[item->anim_num].frame_base; + g_Lara.calc_fallspeed = -116; + Lara_Animate(item); + } else if ( + g_Lara.climb_status + && (front_floor < -STEP_L * 4 || front_ceiling >= LARA_HEIGHT - STEP_L) + && coll->side_mid.ceiling <= -STEP_L * 5 + LARA_HEIGHT) { + Item_ShiftCol(item, coll); + if (Lara_TestClimbStance(item, coll)) { + item->goal_anim_state = LS_CLIMB_STANCE; + item->current_anim_state = LS_STOP; + item->anim_num = LA_STAND_STILL; + item->frame_num = g_Anims[item->anim_num].frame_base; + Lara_Animate(item); + item->rot.y = angle; + g_Lara.gun_status = LGS_HANDS_BUSY; + return 1; + } + return 0; + } else { + return 0; + } + + item->rot.y = angle; + Item_ShiftCol(item, coll); + return 1; +} + +int32_t __cdecl Lara_TestSlide(ITEM_INFO *item, COLL_INFO *coll) +{ + if (ABS(coll->x_tilt) <= 2 && ABS(coll->z_tilt) <= 2) { + return 0; + } + + int16_t angle = 0; + if (coll->x_tilt > 2) { + angle = -PHD_90; + } else if (coll->x_tilt < -2) { + angle = PHD_90; + } + + if (coll->z_tilt > 2 && coll->z_tilt > ABS(coll->x_tilt)) { + angle = PHD_180; + } else if (coll->z_tilt < -2 && -coll->z_tilt > ABS(coll->x_tilt)) { + angle = 0; + } + + const int16_t angle_dif = angle - item->rot.y; + Item_ShiftCol(item, coll); + + if (angle_dif >= -PHD_90 && angle_dif <= PHD_90) { + if (item->current_anim_state == LS_SLIDE + && g_LaraOldSlideAngle == angle) { + return 1; + } + item->goal_anim_state = LS_SLIDE; + item->current_anim_state = LS_SLIDE; + item->anim_num = LA_SLIDE_FORWARD; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->rot.y = angle; + } else { + if (item->current_anim_state == LS_SLIDE_BACK + && g_LaraOldSlideAngle == angle) { + return 1; + } + item->goal_anim_state = LS_SLIDE_BACK; + item->current_anim_state = LS_SLIDE_BACK; + item->anim_num = LA_SLIDE_BACKWARD_START; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->rot.y = angle + PHD_180; + } + + g_Lara.move_angle = angle; + g_LaraOldSlideAngle = angle; + return 1; +} + +int16_t __cdecl Lara_FloorFront(ITEM_INFO *item, int16_t ang, int32_t dist) +{ + const int32_t x = item->pos.x + ((dist * Math_Sin(ang)) >> W2V_SHIFT); + const int32_t y = item->pos.y - LARA_HEIGHT; + const int32_t z = item->pos.z + ((dist * Math_Cos(ang)) >> W2V_SHIFT); + int16_t room_num = item->room_num; + const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); + int32_t height = Room_GetHeight(sector, x, y, z); + if (height != NO_HEIGHT) { + height -= item->pos.y; + } + return height; +} + +int32_t __cdecl Lara_LandedBad(ITEM_INFO *item, COLL_INFO *coll) +{ + const int32_t x = item->pos.x; + const int32_t y = item->pos.y; + const int32_t z = item->pos.z; + + int16_t room_num = item->room_num; + const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); + const int32_t height = Room_GetHeight(sector, x, y - LARA_HEIGHT, z); + item->pos.y = height; + item->floor = height; + + Room_TestTriggers(g_TriggerIndex, 0); + int32_t land_speed = item->fall_speed - DAMAGE_START; + item->pos.y = y; + if (land_speed <= 0) { + return 0; + } + if (land_speed <= DAMAGE_LENGTH) { + item->hit_points += -LARA_MAX_HITPOINTS * land_speed * land_speed + / (DAMAGE_LENGTH * DAMAGE_LENGTH); + } else { + item->hit_points = -1; + } + return item->hit_points <= 0; +} + +int32_t __cdecl Lara_CheckForLetGo(ITEM_INFO *item, COLL_INFO *coll) +{ + item->gravity = 0; + item->fall_speed = 0; + + int16_t room_num = item->room_num; + int32_t x = item->pos.x; + int32_t y = item->pos.y; + int32_t z = item->pos.z; + const SECTOR_INFO *const sector = Room_GetSector(x, y, z, &room_num); + Room_GetHeight(sector, x, y, z); + coll->trigger = g_TriggerIndex; + if ((g_Input & IN_ACTION) && item->hit_points > 0) { + return 0; + } + + item->goal_anim_state = LS_FORWARD_JUMP; + item->current_anim_state = LS_FORWARD_JUMP; + item->anim_num = LA_FALL_START; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->gravity = 1; + item->speed = 2; + item->fall_speed = 1; + g_Lara.gun_status = LGS_ARMLESS; + return 1; +} + +void __cdecl Lara_GetJointAbsPosition(XYZ_32 *vec, int32_t joint) +{ + FRAME_INFO *frmptr[2] = { NULL, NULL }; + if (g_Lara.hit_direction < 0) { + int32_t rate; + int32_t frac = Item_GetFrames(g_LaraItem, frmptr, &rate); + if (frac) { + Lara_GetJointAbsPosition_I( + g_LaraItem, vec, frmptr[0], frmptr[1], frac, rate); + return; + } + } + + const FRAME_INFO *frame_ptr = NULL; + const OBJECT_INFO *obj = &g_Objects[g_LaraItem->object_id]; + if (g_Lara.hit_direction >= 0) { + LARA_ANIMATION anim_num; + switch (g_Lara.hit_direction) { + case DIR_EAST: + anim_num = LA_HIT_RIGHT; + break; + case DIR_SOUTH: + anim_num = LA_HIT_BACK; + break; + case DIR_WEST: + anim_num = LA_HIT_LEFT; + break; + default: + anim_num = LA_HIT_FRONT; + break; + } + const ANIM *anim = &g_Anims[anim_num]; + int32_t interpolation = anim->interpolation; + frame_ptr = (const FRAME_INFO *)(anim->frame_ptr + + (int32_t)(g_Lara.hit_frame + * (interpolation >> 8))); + } else { + frame_ptr = frmptr[0]; + } + + Matrix_PushUnit(); + g_MatrixPtr->_03 = 0; + g_MatrixPtr->_13 = 0; + g_MatrixPtr->_23 = 0; + Matrix_RotYXZ(g_LaraItem->rot.y, g_LaraItem->rot.x, g_LaraItem->rot.z); + + const int16_t *rot = frame_ptr->mesh_rots; + const int32_t *bone = &g_AnimBones[obj->bone_idx]; + + Matrix_TranslateRel( + frame_ptr->offset.x, frame_ptr->offset.y, frame_ptr->offset.z); + Matrix_RotYXZsuperpack(&rot, 0); + + Matrix_TranslateRel(bone[25], bone[26], bone[27]); + Matrix_RotYXZsuperpack(&rot, 6); + Matrix_RotYXZ(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); + + LARA_GUN_TYPE gun_type = LGT_UNARMED; + if (g_Lara.gun_status == LGS_READY || g_Lara.gun_status == LGS_SPECIAL + || g_Lara.gun_status == LGS_DRAW || g_Lara.gun_status == LGS_UNDRAW) { + gun_type = g_Lara.gun_type; + } + + if (g_Lara.gun_type == LGT_FLARE) { + Matrix_TranslateRel(bone[41], bone[42], bone[43]); + if (g_Lara.flare_control_left) { + const LARA_ARM *arm = &g_Lara.left_arm; + const ANIM *anim = &g_Anims[arm->anim_num]; + rot = &arm->frame_base + [(anim->interpolation >> 8) + * (arm->frame_num - anim->frame_base) + + FBBOX_ROT]; + } else { + rot = frame_ptr->mesh_rots; + } + Matrix_RotYXZsuperpack(&rot, 11); + + Matrix_TranslateRel(bone[45], bone[46], bone[47]); + Matrix_RotYXZsuperpack(&rot, 0); + + Matrix_TranslateRel(bone[49], bone[50], bone[51]); + Matrix_RotYXZsuperpack(&rot, 0); + } else if (gun_type != LGT_UNARMED) { + Matrix_TranslateRel(bone[29], bone[30], bone[31]); + + const LARA_ARM *arm = &g_Lara.right_arm; + const ANIM *anim = &g_Anims[arm->anim_num]; + rot = &arm->frame_base + [arm->frame_num * (anim->interpolation >> 8) + FBBOX_ROT]; + Matrix_RotYXZsuperpack(&rot, 8); + + Matrix_TranslateRel(bone[33], bone[34], bone[35]); + Matrix_RotYXZsuperpack(&rot, 0); + + Matrix_TranslateRel(bone[37], bone[38], bone[39]); + Matrix_RotYXZsuperpack(&rot, 0); + } + + Matrix_TranslateRel(vec->x, vec->y, vec->z); + vec->x = g_LaraItem->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT); + vec->y = g_LaraItem->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT); + vec->z = g_LaraItem->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT); + Matrix_Pop(); +} + +void __cdecl Lara_GetJointAbsPosition_I( + ITEM_INFO *item, XYZ_32 *vec, FRAME_INFO *frame1, FRAME_INFO *frame2, + int32_t frac, int32_t rate) +{ + const OBJECT_INFO *obj = &g_Objects[item->object_id]; + + Matrix_PushUnit(); + g_MatrixPtr->_03 = 0; + g_MatrixPtr->_13 = 0; + g_MatrixPtr->_23 = 0; + Matrix_RotYXZ(item->rot.y, item->rot.x, item->rot.z); + + const int32_t *const bone = &g_AnimBones[obj->bone_idx]; + const int16_t *rot1 = frame1->mesh_rots; + const int16_t *rot2 = frame2->mesh_rots; + Matrix_InitInterpolate(frac, rate); + + Matrix_TranslateRel_ID( + frame1->offset.x, frame1->offset.y, frame1->offset.z, frame2->offset.x, + frame2->offset.y, frame2->offset.z); + Matrix_RotYXZsuperpack_I(&rot1, &rot2, 0); + + Matrix_TranslateRel_I(bone[25], bone[26], bone[27]); + Matrix_RotYXZsuperpack_I(&rot1, &rot2, 6); + Matrix_RotYXZ_I(g_Lara.torso_y_rot, g_Lara.torso_x_rot, g_Lara.torso_z_rot); + + LARA_GUN_TYPE gun_type = LGT_UNARMED; + if (g_Lara.gun_status == LGS_READY || g_Lara.gun_status == LGS_SPECIAL + || g_Lara.gun_status == LGS_DRAW || g_Lara.gun_status == LGS_UNDRAW) { + gun_type = g_Lara.gun_type; + } + + if (g_Lara.gun_type == LGT_FLARE) { + Matrix_Interpolate(); + Matrix_TranslateRel(bone[29], bone[30], bone[31]); + if (g_Lara.flare_control_left) { + const LARA_ARM *arm = &g_Lara.left_arm; + const ANIM *anim = &g_Anims[arm->anim_num]; + rot1 = &arm->frame_base + [(anim->interpolation >> 8) + * (arm->frame_num - anim->frame_base) + + FBBOX_ROT]; + } else { + rot1 = frame1->mesh_rots; + } + Matrix_RotYXZsuperpack(&rot1, 11); + + Matrix_TranslateRel(bone[45], bone[46], bone[47]); + Matrix_RotYXZsuperpack(&rot1, 0); + + Matrix_TranslateRel(bone[49], bone[50], bone[51]); + Matrix_RotYXZsuperpack(&rot1, 0); + } else if (gun_type != LGT_UNARMED) { + Matrix_Interpolate(); + Matrix_TranslateRel(bone[29], bone[30], bone[31]); + + const LARA_ARM *arm = &g_Lara.right_arm; + const ANIM *anim = &g_Anims[arm->anim_num]; + rot1 = &arm->frame_base + [arm->frame_num * (anim->interpolation >> 8) + FBBOX_ROT]; + Matrix_RotYXZsuperpack(&rot1, 8); + + Matrix_TranslateRel(bone[33], bone[34], bone[35]); + Matrix_RotYXZsuperpack(&rot1, 0); + + Matrix_TranslateRel(bone[37], bone[38], bone[39]); + Matrix_RotYXZsuperpack(&rot1, 0); + } + + Matrix_TranslateRel(vec->x, vec->y, vec->z); + vec->x = item->pos.x + (g_MatrixPtr->_03 >> W2V_SHIFT); + vec->y = item->pos.y + (g_MatrixPtr->_13 >> W2V_SHIFT); + vec->z = item->pos.z + (g_MatrixPtr->_23 >> W2V_SHIFT); + + Matrix_Pop(); +} + +void __cdecl Lara_TakeHit( + ITEM_INFO *const lara_item, const COLL_INFO *const coll) +{ + const int32_t dx = g_Lara.spaz_effect->pos.x - lara_item->pos.x; + const int32_t dz = g_Lara.spaz_effect->pos.z - lara_item->pos.z; + M_TakeHit(lara_item, dx, dz); + g_Lara.spaz_effect_count--; +} + +void __cdecl Lara_BaddieCollision(ITEM_INFO *lara_item, COLL_INFO *coll) +{ + lara_item->hit_status = 0; + g_Lara.hit_direction = -1; + if (lara_item->hit_points <= 0) { + return; + } + + int16_t roomies[MAX_BADDIE_COLLISION] = { 0 }; + int32_t roomies_count = 0; + + roomies[roomies_count++] = lara_item->room_num; + + DOOR_INFOS *doors = g_Rooms[roomies[0]].doors; + if (doors != NULL) { + for (int32_t i = 0; i < doors->count; i++) { + if (roomies_count >= MAX_BADDIE_COLLISION) { + break; + } + roomies[roomies_count++] = doors->door[i].room; + } + } + + for (int32_t i = 0; i < roomies_count; i++) { + int16_t item_num = g_Rooms[roomies[i]].item_num; + while (item_num != NO_ITEM) { + const ITEM_INFO *const item = &g_Items[item_num]; + + // the collision routine can destroy the item - need to store the + // next item beforehand + const int16_t next_item_num = item->next_item; + + if (item->collidable && item->status != IS_INVISIBLE) { + const OBJECT_INFO *const object = &g_Objects[item->object_id]; + if (object->collision) { + // clang-format off + const XYZ_32 d = { + .x = lara_item->pos.x - item->pos.x, + .y = lara_item->pos.y - item->pos.y, + .z = lara_item->pos.z - item->pos.z, + }; + if (d.x > -TARGET_DIST && d.x < TARGET_DIST && + d.y > -TARGET_DIST && d.y < TARGET_DIST && + d.z > -TARGET_DIST && d.z < TARGET_DIST) { + object->collision(item_num, lara_item, coll); + } + // clang-format on + } + } + + item_num = next_item_num; + } + } + + if (g_Lara.spaz_effect_count) { + Lara_TakeHit(lara_item, coll); + } + + if (g_Lara.hit_direction == -1) { + g_Lara.hit_frame = 0; + } + + g_Inv_Chosen = -1; +} + +void __cdecl Lara_Push( + const ITEM_INFO *const item, ITEM_INFO *const lara_item, + COLL_INFO *const coll, const bool spaz_on, const bool big_push) +{ + int32_t dx = lara_item->pos.x - item->pos.x; + int32_t dz = lara_item->pos.z - item->pos.z; + const int32_t c = Math_Cos(item->rot.y); + const int32_t s = Math_Sin(item->rot.y); + int32_t rx = (c * dx - s * dz) >> W2V_SHIFT; + int32_t rz = (c * dz + s * dx) >> W2V_SHIFT; + + const BOUNDS_16 *const bounds = &Item_GetBestFrame(item)->bounds; + int32_t min_x = bounds->min_x; + int32_t max_x = bounds->max_x; + int32_t min_z = bounds->min_z; + int32_t max_z = bounds->max_z; + + if (big_push) { + max_x += coll->radius; + min_z -= coll->radius; + max_z += coll->radius; + min_x -= coll->radius; + } + + if (rx < min_x || rx > max_x || rz < min_z || rz > max_z) { + return; + } + + int32_t l = rx - min_x; + int32_t r = max_x - rx; + int32_t t = max_z - rz; + int32_t b = rz - min_z; + + if (l <= r && l <= t && l <= b) { + rx -= l; + } else if (r <= l && r <= t && r <= b) { + rx += r; + } else if (t <= l && t <= r && t <= b) { + rz += t; + } else { + rz = min_z; + } + + lara_item->pos.x = item->pos.x + ((rz * s + rx * c) >> W2V_SHIFT); + lara_item->pos.z = item->pos.z + ((rz * c - rx * s) >> W2V_SHIFT); + + rz = (bounds->max_z + bounds->min_z) / 2; + rx = (bounds->max_x + bounds->min_x) / 2; + dx -= (c * rx + s * rz) >> W2V_SHIFT; + dz -= (c * rz - s * rx) >> W2V_SHIFT; + + if (spaz_on && bounds->max_y - bounds->min_y > STEP_L) { + M_TakeHit(lara_item, dx, dz); + } + + int16_t old_facing = coll->facing; + coll->bad_pos = NO_BAD_POS; + coll->bad_neg = -STEPUP_HEIGHT; + coll->bad_ceiling = 0; + coll->facing = Math_Atan( + lara_item->pos.z - coll->old.z, lara_item->pos.x - coll->old.x); + Collide_GetCollisionInfo( + coll, lara_item->pos.x, lara_item->pos.y, lara_item->pos.z, + lara_item->room_num, LARA_HEIGHT); + coll->facing = old_facing; + + if (coll->coll_type != COLL_NONE) { + lara_item->pos.x = coll->old.x; + lara_item->pos.z = coll->old.z; + } else { + coll->old.x = lara_item->pos.x; + coll->old.y = lara_item->pos.y; + coll->old.z = lara_item->pos.z; + Item_UpdateRoom(lara_item, -WALL_SHIFT); + } +} + +int32_t __cdecl Lara_MovePosition( + XYZ_32 *vec, ITEM_INFO *item, ITEM_INFO *lara_item) +{ + const XYZ_16 rot = { + .x = item->rot.x, + .y = item->rot.y, + .z = item->rot.z, + }; + + Matrix_PushUnit(); + Matrix_RotYXZ(rot.y, rot.x, rot.z); + const MATRIX *const m = g_MatrixPtr; + const XYZ_32 shift = { + .x = (vec->y * m->_01 + vec->z * m->_02 + vec->x * m->_00) >> W2V_SHIFT, + .y = (vec->x * m->_10 + vec->z * m->_12 + vec->y * m->_11) >> W2V_SHIFT, + .z = (vec->y * m->_21 + vec->x * m->_20 + vec->z * m->_22) >> W2V_SHIFT, + }; + Matrix_Pop(); + + const XYZ_32 new_pos = { + .x = item->pos.x + shift.x, + .y = item->pos.y + shift.y, + .z = item->pos.z + shift.z, + }; + + if (item->object_id == O_FLARE_ITEM) { + int16_t room_num = lara_item->room_num; + const SECTOR_INFO *const sector = + Room_GetSector(new_pos.x, new_pos.y, new_pos.z, &room_num); + const int32_t height = + Room_GetHeight(sector, new_pos.x, new_pos.y, new_pos.z); + if (ABS(height - lara_item->pos.y) > STEP_L * 2) { + return false; + } + if (XYZ_32_GetDistance(&new_pos, &lara_item->pos) < STEP_L) { + return true; + } + } + + // TODO: get rid of this conversion + const PHD_3DPOS new_pos_full = { + .pos = new_pos, + .rot = rot, + }; + PHD_3DPOS src_pos = { + .pos = lara_item->pos, + .rot = lara_item->rot, + }; + const int32_t result = + Misc_Move3DPosTo3DPos(&src_pos, &new_pos_full, MOVE_SPEED, MOVE_ANGLE); + lara_item->pos = src_pos.pos; + lara_item->rot = src_pos.rot; + return result; +} + +int32_t __cdecl Lara_IsNearItem(const XYZ_32 *const pos, const int32_t distance) +{ + return Item_IsNearItem(g_LaraItem, pos, distance); +} + +int32_t __cdecl Lara_TestClimb( + const int32_t x, const int32_t y, const int32_t z, const int32_t x_front, + const int32_t z_front, const int32_t item_height, const int16_t item_room, + int32_t *const shift) +{ + *shift = 0; + bool hang = true; + if (!g_Lara.climb_status) { + return 0; + } + + const SECTOR_INFO *sector; + int32_t height; + int32_t ceiling; + + int16_t room_num = item_room; + sector = Room_GetSector(x, y - 128, z, &room_num); + height = Room_GetHeight(sector, x, y, z); + if (height == NO_HEIGHT) { + return 0; + } + + height -= y + item_height + STEP_L / 2; + if (height < -CLIMB_SHIFT) { + return 0; + } + if (height < 0) { + *shift = height; + } + + ceiling = Room_GetCeiling(sector, x, y, z) - y; + if (ceiling > CLIMB_SHIFT) { + return 0; + } + if (ceiling > 0) { + if (*shift) { + return 0; + } + *shift = ceiling; + } + + if (item_height + height < CLIMB_HANG) { + hang = false; + } + + const int32_t x2 = x + x_front; + const int32_t z2 = z + z_front; + sector = Room_GetSector(x2, y, z2, &room_num); + height = Room_GetHeight(sector, x2, y, z2); + if (height != NO_HEIGHT) { + height -= y; + } + + if (height > CLIMB_SHIFT) { + ceiling = Room_GetCeiling(sector, x2, y, z2) - y; + if (ceiling >= LARA_CLIMB_HEIGHT) { + return 1; + } + + if (ceiling > LARA_CLIMB_HEIGHT - CLIMB_SHIFT) { + if (*shift > 0) { + return hang ? -1 : 0; + } + *shift = ceiling - LARA_CLIMB_HEIGHT; + return 1; + } + + if (ceiling > 0) { + return hang ? -1 : 0; + } + + if (ceiling > -CLIMB_SHIFT && hang && *shift <= 0) { + if (*shift > ceiling) { + *shift = ceiling; + } + + return -1; + } + + return 0; + } + + if (height > 0) { + if (*shift < 0) { + return 0; + } + if (height > *shift) { + *shift = height; + } + } + + room_num = item_room; + sector = Room_GetSector(x, item_height + y, z, &room_num); + sector = Room_GetSector(x2, item_height + y, z2, &room_num); + ceiling = Room_GetCeiling(sector, x2, item_height + y, z2); + if (ceiling == NO_HEIGHT) { + return 1; + } + + ceiling -= y; + if (ceiling <= height) { + return 1; + } + + if (ceiling >= LARA_CLIMB_HEIGHT) { + return 1; + } + + if (ceiling > LARA_CLIMB_HEIGHT - CLIMB_SHIFT) { + if (*shift > 0) { + return hang ? -1 : 0; + } + *shift = ceiling - LARA_CLIMB_HEIGHT; + return 1; + } + + return hang ? -1 : 0; +} + +int32_t __cdecl Lara_TestClimbPos( + const ITEM_INFO *const item, const int32_t front, const int32_t right, + const int32_t origin, const int32_t height, int32_t *const shift) +{ + const int32_t y = item->pos.y + origin; + int32_t x; + int32_t z; + int32_t x_front = 0; + int32_t z_front = 0; + + switch (Math_GetDirection(item->rot.y)) { + case DIR_NORTH: + x = item->pos.x + right; + z = item->pos.z + front; + z_front = 2; + break; + + case DIR_EAST: + x = item->pos.x + front; + z = item->pos.z - right; + x_front = 2; + break; + + case DIR_SOUTH: + x = item->pos.x - right; + z = item->pos.z - front; + z_front = -2; + break; + + case DIR_WEST: + x = item->pos.x - front; + z = item->pos.z + right; + x_front = -2; + break; + + default: + x = front; + z = front; + break; + } + + return Lara_TestClimb( + x, y, z, x_front, z_front, height, item->room_num, shift); +} + +void __cdecl Lara_DoClimbLeftRight( + ITEM_INFO *const item, const COLL_INFO *const coll, const int32_t result, + const int32_t shift) +{ + if (result == 1) { + if (g_Input & IN_LEFT) { + item->goal_anim_state = LS_CLIMB_LEFT; + } else if (g_Input & IN_RIGHT) { + item->goal_anim_state = LS_CLIMB_RIGHT; + } else { + item->goal_anim_state = LS_CLIMB_STANCE; + } + item->pos.y += shift; + return; + } + + if (result) { + item->goal_anim_state = LS_HANG; + do { + Item_Animate(item); + } while (item->current_anim_state != LS_HANG); + item->pos.x = coll->old.x; + item->pos.z = coll->old.z; + return; + } + + item->pos.x = coll->old.x; + item->pos.z = coll->old.z; + item->goal_anim_state = LS_CLIMB_STANCE; + item->current_anim_state = LS_CLIMB_STANCE; + if (coll->old_anim_state == LS_CLIMB_STANCE) { + item->frame_num = coll->old_frame_num; + item->anim_num = coll->old_anim_num; + Lara_Animate(item); + } else { + item->anim_num = LA_LADDER_IDLE; + item->frame_num = g_Anims[item->anim_num].frame_base; + } +} + +int32_t __cdecl Lara_TestClimbUpPos( + const ITEM_INFO *const item, const int32_t front, const int32_t right, + int32_t *const shift, int32_t *const ledge) +{ + const int32_t y = item->pos.y - LARA_CLIMB_HEIGHT - STEP_L; + int32_t x; + int32_t z; + int32_t x_front = 0; + int32_t z_front = 0; + + switch (Math_GetDirection(item->rot.y)) { + case DIR_NORTH: + x = item->pos.x + right; + z = item->pos.z + front; + z_front = 2; + break; + + case DIR_EAST: + x = item->pos.x + front; + z = item->pos.z - right; + x_front = 2; + break; + + case DIR_SOUTH: + x = item->pos.x - right; + z = item->pos.z - front; + z_front = -2; + break; + + case DIR_WEST: + z = item->pos.z + right; + x = item->pos.x - front; + x_front = -2; + break; + + default: + x = front; + z = front; + break; + } + + *shift = 0; + + const SECTOR_INFO *sector; + int32_t height; + int32_t ceiling; + + int16_t room_num = item->room_num; + sector = Room_GetSector(x, y, z, &room_num); + ceiling = Room_GetCeiling(sector, x, y, z) + STEP_L - y; + if (ceiling > CLIMB_SHIFT) { + return 0; + } + + if (ceiling > 0) { + *shift = ceiling; + } + + const int32_t x2 = x + x_front; + const int32_t z2 = z + z_front; + sector = Room_GetSector(x2, y, z2, &room_num); + height = Room_GetHeight(sector, x2, y, z2); + if (height == NO_HEIGHT) { + *ledge = NO_HEIGHT; + return 1; + } + + height -= y; + *ledge = height; + if (height > STEP_L / 2) { + ceiling = Room_GetCeiling(sector, x2, y, z2) - y; + if (ceiling >= LARA_CLIMB_HEIGHT) { + return 1; + } + + if (height - ceiling > LARA_HEIGHT) { + *shift = height; + return -1; + } + + return 0; + } + + if (height > 0 && height > *shift) { + *shift = height; + } + + room_num = item->room_num; + sector = Room_GetSector(x, y + LARA_CLIMB_HEIGHT, z, &room_num); + sector = Room_GetSector(x2, y + LARA_CLIMB_HEIGHT, z2, &room_num); + ceiling = Room_GetCeiling(sector, x2, y + LARA_CLIMB_HEIGHT, z2) - y; + if (ceiling <= height) { + return 1; + } + + if (ceiling >= LARA_CLIMB_HEIGHT) { + return 1; + } + return 0; +} + +int32_t __cdecl Lara_GetWaterDepth( + const int32_t x, const int32_t y, const int32_t z, int16_t room_num) +{ + const ROOM_INFO *r = &g_Rooms[room_num]; + const SECTOR_INFO *sector; + + while (true) { + int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; + int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; + + if (z_sector <= 0) { + z_sector = 0; + if (x_sector < 1) { + x_sector = 1; + } else if (x_sector > r->x_size - 2) { + x_sector = r->x_size - 2; + } + } else if (z_sector >= r->z_size - 1) { + z_sector = r->z_size - 1; + if (x_sector < 1) { + x_sector = 1; + } else if (x_sector > r->x_size - 2) { + x_sector = r->x_size - 2; + } + } else if (x_sector < 0) { + x_sector = 0; + } else if (x_sector >= r->x_size) { + x_sector = r->x_size - 1; + } + + sector = &r->sector[z_sector + x_sector * r->z_size]; + const int16_t data = Room_GetDoor(sector); + if (data == NO_ROOM) { + break; + } + room_num = data; + r = &g_Rooms[room_num]; + } + + if (r->flags & RF_UNDERWATER) { + while (sector->sky_room != NO_ROOM) { + r = &g_Rooms[sector->sky_room]; + if (!(r->flags & RF_UNDERWATER)) { + const int32_t water_height = sector->ceiling << 8; + sector = Room_GetSector(x, y, z, &room_num); + return Room_GetHeight(sector, x, y, z) - water_height; + } + const int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; + const int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; + sector = &r->sector[z_sector + x_sector * r->z_size]; + } + return 0x7FFF; + } + + while (sector->pit_room != NO_ROOM) { + r = &g_Rooms[sector->pit_room]; + if (r->flags & RF_UNDERWATER) { + const int32_t water_height = sector->floor << 8; + sector = Room_GetSector(x, y, z, &room_num); + return Room_GetHeight(sector, x, y, z) - water_height; + } + const int32_t z_sector = (z - r->pos.z) >> WALL_SHIFT; + const int32_t x_sector = (x - r->pos.x) >> WALL_SHIFT; + sector = &r->sector[z_sector + x_sector * r->z_size]; + } + return NO_HEIGHT; +} + +void __cdecl Lara_TestWaterDepth( + ITEM_INFO *const item, const COLL_INFO *const coll) +{ + int16_t room_num = item->room_num; + + const SECTOR_INFO *const sector = + Room_GetSector(item->pos.x, item->pos.y, item->pos.z, &room_num); + const int32_t water_depth = + Lara_GetWaterDepth(item->pos.x, item->pos.y, item->pos.z, room_num); + + if (water_depth == NO_HEIGHT) { + item->pos = coll->old; + item->fall_speed = 0; + } else if (water_depth <= STEP_L * 2) { + item->anim_num = LA_UNDERWATER_TO_STAND; + item->frame_num = g_Anims[item->anim_num].frame_base; + item->current_anim_state = LS_WATER_OUT; + item->goal_anim_state = LS_STOP; + item->rot.x = 0; + item->rot.z = 0; + item->gravity = 0; + item->speed = 0; + item->fall_speed = 0; + g_Lara.water_status = LWS_WADE; + item->pos.y = + Room_GetHeight(sector, item->pos.x, item->pos.y, item->pos.z); + } +} + +void __cdecl Lara_SwimCollision(ITEM_INFO *const item, COLL_INFO *const coll) +{ + if (item->rot.x < -PHD_90 || item->rot.x > PHD_90) { + g_Lara.move_angle = item->rot.y + PHD_180; + } else { + g_Lara.move_angle = item->rot.y; + } + + coll->facing = g_Lara.move_angle; + + int32_t height = (LARA_HEIGHT * Math_Sin(item->rot.x)) >> W2V_SHIFT; + if (height < 0) { + height = -height; + } + CLAMPL(height, 200); + + coll->bad_neg = -height; + Collide_GetCollisionInfo( + coll, item->pos.x, item->pos.y + height / 2, item->pos.z, + item->room_num, height); + Item_ShiftCol(item, coll); + + switch (coll->coll_type) { + case COLL_FRONT: + if (item->rot.x > 35 * PHD_DEGREE) { + item->rot.x += LARA_UW_WALL_DEFLECT; + } else if (item->rot.x < -35 * PHD_DEGREE) { + item->rot.x -= LARA_UW_WALL_DEFLECT; + } else { + item->fall_speed = 0; + } + break; + + case COLL_TOP: + if (item->rot.x >= -45 * PHD_DEGREE) { + item->rot.x -= LARA_UW_WALL_DEFLECT; + } + break; + + case COLL_TOP_FRONT: + item->fall_speed = 0; + break; + + case COLL_LEFT: + item->rot.y += 5 * PHD_DEGREE; + break; + + case COLL_RIGHT: + item->rot.y -= 5 * PHD_DEGREE; + break; + + case COLL_CLAMP: + item->pos = coll->old; + item->fall_speed = 0; + return; + } + + if (coll->side_mid.floor < 0) { + item->rot.x += LARA_UW_WALL_DEFLECT; + item->pos.y = coll->side_mid.floor + item->pos.y; + } + + if (g_Lara.water_status != LWS_CHEAT && !g_Lara.extra_anim) { + Lara_TestWaterDepth(item, coll); + } +} + +void __cdecl Lara_WaterCurrent(COLL_INFO *const coll) +{ + ITEM_INFO *const item = g_LaraItem; + + int16_t room_num = g_LaraItem->room_num; + const ROOM_INFO *const r = &g_Rooms[g_LaraItem->room_num]; + const int32_t z_sector = (g_LaraItem->pos.z - r->pos.z) >> WALL_SHIFT; + const int32_t x_sector = (g_LaraItem->pos.x - r->pos.x) >> WALL_SHIFT; + g_LaraItem->box_num = r->sector[z_sector + x_sector * r->z_size].box; + + if (g_Lara.creature == NULL) { + g_Lara.current_active = 0; + return; + } + + XYZ_32 target; + if (Box_CalculateTarget(&target, item, &g_Lara.creature->lot) + == TARGET_NONE) { + return; + } + + target.x -= item->pos.x; + if (target.x > g_Lara.current_active) { + item->pos.x += g_Lara.current_active; + } else if (target.x < -g_Lara.current_active) { + item->pos.x -= g_Lara.current_active; + } else { + item->pos.x += target.x; + } + + target.z -= item->pos.z; + if (target.z > g_Lara.current_active) { + item->pos.z += g_Lara.current_active; + } else if (target.z < -g_Lara.current_active) { + item->pos.z -= g_Lara.current_active; + } else { + item->pos.z += target.z; + } + + target.y = target.y - item->pos.y; + if (target.y > g_Lara.current_active) { + item->pos.y += g_Lara.current_active; + } else if (target.y < -g_Lara.current_active) { + item->pos.y -= g_Lara.current_active; + } else { + item->pos.y += target.y; + } + + g_Lara.current_active = 0; + coll->facing = + Math_Atan(item->pos.z - coll->old.z, item->pos.x - coll->old.x); + Collide_GetCollisionInfo( + coll, item->pos.x, item->pos.y + LARA_HEIGHT_UW / 2, item->pos.z, + room_num, LARA_HEIGHT_UW); + + switch (coll->coll_type) { + case COLL_FRONT: + if (item->rot.x > 35 * PHD_DEGREE) { + item->rot.x = item->rot.x + LARA_UW_WALL_DEFLECT; + } else if (item->rot.x < -35 * PHD_DEGREE) { + item->rot.x = item->rot.x - LARA_UW_WALL_DEFLECT; + } else { + item->fall_speed = 0; + } + break; + + case COLL_TOP: + item->rot.x -= LARA_UW_WALL_DEFLECT; + break; + + case COLL_TOP_FRONT: + item->fall_speed = 0; + break; + + case COLL_LEFT: + item->rot.y += 910; + break; + + case COLL_RIGHT: + item->rot.y -= 910; + break; + + default: + break; + } + + if (coll->side_mid.floor < 0) { + item->pos.y += coll->side_mid.floor; + item->rot.x += LARA_UW_WALL_DEFLECT; + } + Item_ShiftCol(item, coll); + + coll->old = item->pos; +} + +void __cdecl Lara_CatchFire(void) +{ + if (g_Lara.burn || g_Lara.water_status == LWS_CHEAT) { + return; + } + + const int16_t fx_num = Effect_Create(g_LaraItem->room_num); + if (fx_num == NO_ITEM) { + return; + } + + FX_INFO *const fx = &g_Effects[fx_num]; + fx->frame_num = 0; + fx->object_id = O_FLAME; + fx->counter = -1; + g_Lara.burn = 1; +} + +void __cdecl Lara_TouchLava(ITEM_INFO *const item) +{ + if (item->hit_points < 0 || g_Lara.water_status == LWS_CHEAT) { + return; + } + + int16_t room_num = item->room_num; + const SECTOR_INFO *const sector = + Room_GetSector(item->pos.x, MAX_HEIGHT, item->pos.z, &room_num); + const int32_t height = + Room_GetHeight(sector, item->pos.x, MAX_HEIGHT, item->pos.z); + if (item->floor != height) { + return; + } + + item->hit_points = -1; + item->hit_status = 1; + + for (int32_t i = 0; i < 10; i++) { + const int16_t fx_num = Effect_Create(item->room_num); + if (fx_num != NO_ITEM) { + FX_INFO *const fx = &g_Effects[fx_num]; + fx->object_id = O_FLAME; + fx->frame_num = + g_Objects[O_FLAME].mesh_count * Random_GetControl() / 0x7FFF; + fx->counter = -1 - 24 * Random_GetControl() / 0x7FFF; + } + } +} void __cdecl Lara_Extinguish(void) { diff --git a/src/game/lara/lara_misc.h b/src/game/lara/misc.h similarity index 100% rename from src/game/lara/lara_misc.h rename to src/game/lara/misc.h diff --git a/src/game/lara/lara_state.c b/src/game/lara/state.c similarity index 99% rename from src/game/lara/lara_state.c rename to src/game/lara/state.c index 409af56e..02bb64aa 100644 --- a/src/game/lara/lara_state.c +++ b/src/game/lara/state.c @@ -1,10 +1,10 @@ -#include "game/lara/lara_state.h" +#include "game/lara/state.h" #include "game/input.h" #include "game/inventory/backpack.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_look.h" -#include "game/lara/lara_misc.h" +#include "game/lara/control.h" +#include "game/lara/look.h" +#include "game/lara/misc.h" #include "game/music.h" #include "game/output.h" #include "game/room.h" diff --git a/src/game/lara/lara_state.h b/src/game/lara/state.h similarity index 100% rename from src/game/lara/lara_state.h rename to src/game/lara/state.h diff --git a/src/game/level.c b/src/game/level.c index 4fd4b037..5a8353f9 100644 --- a/src/game/level.c +++ b/src/game/level.c @@ -243,13 +243,13 @@ static int32_t __cdecl M_LoadAnims(VFILE *const file, int32_t **frame_pointers) BENCHMARK *const benchmark = Benchmark_Start(); const int32_t num_anims = VFile_ReadS32(file); LOG_INFO("anims: %d", num_anims); - g_Anims = game_malloc(sizeof(ANIM_STRUCT) * num_anims, GBUF_ANIMS); + g_Anims = game_malloc(sizeof(ANIM) * num_anims, GBUF_ANIMS); if (frame_pointers != NULL) { *frame_pointers = Memory_Alloc(sizeof(int32_t) * num_anims); } for (int32_t i = 0; i < num_anims; i++) { - ANIM_STRUCT *const anim = &g_Anims[i]; + ANIM *const anim = &g_Anims[i]; const int32_t frame_idx = VFile_ReadS32(file); if (frame_pointers != NULL) { (*frame_pointers)[i] = frame_idx; @@ -886,7 +886,7 @@ bool __cdecl Level_Load(const char *const file_name, const int32_t level_num) M_LoadAnimFrames(file); for (int32_t i = 0; i < num_anims; i++) { - ANIM_STRUCT *const anim = &g_Anims[i]; + ANIM *const anim = &g_Anims[i]; // TODO: this is horrible anim->frame_ptr = ((int16_t *)g_AnimFrames) + frame_pointers[i] / 2; } diff --git a/src/game/objects/common.c b/src/game/objects/common.c index 7276dd5c..3f1586c8 100644 --- a/src/game/objects/common.c +++ b/src/game/objects/common.c @@ -1,7 +1,7 @@ #include "game/objects/common.h" #include "game/items.h" -#include "game/lara/lara_misc.h" +#include "game/lara/misc.h" #include "global/funcs.h" #include "global/vars.h" diff --git a/src/game/objects/effects/ember.c b/src/game/objects/effects/ember.c index d1b82cc1..ceebb2c9 100644 --- a/src/game/objects/effects/ember.c +++ b/src/game/objects/effects/ember.c @@ -1,8 +1,8 @@ #include "game/objects/effects/ember.h" #include "game/effects.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_misc.h" +#include "game/lara/control.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/room.h" #include "global/vars.h" diff --git a/src/game/objects/effects/flame.c b/src/game/objects/effects/flame.c index efb8602c..8ee20f0d 100644 --- a/src/game/objects/effects/flame.c +++ b/src/game/objects/effects/flame.c @@ -2,8 +2,8 @@ #include "game/collide.h" #include "game/effects.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_misc.h" +#include "game/lara/control.h" +#include "game/lara/misc.h" #include "game/room.h" #include "game/sound.h" #include "global/funcs.h" diff --git a/src/game/objects/general/body_part.c b/src/game/objects/general/body_part.c index 274e0e3d..00bef5c8 100644 --- a/src/game/objects/general/body_part.c +++ b/src/game/objects/general/body_part.c @@ -1,8 +1,8 @@ #include "game/objects/general/body_part.h" #include "game/effects.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_misc.h" +#include "game/lara/control.h" +#include "game/lara/misc.h" #include "game/math.h" #include "game/room.h" #include "game/sound.h" diff --git a/src/game/objects/general/door.c b/src/game/objects/general/door.c index cf904274..416a35c7 100644 --- a/src/game/objects/general/door.c +++ b/src/game/objects/general/door.c @@ -1,7 +1,7 @@ #include "game/objects/general/door.h" #include "game/items.h" -#include "game/lara/lara_misc.h" +#include "game/lara/misc.h" #include "global/funcs.h" #include "global/vars.h" diff --git a/src/game/objects/vehicles/boat.c b/src/game/objects/vehicles/boat.c index cfb04c4a..15c3ece0 100644 --- a/src/game/objects/vehicles/boat.c +++ b/src/game/objects/vehicles/boat.c @@ -4,7 +4,7 @@ #include "game/effects.h" #include "game/input.h" #include "game/items.h" -#include "game/lara/lara_look.h" +#include "game/lara/look.h" #include "game/math.h" #include "game/objects/common.h" #include "game/random.h" diff --git a/src/game/room.c b/src/game/room.c index 1bc5c093..78a163b0 100644 --- a/src/game/room.c +++ b/src/game/room.c @@ -3,7 +3,7 @@ #include "game/box.h" #include "game/camera.h" #include "game/items.h" -#include "game/lara/lara_misc.h" +#include "game/lara/misc.h" #include "game/lot.h" #include "game/math.h" #include "game/music.h" diff --git a/src/game/room_draw.c b/src/game/room_draw.c index ed65f9d9..1a04bf18 100644 --- a/src/game/room_draw.c +++ b/src/game/room_draw.c @@ -1,7 +1,7 @@ #include "game/room_draw.h" #include "game/effects.h" -#include "game/lara/lara_draw.h" +#include "game/lara/draw.h" #include "game/matrix.h" #include "game/output.h" #include "global/funcs.h" @@ -434,7 +434,7 @@ void __cdecl Room_DrawSingleRoomObjects(const int16_t room_num) while (fx_num != NO_ITEM) { const FX_INFO *const fx = &g_Effects[fx_num]; Effect_Draw(fx_num); - fx_num = fx->next_fx; + fx_num = fx->next_free; } Matrix_Pop(); diff --git a/src/global/types.h b/src/global/types.h index 7e2f4fc0..7879c65d 100644 --- a/src/global/types.h +++ b/src/global/types.h @@ -5,7 +5,10 @@ #include "const.h" #include +#include #include +#include +#include #include #include @@ -465,15 +468,6 @@ typedef enum { DRAW_COLOR_KEY = 1, } DRAW_TYPE; -typedef struct __unaligned { - int16_t min_x; - int16_t max_x; - int16_t min_y; - int16_t max_y; - int16_t min_z; - int16_t max_z; -} BOUNDS_16; - typedef struct __unaligned { int16_t mesh_idx; uint16_t flags; @@ -553,20 +547,6 @@ typedef struct __unaligned { int16_t sample_num; } WEAPON_INFO; -typedef struct __unaligned { - XYZ_32 pos; - XYZ_16 rot; - int16_t room_num; - int16_t object_id; - int16_t next_fx; - int16_t next_active; - int16_t speed; - int16_t fall_speed; - int16_t frame_num; - int16_t counter; - int16_t shade; -} FX_INFO; - typedef struct __unaligned { int16_t zone_num; int16_t enemy_zone_num; @@ -577,28 +557,6 @@ typedef struct __unaligned { int16_t enemy_facing; } AI_INFO; -typedef struct __unaligned { - int16_t exit_box; - uint16_t search_num; - int16_t next_expansion; - int16_t box_num; -} BOX_NODE; - -typedef struct __unaligned { - BOX_NODE *node; - int16_t head; - int16_t tail; - uint16_t search_num; - uint16_t block_mask; - int16_t step; - int16_t drop; - int16_t fly; - int16_t zone_count; - int16_t target_box; - int16_t required_box; - XYZ_32 target; -} LOT_INFO; - typedef enum { GFL_NOLEVEL = -1, GFL_TITLE = 0, @@ -750,13 +708,6 @@ typedef enum { GFE_REMOVE_AMMO = 22, } GF_EVENTS; -typedef enum { - MOOD_BORED = 0, - MOOD_ATTACK = 1, - MOOD_ESCAPE = 2, - MOOD_STALK = 3, -} MOOD_TYPE; - typedef enum { TARGET_NONE = 0, TARGET_PRIMARY = 1, @@ -768,35 +719,6 @@ typedef struct __unaligned { int32_t mesh_num; } BITE_INFO; -typedef struct __unaligned { - int16_t *frame_ptr; - int16_t interpolation; - int16_t current_anim_state; - int32_t velocity; - int32_t acceleration; - int16_t frame_base; - int16_t frame_end; - int16_t jump_anim_num; - int16_t jump_frame_num; - int16_t num_changes; - int16_t change_idx; - int16_t num_commands; - int16_t command_idx; -} ANIM_STRUCT; - -typedef struct { - int16_t goal_anim_state; - int16_t num_ranges; - int16_t range_idx; -} ANIM_CHANGE; - -typedef struct { - int16_t start_frame; - int16_t end_frame; - int16_t link_anim_num; - int16_t link_frame_num; -} ANIM_RANGE; - typedef struct __unaligned { int16_t room; int16_t x; @@ -874,18 +796,6 @@ typedef struct __unaligned { uint16_t flags; } ROOM_INFO; -typedef struct __unaligned { - int16_t head_rotation; - int16_t neck_rotation; - int16_t maximum_turn; - uint16_t flags; - int16_t item_num; - MOOD_TYPE mood; - LOT_INFO lot; - XYZ_32 target; - ITEM_INFO *enemy; -} CREATURE_INFO; - typedef enum { CAM_CHASE = 0, CAM_FIXED = 1, @@ -1048,86 +958,6 @@ typedef struct __unaligned { XYZ_32 mic_pos; } CAMERA_INFO; -typedef struct __unaligned { - int16_t *frame_base; - int16_t frame_num; - int16_t anim_num; - int16_t lock; - struct __unaligned { - int16_t y; - int16_t x; - int16_t z; - } rot; // TODO: XYZ_16 - int16_t flash_gun; -} LARA_ARM; - -typedef struct __unaligned { - int32_t ammo; -} AMMO_INFO; - -typedef enum { - LWS_ABOVE_WATER = 0, - LWS_UNDERWATER = 1, - LWS_SURFACE = 2, - LWS_CHEAT = 3, - LWS_WADE = 4, -} LARA_WATER_STATE; - -typedef struct __unaligned { - int16_t item_num; - int16_t gun_status; - int16_t gun_type; - int16_t request_gun_type; - int16_t last_gun_type; - int16_t calc_fallspeed; - int16_t water_status; - int16_t climb_status; - int16_t pose_count; - int16_t hit_frame; - int16_t hit_direction; - int16_t air; - int16_t dive_count; - int16_t death_timer; - int16_t current_active; - int16_t spaz_effect_count; - int16_t flare_age; - int16_t skidoo; - int16_t weapon_item; - int16_t back_gun; - int16_t flare_frame; - uint16_t flare_control_left: 1; // 0x01 1 - uint16_t flare_control_right: 1; // 0x02 2 - uint16_t extra_anim: 1; // 0x04 4 - uint16_t look: 1; // 0x08 8 - uint16_t burn: 1; // 0x10 16 - uint16_t pad: 11; - int32_t water_surface_dist; - XYZ_32 last_pos; - FX_INFO *spaz_effect; - uint32_t mesh_effects; - int16_t *mesh_ptrs[15]; - ITEM_INFO *target; - int16_t target_angles[2]; - int16_t turn_rate; - int16_t move_angle; - int16_t head_y_rot; - int16_t head_x_rot; - int16_t head_z_rot; - int16_t torso_y_rot; - int16_t torso_x_rot; - int16_t torso_z_rot; - LARA_ARM left_arm; - LARA_ARM right_arm; - AMMO_INFO pistol_ammo; - AMMO_INFO magnum_ammo; - AMMO_INFO uzi_ammo; - AMMO_INFO shotgun_ammo; - AMMO_INFO harpoon_ammo; - AMMO_INFO grenade_ammo; - AMMO_INFO m16_ammo; - CREATURE_INFO *creature; -} LARA_INFO; - typedef enum { SFX_LARA_FEET = 0, SFX_LARA_CLIMB2 = 1, @@ -1511,14 +1341,6 @@ typedef struct __unaligned { int16_t roll; } CINE_FRAME; -typedef enum { - IF_ONE_SHOT = 0x0100, - IF_CODE_BITS = 0x3E00, - IF_REVERSE = 0x4000, - IF_INVISIBLE = 0x0100, - IF_KILLED = 0x8000, -} ITEM_FLAG; - typedef enum { IS_INACTIVE = 0, IS_ACTIVE = 1, @@ -1530,364 +1352,6 @@ typedef struct __unaligned { uint16_t key[14]; // INPUT_ROLE_NUMBER_OF } CONTROL_LAYOUT; -typedef enum { - LA_RUN = 0, - LA_WALK_FORWARD = 1, - LA_WALK_STOP_RIGHT = 2, - LA_WALK_STOP_LEFT = 3, - LA_WALK_TO_RUN_RIGHT = 4, - LA_WALK_TO_RUN_LEFT = 5, - LA_RUN_START = 6, - LA_RUN_TO_WALK_RIGHT = 7, - LA_RUN_TO_STAND_LEFT = 8, - LA_RUN_TO_WALK_LEFT = 9, - LA_RUN_TO_STAND_RIGHT = 10, - LA_STAND_STILL = 11, - LA_TURN_RIGHT_SLOW = 12, - LA_TURN_LEFT_SLOW = 13, - LA_JUMP_FORWARD_LAND_START = 14, - LA_JUMP_FORWARD_LAND_END_UNUSED = 15, - LA_RUN_JUMP_RIGHT_START = 16, - LA_RUN_JUMP_RIGHT_CONTINUE = 17, - LA_RUN_JUMP_LEFT_START = 18, - LA_RUN_JUMP_LEFT_CONTINUE = 19, - LA_WALK_FORWARD_START = 20, - LA_WALK_FORWARD_START_CONTINUE = 21, - LA_JUMP_FORWARD_TO_FREEFALL = 22, - LA_FREEFALL = 23, - LA_FREEFALL_LAND = 24, - LA_FREEFALL_LAND_DEATH = 25, - LA_STAND_TO_JUMP_UP = 26, - LA_STAND_TO_JUMP_UP_CONTINUE = 27, - LA_JUMP_UP = 28, - LA_JUMP_UP_TO_HANG = 29, - LA_JUMP_UP_TO_FREEFALL = 30, - LA_JUMP_UP_LAND = 31, - LA_SMASH_JUMP = 32, - LA_SMASH_JUMP_CONTINUE = 33, - LA_FALL_START = 34, - LA_FALL = 35, - LA_FALL_TO_FREEFALL = 36, - LA_HANG_TO_FREEFALL = 37, - LA_WALK_BACK_END_RIGHT = 38, - LA_WALK_BACK_END_LEFT = 39, - LA_WALK_BACK = 40, - LA_WALK_BACK_START = 41, - LA_CLIMB_3CLICK = 42, - LA_CLIMB_3CLICK_END_TO_RUN = 43, - LA_TURN_RIGHT = 44, - LA_JUMP_FORWARD_TO_FREEFALL_2 = 45, - LA_REACH_TO_FREEFALL = 46, - LA_ROLL_ALTERNATE = 47, - LA_ROLL_END_ALTERNATE = 48, - LA_JUMP_FORWARD_END_TO_FREEFALL = 49, - LA_CLIMB_2CLICK = 50, - LA_CLIMB_2CLICK_END = 51, - LA_CLIMB_2CLICK_END_TO_RUN = 52, - LA_WALL_SMASH_LEFT = 53, - LA_WALL_SMASH_RIGHT = 54, - LA_RUN_UP_STEP_RIGHT = 55, - LA_RUN_UP_STEP_LEFT = 56, - LA_WALK_UP_STEP_RIGHT = 57, - LA_WALK_UP_STEP_LEFT = 58, - LA_WALK_DOWN_LEFT = 59, - LA_WALK_DOWN_RIGHT = 60, - LA_WALK_DOWN_BACK_LEFT = 61, - LA_WALK_DOWN_BACK_RIGHT = 62, - LA_WALLSWITCH_DOWN = 63, - LA_WALLSWITCH_UP = 64, - LA_SIDESTEP_LEFT = 65, - LA_SIDESTEP_LEFT_END = 66, - LA_SIDESTEP_RIGHT = 67, - LA_SIDESTEP_RIGHT_END = 68, - LA_ROTATE_LEFT = 69, - LA_SLIDE_FORWARD = 70, - LA_SLIDE_FORWARD_END = 71, - LA_SLIDE_FORWARD_STOP = 72, - LA_STAND_TO_JUMP = 73, - LA_JUMP_BACK_START = 74, - LA_JUMP_BACK = 75, - LA_JUMP_FORWARD_START = 76, - LA_JUMP_FORWARD = 77, - LA_JUMP_LEFT_START = 78, - LA_JUMP_LEFT = 79, - LA_JUMP_RIGHT_START = 80, - LA_JUMP_RIGHT = 81, - LA_LAND = 82, - LA_JUMP_BACK_TO_FREEFALL = 83, - LA_JUMP_LEFT_TO_FREEFALL = 84, - LA_JUMP_RIGHT_TO_FREEFALL = 85, - LA_UNDERWATER_SWIM_FORWARD = 86, - LA_UNDERWATER_SWIM_FORWARD_DRIFT = 87, - LA_SMALL_JUMP_BACK_START = 88, - LA_SMALL_JUMP_BACK = 89, - LA_SMALL_JUMP_BACK_END = 90, - LA_JUMP_UP_START = 91, - LA_LAND_TO_RUN = 92, - LA_FALL_BACK = 93, - LA_JUMP_FORWARD_TO_REACH = 94, - LA_REACH = 95, - LA_REACH_TO_HANG = 96, - LA_CLIMB_ON = 97, - LA_REACH_TO_FREEFALL_2 = 98, - LA_FALL_CROUCHING_LANDING = 99, - LA_JUMP_FORWARD_TO_REACH_LATE = 100, - LA_JUMP_FORWARD_START_TO_REACH_ALTERNATE = 101, - LA_CLIMB_ON_END = 102, - LA_STAND_IDLE = 103, - LA_SLIDE_BACKWARD_START = 104, - LA_SLIDE_BACKWARD = 105, - LA_SLIDE_BACKWARD_END = 106, - LA_UNDERWATER_SWIM_TO_IDLE = 107, - LA_UNDERWATER_IDLE = 108, - LA_UNDERWARER_IDLE_TO_SWIM = 109, - LA_ONWATER_IDLE = 110, - LA_ONWATER_TO_STAND_HIGH = 111, - LA_FREEFALL_TO_UNDERWATER = 112, - LA_ONWATER_DIVE_ALTERNATE = 113, - LA_UNDERWATER_TO_ONWATER = 114, - LA_ONWATER_SWIM_FORWARD_DIVE = 115, - LA_ONWATER_SWIM_FORWARD = 116, - LA_ONWATER_SWIM_FORWARD_TO_IDLE = 117, - LA_ONWATER_IDLE_TO_SWIM_FORWARD = 118, - LA_ONWATER_DIVE = 119, - LA_PUSHABLE_GRAB = 120, - LA_PUSHABLE_RELEASE = 121, - LA_PUSHABLE_PULL = 122, - LA_PUSHABLE_PUSH = 123, - LA_UNDERWATER_DEATH = 124, - LA_HIT_FRONT = 125, - LA_HIT_BACK = 126, - LA_HIT_LEFT = 127, - LA_HIT_RIGHT = 128, - LA_UNDERWATER_SWITCH = 129, - LA_UNDERWATER_PICKUP = 130, - LA_USE_KEY = 131, - LA_ONWATER_DEATH = 132, - LA_RUN_DEATH = 133, - LA_USE_PUZZLE = 134, - LA_PICKUP = 135, - LA_SHIMMY_LEFT = 136, - LA_SHIMMY_RIGHT = 137, - LA_STAND_DEATH = 138, - LA_BOULDER_DEATH = 139, - LA_ONWATER_IDLE_TO_SWIM_BACK = 140, - LA_ONWATER_SWIM_BACK = 141, - LA_ONWATER_SWIM_BACK_TO_IDLE = 142, - LA_ONWATER_SWIM_LEFT = 143, - LA_ONWATER_SWIM_RIGHT = 144, - LA_DEATH_JUMP = 145, - LA_ROLL_START = 146, - LA_ROLL_CONTINUE = 147, - LA_ROLL_END = 148, - LA_SPIKE_DEATH = 149, - LA_REACH_TO_THIN_LEDGE = 150, - LA_SWANDIVE_ROLL = 151, - LA_SWANDIVE_TO_UNDERWATER = 152, - LA_FREEFALL_SWANDIVE = 153, - LA_FREEFALL_SWANDIVE_TO_UNDERWATER = 154, - LA_SWANDIVE_DEATH = 155, - LA_SWANDIVE_LEFT = 156, - LA_SWANDIVE_RIGHT = 157, - LA_SWANDIVE_START = 158, - LA_CLIMB_ON_HANDSTAND = 159, - LA_STAND_TO_LADDER = 160, - LA_LADDER_UP = 161, - LA_LADDER_UP_STOP_RIGHT = 162, - LA_LADDER_UP_STOP_LEFT = 163, - LA_LADDER_IDLE = 164, - LA_LADDER_UP_START = 165, - LA_LADDER_DOWN_STOP_LEFT = 166, - LA_LADDER_DOWN_STOP_RIGHT = 167, - LA_LADDER_DOWN = 168, - LA_LADDER_DOWN_START = 169, - LA_LADDER_RIGHT = 170, - LA_LADDER_LEFT = 171, - LA_LADDER_HANG = 172, - LA_LADDER_HANG_TO_IDLE = 173, - LA_LADDER_CLIMB_ON = 174, - LA_UNKNOWN = 175, - LA_ONWATER_TO_WADE_SHALLOW = 176, - LA_WADE = 177, - LA_RUN_TO_WADE_LEFT = 178, - LA_RUN_TO_WADE_RIGHT = 179, - LA_WADE_TO_RUN_LEFT = 180, - LA_WADE_TO_RUN_RIGHT = 181, - LA_LADDER_BACKFLIP_START = 182, - LA_LADDER_BACKFLIP_CONTINUE = 183, - LA_WADE_TO_STAND_RIGHT = 184, - LA_WADE_TO_STAND_LEFT = 185, - LA_STAND_TO_WADE = 186, - LA_LADDER_UP_HANGING = 187, - LA_LADDER_DOWN_HANGING = 188, - LA_FLARE_THROW = 189, - LA_ONWATER_TO_WADE = 190, - LA_ONWATER_TO_STAND_MEDIUM = 191, - LA_UNDERWATER_TO_STAND = 192, - LA_ONWATER_TO_WADE_LOW = 193, - LA_LADDER_TO_HANG_DOWN = 194, - LA_SWITCH_SMALL_DOWN = 195, - LA_SWITCH_SMALL_UP = 196, - LA_BUTTON_PUSH = 197, - LA_UNDERWATER_SWIM_TO_STILL_HUDDLE = 198, - LA_UNDERWATER_SWIM_TO_STILL_SPRAWL = 199, - LA_UNDERWATER_SWIM_TO_STILL_MEDIUM = 200, - LA_LADDER_TO_HANG_RIGHT = 201, - LA_LADDER_TO_HANG_LEFT = 202, - LA_UNDERWATER_ROLL_START = 203, - LA_FLARE_PICKUP = 204, - LA_UNDERWATER_ROLL_END = 205, - LA_UNDERWATER_FLARE_PICKUP = 206, - LA_RUN_JUMP_ROLL_START = 207, - LA_SOMERSAULT = 208, - LA_RUN_JUMP_ROLL_END = 209, - LA_JUMP_FORWARD_ROLL_START = 210, - LA_JUMP_FORWARD_ROLL_END = 211, - LA_JUMP_BACK_ROLL_START = 212, - LA_JUMP_BACK_ROLL_END = 213, - LA_KICK = 214, - LA_ZIPLINE_GRAB = 215, - LA_ZIPLINE_RIDE = 216, - LA_ZIPLINE_FALL = 217, -} LARA_ANIMATION; - -typedef enum { - LA_EXTRA_BREATH = 0, - LA_EXTRA_PLUNGER = 1, - LA_EXTRA_YETI_KILL = 2, - LA_EXTRA_SHARK_KILL = 3, - LA_EXTRA_AIRLOCK = 4, - LA_EXTRA_GONG_BONG = 5, - LA_EXTRA_DINO_KILL = 6, - LA_EXTRA_PULL_DAGGER = 7, - LA_EXTRA_START_ANIM = 8, - LA_EXTRA_START_HOUSE = 9, - LA_EXTRA_FINAL_ANIM = 10, -} LARA_EXTRA_ANIMATION; - -typedef enum { - LS_WALK = 0, - LS_RUN = 1, - LS_STOP = 2, - LS_FORWARD_JUMP = 3, - LS_POSE = 4, - LS_FAST_BACK = 5, - LS_TURN_RIGHT = 6, - LS_TURN_LEFT = 7, - LS_DEATH = 8, - LS_FAST_FALL = 9, - LS_HANG = 10, - LS_REACH = 11, - LS_SPLAT = 12, - LS_TREAD = 13, - LS_LAND = 14, - LS_COMPRESS = 15, - LS_BACK = 16, - LS_SWIM = 17, - LS_GLIDE = 18, - LS_NULL = 19, - LS_FAST_TURN = 20, - LS_STEP_RIGHT = 21, - LS_STEP_LEFT = 22, - LS_HIT = 23, - LS_SLIDE = 24, - LS_BACK_JUMP = 25, - LS_RIGHT_JUMP = 26, - LS_LEFT_JUMP = 27, - LS_UP_JUMP = 28, - LS_FALL_BACK = 29, - LS_HANG_LEFT = 30, - LS_HANG_RIGHT = 31, - LS_SLIDE_BACK = 32, - LS_SURF_TREAD = 33, - LS_SURF_SWIM = 34, - LS_DIVE = 35, - LS_PUSH_BLOCK = 36, - LS_PULL_BLOCK = 37, - LS_PP_READY = 38, - LS_PICKUP = 39, - LS_SWITCH_ON = 40, - LS_SWITCH_OFF = 41, - LS_USE_KEY = 42, - LS_USE_PUZZLE = 43, - LS_UW_DEATH = 44, - LS_ROLL = 45, - LS_SPECIAL = 46, - LS_SURF_BACK = 47, - LS_SURF_LEFT = 48, - LS_SURF_RIGHT = 49, - LS_USE_MIDAS = 50, - LS_DIE_MIDAS = 51, - LS_SWAN_DIVE = 52, - LS_FAST_DIVE = 53, - LS_GYMNAST = 54, - LS_WATER_OUT = 55, - LS_CLIMB_STANCE = 56, - LS_CLIMBING = 57, - LS_CLIMB_LEFT = 58, - LS_CLIMB_END = 59, - LS_CLIMB_RIGHT = 60, - LS_CLIMB_DOWN = 61, - LS_LARA_TEST1 = 62, - LS_LARA_TEST2 = 63, - LS_LARA_TEST3 = 64, - LS_WADE = 65, - LS_WATER_ROLL = 66, - LS_FLARE_PICKUP = 67, - LS_TWIST = 68, - LS_KICK = 69, - LS_DEATH_SLIDE = 70, - LS_DUCK = 71, - LS_DUCK_ROLL = 72, - LS_DASH = 73, - LS_DASH_DIVE = 74, - LS_MONKEY_SWING = 75, - LS_MONKEYF = 76, - LS_LAST = 77, -} LARA_STATE; - -typedef enum { - LGS_ARMLESS = 0, - LGS_HANDS_BUSY = 1, - LGS_DRAW = 2, - LGS_UNDRAW = 3, - LGS_READY = 4, - LGS_SPECIAL = 5, -} LARA_GUN_STATE; - -typedef enum { - LGT_UNARMED = 0, - LGT_PISTOLS = 1, - LGT_MAGNUMS = 2, - LGT_UZIS = 3, - LGT_SHOTGUN = 4, - LGT_M16 = 5, - LGT_GRENADE = 6, - LGT_HARPOON = 7, - LGT_FLARE = 8 , - LGT_SKIDOO = 9, - NUM_WEAPONS = 10, -} LARA_GUN_TYPE; - -typedef enum { - LM_HIPS = 0, - LM_THIGH_L = 1, - LM_CALF_L = 2, - LM_FOOT_L = 3, - LM_THIGH_R = 4, - LM_CALF_R = 5, - LM_FOOT_R = 6, - LM_TORSO = 7, - LM_UARM_R = 8, - LM_LARM_R = 9, - LM_HAND_R = 10, - LM_UARM_L = 11, - LM_LARM_L = 12, - LM_HAND_L = 13, - LM_HEAD = 14, - LM_NUMBER_OF = 15, -} LARA_MESH; - typedef enum { MX_INACTIVE = -1, MX_UNUSED_0 = 0, // 2.mp3 @@ -1984,14 +1448,6 @@ typedef enum { HT_BIG_SLOPE = 2, } HEIGHT_TYPE; -typedef enum { - DIR_UNKNOWN = -1, - DIR_NORTH = 0, - DIR_EAST = 1, - DIR_SOUTH = 2, - DIR_WEST = 3, -} DIRECTION; - typedef struct __unaligned { uint16_t x; uint16_t y; diff --git a/src/global/vars_decomp.h b/src/global/vars_decomp.h index c38aa819..2fd5551a 100644 --- a/src/global/vars_decomp.h +++ b/src/global/vars_decomp.h @@ -450,7 +450,7 @@ #define g_IMMatrixStack (*(MATRIX(*)[256])0x005252C0) #define g_DoorVBuf (*(DOOR_VBUF(*)[4])0x005258C0) #define g_IMFrac (*(int32_t*)0x005258F0) -#define g_Anims (*(ANIM_STRUCT **)0x005258F4) +#define g_Anims (*(ANIM **)0x005258F4) #define g_BoundRooms (*(int32_t(*)[128])0x00525900) #define g_OutsideBottom (*(int32_t*)0x00525B00) #define g_AnimRanges (*(ANIM_RANGE **)0x00525B04) diff --git a/src/inject_exec.c b/src/inject_exec.c index 3af86d2d..94045194 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -22,13 +22,13 @@ #include "game/inventory/common.h" #include "game/inventory/ring.h" #include "game/items.h" -#include "game/lara/lara_cheat.h" -#include "game/lara/lara_col.h" -#include "game/lara/lara_control.h" -#include "game/lara/lara_draw.h" -#include "game/lara/lara_look.h" -#include "game/lara/lara_misc.h" -#include "game/lara/lara_state.h" +#include "game/lara/cheat.h" +#include "game/lara/col.h" +#include "game/lara/control.h" +#include "game/lara/draw.h" +#include "game/lara/look.h" +#include "game/lara/misc.h" +#include "game/lara/state.h" #include "game/level.h" #include "game/los.h" #include "game/lot.h" diff --git a/src/specific/s_input.c b/src/specific/s_input.c index 97936260..b57ffbdc 100644 --- a/src/specific/s_input.c +++ b/src/specific/s_input.c @@ -5,7 +5,7 @@ #include "game/gameflow/gameflow_new.h" #include "game/input.h" #include "game/inventory/backpack.h" -#include "game/lara/lara_control.h" +#include "game/lara/control.h" #include "global/const.h" #include "global/funcs.h" #include "global/vars.h" diff --git a/subprojects/libtrx b/subprojects/libtrx index 41cd1a09..c984f369 160000 --- a/subprojects/libtrx +++ b/subprojects/libtrx @@ -1 +1 @@ -Subproject commit 41cd1a09e3ea1c445df702cd9fa0d7682761459f +Subproject commit c984f369d2e7903ec0cd4c5fa5724aeaa8d571b2 diff --git a/tools/generate_funcs b/tools/generate_funcs index 7bfd2608..08afe5ba 100755 --- a/tools/generate_funcs +++ b/tools/generate_funcs @@ -114,7 +114,10 @@ def make_types_h(types: list[str]) -> None: '#include "const.h"', "", "#include ", + "#include ", "#include ", + "#include ", + "#include ", "#include ", "#include ", "",