X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_mm%2Fmm_game.c;h=bc72f5bd43c2169505ae7eaae1a1827c3437856e;hb=b086cf74ed94a4e3e57f42242e0f066e01ea751c;hp=204ddf63a95daef1328ee1d399f8a304fd4348ee;hpb=a74e63d538386ee5de073a48fc2aea6b5ed2c5ce;p=rocksndiamonds.git diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index 204ddf63..bc72f5bd 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -837,16 +837,24 @@ void InitGameActions_MM(void) AdvanceFrameCounter(); AdvanceGfxFrame(); - DrawLevel_MM(); - - BackToFront_MM(); + if (PendingEscapeKeyEvent()) + continue; #ifdef DEBUG if (setup.quick_doors) continue; #endif + + DrawLevel_MM(); + + BackToFront_MM(); } +#ifdef DEBUG + if (setup.quick_doors) + DrawLevel_MM(); +#endif + ScanLaser(); if (game_mm.kettles_still_needed == 0) @@ -1201,14 +1209,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); @@ -1324,29 +1328,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)) @@ -1703,6 +1684,39 @@ static boolean HitElement(int element, int hit_mask) { if (IS_DF_SLOPE(element)) { + // 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)); + + // 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) + { + 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) + { + // check both sides of potentially diagonal side of slope + int dx1 = (LX + XS) % TILEX; + int dy1 = (LY + YS) % TILEY; + int dx2 = (LX + XS + 2) % TILEX; + int dy2 = (LY + YS + 2) % TILEY; + int pos = getMaskFromElement(element); + + // check if we are entering empty space area after hitting edge + if (mm_masks[pos][dy1 / 2][dx1 / 2] != 'X' && + mm_masks[pos][dy2 / 2][dx2 / 2] != 'X') + { + // we already know that we hit an edge, but use this function to go on + if (HitOnlyAnEdge(hit_mask)) + return FALSE; + } + } + int mirrored_angle = get_mirrored_angle(laser.current_angle, get_element_angle(element)); int opposite_angle = get_opposite_angle(laser.current_angle); @@ -1710,9 +1724,6 @@ static boolean HitElement(int element, int hit_mask) // 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; @@ -1893,13 +1904,27 @@ static boolean HitElement(int element, int hit_mask) XS = 2 * Step[laser.current_angle].x; YS = 2 * Step[laser.current_angle].y; - if (!IS_22_5_ANGLE(laser.current_angle)) // 90° or 45° angle - step_size = 8; - else - step_size = 4; + if (through_center) + { + // start from center position for all game elements but slope + if (!IS_22_5_ANGLE(laser.current_angle)) // 90° or 45° angle + step_size = 8; + else + step_size = 4; - LX += step_size * XS; - LY += step_size * YS; + LX += step_size * XS; + LY += step_size * YS; + } + else + { + // advance laser position until reaching the next tile (slopes) + while (LX / TILEX == ELX && (LX + 2) / TILEX == ELX && + LY / TILEY == ELY && (LY + 2) / TILEY == ELY) + { + LX += XS; + LY += YS; + } + } // draw sparkles on mirror if ((IS_MIRROR(element) || @@ -1973,7 +1998,7 @@ static boolean HitElement(int element, int hit_mask) { int pos = getMaskFromElement(element_side); - if (mm_masks[pos][dx / 2][dx / 2] == 'X') + if (mm_masks[pos][dy / 2][dx / 2] == 'X') laser.overloaded = TRUE; } }