X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fgame_mm%2Fmm_game.c;h=b258e374b7f0bbeb868be9b873e831e331394af0;hp=fbbffe1898a151de41474b40f696eaf542c45128;hb=HEAD;hpb=5d17c2d5da052807393bfef854b9406232329666 diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index fbbffe18..b258e374 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -981,6 +981,11 @@ static int getMaskFromElement(int element) return MM_MASK_CIRCLE; } +static int getPixelFromMask(int pos, int dx, int dy) +{ + return (mm_masks[pos][dy / 2][dx / 2] == 'X' ? 1 : 0); +} + static int getLevelFromLaserX(int x) { return x / TILEX - (x < 0 ? 1 : 0); // correct negative values @@ -1064,7 +1069,7 @@ static int ScanPixel(void) { int pos = getMaskFromElement(element); - pixel = (mm_masks[pos][dy / 2][dx / 2] == 'X' ? 1 : 0); + pixel = getPixelFromMask(pos, dx, dy); } } else @@ -1209,14 +1214,10 @@ 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); @@ -1332,29 +1333,6 @@ 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)) @@ -1714,6 +1692,37 @@ static boolean HitElement(int element, int hit_mask) // check if laser scan has crossed element boundaries (not just mini tiles) boolean cross_x = (getLevelFromLaserX(LX) != getLevelFromLaserX(LX + 2)); boolean cross_y = (getLevelFromLaserY(LY) != getLevelFromLaserY(LY + 2)); + int element_angle = get_element_angle(element); + int mirrored_angle = get_mirrored_angle(laser.current_angle, element_angle); + int opposite_angle = get_opposite_angle(laser.current_angle); + + // check if wall (horizontal or vertical) side of slope was hit + if (hit_mask == HIT_MASK_LEFT || + hit_mask == HIT_MASK_RIGHT || + hit_mask == HIT_MASK_TOP || + hit_mask == HIT_MASK_BOTTOM) + { + boolean hit_slope_corner_in_laser_direction = + ((hit_mask == HIT_MASK_LEFT && (element == EL_DF_SLOPE_01 || + element == EL_DF_SLOPE_02)) || + (hit_mask == HIT_MASK_RIGHT && (element == EL_DF_SLOPE_00 || + element == EL_DF_SLOPE_03)) || + (hit_mask == HIT_MASK_TOP && (element == EL_DF_SLOPE_02 || + element == EL_DF_SLOPE_03)) || + (hit_mask == HIT_MASK_BOTTOM && (element == EL_DF_SLOPE_00 || + element == EL_DF_SLOPE_01))); + + boolean hit_slope_corner_in_laser_direction_double_checked = + (cross_x && cross_y && + laser.current_angle == mirrored_angle && + hit_slope_corner_in_laser_direction); + + // check special case of laser hitting the corner of a slope and another + // element (either wall or another slope), following the diagonal side + // of the slope which has the same angle as the direction of the laser + if (!hit_slope_corner_in_laser_direction_double_checked) + return HitReflectingWalls(element, hit_mask); + } // check if an edge was hit while crossing element borders if (cross_x && cross_y && get_number_of_bits(hit_mask) == 1) @@ -1726,8 +1735,8 @@ static boolean HitElement(int element, int hit_mask) int pos = getMaskFromElement(element); // check if we are entering empty space area after hitting edge - if (mm_masks[pos][dx1 / 2][dy1 / 2] != 'X' && - mm_masks[pos][dx2 / 2][dy2 / 2] != 'X') + if (!getPixelFromMask(pos, dx1, dy1) && + !getPixelFromMask(pos, dx2, dy2)) { // we already know that we hit an edge, but use this function to go on if (HitOnlyAnEdge(hit_mask)) @@ -1735,16 +1744,9 @@ static boolean HitElement(int element, int hit_mask) } } - 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; @@ -1972,8 +1974,8 @@ static boolean HitElement(int element, int hit_mask) { int elx, ely; - elx = getLevelFromLaserX(LX); - ely = getLevelFromLaserY(LY); + elx = getLevelFromLaserX(LX + XS); + ely = getLevelFromLaserY(LY + YS); if (IN_LEV_FIELD(elx, ely)) { @@ -1986,8 +1988,8 @@ static boolean HitElement(int element, int hit_mask) 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 == 1 ? (XS > 0 ? TILEX : 0) : + nr == 2 ? (XS > 0 ? TILEX : 0) : nr == 3 ? (XS > 0 ? TILEX - 1 : -1) : 0); int dy = (nr == 0 ? (YS > 0 ? TILEY - 1 : -1) : nr == 1 ? (YS > 0 ? TILEY - 1 : -1) : @@ -2019,7 +2021,7 @@ static boolean HitElement(int element, int hit_mask) { int pos = getMaskFromElement(element_side); - if (mm_masks[pos][dx / 2][dy / 2] == 'X') + if (getPixelFromMask(pos, dx, dy)) laser.overloaded = TRUE; } }