Skip to content

Commit

Permalink
types: refactor sector floor and ceiling properties (LostArtefacts#1430)
Browse files Browse the repository at this point in the history
This introduces a struct in SECTOR_INFO which currently stores the
click height for the floor and ceiling values.
Height values are now stored as int16_t in the sector to avoid shifting
from clicks to world units throughout the codebase.
Object functions that determine floor and ceiling heights have been
renamed.

Part of LostArtefacts#941.
  • Loading branch information
lahm86 authored Aug 7, 2024
1 parent 99588b2 commit 83b1f4a
Show file tree
Hide file tree
Showing 15 changed files with 207 additions and 176 deletions.
2 changes: 1 addition & 1 deletion src/game/carrier.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ static void Carrier_AnimateDrop(CARRIED_ITEM *item)
pickup->rot.y += in_water ? DROP_SLOW_TURN : DROP_FAST_TURN;

if (sector->pit_room != NO_ROOM
&& pickup->pos.y > (sector->floor << 8)) {
&& pickup->pos.y > sector->floor.height) {
room_num = sector->pit_room;
}
}
Expand Down
19 changes: 11 additions & 8 deletions src/game/inject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1346,6 +1346,10 @@ static void Inject_RoomShift(INJECTION *injection, int16_t room_num)
File_Read(&z_shift, sizeof(uint32_t), 1, fp);
File_Read(&y_shift, sizeof(int32_t), 1, fp);

x_shift = ROUND_TO_SECTOR(x_shift);
y_shift = ROUND_TO_CLICK(y_shift);
z_shift = ROUND_TO_SECTOR(z_shift);

ROOM_INFO *room = &g_RoomInfo[room_num];
room->x += x_shift;
room->z += z_shift;
Expand All @@ -1368,17 +1372,16 @@ static void Inject_RoomShift(INJECTION *injection, int16_t room_num)
return;
}

// Update the sector floor and ceiling clicks to match.
const int8_t click_shift = y_shift / STEP_L;
const int8_t wall_height = NO_HEIGHT / STEP_L;
for (int i = 0; i < room->z_size * room->x_size; i++) {
SECTOR_INFO *sector = &room->sectors[i];
if (sector->floor == wall_height || sector->ceiling == wall_height) {
// Update the sector floor and ceiling heights to match.
for (int32_t i = 0; i < room->z_size * room->x_size; i++) {
SECTOR_INFO *const sector = &room->sectors[i];
if (sector->floor.height == NO_HEIGHT
|| sector->ceiling.height == NO_HEIGHT) {
continue;
}

sector->floor += click_shift;
sector->ceiling += click_shift;
sector->floor.height += y_shift;
sector->ceiling.height += y_shift;
}

// Update vertex Y values to match; x and z are room-relative.
Expand Down
2 changes: 1 addition & 1 deletion src/game/items.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void Item_Initialise(int16_t item_num)
const int32_t x_sector = (item->pos.x - r->x) >> WALL_SHIFT;
const SECTOR_INFO *const sector =
&r->sectors[z_sector + x_sector * r->z_size];
item->floor = sector->floor << 8;
item->floor = sector->floor.height;

if (g_GameInfo.bonus_flag & GBF_NGPLUS) {
item->hit_points *= 2;
Expand Down
9 changes: 7 additions & 2 deletions src/game/level.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,17 @@ static bool Level_LoadRooms(MYFILE *fp)
GameBuf_Alloc(sizeof(SECTOR_INFO) * count4, GBUF_ROOM_SECTOR);
for (int32_t j = 0; j < (signed)count4; j++) {
SECTOR_INFO *const sector = &current_room_info->sectors[j];
int8_t floor_clicks;
int8_t ceiling_clicks;
File_Read(&sector->index, sizeof(uint16_t), 1, fp);
File_Read(&sector->box, sizeof(int16_t), 1, fp);
File_Read(&sector->pit_room, sizeof(uint8_t), 1, fp);
File_Read(&sector->floor, sizeof(int8_t), 1, fp);
File_Read(&floor_clicks, sizeof(int8_t), 1, fp);
File_Read(&sector->sky_room, sizeof(uint8_t), 1, fp);
File_Read(&sector->ceiling, sizeof(int8_t), 1, fp);
File_Read(&ceiling_clicks, sizeof(int8_t), 1, fp);

sector->floor.height = floor_clicks * STEP_L;
sector->ceiling.height = ceiling_clicks * STEP_L;
}

// Room lights
Expand Down
146 changes: 77 additions & 69 deletions src/game/objects/general/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <stdbool.h>

static bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM_INFO *item);
static bool Bridge_OnDrawBridge(ITEM_INFO *item, int32_t x, int32_t z);
static bool Bridge_OnDrawBridge(const ITEM_INFO *item, int32_t x, int32_t z);
static int32_t Bridge_GetOffset(
const ITEM_INFO *item, int32_t x, int32_t y, int32_t z);
static void Bridge_FixEmbeddedPosition(int16_t item_num);
Expand All @@ -27,7 +27,7 @@ static bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM_INFO *item)
return sector_x == item_sector_x && sector_z == item_sector_z;
}

static bool Bridge_OnDrawBridge(ITEM_INFO *item, int32_t x, int32_t z)
static bool Bridge_OnDrawBridge(const ITEM_INFO *item, int32_t x, int32_t z)
{
int32_t ix = item->pos.x >> WALL_SHIFT;
int32_t iz = item->pos.z >> WALL_SHIFT;
Expand Down Expand Up @@ -123,35 +123,35 @@ static void Bridge_FixEmbeddedPosition(int16_t item_num)
void Bridge_SetupFlat(OBJECT_INFO *obj)
{
obj->initialise = Bridge_Initialise;
obj->floor = Bridge_FlatFloor;
obj->ceiling = Bridge_FlatCeiling;
obj->floor_height_func = Bridge_GetFlatFloorHeight;
obj->ceiling_height_func = Bridge_GetFlatCeilingHeight;
}

void Bridge_SetupTilt1(OBJECT_INFO *obj)
{
obj->initialise = Bridge_Initialise;
obj->floor = Bridge_Tilt1Floor;
obj->ceiling = Bridge_Tilt1Ceiling;
obj->floor_height_func = Bridge_GetTilt1FloorHeight;
obj->ceiling_height_func = Bridge_GetTilt1CeilingHeight;
}

void Bridge_SetupTilt2(OBJECT_INFO *obj)
{
obj->initialise = Bridge_Initialise;
obj->floor = Bridge_Tilt2Floor;
obj->ceiling = Bridge_Tilt2Ceiling;
obj->floor_height_func = Bridge_GetTilt2FloorHeight;
obj->ceiling_height_func = Bridge_GetTilt2CeilingHeight;
}

void Bridge_SetupDrawBridge(OBJECT_INFO *obj)
{
if (!obj->loaded) {
return;
}
obj->ceiling = Bridge_DrawBridgeCeiling;
obj->ceiling_height_func = Bridge_GetDrawBridgeCeilingHeight;
obj->collision = Bridge_DrawBridgeCollision;
obj->control = Cog_Control;
obj->save_anim = 1;
obj->save_flags = 1;
obj->floor = Bridge_DrawBridgeFloor;
obj->floor_height_func = Bridge_GetDrawBridgeFloorHeight;
}

void Bridge_Initialise(int16_t item_num)
Expand All @@ -162,48 +162,50 @@ void Bridge_Initialise(int16_t item_num)
Bridge_FixEmbeddedPosition(item_num);
}

void Bridge_DrawBridgeFloor(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetDrawBridgeFloorHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (item->current_anim_state != DOOR_OPEN) {
return;
return height;
}

if (!Bridge_OnDrawBridge(item, x, z)) {
return;
return height;
}

if (y > item->pos.y) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y >= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y >= height) {
return height;
}

*height = item->pos.y;
return item->pos.y;
}

void Bridge_DrawBridgeCeiling(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetDrawBridgeCeilingHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (item->current_anim_state != DOOR_OPEN) {
return;
return height;
}

if (!Bridge_OnDrawBridge(item, x, z)) {
return;
return height;
}

if (y <= item->pos.y) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y <= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y <= height) {
return height;
}

*height = item->pos.y + STEP_L;
return item->pos.y + STEP_L;
}

void Bridge_DrawBridgeCollision(
Expand All @@ -215,118 +217,124 @@ void Bridge_DrawBridgeCollision(
}
}

void Bridge_FlatFloor(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetFlatFloorHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

if (y > item->pos.y) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y >= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y >= height) {
return height;
}

*height = item->pos.y;
return item->pos.y;
}

void Bridge_FlatCeiling(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetFlatCeilingHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

if (y <= item->pos.y) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y <= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y <= height) {
return height;
}

*height = item->pos.y + STEP_L;
return item->pos.y + STEP_L;
}

void Bridge_Tilt1Floor(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetTilt1FloorHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

const int32_t offset_height =
item->pos.y + (Bridge_GetOffset(item, x, y, z) / 4);
if (y > offset_height || item->pos.y >= *height) {
return;
if (y > offset_height || item->pos.y >= height) {
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y >= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y >= height) {
return height;
}

*height = offset_height;
return offset_height;
}

void Bridge_Tilt1Ceiling(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetTilt1CeilingHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

const int32_t offset_height =
item->pos.y + (Bridge_GetOffset(item, x, y, z) / 4);
if (y <= offset_height) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y <= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y <= height) {
return height;
}

*height = offset_height + STEP_L;
return offset_height + STEP_L;
}

void Bridge_Tilt2Floor(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetTilt2FloorHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

const int32_t offset_height =
item->pos.y + (Bridge_GetOffset(item, x, y, z) / 2);
if (y > offset_height) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y >= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y >= height) {
return height;
}

*height = offset_height;
return offset_height;
}

void Bridge_Tilt2Ceiling(
ITEM_INFO *item, int32_t x, int32_t y, int32_t z, int16_t *height)
int16_t Bridge_GetTilt2CeilingHeight(
const ITEM_INFO *item, const int32_t x, const int32_t y, const int32_t z,
const int16_t height)
{
if (g_Config.fix_bridge_collision && !Bridge_IsSameSector(x, z, item)) {
return;
return height;
}

const int32_t offset_height =
item->pos.y + (Bridge_GetOffset(item, x, y, z) / 2);
if (y <= offset_height) {
return;
return height;
}

if (g_Config.fix_bridge_collision && item->pos.y <= *height) {
return;
if (g_Config.fix_bridge_collision && item->pos.y <= height) {
return height;
}

*height = offset_height + STEP_L;
return offset_height + STEP_L;
}
Loading

0 comments on commit 83b1f4a

Please sign in to comment.