From a74e63d538386ee5de073a48fc2aea6b5ed2c5ce Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Sat, 6 May 2023 14:34:58 +0200 Subject: [PATCH] added new steel slope game element for MM game engine --- docs/elements/df_slope.txt | 1 + graphics/gfx_classic/RocksDF.png | Bin 18288 -> 18875 bytes src/conf_gfx.c | 17 +++ src/editor.c | 13 +- src/game_mm/export.h | 2 +- src/game_mm/mm_game.c | 236 +++++++++++++++++++++++++++++-- src/game_mm/mm_main.h | 12 +- src/game_mm/mm_tools.c | 12 +- src/main.c | 20 +++ src/main.h | 13 +- 10 files changed, 308 insertions(+), 18 deletions(-) create mode 100644 docs/elements/df_slope.txt diff --git a/docs/elements/df_slope.txt b/docs/elements/df_slope.txt new file mode 100644 index 00000000..ac49f185 --- /dev/null +++ b/docs/elements/df_slope.txt @@ -0,0 +1 @@ +Steel slopes reflect the laser beam similar to steel walls. diff --git a/graphics/gfx_classic/RocksDF.png b/graphics/gfx_classic/RocksDF.png index 3d881babd8129d136d44cd45867a9f0713726203..9bf2b6122f5194ab90e2f6218de7712fc995371a 100644 GIT binary patch delta 18101 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 T4@RfW00000NkvXXu0mjf>y9ZM diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 67fc1807..be3f3577 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -5852,6 +5852,23 @@ struct ConfigInfo image_config[] = { "df_mirror_fixed_16.ypos", "10" }, { "df_mirror_fixed_16.frames", "1" }, + { "df_slope_1", "RocksDF.png" }, + { "df_slope_1.xpos", "0" }, + { "df_slope_1.ypos", "11" }, + { "df_slope_1.frames", "1" }, + { "df_slope_2", "RocksDF.png" }, + { "df_slope_2.xpos", "1" }, + { "df_slope_2.ypos", "11" }, + { "df_slope_2.frames", "1" }, + { "df_slope_3", "RocksDF.png" }, + { "df_slope_3.xpos", "2" }, + { "df_slope_3.ypos", "11" }, + { "df_slope_3.frames", "1" }, + { "df_slope_4", "RocksDF.png" }, + { "df_slope_4.xpos", "3" }, + { "df_slope_4.ypos", "11" }, + { "df_slope_4.frames", "1" }, + // (these are only defined as elements to support ".PANEL" definitions) { "graphic_1", UNDEFINED_FILENAME }, { "graphic_2", UNDEFINED_FILENAME }, diff --git a/src/editor.c b/src/editor.c index 7c902070..d4e2bc8e 100644 --- a/src/editor.c +++ b/src/editor.c @@ -4713,7 +4713,12 @@ static int editor_el_deflektor[] = EL_DF_STEEL_WALL, EL_DF_WOODEN_WALL, EL_DF_REFRACTOR, - EL_DF_MINE + EL_DF_MINE, + + EL_DF_SLOPE_1, + EL_DF_SLOPE_2, + EL_DF_SLOPE_3, + EL_DF_SLOPE_4 }; static int *editor_hl_deflektor_ptr = editor_hl_deflektor; static int *editor_el_deflektor_ptr = editor_el_deflektor; @@ -11702,6 +11707,12 @@ static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element, EL_DF_RECEIVER_DOWN, EL_DF_RECEIVER_LEFT }, + { + EL_DF_SLOPE_1, + EL_DF_SLOPE_4, + EL_DF_SLOPE_3, + EL_DF_SLOPE_2 + }, { -1, diff --git a/src/game_mm/export.h b/src/game_mm/export.h index 184ce216..b555511b 100644 --- a/src/game_mm/export.h +++ b/src/game_mm/export.h @@ -43,7 +43,7 @@ #define EL_MM_END_2_NATIVE 430 #define EL_MM_START_3_NATIVE 431 -#define EL_MM_END_3_NATIVE 446 +#define EL_MM_END_3_NATIVE 450 #define EL_MM_RUNTIME_START_NATIVE 500 #define EL_MM_RUNTIME_END_NATIVE 504 diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index a5b34f29..204ddf63 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -139,10 +139,14 @@ static DelayCounter overload_delay = { 0 }; #define MM_MASK_GRID_2 5 #define MM_MASK_GRID_3 6 #define MM_MASK_GRID_4 7 -#define MM_MASK_RECTANGLE 8 -#define MM_MASK_CIRCLE 9 +#define MM_MASK_SLOPE_1 8 +#define MM_MASK_SLOPE_2 9 +#define MM_MASK_SLOPE_3 10 +#define MM_MASK_SLOPE_4 11 +#define MM_MASK_RECTANGLE 12 +#define MM_MASK_CIRCLE 13 -#define NUM_MM_MASKS 10 +#define NUM_MM_MASKS 14 // element masks for scanning pixels of MM elements static const char mm_masks[NUM_MM_MASKS][16][16 + 1] = @@ -291,6 +295,78 @@ static const char mm_masks[NUM_MM_MASKS][16][16 + 1] = " XXX XXXX ", " XX XXXXX ", }, + { + " X", + " XX", + " XXX", + " XXXX", + " XXXXX", + " XXXXXX", + " XXXXXXX", + " XXXXXXXX", + " XXXXXXXXX", + " XXXXXXXXXX", + " XXXXXXXXXXX", + " XXXXXXXXXXXX", + " XXXXXXXXXXXXX", + " XXXXXXXXXXXXXX", + " XXXXXXXXXXXXXXX", + "XXXXXXXXXXXXXXXX", + }, + { + "X ", + "XX ", + "XXX ", + "XXXX ", + "XXXXX ", + "XXXXXX ", + "XXXXXXX ", + "XXXXXXXX ", + "XXXXXXXXX ", + "XXXXXXXXXX ", + "XXXXXXXXXXX ", + "XXXXXXXXXXXX ", + "XXXXXXXXXXXXX ", + "XXXXXXXXXXXXXX ", + "XXXXXXXXXXXXXXX ", + "XXXXXXXXXXXXXXXX", + }, + { + "XXXXXXXXXXXXXXXX", + "XXXXXXXXXXXXXXX ", + "XXXXXXXXXXXXXX ", + "XXXXXXXXXXXXX ", + "XXXXXXXXXXXX ", + "XXXXXXXXXXX ", + "XXXXXXXXXX ", + "XXXXXXXXX ", + "XXXXXXXX ", + "XXXXXXX ", + "XXXXXX ", + "XXXXX ", + "XXXX ", + "XXX ", + "XX ", + "X ", + }, + { + "XXXXXXXXXXXXXXXX", + " XXXXXXXXXXXXXXX", + " XXXXXXXXXXXXXX", + " XXXXXXXXXXXXX", + " XXXXXXXXXXXX", + " XXXXXXXXXXX", + " XXXXXXXXXX", + " XXXXXXXXX", + " XXXXXXXX", + " XXXXXXX", + " XXXXXX", + " XXXXX", + " XXXX", + " XXX", + " XX", + " X", + }, { "XXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXX", @@ -338,6 +414,8 @@ static int get_element_angle(int element) IS_LASER(element) || IS_RECEIVER(element)) return 4 * element_phase; + else if (IS_DF_SLOPE(element)) + return 4 + (element_phase % 2) * 8; else return element_phase; } @@ -887,6 +965,8 @@ static int getMaskFromElement(int element) return MM_MASK_GRID_1 + get_element_phase(element); else if (IS_DF_GRID(element)) return MM_MASK_RECTANGLE; + else if (IS_DF_SLOPE(element)) + return MM_MASK_SLOPE_1 + get_element_phase(element); else if (IS_RECTANGLE(element)) return MM_MASK_RECTANGLE; else @@ -1121,10 +1201,14 @@ static void ScanLaser(void) break; } + boolean diagonally_adjacent_hit = FALSE; + // handle special case of laser hitting two diagonally adjacent elements // (with or without a third corner element behind these two elements) if ((diag_1 || diag_2) && cross_x && cross_y) { + diagonally_adjacent_hit = TRUE; + // compare the two diagonally adjacent elements int xoffset = 2; int yoffset = 2 * (diag_1 ? -1 : +1); @@ -1240,6 +1324,29 @@ static void ScanLaser(void) break; } } + else if (IS_DF_SLOPE(element)) + { + if (diagonally_adjacent_hit) + { + laser.overloaded = TRUE; + + break; + } + + if (hit_mask == HIT_MASK_LEFT || + hit_mask == HIT_MASK_RIGHT || + hit_mask == HIT_MASK_TOP || + hit_mask == HIT_MASK_BOTTOM) + { + if (HitReflectingWalls(element, hit_mask)) + break; + } + else + { + if (HitElement(element, hit_mask)) + break; + } + } else { if (HitElement(element, hit_mask)) @@ -1594,8 +1701,30 @@ void DrawLaser_MM(void) static boolean HitElement(int element, int hit_mask) { - if (HitOnlyAnEdge(hit_mask)) - return FALSE; + if (IS_DF_SLOPE(element)) + { + int mirrored_angle = get_mirrored_angle(laser.current_angle, + get_element_angle(element)); + int opposite_angle = get_opposite_angle(laser.current_angle); + + // check if laser is reflected by slope by 180° + if (mirrored_angle == opposite_angle) + { + LX += XS; + LY += YS; + + AddDamagedField(LX / TILEX, LY / TILEY); + + laser.overloaded = TRUE; + + return TRUE; + } + } + else + { + if (HitOnlyAnEdge(hit_mask)) + return FALSE; + } if (IS_MOVING(ELX, ELY) || IS_BLOCKED(ELX, ELY)) element = MovingOrBlocked2Element_MM(ELX, ELY); @@ -1615,8 +1744,11 @@ static boolean HitElement(int element, int hit_mask) AddDamagedField(ELX, ELY); + boolean through_center = ((ELX * TILEX + 14 - LX) * YS == + (ELY * TILEY + 14 - LY) * XS); + // this is more precise: check if laser would go through the center - if ((ELX * TILEX + 14 - LX) * YS != (ELY * TILEY + 14 - LY) * XS) + if (!IS_DF_SLOPE(element) && !through_center) { int skip_count = 0; @@ -1687,10 +1819,28 @@ static boolean HitElement(int element, int hit_mask) return TRUE; } - if (!IS_BEAMER(element) && - !IS_FIBRE_OPTIC(element) && - !IS_GRID_WOOD(element) && - element != EL_FUEL_EMPTY) + if (IS_DF_SLOPE(element) && !through_center) + { + int correction = 2; + + if (hit_mask == HIT_MASK_ALL) + { + // laser already inside slope -- go back half step + LX -= XS / 2; + LY -= YS / 2; + + correction = 1; + } + + AddLaserEdge(LX, LY); + + LX -= (ABS(XS) < ABS(YS) ? correction * SIGN(XS) : 0); + LY -= (ABS(YS) < ABS(XS) ? correction * SIGN(YS) : 0); + } + else if (!IS_BEAMER(element) && + !IS_FIBRE_OPTIC(element) && + !IS_GRID_WOOD(element) && + element != EL_FUEL_EMPTY) { #if 0 if ((ELX * TILEX + 14 - LX) * YS == (ELY * TILEY + 14 - LY) * XS) @@ -1712,6 +1862,7 @@ static boolean HitElement(int element, int hit_mask) IS_DF_MIRROR(element) || IS_DF_MIRROR_AUTO(element) || IS_DF_MIRROR_FIXED(element) || + IS_DF_SLOPE(element) || element == EL_PRISM || element == EL_REFRACTOR) { @@ -1731,7 +1882,8 @@ static boolean HitElement(int element, int hit_mask) IS_MIRROR_FIXED(element) || IS_DF_MIRROR(element) || IS_DF_MIRROR_AUTO(element) || - IS_DF_MIRROR_FIXED(element)) + IS_DF_MIRROR_FIXED(element) || + IS_DF_SLOPE(element)) laser.current_angle = get_mirrored_angle(laser.current_angle, get_element_angle(element)); @@ -1766,6 +1918,68 @@ static boolean HitElement(int element, int hit_mask) (get_opposite_angle(laser.current_angle) == laser.damage[laser.num_damages - 1].angle ? TRUE : FALSE); + if (IS_DF_SLOPE(element)) + { + // handle special cases for slope element + + if (IS_45_ANGLE(laser.current_angle)) + { + int elx, ely; + + elx = getLevelFromLaserX(LX); + ely = getLevelFromLaserY(LY); + + if (IN_LEV_FIELD(elx, ely)) + { + int element_next = Tile[elx][ely]; + + // check if slope is followed by slope with opposite orientation + if (IS_DF_SLOPE(element_next) && ABS(element - element_next) == 2) + laser.overloaded = TRUE; + } + + int nr = element - EL_DF_SLOPE_START; + int dx = (nr == 0 ? (XS > 0 ? TILEX - 1 : -1) : + nr == 1 ? (XS > 0 ? TILEX : 1) : + nr == 2 ? (XS > 0 ? TILEX : 1) : + nr == 3 ? (XS > 0 ? TILEX - 1 : -1) : 0); + int dy = (nr == 0 ? (YS > 0 ? TILEY - 1 : -1) : + nr == 1 ? (YS > 0 ? TILEY - 1 : -1) : + nr == 2 ? (YS > 0 ? TILEY : 0) : + nr == 3 ? (YS > 0 ? TILEY : 0) : 0); + + int px = ELX * TILEX + dx; + int py = ELY * TILEY + dy; + + dx = px % TILEX; + dy = py % TILEY; + + elx = getLevelFromLaserX(px); + ely = getLevelFromLaserY(py); + + if (IN_LEV_FIELD(elx, ely)) + { + int element_side = Tile[elx][ely]; + + // check if end of slope is blocked by other element + if (IS_WALL(element_side) || IS_WALL_CHANGING(element_side)) + { + int pos = dy / MINI_TILEY * 2 + dx / MINI_TILEX; + + if (element & (1 << pos)) + laser.overloaded = TRUE; + } + else + { + int pos = getMaskFromElement(element_side); + + if (mm_masks[pos][dx / 2][dx / 2] == 'X') + laser.overloaded = TRUE; + } + } + } + } + return (laser.overloaded ? TRUE : FALSE); } diff --git a/src/game_mm/mm_main.h b/src/game_mm/mm_main.h index b9dd47a8..684647ce 100644 --- a/src/game_mm/mm_main.h +++ b/src/game_mm/mm_main.h @@ -105,6 +105,8 @@ (e) <= EL_DF_MIRROR_AUTO_END) #define IS_DF_MIRROR_FIXED(e) ((e) >= EL_DF_MIRROR_FIXED_START && \ (e) <= EL_DF_MIRROR_FIXED_END) +#define IS_DF_SLOPE(e) ((e) >= EL_DF_SLOPE_START && \ + (e) <= EL_DF_SLOPE_END) #define IS_LASER(e) ((e) >= EL_LASER_START && \ (e) <= EL_LASER_END) #define IS_RECEIVER(e) ((e) >= EL_RECEIVER_START && \ @@ -606,7 +608,14 @@ extern int num_element_info; #define EL_DF_MIRROR_FIXED_15 (EL_DF_MIRROR_FIXED_START + 15) #define EL_DF_MIRROR_FIXED_END EL_DF_MIRROR_FIXED_15 -#define EL_MM_END_2 446 +#define EL_DF_SLOPE_START 447 +#define EL_DF_SLOPE_00 (EL_DF_SLOPE_START + 0) +#define EL_DF_SLOPE_01 (EL_DF_SLOPE_START + 1) +#define EL_DF_SLOPE_02 (EL_DF_SLOPE_START + 2) +#define EL_DF_SLOPE_03 (EL_DF_SLOPE_START + 3) +#define EL_DF_SLOPE_END EL_DF_SLOPE_03 + +#define EL_MM_END_2 450 #define EL_MM_END EL_MM_END_2 // "real" (and therefore drawable) runtime elements @@ -714,6 +723,7 @@ extern int num_element_info; #define ANG_RAY_270 12 #define IS_22_5_ANGLE(angle) ((angle) % 2) #define IS_90_ANGLE(angle) (!((angle) % 4)) +#define IS_45_ANGLE(angle) (!(((angle) + 2) % 4)) #define IS_HORIZ_ANGLE(angle) (!((angle) % 8)) #define IS_VERT_ANGLE(angle) (!(((angle) + 4) % 8)) diff --git a/src/game_mm/mm_tools.c b/src/game_mm/mm_tools.c index aa9c2a5d..6aeadd31 100644 --- a/src/game_mm/mm_tools.c +++ b/src/game_mm/mm_tools.c @@ -1149,6 +1149,8 @@ int get_base_element(int element) return EL_DF_MIRROR_AUTO_START; else if (IS_DF_MIRROR_FIXED(element)) return EL_DF_MIRROR_FIXED_START; + else if (IS_DF_SLOPE(element)) + return EL_DF_SLOPE_START; else if (IS_PACMAN(element)) return EL_PACMAN_START; else if (IS_GRID_STEEL(element)) @@ -1207,7 +1209,8 @@ int get_num_elements(int element) IS_RECEIVER(element) || IS_PACMAN(element) || IS_GRID_STEEL(element) || - IS_GRID_WOOD(element)) + IS_GRID_WOOD(element) || + IS_DF_SLOPE(element)) return 4; else return 1; @@ -1278,6 +1281,13 @@ static int getFlippedTileExt_MM(int element, int mode) (mode != MM_FLIP_XY && element_phase > 1)) element_phase ^= 1; } + else if (IS_DF_SLOPE(element)) + { + element_phase = (mode == MM_FLIP_X ? 5 - element_phase : + mode == MM_FLIP_Y ? 3 - element_phase : + mode == MM_FLIP_XY ? 4 - element_phase : + element_phase); + } else { int num_elements_flip = num_elements; diff --git a/src/main.c b/src/main.c index 04576fe0..bb8e1f0d 100644 --- a/src/main.c +++ b/src/main.c @@ -6440,6 +6440,26 @@ struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] = "df_mirror_fixed", "fixed mirror (DF style) (168.75\xb0)" }, + { + "df_slope_1", + "df_slope", + "slope (DF style) (45\xb0)" + }, + { + "df_slope_2", + "df_slope", + "slope (DF style) (135\xb0)" + }, + { + "df_slope_3", + "df_slope", + "slope (DF style) (225\xb0)" + }, + { + "df_slope_4", + "df_slope", + "slope (DF style) (315\xb0)" + }, // -------------------------------------------------------------------------- // "real" (and therefore drawable) runtime elements diff --git a/src/main.h b/src/main.h index 48752bd0..f021fd74 100644 --- a/src/main.h +++ b/src/main.h @@ -1980,10 +1980,17 @@ #define EL_DF_MIRROR_FIXED_16 (EL_DF_MIRROR_FIXED_START + 15) #define EL_DF_MIRROR_FIXED_END EL_DF_MIRROR_FIXED_16 -#define EL_MM_END_3 EL_DF_MIRROR_FIXED_END -#define EL_DF_END_2 EL_DF_MIRROR_FIXED_END +#define EL_DF_SLOPE_START 1249 +#define EL_DF_SLOPE_1 (EL_DF_SLOPE_START + 0) +#define EL_DF_SLOPE_2 (EL_DF_SLOPE_START + 1) +#define EL_DF_SLOPE_3 (EL_DF_SLOPE_START + 2) +#define EL_DF_SLOPE_4 (EL_DF_SLOPE_START + 3) +#define EL_DF_SLOPE_END EL_DF_SLOPE_4 -#define NUM_FILE_ELEMENTS 1249 +#define EL_MM_END_3 EL_DF_SLOPE_END +#define EL_DF_END_2 EL_DF_SLOPE_END + +#define NUM_FILE_ELEMENTS 1253 // "real" (and therefore drawable) runtime elements -- 2.34.1