rooms: use flip status flag for finding rooms

This introduces a flip status flag on rooms so that we can avoid
yielding rooms that are not in the correct state when finding one by
position.

Resolves #2362.
Resolves #2370.
This commit is contained in:
lahm86 2025-01-24 12:51:38 +00:00
parent 6a261d23af
commit be39629dcc
10 changed files with 35 additions and 0 deletions

View file

@ -20,6 +20,8 @@
- changed the `/kill` command with no arguments to look for enemies within 5 tiles (#2297)
- fixed blood spawning on Lara from gunshots using incorrect positioning data (#2253)
- fixed ghost meshes appearing near statics in custom levels (#2310)
- fixed photo mode switching to the wrong flipmap rooms at times (#2362)
- fixed the teleporting command sometimes putting Lara in invalid flipmap rooms (#2370)
- fixed the upside-down camera fix to no longer limit Lara's vision (#2276, regression from 4.2)
- fixed being unable to load some old custom levels that contain certain (invalid) floor data (#2114, regression from 4.3)
- fixed a desync in the Lost Valley demo if responsive swim cancellation was enabled (#2113, regression from 4.6)

View file

@ -22,6 +22,8 @@
- fixed blood spawning on Lara from gunshots using incorrect positioning data (#2253)
- fixed ghost meshes appearing near statics in custom levels (#2310)
- fixed potential memory corruption when reading a custom level with more than 512 sprite textures (#2338)
- fixed photo mode switching to the wrong flipmap rooms at times (#2362)
- fixed the teleporting command sometimes putting Lara in invalid flipmap rooms (#2370)
- fixed Lara activating triggers one frame too early (#2205, regression from 0.7)
- fixed savegame incompatibility with OG (#2271, regression from 0.8)
- fixed stopwatch showing wrong UI in some circumstances (#2221, regression from 0.8)

View file

@ -96,6 +96,20 @@ static const int16_t *M_ReadTrigger(
return data;
}
void Room_InitialiseFlipStatus(void)
{
for (int32_t i = 0; i < Room_GetTotalCount(); i++) {
ROOM *const room = Room_Get(i);
if (room->flipped_room == -1) {
room->flip_status = RFS_NONE;
} else if (room->flip_status != RFS_FLIPPED) {
ROOM *const flipped_room = Room_Get(room->flipped_room);
room->flip_status = RFS_UNFLIPPED;
flipped_room->flip_status = RFS_FLIPPED;
}
}
}
void Room_ParseFloorData(const int16_t *floor_data)
{
for (int32_t i = 0; i < Room_GetTotalCount(); i++) {
@ -200,6 +214,9 @@ int32_t Room_FindByPos(const int32_t x, const int32_t y, const int32_t z)
{
for (int32_t i = 0; i < Room_GetTotalCount(); i++) {
const ROOM *const room = Room_Get(i);
if (room->flip_status == RFS_FLIPPED) {
continue;
}
const int32_t x1 = room->pos.x + WALL_L;
const int32_t x2 = room->pos.x + (room->size.x - 1) * WALL_L;
const int32_t y1 = room->max_ceiling;

View file

@ -6,6 +6,7 @@
extern int32_t Room_GetTotalCount(void);
extern ROOM *Room_Get(int32_t room_num);
void Room_InitialiseFlipStatus(void);
extern void Room_FlipMap(void);
extern bool Room_GetFlipStatus(void);

View file

@ -16,6 +16,12 @@ typedef enum {
RLM_NUMBER_OF = 4,
} ROOM_LIGHT_MODE;
typedef enum {
RFS_NONE = 0,
RFS_UNFLIPPED = 1,
RFS_FLIPPED = 2,
} ROOM_FLIP_STATUS;
typedef enum {
FT_FLOOR = 0,
FT_DOOR = 1,

View file

@ -130,5 +130,6 @@ typedef struct {
int16_t item_num;
int16_t effect_num;
int16_t flipped_room;
ROOM_FLIP_STATUS flip_status;
uint16_t flags;
} ROOM;

View file

@ -257,6 +257,7 @@ static void M_LoadRooms(VFILE *file)
r->effect_num = NO_EFFECT;
}
Room_InitialiseFlipStatus();
Level_ReadFloorData(file);
Benchmark_End(benchmark, NULL);

View file

@ -582,6 +582,8 @@ void Room_FlipMap(void)
r->flipped_room = flipped->flipped_room;
flipped->flipped_room = -1;
r->flip_status = RFS_UNFLIPPED;
flipped->flip_status = RFS_FLIPPED;
// XXX: is this really necessary given the assignments above?
r->item_num = flipped->item_num;

View file

@ -230,6 +230,7 @@ static void M_LoadRooms(VFILE *const file)
r->effect_num = NO_EFFECT;
}
Room_InitialiseFlipStatus();
Level_ReadFloorData(file);
finish:

View file

@ -773,6 +773,8 @@ void Room_FlipMap(void)
r->flipped_room = flipped->flipped_room;
flipped->flipped_room = NO_ROOM_NEG;
r->flip_status = RFS_UNFLIPPED;
flipped->flip_status = RFS_FLIPPED;
// TODO: is this really necessary given the assignments above?
r->item_num = flipped->item_num;