From f017029ed0e534458371c2fec1d9a80530749511 Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Sat, 3 Aug 2024 19:10:00 +0200 Subject: [PATCH] port Lara_TestClimb --- docs/progress.svg | 16 ++--- docs/progress.txt | 2 +- src/game/lara/lara_misc.c | 125 +++++++++++++++++++++++++++++++++++++- src/game/lara/lara_misc.h | 4 ++ src/global/funcs.h | 1 - src/inject_exec.c | 1 + 6 files changed, 137 insertions(+), 12 deletions(-) diff --git a/docs/progress.svg b/docs/progress.svg index c61e846..bdbd86b 100644 --- a/docs/progress.svg +++ b/docs/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -49.10% (598) · 48.44% (590) · 0% (0) · 2.46% (30) +49.18% (599) · 48.36% (589) · 0% (0) · 2.46% (30) - - + + @@ -609,7 +609,7 @@ void __cdecl Lara_Col_Climbing(ITEM_INFO *item, COLL_INFO *coll); void __cdecl Lara_Col_ClimbDown(ITEM_INFO *item, COLL_INFO *coll); int32_t __cdecl Lara_CheckForLetGo(ITEM_INFO *item, COLL_INFO *coll); -int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); +int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); int32_t __cdecl Lara_TestClimbPos(ITEM_INFO *item, int32_t front, int32_t right, int32_t origin, int32_t height, int32_t *shift); void __cdecl Lara_DoClimbLeftRight(ITEM_INFO *item, COLL_INFO *coll, int32_t result, int32_t shift); int32_t __cdecl Lara_TestClimbUpPos(ITEM_INFO *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge); @@ -1298,10 +1298,10 @@ Tomb2.exe progress according to the function sizes: -48.72% · 50.96% · 0% · 0.33% +48.90% · 50.78% · 0% · 0.33% - - + + @@ -1444,7 +1444,7 @@ void __cdecl Output_Init(int16_t x, int16_t y, int32_t width, int32_t height, int32_t near_z, int32_t far_z, int16_t view_angle, int32_t screen_width, int32_t screen_height); int32_t __cdecl Room_GetHeight(const FLOOR_INFO *floor, int32_t x, int32_t y, int32_t z); BOOL __cdecl LoadSamples(HANDLE handle); -int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); +int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); bool __cdecl SE_WriteAppSettings(APP_SETTINGS *settings); void __cdecl S_CopyBufferToScreen(void); void __cdecl DrawTextureTile(int32_t sx, int32_t sy, int32_t width, int32_t height, HWR_TEXTURE_HANDLE tex_source, int32_t tu, int32_t tv, int32_t t_width, int32_t t_height, D3DCOLOR color0, D3DCOLOR color1, D3DCOLOR color2, D3DCOLOR color3); diff --git a/docs/progress.txt b/docs/progress.txt index ee13f4c..4c79ca5 100644 --- a/docs/progress.txt +++ b/docs/progress.txt @@ -3247,7 +3247,7 @@ typedef enum { 0x0042DC80 0x014D + void __cdecl Lara_Col_Climbing(ITEM_INFO *item, COLL_INFO *coll); 0x0042DDD0 0x019C + void __cdecl Lara_Col_ClimbDown(ITEM_INFO *item, COLL_INFO *coll); 0x0042DF70 0x00AA + int32_t __cdecl Lara_CheckForLetGo(ITEM_INFO *item, COLL_INFO *coll); -0x0042E020 0x0263 - int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); +0x0042E020 0x0263 + int32_t __cdecl Lara_TestClimb(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift); 0x0042E290 0x00BC - int32_t __cdecl Lara_TestClimbPos(ITEM_INFO *item, int32_t front, int32_t right, int32_t origin, int32_t height, int32_t *shift); 0x0042E360 0x00EF - void __cdecl Lara_DoClimbLeftRight(ITEM_INFO *item, COLL_INFO *coll, int32_t result, int32_t shift); 0x0042E450 0x0235 - int32_t __cdecl Lara_TestClimbUpPos(ITEM_INFO *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge); diff --git a/src/game/lara/lara_misc.c b/src/game/lara/lara_misc.c index 43a9998..79d75c3 100644 --- a/src/game/lara/lara_misc.c +++ b/src/game/lara/lara_misc.c @@ -15,6 +15,8 @@ #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 Lara_TakeHit_Impl( ITEM_INFO *const lara_item, const int32_t dx, const int32_t dz); @@ -252,8 +254,8 @@ int32_t __cdecl Lara_TestWall( } const FLOOR_INFO *floor = Room_GetFloor(x, y, z, &room_num); - int32_t height = Room_GetHeight(floor, x, y, z); - int32_t ceiling = Room_GetCeiling(floor, x, y, z); + const int32_t height = Room_GetHeight(floor, x, y, z); + const int32_t ceiling = Room_GetCeiling(floor, x, y, z); if (height == NO_HEIGHT) { return 1; } @@ -1220,3 +1222,122 @@ 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 FLOOR_INFO *floor; + int32_t height; + int32_t ceiling; + + int16_t room_num = item_room; + floor = Room_GetFloor(x, y - 128, z, &room_num); + height = Room_GetHeight(floor, 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(floor, 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; + floor = Room_GetFloor(x2, y, z2, &room_num); + height = Room_GetHeight(floor, x2, y, z2); + if (height != NO_HEIGHT) { + height -= y; + } + + if (height > CLIMB_SHIFT) { + ceiling = Room_GetCeiling(floor, 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; + floor = Room_GetFloor(x, item_height + y, z, &room_num); + floor = Room_GetFloor(x2, item_height + y, z2, &room_num); + ceiling = Room_GetCeiling(floor, 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; +} diff --git a/src/game/lara/lara_misc.h b/src/game/lara/lara_misc.h index 3a9a064..c534988 100644 --- a/src/game/lara/lara_misc.h +++ b/src/game/lara/lara_misc.h @@ -56,3 +56,7 @@ void __cdecl Lara_Push( int32_t __cdecl Lara_MovePosition( XYZ_32 *vec, ITEM_INFO *item, ITEM_INFO *lara_item); int32_t __cdecl Lara_IsNearItem(const XYZ_32 *pos, int32_t distance); + +int32_t __cdecl Lara_TestClimb( + int32_t x, int32_t y, int32_t z, int32_t x_front, int32_t z_front, + int32_t item_height, int16_t item_room, int32_t *shift); diff --git a/src/global/funcs.h b/src/global/funcs.h index 30a9e79..ad539cb 100644 --- a/src/global/funcs.h +++ b/src/global/funcs.h @@ -172,7 +172,6 @@ #define undraw_pistol_mesh_right ((void __cdecl (*)(int32_t weapon_type))0x0042D350) #define PistolHandler ((void __cdecl (*)(int32_t weapon_type))0x0042D390) #define AnimatePistols ((void __cdecl (*)(int32_t weapon_type))0x0042D520) -#define Lara_TestClimb ((int32_t __cdecl (*)(int32_t x, int32_t y, int32_t z, int32_t xfront, int32_t zfront, int32_t item_height, int16_t item_room, int32_t *shift))0x0042E020) #define Lara_TestClimbPos ((int32_t __cdecl (*)(ITEM_INFO *item, int32_t front, int32_t right, int32_t origin, int32_t height, int32_t *shift))0x0042E290) #define Lara_DoClimbLeftRight ((void __cdecl (*)(ITEM_INFO *item, COLL_INFO *coll, int32_t result, int32_t shift))0x0042E360) #define Lara_TestClimbUpPos ((int32_t __cdecl (*)(ITEM_INFO *item, int32_t front, int32_t right, int32_t *shift, int32_t *ledge))0x0042E450) diff --git a/src/inject_exec.c b/src/inject_exec.c index c665494..b94768d 100644 --- a/src/inject_exec.c +++ b/src/inject_exec.c @@ -567,6 +567,7 @@ static void Inject_Lara_Misc(const bool enable) INJECT(enable, 0x00413A30, Lara_Push); INJECT(enable, 0x00414090, Lara_MovePosition); INJECT(enable, 0x0041C4D0, Lara_IsNearItem); + INJECT(enable, 0x0042E020, Lara_TestClimb); } static void Inject_Lara_State(const bool enable)