diff --git a/docs/tr2/progress.svg b/docs/tr2/progress.svg index 42f3b84c3..0964cc55c 100644 --- a/docs/tr2/progress.svg +++ b/docs/tr2/progress.svg @@ -69,10 +69,10 @@ Tomb2.exe progress according to the physical function order: -69.94% (870) · 27.65% (344) · 0% (0) · 2.41% (30) +70.02% (871) · 27.57% (343) · 0% (0) · 2.41% (30) - - + + @@ -269,7 +269,7 @@ void __cdecl Demo_LoadLaraPos(void); void __cdecl Demo_GetInput(void); int16_t __cdecl Diver_Harpoon(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE y_rot, int16_t room_num); -int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); +int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl Diver_Control(int16_t item_num); void __cdecl Dog_Control(int16_t item_num); void __cdecl Tiger_Control(int16_t item_num); @@ -1324,10 +1324,10 @@ Tomb2.exe progress according to the function sizes: -74.26% · 25.42% · 0% · 0.33% +74.33% · 25.34% · 0% · 0.33% - - + + @@ -1680,7 +1680,7 @@ void __cdecl Pendulum(int16_t item_num); void __cdecl KillerStatueControl(int16_t item_num); int32_t __cdecl Text_GetWidth(TEXTSTRING *string); -int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); +int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); void __cdecl LOT_InitialiseSlot(int16_t item_num, int32_t slot); int32_t __cdecl Skidoo_CheckGetOffOK(int32_t direction); INT_PTR __stdcall SE_ControlsDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/docs/tr2/progress.txt b/docs/tr2/progress.txt index 9d47bd796..147db1891 100644 --- a/docs/tr2/progress.txt +++ b/docs/tr2/progress.txt @@ -3094,7 +3094,7 @@ typedef enum { # game/diver.c 0x00416C20 0x007A + int16_t __cdecl Diver_Harpoon(int32_t x, int32_t y, int32_t z, int16_t speed, PHD_ANGLE y_rot, int16_t room_num); -0x00416CA0 0x0106 - int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); +0x00416CA0 0x0106 + int32_t __cdecl Diver_GetWaterSurface(int32_t x, int32_t y, int32_t z, int16_t room_num); 0x00416DB0 0x0389 + void __cdecl Diver_Control(int16_t item_num); # game/dog.c diff --git a/src/tr2/game/objects/creatures/diver.c b/src/tr2/game/objects/creatures/diver.c index 924b6d05f..8941c9bac 100644 --- a/src/tr2/game/objects/creatures/diver.c +++ b/src/tr2/game/objects/creatures/diver.c @@ -3,6 +3,7 @@ #include "game/creature.h" #include "game/effects.h" #include "game/los.h" +#include "game/room.h" #include "global/const.h" #include "global/funcs.h" #include "global/vars.h" @@ -29,6 +30,44 @@ typedef enum { DIVER_ANIM_DEATH = 9, } DIVER_ANIM; +static const SECTOR *M_GetRelSector(const ROOM *r, int32_t x, int32_t z); + +static const SECTOR *M_GetRelSector( + const ROOM *const r, const int32_t x, const int32_t z) +{ + const XZ_32 sector_pos = { + .x = (x - r->pos.x) >> WALL_SHIFT, + .z = (z - r->pos.z) >> WALL_SHIFT, + }; + return &r->sectors[sector_pos.z + r->size.z * sector_pos.x]; +} + +int32_t __cdecl Diver_GetWaterSurface( + const int32_t x, const int32_t y, const int32_t z, const int16_t room_num) +{ + const ROOM *r = Room_Get(room_num); + const SECTOR *sector = M_GetRelSector(r, x, z); + + if ((r->flags & RF_UNDERWATER)) { + while (sector->sky_room != NO_ROOM) { + r = Room_Get(sector->sky_room); + if (!(r->flags & RF_UNDERWATER)) { + return sector->ceiling << 8; + } + sector = M_GetRelSector(r, x, z); + } + } else { + while (sector->pit_room != NO_ROOM) { + r = Room_Get(sector->pit_room); + if ((r->flags & RF_UNDERWATER)) { + return sector->floor << 8; + } + sector = M_GetRelSector(r, x, z); + } + } + return NO_HEIGHT; +} + void Diver_Setup(void) { OBJECT *const obj = &g_Objects[O_DIVER]; diff --git a/src/tr2/game/objects/creatures/diver.h b/src/tr2/game/objects/creatures/diver.h index 6a2e539f2..96b2bc1e5 100644 --- a/src/tr2/game/objects/creatures/diver.h +++ b/src/tr2/game/objects/creatures/diver.h @@ -2,6 +2,9 @@ #include +int32_t __cdecl Diver_GetWaterSurface( + int32_t x, int32_t y, int32_t z, int16_t room_num); + void Diver_Setup(void); void __cdecl Diver_Control(int16_t item_num); diff --git a/src/tr2/global/funcs.h b/src/tr2/global/funcs.h index 23d29ed8b..65c8efb78 100644 --- a/src/tr2/global/funcs.h +++ b/src/tr2/global/funcs.h @@ -6,7 +6,6 @@ // clang-format off #define Output_InsertInventoryBackground ((void __cdecl (*)(const int16_t *obj_ptr))0x00401D50) -#define Diver_GetWaterSurface ((int32_t __cdecl (*)(int32_t x, int32_t y, int32_t z, int16_t room_num))0x00416CA0) #define Dog_Control ((void __cdecl (*)(int16_t item_num))0x00417160) #define Tiger_Control ((void __cdecl (*)(int16_t item_num))0x00417510) #define TRex_Control ((void __cdecl (*)(int16_t item_num))0x004186A0) diff --git a/src/tr2/inject_exec.c b/src/tr2/inject_exec.c index d84aba1bd..2f8e7d463 100644 --- a/src/tr2/inject_exec.c +++ b/src/tr2/inject_exec.c @@ -1018,6 +1018,7 @@ static void M_Objects(const bool enable) INJECT(enable, 0x00413940, Door_Collision); INJECT(enable, 0x004139C0, Object_Collision_Trap); INJECT(enable, 0x00416C20, Diver_Harpoon); + INJECT(enable, 0x00416CA0, Diver_GetWaterSurface); INJECT(enable, 0x00416DB0, Diver_Control); INJECT(enable, 0x004177B0, Twinkle_Control); INJECT(enable, 0x00417AC0, Dragon_Collision);