Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tunnels displaying correctly in low walls mode #3699

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
2 changes: 1 addition & 1 deletion src/bflib_coroutine.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* "Improvised coroutine-like functions"
* @par Purpose:
* Implementation
* @author KeeperFF Team
* @author KeeperFX Team
* @date 01 Nov 2020
* @par Copying and copyrights:
* This program is free software; you can redistribute it and/or modify
Expand Down
32 changes: 22 additions & 10 deletions src/engine_render.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ struct EngineCoord object_origin;
short mx;
short my;
short mz;
unsigned char temp_cluedo_mode; // This is true(1) if the "short wall" have been enabled in the graphics options
unsigned char temp_cluedo_mode; // This is true(1) if "low walls/"short wall" has been enabled in the graphics options
struct Thing *thing_being_displayed;

TbSpriteData *keepsprite[KEEPSPRITE_LENGTH];
Expand Down Expand Up @@ -1116,6 +1116,16 @@ static void fill_in_points_perspective(struct Camera *cam, long bstl_x, long bst
}
}

TbBool has_cube_higher_up(struct Column *col)
{
for (int i = 3; i < COLUMN_STACK_HEIGHT; i++) {
if (col->cubes[i] != 0) {
return true;
}
}
return false;
}

static void fill_in_points_cluedo(struct Camera *cam, long bstl_x, long bstl_y, struct MinMax *mm)
{
if ((bstl_y < 0) || (bstl_y > gameadd.map_subtiles_y-1)) {
Expand Down Expand Up @@ -1160,15 +1170,17 @@ static void fill_in_points_cluedo(struct Camera *cam, long bstl_x, long bstl_y,
if (map_block_revealed(mapblk, my_player_number)) {
col = get_map_column(mapblk);
mask_cur = col->solidmask;
if ((mask_cur >= 8) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & 0xE) == 0)) {

if (has_cube_higher_up(col) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & CLF_CEILING_MASK) == 0)) {
mask_cur &= 3;
}
}
mapblk = get_map_block_at(stl_x-1, stl_y);
if (map_block_revealed(mapblk, my_player_number)) {
col = get_map_column(mapblk);
mask_yp = col->solidmask;
if ((mask_yp >= 8) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & 0xE) == 0)) {

if (has_cube_higher_up(col) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & CLF_CEILING_MASK) == 0)) {
mask_yp &= 3;
}
}
Expand Down Expand Up @@ -1234,15 +1246,15 @@ static void fill_in_points_cluedo(struct Camera *cam, long bstl_x, long bstl_y,
if (map_block_revealed(mapblk, my_player_number)) {
col = get_map_column(mapblk);
mask_cur = col->solidmask;
if ((mask_cur >= 8) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & 0xE) == 0)) {
if (has_cube_higher_up(col) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & CLF_CEILING_MASK) == 0)) {
mask_cur &= 3;
}
}
mapblk = get_map_block_at(stl_x, stl_y);
if (map_block_revealed(mapblk, my_player_number)) {
col = get_map_column(mapblk);
mask_yp = col->solidmask;
if ((mask_yp >= 8) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & 0xE) == 0)) {
if (has_cube_higher_up(col) && ((mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((col->bitfields & CLF_CEILING_MASK) == 0)) {
mask_yp &= 3;
}
}
Expand Down Expand Up @@ -4467,7 +4479,7 @@ static void do_a_plane_of_engine_columns_cluedo(long stl_x, long stl_y, long pla
solidmsk_cur = solidmsk_cur_raw;
if (solidmsk_cur >= (1<<3))
{
if (((cur_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((cur_colmn->bitfields & 0xE) == 0)) {
if (((cur_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((cur_colmn->bitfields & CLF_CEILING_MASK) == 0)) {
solidmsk_cur &= 3;
}
}
Expand All @@ -4480,7 +4492,7 @@ static void do_a_plane_of_engine_columns_cluedo(long stl_x, long stl_y, long pla
solidmsk_back = colmn->solidmask;
if (solidmsk_back >= (1<<3))
{
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & 0xE) == 0)) {
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & CLF_CEILING_MASK) == 0)) {
solidmsk_back &= 3;
}
}
Expand All @@ -4492,7 +4504,7 @@ static void do_a_plane_of_engine_columns_cluedo(long stl_x, long stl_y, long pla
solidmsk_front = colmn->solidmask;
if (solidmsk_front >= (1<<3))
{
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & 0xE) == 0)) {
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & CLF_CEILING_MASK) == 0)) {
solidmsk_front &= 3;
}
}
Expand All @@ -4504,7 +4516,7 @@ static void do_a_plane_of_engine_columns_cluedo(long stl_x, long stl_y, long pla
solidmsk_left = colmn->solidmask;
if (solidmsk_left >= (1<<3))
{
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & 0xE) == 0)) {
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & CLF_CEILING_MASK) == 0)) {
solidmsk_left &= 3;
}
}
Expand All @@ -4516,7 +4528,7 @@ static void do_a_plane_of_engine_columns_cluedo(long stl_x, long stl_y, long pla
solidmsk_right = colmn->solidmask;
if (solidmsk_right >= (1<<3))
{
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & 0xE) == 0)) {
if (((sib_mapblk->flags & (SlbAtFlg_IsDoor|SlbAtFlg_IsRoom)) == 0) && ((colmn->bitfields & CLF_CEILING_MASK) == 0)) {
solidmsk_right &= 3;
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/engine_render.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ void draw_map_volume_box(long cor1_x, long cor1_y, long cor2_x, long cor2_y, lon
void update_engine_settings(struct PlayerInfo *player);
void draw_view(struct Camera *cam, unsigned char a2);
void draw_frontview_engine(struct Camera *cam);

TbBool has_cube(struct Column *col);
/******************************************************************************/
#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion src/lvl_filesdk1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Free implementation of Bullfrog's Dungeon Keeper strategy game.
/******************************************************************************/
/** @file lvl_filesdk1.c
* Level files reading routines fore standard DK1 levels.
* Level files reading routines for standard DK1 levels.
* @par Purpose:
* Allows reading level files in DK1 format.
* @par Comment:
Expand Down
70 changes: 38 additions & 32 deletions src/map_columns.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,22 @@ TbBool column_invalid(const struct Column *colmn)
}

/**
* Returns amount of filled subtiles at bottom of given column.
* These commands retrieve and set how much of the column intersects with the standard floor and ceiling
*
*
*/

/**
* Returns amount of filled subtiles at bottom of given column (how many make up the floor).
* @param col The column which filled height should be returned.
*/
long get_column_floor_filled_subtiles(const struct Column *col)
{
return (col->bitfields & 0xF0) >> 4;
return (col->bitfields & CLF_FLOOR_MASK) >> 4; // Returns standard floor level or lower
}

/**
* Returns amount of filled subtiles at bottom of column at given map block.
* Returns amount of filled subtiles at bottom of column at given map block (how many make up the floor).
* @param mapblk The map block for which column height should be returned.
*/
long get_map_floor_filled_subtiles(const struct Map *mapblk)
Expand All @@ -81,11 +87,11 @@ long get_map_floor_filled_subtiles(const struct Map *mapblk)
col = get_map_column(mapblk);
if (column_invalid(col))
return 0;
return (col->bitfields & 0xF0) >> 4;
return (col->bitfields & CLF_FLOOR_MASK) >> 4; // Returns standard floor level or lower
}

/**
* Returns amount of filled subtiles at bottom of column at given coords.
* Returns amount of filled subtiles at bottom of column at given coords (how many make up the floor).
* @param stl_x Subtile for which column height should be returned, X coord.
* @param stl_y Subtile for which column height should be returned, Y coord.
*/
Expand All @@ -95,22 +101,22 @@ long get_floor_filled_subtiles_at(MapSubtlCoord stl_x, MapSubtlCoord stl_y)
col = get_column_at(stl_x, stl_y);
if (column_invalid(col))
return 0;
return (col->bitfields & 0xF0) >> 4;
return (col->bitfields & CLF_FLOOR_MASK) >> 4; // Returns standard floor level or lower
}

/**
* Sets amount of filled subtiles at bottom of given column.
* Sets amount of filled subtiles at bottom of given column (how many make up the floor).
* @param col The column which filled height should be set.
* @param n Amount of subtiles.
*/
void set_column_floor_filled_subtiles(struct Column *col, MapSubtlCoord n)
{
col->bitfields &= ~0xF0;
col->bitfields |= (n<<4) & 0xF0;
col->bitfields &= ~CLF_FLOOR_MASK;
col->bitfields |= (n<<4) & CLF_FLOOR_MASK; // sets standard floor level or lower
}

/**
* Sets amount of filled subtiles at bottom of a column at given map block.
* Sets amount of filled subtiles at bottom of a column at given map block (how many make up the floor).
* @param mapblk The map block for which filled height should be set.
* @param n Amount of subtiles.
*/
Expand All @@ -120,21 +126,21 @@ void set_map_floor_filled_subtiles(struct Map *mapblk, MapSubtlCoord n)
col = get_map_column(mapblk);
if (column_invalid(col))
return;
col->bitfields &= ~0xF0;
col->bitfields |= (n<<4) & 0xF0;
col->bitfields &= ~CLF_FLOOR_MASK;
col->bitfields |= (n<<4) & CLF_FLOOR_MASK; // sets standard floor level or lower
}

/**
* Returns amount of filled subtiles at top of given column.
* Returns amount of filled subtiles at top of given column (how many make up the ceiling).
* @param col The column which filled height should be returned.
*/
long get_column_ceiling_filled_subtiles(const struct Column *col)
{
return (col->bitfields & CLF_CEILING_MASK) >> 1;
return (col->bitfields & CLF_CEILING_MASK) >> 1; // Returns ceiling length or lower if column is shorter
}

/**
* Returns amount of filled subtiles at top of column at given map block.
* Returns amount of filled subtiles at top of column at given map block (how many make up the ceiling).
* @param mapblk The map block for which column height should be returned.
*/
long get_map_ceiling_filled_subtiles(const struct Map *mapblk)
Expand Down Expand Up @@ -345,7 +351,7 @@ long create_column(struct Column *col)
{
long result;
struct Column *dst;
unsigned char v6;
unsigned char floor_level;
unsigned char top_of_floor;

// Find an empty column
Expand All @@ -367,12 +373,12 @@ long create_column(struct Column *col)
make_solidmask(dst);

// Find lowest cube
for (v6 = 0; v6 < COLUMN_STACK_HEIGHT;v6++)
for (floor_level = 0; floor_level < COLUMN_STACK_HEIGHT;floor_level++)
{
if ( dst->cubes[v6] == 0)
if ( dst->cubes[floor_level] == 0) // first empty cube from bottom
break;
}
top_of_floor = v6;
top_of_floor = floor_level;
// set lowest cube info
dst->bitfields &= ~CLF_FLOOR_MASK;
dst->bitfields |= (top_of_floor << 4);
Expand All @@ -387,7 +393,7 @@ long create_column(struct Column *col)
unsigned char ceiling = top_of_floor;
for (; ceiling < COLUMN_STACK_HEIGHT; ceiling++)
{
if (dst->cubes[ceiling])
if (dst->cubes[ceiling]) // first solid cube above that
break;
}

Expand All @@ -397,14 +403,14 @@ long create_column(struct Column *col)
}
else
{
unsigned short *v13 = &dst->cubes[7];
unsigned short *ceiling_cube_id = &dst->cubes[7];
unsigned char v12 = 0;
// Counting ceiling height
for (int i = 0; i < COLUMN_STACK_HEIGHT-1; i++)
{
if (*v13)
if (*ceiling_cube_id)
dst->bitfields ^= (v12 ^ dst->bitfields) & CLF_CEILING_MASK;
--v13;
--ceiling_cube_id;
v12 += 2;
}
}
Expand Down Expand Up @@ -443,43 +449,43 @@ void init_columns(void)
mskbit = 1;
col->solidmask = 0;
int n;
for (n=0; n < COLUMN_STACK_HEIGHT; n++)
for (n=0; n < COLUMN_STACK_HEIGHT; n++)
{
if (col->cubes[n] != 0) {
col->solidmask |= mskbit;
col->solidmask |= mskbit; //set nth bit to 1 if the cube is nonempty
}
mskbit *= 2;
}
if (col->solidmask)
if (col->solidmask) // if column contains any cubes
{
for (n=0; n < COLUMN_STACK_HEIGHT; n++)
{
if (col->cubes[n] == 0) {
break;
break; // set the number of solid cubes from the floor
}
}
} else
{
n = 0;
}
set_column_floor_filled_subtiles(col, n);
n = get_column_floor_filled_subtiles(col);
set_column_floor_filled_subtiles(col, n);
n = get_column_floor_filled_subtiles(col); // adjusts n against floor level
for (;n < COLUMN_STACK_HEIGHT; n++)
{
if (col->cubes[n] != 0) {
break;
break; // get first nonempty cube above floor
}
}
if (n >= COLUMN_STACK_HEIGHT)
{
col->bitfields &= ~0x0E;
col->bitfields &= ~CLF_CEILING_MASK; // zero out any that are in ceiling
} else
{
mskbit = 0;
for (n=COLUMN_STACK_HEIGHT-1; n > 0; n--)
{
if (col->cubes[n] != 0) {
col->bitfields ^= (mskbit ^ col->bitfields) & 0xE;
col->bitfields ^= (mskbit ^ col->bitfields) & CLF_CEILING_MASK;
}
mskbit += 2;
}
Expand Down