X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_mm%2Fmm_game.c;h=5cdc8ed3114712b6e97fd8f11d1ce9c22a8f8b21;hb=258d9d4ffe4374628f4bf49f2f0a30c4c1701933;hp=d4a69181a3f608d0c19245d0ed5f13b053468bd7;hpb=a476bb35e8b7a41f8bef49d6ffd7ec9478ece646;p=rocksndiamonds.git diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index d4a69181..5cdc8ed3 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -570,6 +570,8 @@ static void InitField(int x, int y, boolean init_game) game_mm.laser_green = native_mm_level.df_laser_green; game_mm.laser_blue = native_mm_level.df_laser_blue; } + + game_mm.has_mcduffin = (IS_MCDUFFIN(element)); } break; @@ -662,10 +664,12 @@ void InitGameEngine_MM(void) game_mm.laser_red = FALSE; game_mm.laser_green = FALSE; game_mm.laser_blue = TRUE; + game_mm.has_mcduffin = TRUE; game_mm.level_solved = FALSE; game_mm.game_over = FALSE; game_mm.game_over_cause = 0; + game_mm.game_over_message = NULL; game_mm.laser_overload_value = 0; game_mm.laser_enabled = FALSE; @@ -802,21 +806,23 @@ static void FadeOutLaser(void) static void GameOver_MM(int game_over_cause) { - // do not handle game over if request dialog is already active - if (game.request_active) - return; - game_mm.game_over = TRUE; game_mm.game_over_cause = game_over_cause; - - if (setup.ask_on_game_over) - game.restart_game_message = (game_over_cause == GAME_OVER_BOMB ? - "Bomb killed Mc Duffin! Play it again?" : - game_over_cause == GAME_OVER_NO_ENERGY ? - "Out of magic energy! Play it again?" : - game_over_cause == GAME_OVER_OVERLOADED ? - "Magic spell hit Mc Duffin! Play it again?" : - NULL); + game_mm.game_over_message = (game_mm.has_mcduffin ? + (game_over_cause == GAME_OVER_BOMB ? + "Bomb killed Mc Duffin!" : + game_over_cause == GAME_OVER_NO_ENERGY ? + "Out of magic energy!" : + game_over_cause == GAME_OVER_OVERLOADED ? + "Magic spell hit Mc Duffin!" : + NULL) : + (game_over_cause == GAME_OVER_BOMB ? + "Bomb destroyed laser cannon!" : + game_over_cause == GAME_OVER_NO_ENERGY ? + "Out of laser energy!" : + game_over_cause == GAME_OVER_OVERLOADED ? + "Laser beam hit laser cannon!" : + NULL)); SetTileCursorActive(FALSE); } @@ -909,6 +915,26 @@ static int ScanPixel(void) } #endif + // check if laser scan has crossed element boundaries (not just mini tiles) + boolean cross_x = (LX / TILEX != (LX + 2) / TILEX); + boolean cross_y = (LY / TILEY != (LY + 2) / TILEY); + + if (cross_x && cross_y) + { + int elx1 = (LX - XS) / TILEX; + int ely1 = (LY + YS) / TILEY; + int elx2 = (LX + XS) / TILEX; + int ely2 = (LY - YS) / TILEY; + + // add element corners left and right from the laser beam to damage list + + if (IN_LEV_FIELD(elx1, ely1) && Tile[elx1][ely1] != EL_EMPTY) + AddDamagedField(elx1, ely1); + + if (IN_LEV_FIELD(elx2, ely2) && Tile[elx2][ely2] != EL_EMPTY) + AddDamagedField(elx2, ely2); + } + for (i = 0; i < 4; i++) { int px = LX + (i % 2) * 2; @@ -1049,12 +1075,21 @@ static void ScanLaser(void) break; } - if (hit_mask == HIT_MASK_DIAGONAL_1 || hit_mask == HIT_MASK_DIAGONAL_2) + // check if laser scan has hit two diagonally adjacent element corners + boolean diag_1 = ((hit_mask & HIT_MASK_DIAGONAL_1) == HIT_MASK_DIAGONAL_1); + boolean diag_2 = ((hit_mask & HIT_MASK_DIAGONAL_2) == HIT_MASK_DIAGONAL_2); + + // check if laser scan has crossed element boundaries (not just mini tiles) + boolean cross_x = (LX / TILEX != (LX + 2) / TILEX); + boolean cross_y = (LY / TILEY != (LY + 2) / TILEY); + + // 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) { - // we have hit two diagonally adjacent elements -- compare them - boolean dia_1 = (hit_mask == HIT_MASK_DIAGONAL_1); + // compare the two diagonally adjacent elements int xoffset = 2; - int yoffset = 2 * (dia_1 ? -1 : +1); + int yoffset = 2 * (diag_1 ? -1 : +1); int elx1 = (LX - xoffset) / TILEX; int ely1 = (LY + yoffset) / TILEY; int elx2 = (LX + xoffset) / TILEX; @@ -1072,16 +1107,14 @@ static void ScanLaser(void) } else if (IS_WALL_AMOEBA(e1) || IS_WALL_AMOEBA(e2)) { - if (IS_WALL_AMOEBA(e1) && IS_WALL_AMOEBA(e2)) - use_element_1 = (RND(2) ? TRUE : FALSE); - else if (IS_WALL_AMOEBA(e1)) + // if both tiles match, we can just select the first one + if (IS_WALL_AMOEBA(e1)) use_element_1 = TRUE; } else if (IS_ABSORBING_BLOCK(e1) || IS_ABSORBING_BLOCK(e2)) { - if (IS_ABSORBING_BLOCK(e1) && IS_ABSORBING_BLOCK(e2)) - use_element_1 = (RND(2) ? TRUE : FALSE); - else if (IS_ABSORBING_BLOCK(e1)) + // if both tiles match, we can just select the first one + if (IS_ABSORBING_BLOCK(e1)) use_element_1 = TRUE; } @@ -1995,10 +2028,16 @@ static boolean HitPolarizer(int element, int hit_mask) } else if (IS_GRID_STEEL(element)) { + // may be required if graphics for steel grid redefined + AddDamagedField(ELX, ELY); + return HitReflectingWalls(element, hit_mask); } else // IS_GRID_WOOD { + // may be required if graphics for wooden grid redefined + AddDamagedField(ELX, ELY); + return HitAbsorbingWalls(element, hit_mask); } @@ -2048,11 +2087,9 @@ static boolean HitBlock(int element, int hit_mask) if (element == EL_GATE_STONE || element == EL_GATE_WOOD) { int xs = XS / 2, ys = YS / 2; - int hit_mask_diagonal1 = HIT_MASK_TOPRIGHT | HIT_MASK_BOTTOMLEFT; - int hit_mask_diagonal2 = HIT_MASK_TOPLEFT | HIT_MASK_BOTTOMRIGHT; - if ((hit_mask & hit_mask_diagonal1) == hit_mask_diagonal1 || - (hit_mask & hit_mask_diagonal2) == hit_mask_diagonal2) + if ((hit_mask & HIT_MASK_DIAGONAL_1) == HIT_MASK_DIAGONAL_1 || + (hit_mask & HIT_MASK_DIAGONAL_2) == HIT_MASK_DIAGONAL_2) { laser.overloaded = (element == EL_GATE_STONE); @@ -2091,11 +2128,9 @@ static boolean HitBlock(int element, int hit_mask) if (element == EL_BLOCK_STONE || element == EL_BLOCK_WOOD) { int xs = XS / 2, ys = YS / 2; - int hit_mask_diagonal1 = HIT_MASK_TOPRIGHT | HIT_MASK_BOTTOMLEFT; - int hit_mask_diagonal2 = HIT_MASK_TOPLEFT | HIT_MASK_BOTTOMRIGHT; - if ((hit_mask & hit_mask_diagonal1) == hit_mask_diagonal1 || - (hit_mask & hit_mask_diagonal2) == hit_mask_diagonal2) + if ((hit_mask & HIT_MASK_DIAGONAL_1) == HIT_MASK_DIAGONAL_1 || + (hit_mask & HIT_MASK_DIAGONAL_2) == HIT_MASK_DIAGONAL_2) { laser.overloaded = (element == EL_BLOCK_STONE); @@ -2797,11 +2832,9 @@ static void Explode_MM(int x, int y, int phase, int mode) Bang_MM(laser.start_edge.x, laser.start_edge.y); - GameOver_MM(GAME_OVER_DELAYED); - laser.overloaded = FALSE; } - else if (IS_MCDUFFIN(center_element)) + else if (IS_MCDUFFIN(center_element) || IS_LASER(center_element)) { GameOver_MM(GAME_OVER_BOMB); }