mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
objects/movable_block: fix angle resetting and snapping
This restores pushblock angles after performing collision tests, and also snaps them to the grid on initialisation if a builder places them at non 90 degree angles to avoid instead snapping during collision. Resolves #2776.
This commit is contained in:
parent
dd2af3377a
commit
3e959a34db
10 changed files with 68 additions and 8 deletions
|
@ -17,6 +17,7 @@
|
|||
- fixed enemies in one-click high water appearing with a water tint, and not making any animation sounds (#2753)
|
||||
- fixed the scale of the four keys in St. Francis' Folly (#2652)
|
||||
- fixed the panther at times not making a sound when it dies, and restored Skate Kid's death SFX (#2647)
|
||||
- fixed pushblocks being rotated when Lara grabs them, most noticeable if asymmetric textures have been used (#2776)
|
||||
- fixed a crash when 3D pickups are disabled and Lara crosses a trigger to look at a pickup item (#2711, regression from 4.8)
|
||||
- fixed trapezoid filter warping on faces close to the camera (#2629, regression from 4.9)
|
||||
- fixed Mac builds crashing upon start (regression from 4.9)
|
||||
|
|
|
@ -475,6 +475,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
|
|||
- fixed a potential softlock when killing the Torso boss in Great Pyramid
|
||||
- fixed being able to shoot the scion multiple times if save/load is used while it blows up
|
||||
- fixed the game crashing if a cinematic is triggered but the level contains no cinematic frames
|
||||
- fixed pushblocks being rotated when Lara grabs them, most noticeable if asymmetric textures have been used
|
||||
|
||||
#### Cheats
|
||||
- added a fly cheat
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
- fixed a potential softlock in Floating Islands if returning towards the level start from the gold secret (#2590)
|
||||
- fixed a potential softlock in Nightmare in Vegas where the bird monster could remain inactive, or the flip map not set (#1851)
|
||||
- fixed invalid portals in The Deck between rooms 17 and 104, which could result in Lara seeing enemies in disconnected rooms (#2393)
|
||||
- fixed pushblocks being rotated when Lara grabs them, most noticeable if asymmetric textures have been used (#2776)
|
||||
- fixed the camera going out of bounds in 60fps near specific invalid floor data (known as no-space) (#2764, regression from 0.10)
|
||||
- fixed sprites rendering black if no shade value is assigned in the level (#2701, regression from 0.8)
|
||||
- fixed a crash if an image was missing
|
||||
|
|
|
@ -243,6 +243,7 @@ as Notepad.
|
|||
- increased Barkhang Monastery rooftops key size
|
||||
- increased Temple of Xian dragon seal size, and fixed inventory rotation
|
||||
- fixed Floating Islands mystic plaque inventory rotation
|
||||
- fixed pushblocks being rotated when Lara grabs them, most noticeable if asymmetric textures have been used
|
||||
- improved the animation of Lara's braid
|
||||
|
||||
#### Cheats
|
||||
|
|
|
@ -185,6 +185,17 @@ void Object_DrawInterpolatedObject(
|
|||
Matrix_TranslateRel16_ID(frame1->offset, frame2->offset);
|
||||
Matrix_Rot16_ID(
|
||||
frame1->mesh_rots[mesh_idx], frame2->mesh_rots[mesh_idx]);
|
||||
if (extra_rotation != nullptr) {
|
||||
if (obj->base_rot.y) {
|
||||
Matrix_RotY_I(*extra_rotation++);
|
||||
}
|
||||
if (obj->base_rot.x) {
|
||||
Matrix_RotX_I(*extra_rotation++);
|
||||
}
|
||||
if (obj->base_rot.z) {
|
||||
Matrix_RotZ_I(*extra_rotation++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const ANIM_BONE *const bone = Object_GetBone(obj, mesh_idx - 1);
|
||||
if (bone->matrix_pop) {
|
||||
|
@ -219,6 +230,17 @@ void Object_DrawInterpolatedObject(
|
|||
if (mesh_idx == 0) {
|
||||
Matrix_TranslateRel16(frame1->offset);
|
||||
Matrix_Rot16(frame1->mesh_rots[mesh_idx]);
|
||||
if (extra_rotation != nullptr) {
|
||||
if (obj->base_rot.y) {
|
||||
Matrix_RotY(*extra_rotation++);
|
||||
}
|
||||
if (obj->base_rot.x) {
|
||||
Matrix_RotX(*extra_rotation++);
|
||||
}
|
||||
if (obj->base_rot.z) {
|
||||
Matrix_RotZ(*extra_rotation++);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const ANIM_BONE *const bone = Object_GetBone(obj, mesh_idx - 1);
|
||||
if (bone->matrix_pop) {
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
int16_t counter_rot[3];
|
||||
int16_t original_rot;
|
||||
} M_PRIV;
|
||||
|
||||
static int32_t m_BlockCount = 0;
|
||||
static VECTOR *m_UnsortedBlocks = nullptr;
|
||||
static int16_t *m_SortedBlocks = nullptr;
|
||||
|
@ -54,6 +59,24 @@ void MovableBlock_Initialise(const int16_t item_num)
|
|||
m_UnsortedBlocks = Vector_Create(sizeof(int16_t));
|
||||
}
|
||||
Vector_Add(m_UnsortedBlocks, (void *)&item_num);
|
||||
|
||||
// Ensure the block is snapped to the grid, otherwise the snapping occurs
|
||||
// during collision tests and can appear jarring. Additional angles are
|
||||
// stored to preserve item appearance in spite of control angle changes.
|
||||
ITEM *const item = Item_Get(item_num);
|
||||
M_PRIV *const data = GameBuf_Alloc(sizeof(M_PRIV), GBUF_ITEM_DATA);
|
||||
item->data = data;
|
||||
data->original_rot =
|
||||
(((item->rot.y + DEG_180) / DEG_90) * DEG_90) - DEG_180;
|
||||
MovableBlock_UpdateRotation(item, data->original_rot);
|
||||
}
|
||||
|
||||
// TODO: make private
|
||||
void MovableBlock_UpdateRotation(ITEM *const item, const int16_t rot_y)
|
||||
{
|
||||
item->rot.y = rot_y;
|
||||
M_PRIV *const data = (M_PRIV *)item->data;
|
||||
data->counter_rot[0] = data->original_rot - rot_y;
|
||||
}
|
||||
|
||||
void MovableBlock_SetupFloor(void)
|
||||
|
|
|
@ -3,5 +3,6 @@
|
|||
#include "../../rooms.h"
|
||||
|
||||
void MovableBlock_Initialise(int16_t item_num);
|
||||
void MovableBlock_UpdateRotation(ITEM *item, int16_t rot_y);
|
||||
void MovableBlock_SetupFloor(void);
|
||||
void MovableBlock_HandleFlipMap(ROOM_FLIP_STATUS flip_status);
|
||||
|
|
|
@ -79,6 +79,12 @@ typedef struct OBJECT {
|
|||
int16_t smartness;
|
||||
bool enable_interpolation;
|
||||
|
||||
struct {
|
||||
bool x;
|
||||
bool y;
|
||||
bool z;
|
||||
} base_rot;
|
||||
|
||||
union {
|
||||
uint16_t flags;
|
||||
// clang-format off
|
||||
|
|
|
@ -278,6 +278,7 @@ static void M_Setup(OBJECT *const obj)
|
|||
obj->save_position = 1;
|
||||
obj->save_anim = 1;
|
||||
obj->save_flags = 1;
|
||||
obj->base_rot.y = true;
|
||||
obj->bounds_func = M_Bounds;
|
||||
}
|
||||
|
||||
|
@ -290,6 +291,7 @@ static void M_HandleSave(ITEM *const item, const SAVEGAME_STAGE stage)
|
|||
item->status = IS_INACTIVE;
|
||||
}
|
||||
item->priv = item->status == IS_ACTIVE ? (void *)true : (void *)false;
|
||||
MovableBlock_UpdateRotation(item, item->rot.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,16 +369,16 @@ static void M_Collision(
|
|||
|
||||
switch (quadrant) {
|
||||
case DIR_NORTH:
|
||||
item->rot.y = 0;
|
||||
MovableBlock_UpdateRotation(item, 0);
|
||||
break;
|
||||
case DIR_EAST:
|
||||
item->rot.y = DEG_90;
|
||||
MovableBlock_UpdateRotation(item, DEG_90);
|
||||
break;
|
||||
case DIR_SOUTH:
|
||||
item->rot.y = -DEG_180;
|
||||
MovableBlock_UpdateRotation(item, -DEG_180);
|
||||
break;
|
||||
case DIR_WEST:
|
||||
item->rot.y = -DEG_90;
|
||||
MovableBlock_UpdateRotation(item, -DEG_90);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -203,6 +203,7 @@ static void M_Setup(OBJECT *const obj)
|
|||
obj->save_position = 1;
|
||||
obj->save_flags = 1;
|
||||
obj->save_anim = 1;
|
||||
obj->base_rot.y = true;
|
||||
}
|
||||
|
||||
static void M_HandleSave(ITEM *const item, const SAVEGAME_STAGE stage)
|
||||
|
@ -214,6 +215,7 @@ static void M_HandleSave(ITEM *const item, const SAVEGAME_STAGE stage)
|
|||
item->status = IS_INACTIVE;
|
||||
}
|
||||
item->priv = item->status == IS_ACTIVE ? (void *)true : (void *)false;
|
||||
MovableBlock_UpdateRotation(item, item->rot.y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,16 +288,16 @@ static void M_Collision(
|
|||
|
||||
switch (quadrant) {
|
||||
case DIR_NORTH:
|
||||
item->rot.y = 0;
|
||||
MovableBlock_UpdateRotation(item, 0);
|
||||
break;
|
||||
case DIR_EAST:
|
||||
item->rot.y = DEG_90;
|
||||
MovableBlock_UpdateRotation(item, DEG_90);
|
||||
break;
|
||||
case DIR_SOUTH:
|
||||
item->rot.y = -DEG_180;
|
||||
MovableBlock_UpdateRotation(item, -DEG_180);
|
||||
break;
|
||||
case DIR_WEST:
|
||||
item->rot.y = -DEG_90;
|
||||
MovableBlock_UpdateRotation(item, -DEG_90);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue