diff --git a/src/libtrx/game/lara/common.c b/src/libtrx/game/lara/common.c index 6c9173fc7..eded61e70 100644 --- a/src/libtrx/game/lara/common.c +++ b/src/libtrx/game/lara/common.c @@ -2,8 +2,9 @@ #include "game/const.h" #include "game/item_actions.h" +#include "game/lara/const.h" #include "game/matrix.h" -#include "game/rooms/const.h" +#include "game/rooms.h" void Lara_Animate(ITEM *const item) { @@ -206,3 +207,42 @@ bool Lara_TestPosition( ); // clang-format on } + +void Lara_AlignPosition(const ITEM *const item, const XYZ_32 *const vec) +{ + ITEM *const lara = Lara_GetItem(); + lara->rot = item->rot; + Matrix_PushUnit(); + Matrix_Rot16(item->rot); + const MATRIX *const m = g_MatrixPtr; + const XYZ_32 shift = { + .x = (vec->x * m->_00 + vec->y * m->_01 + vec->z * m->_02) >> W2V_SHIFT, + .y = (vec->x * m->_10 + vec->y * m->_11 + vec->z * m->_12) >> W2V_SHIFT, + .z = (vec->x * m->_20 + vec->y * m->_21 + 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 TR_VERSION == 2 + // TODO: check the significance of this in TR1 + int16_t room_num = lara->room_num; + const SECTOR *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); + const int32_t ceiling = + Room_GetCeiling(sector, new_pos.x, new_pos.y, new_pos.z); + + if (ABS(height - lara->pos.y) > STEP_L + || ABS(ceiling - lara->pos.y) < LARA_HEIGHT) { + return; + } +#endif + + lara->pos = new_pos; +} diff --git a/src/libtrx/include/libtrx/game/lara/common.h b/src/libtrx/include/libtrx/game/lara/common.h index ae80131aa..82e2f7357 100644 --- a/src/libtrx/include/libtrx/game/lara/common.h +++ b/src/libtrx/include/libtrx/game/lara/common.h @@ -16,3 +16,4 @@ void Lara_TakeDamage(int16_t damage, bool hit_status); bool Lara_TestBoundsCollide(const ITEM *item, int32_t radius); void Lara_Push(const ITEM *item, COLL_INFO *coll, bool hit_on, bool big_push); bool Lara_TestPosition(const ITEM *item, const OBJECT_BOUNDS *bounds); +void Lara_AlignPosition(const ITEM *item, const XYZ_32 *vec); diff --git a/src/tr1/game/items.c b/src/tr1/game/items.c index 69afbf81a..fdb607cbb 100644 --- a/src/tr1/game/items.c +++ b/src/tr1/game/items.c @@ -196,27 +196,6 @@ bool Item_Test3DRange(int32_t x, int32_t y, int32_t z, int32_t range) && (SQUARE(x) + SQUARE(y) + SQUARE(z) < SQUARE(range)); } -void Item_AlignPosition(ITEM *src_item, ITEM *dst_item, XYZ_32 *vec) -{ - src_item->rot.x = dst_item->rot.x; - src_item->rot.y = dst_item->rot.y; - src_item->rot.z = dst_item->rot.z; - - Matrix_PushUnit(); - Matrix_Rot16(dst_item->rot); - MATRIX *mptr = g_MatrixPtr; - src_item->pos.x = dst_item->pos.x - + ((mptr->_00 * vec->x + mptr->_01 * vec->y + mptr->_02 * vec->z) - >> W2V_SHIFT); - src_item->pos.y = dst_item->pos.y - + ((mptr->_10 * vec->x + mptr->_11 * vec->y + mptr->_12 * vec->z) - >> W2V_SHIFT); - src_item->pos.z = dst_item->pos.z - + ((mptr->_20 * vec->x + mptr->_21 * vec->y + mptr->_22 * vec->z) - >> W2V_SHIFT); - Matrix_Pop(); -} - bool Item_MovePosition( ITEM *item, const ITEM *ref_item, const XYZ_32 *vec, int32_t velocity) { diff --git a/src/tr1/game/items.h b/src/tr1/game/items.h index 1f961833c..c94893dfc 100644 --- a/src/tr1/game/items.h +++ b/src/tr1/game/items.h @@ -11,7 +11,6 @@ int16_t Item_Spawn(const ITEM *item, GAME_OBJECT_ID obj_id); bool Item_IsNearItem(const ITEM *item, const XYZ_32 *pos, int32_t distance); bool Item_Test3DRange(int32_t x, int32_t y, int32_t z, int32_t range); -void Item_AlignPosition(ITEM *src_item, ITEM *dst_item, XYZ_32 *vec); bool Item_MovePosition( ITEM *src_item, const ITEM *dst_item, const XYZ_32 *vec, int32_t velocity); void Item_ShiftCol(ITEM *item, COLL_INFO *coll); diff --git a/src/tr1/game/lara/common.c b/src/tr1/game/lara/common.c index ce9755f7a..6596d42fc 100644 --- a/src/tr1/game/lara/common.c +++ b/src/tr1/game/lara/common.c @@ -701,11 +701,6 @@ bool Lara_IsNearItem(const XYZ_32 *pos, int32_t distance) return Item_IsNearItem(g_LaraItem, pos, distance); } -void Lara_AlignPosition(ITEM *item, XYZ_32 *vec) -{ - Item_AlignPosition(g_LaraItem, item, vec); -} - bool Lara_MovePosition(ITEM *item, XYZ_32 *vec) { int32_t velocity = g_Config.gameplay.enable_walk_to_items diff --git a/src/tr1/game/lara/common.h b/src/tr1/game/lara/common.h index e047b7291..620b0c31e 100644 --- a/src/tr1/game/lara/common.h +++ b/src/tr1/game/lara/common.h @@ -26,7 +26,6 @@ void Lara_SwapMeshExtra(void); bool Lara_IsNearItem(const XYZ_32 *pos, int32_t distance); void Lara_UseItem(GAME_OBJECT_ID obj_id); -void Lara_AlignPosition(ITEM *item, XYZ_32 *vec); bool Lara_MovePosition(ITEM *item, XYZ_32 *vec); void Lara_RevertToPistolsIfNeeded(void); diff --git a/src/tr2/game/items.c b/src/tr2/game/items.c index 92df663c4..09c7b16ca 100644 --- a/src/tr2/game/items.c +++ b/src/tr2/game/items.c @@ -154,44 +154,6 @@ int16_t Item_GetHeight(const ITEM *const item) return height; } -void Item_AlignPosition( - const XYZ_32 *const vec, const ITEM *const src_item, ITEM *const dst_item) -{ - dst_item->rot = src_item->rot; - Matrix_PushUnit(); - Matrix_Rot16(src_item->rot); - const MATRIX *const m = g_MatrixPtr; - const XYZ_32 shift = { - .x = (vec->x * m->_00 + vec->y * m->_01 + vec->z * m->_02) >> W2V_SHIFT, - .y = (vec->x * m->_10 + vec->y * m->_11 + vec->z * m->_12) >> W2V_SHIFT, - .z = (vec->x * m->_20 + vec->y * m->_21 + vec->z * m->_22) >> W2V_SHIFT, - }; - Matrix_Pop(); - - const XYZ_32 new_pos = { - .x = src_item->pos.x + shift.x, - .y = src_item->pos.y + shift.y, - .z = src_item->pos.z + shift.z, - }; - - int16_t room_num = dst_item->room_num; - const SECTOR *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); - const int32_t ceiling = - Room_GetCeiling(sector, new_pos.x, new_pos.y, new_pos.z); - - if (ABS(height - dst_item->pos.y) > STEP_L - || ABS(ceiling - dst_item->pos.y) < LARA_HEIGHT) { - return; - } - - dst_item->pos.x = new_pos.x; - dst_item->pos.y = new_pos.y; - dst_item->pos.z = new_pos.z; -} - int32_t Item_GetFrames(const ITEM *item, ANIM_FRAME *frames[], int32_t *rate) { const ANIM *const anim = Item_GetAnim(item); diff --git a/src/tr2/game/items.h b/src/tr2/game/items.h index cb24b329a..c82d6ec0c 100644 --- a/src/tr2/game/items.h +++ b/src/tr2/game/items.h @@ -8,8 +8,6 @@ void Item_Control(void); void Item_ClearKilled(void); void Item_ShiftCol(ITEM *item, COLL_INFO *coll); void Item_UpdateRoom(ITEM *item, int32_t height); -void Item_AlignPosition( - const XYZ_32 *vec, const ITEM *src_item, ITEM *dst_item); int32_t Item_GetFrames(const ITEM *item, ANIM_FRAME *frmptr[], int32_t *rate); bool Item_IsNearItem(const ITEM *item, const XYZ_32 *pos, int32_t distance); diff --git a/src/tr2/game/objects/general/detonator.c b/src/tr2/game/objects/general/detonator.c index ec84db708..e0b0120a3 100644 --- a/src/tr2/game/objects/general/detonator.c +++ b/src/tr2/game/objects/general/detonator.c @@ -140,7 +140,7 @@ static void M_Collision( } Inv_RemoveItem(O_KEY_OPTION_2); - Item_AlignPosition(&m_DetonatorPosition, item, lara_item); + Lara_AlignPosition(item, &m_DetonatorPosition); Item_SwitchToObjAnim(lara_item, LA_EXTRA_BREATH, 0, O_LARA_EXTRA); lara_item->current_anim_state = LA_EXTRA_BREATH; if (item->object_id == O_DETONATOR_2) { diff --git a/src/tr2/game/objects/general/keyhole.c b/src/tr2/game/objects/general/keyhole.c index c564cd3df..c9b44a88f 100644 --- a/src/tr2/game/objects/general/keyhole.c +++ b/src/tr2/game/objects/general/keyhole.c @@ -57,7 +57,7 @@ static void M_Consume( const GAME_OBJECT_ID key_obj_id) { Inv_RemoveItem(key_obj_id); - Item_AlignPosition(&m_KeyholePosition, keyhole_item, lara_item); + Lara_AlignPosition(keyhole_item, &m_KeyholePosition); lara_item->goal_anim_state = LS_USE_KEY; do { Lara_Animate(lara_item); diff --git a/src/tr2/game/objects/general/pickup.c b/src/tr2/game/objects/general/pickup.c index dab94658f..2f1853f3f 100644 --- a/src/tr2/game/objects/general/pickup.c +++ b/src/tr2/game/objects/general/pickup.c @@ -134,7 +134,7 @@ static void M_DoAboveWater(const int16_t item_num, ITEM *const lara_item) lara_item->goal_anim_state = LS_STOP; g_Lara.gun_status = LGS_HANDS_BUSY; } else { - Item_AlignPosition(&m_PickupPosition, item, lara_item); + Lara_AlignPosition(item, &m_PickupPosition); lara_item->goal_anim_state = LS_PICKUP; do { Lara_Animate(lara_item); diff --git a/src/tr2/game/objects/general/puzzle_hole.c b/src/tr2/game/objects/general/puzzle_hole.c index 45aa8fe52..f63db4c5c 100644 --- a/src/tr2/game/objects/general/puzzle_hole.c +++ b/src/tr2/game/objects/general/puzzle_hole.c @@ -58,7 +58,7 @@ static void M_Consume( const GAME_OBJECT_ID puzzle_obj_id) { Inv_RemoveItem(puzzle_obj_id); - Item_AlignPosition(&m_PuzzleHolePosition, puzzle_hole_item, lara_item); + Lara_AlignPosition(puzzle_hole_item, &m_PuzzleHolePosition); lara_item->goal_anim_state = LS_USE_PUZZLE; do { Lara_Animate(lara_item); diff --git a/src/tr2/game/objects/general/switch.c b/src/tr2/game/objects/general/switch.c index 2053d2a4e..6d3de1203 100644 --- a/src/tr2/game/objects/general/switch.c +++ b/src/tr2/game/objects/general/switch.c @@ -66,15 +66,15 @@ static void M_AlignLara(ITEM *const lara_item, ITEM *const switch_item) { switch (switch_item->object_id) { case O_SWITCH_TYPE_AIRLOCK: - Item_AlignPosition(&m_AirlockPosition, switch_item, lara_item); + Lara_AlignPosition(switch_item, &m_AirlockPosition); break; case O_SWITCH_TYPE_SMALL: - Item_AlignPosition(&g_SmallSwitchPosition, switch_item, lara_item); + Lara_AlignPosition(switch_item, &g_SmallSwitchPosition); break; case O_SWITCH_TYPE_BUTTON: - Item_AlignPosition(&g_PushSwitchPosition, switch_item, lara_item); + Lara_AlignPosition(switch_item, &g_PushSwitchPosition); break; } } diff --git a/src/tr2/game/objects/general/zipline.c b/src/tr2/game/objects/general/zipline.c index 447cfa4fa..0effd9bb6 100644 --- a/src/tr2/game/objects/general/zipline.c +++ b/src/tr2/game/objects/general/zipline.c @@ -156,7 +156,7 @@ static void M_Collision( return; } - Item_AlignPosition(&m_ZiplineHandlePosition, item, lara_item); + Lara_AlignPosition(item, &m_ZiplineHandlePosition); g_Lara.gun_status = LGS_HANDS_BUSY; lara_item->goal_anim_state = LS_ZIPLINE;