X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fgame_mm%2Fmm_game.c;h=d6ba5374db4d5e50448ab0e7ead370bda84bb6c8;hb=869bcbe4049f6135c202740019f6c2f60bde0425;hp=20e27068ffa641502bc60d230642c3fe62f10563;hpb=6d26e1e4259343003f378829a3f18ee5f7e7cdcd;p=rocksndiamonds.git diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index 20e27068..d6ba5374 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -644,8 +644,6 @@ void InitGameEngine_MM(void) game_mm.laser_green = FALSE; game_mm.laser_blue = TRUE; - game_mm.lightball_rnd = TRUE; - game_mm.level_solved = FALSE; game_mm.game_over = FALSE; game_mm.game_over_cause = 0; @@ -716,8 +714,6 @@ void InitGameActions_MM(void) InitLaser(); - game_mm.lightball_rnd = FALSE; - for (i = 0; i <= num_init_game_frames; i++) { if (i == num_init_game_frames) @@ -753,8 +749,6 @@ void InitGameActions_MM(void) #endif } - game_mm.lightball_rnd = TRUE; - ScanLaser(); if (game_mm.kettles_still_needed == 0) @@ -763,7 +757,11 @@ void InitGameActions_MM(void) SetTileCursorXY(laser.start_edge.x, laser.start_edge.y); SetTileCursorActive(TRUE); + // restart all delay counters after initially cycling game elements + ResetFrameCounter(&rotate_delay); + ResetFrameCounter(&pacman_delay); ResetFrameCounter(&energy_delay); + ResetFrameCounter(&overload_delay); } static void FadeOutLaser(void) @@ -827,6 +825,13 @@ void AddLaserEdge(int lx, int ly) void AddDamagedField(int ex, int ey) { + // prevent adding the same field position again + if (laser.num_damages > 0 && + laser.damage[laser.num_damages - 1].x == ex && + laser.damage[laser.num_damages - 1].y == ey && + laser.damage[laser.num_damages - 1].edge == laser.num_edges) + return; + laser.damage[laser.num_damages].is_mirror = FALSE; laser.damage[laser.num_damages].angle = laser.current_angle; laser.damage[laser.num_damages].edge = laser.num_edges; @@ -1658,9 +1663,11 @@ boolean HitElement(int element, int hit_mask) element == EL_KEY || element == EL_LIGHTBALL || element == EL_PACMAN || - IS_PACMAN(element)) + IS_PACMAN(element) || + IS_ENVELOPE(element)) { - if (!IS_PACMAN(element)) + if (!IS_PACMAN(element) && + !IS_ENVELOPE(element)) Bang_MM(ELX, ELY); if (element == EL_PACMAN) @@ -1688,6 +1695,10 @@ boolean HitElement(int element, int hit_mask) { DeletePacMan(ELX, ELY); } + else if (IS_ENVELOPE(element)) + { + Tile[ELX][ELY] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(Tile[ELX][ELY]); + } RaiseScoreElement_MM(element); @@ -2462,6 +2473,8 @@ static void OpenSurpriseBall(int x, int y) BlitBitmap(bitmap, drawto, gx + dx, gy + dy, 6, 6, cSX + x * TILEX + dx, cSY + y * TILEY + dy); + laser.redraw = TRUE; + MarkTileDirty(x, y); } @@ -2477,6 +2490,42 @@ static void OpenSurpriseBall(int x, int y) } } +static void OpenEnvelope(int x, int y) +{ + int num_frames = 8; // seven frames plus final empty space + + if (!MovDelay[x][y]) // next animation frame + MovDelay[x][y] = num_frames; + + if (MovDelay[x][y]) // wait some time before next frame + { + int nr = ENVELOPE_OPENING_NR(Tile[x][y]); + + MovDelay[x][y]--; + + if (MovDelay[x][y] > 0 && IN_SCR_FIELD(x, y)) + { + int graphic = el_act2gfx(EL_ENVELOPE_1 + nr, MM_ACTION_COLLECTING); + int frame = num_frames - MovDelay[x][y] - 1; + + DrawGraphicAnimation_MM(x, y, graphic, frame); + + laser.redraw = TRUE; + } + + if (MovDelay[x][y] == 0) + { + Tile[x][y] = EL_EMPTY; + + DrawField_MM(x, y); + + ScanLaser(); + + ShowEnvelope_MM(nr); + } + } +} + static void MeltIce(int x, int y) { int frames = 5; @@ -2619,15 +2668,14 @@ static void Explode_MM(int x, int y, int phase, int mode) Tile[x][y] = center_element; } - if (center_element == EL_BOMB_ACTIVE || IS_MCDUFFIN(center_element)) - Store[x][y] = center_element; - else - Store[x][y] = EL_EMPTY; - + Store[x][y] = center_element; Store2[x][y] = mode; Tile[x][y] = EL_EXPLODING_OPAQUE; - GfxElement[x][y] = center_element; + + GfxElement[x][y] = (center_element == EL_BOMB_ACTIVE ? EL_BOMB : + IS_MCDUFFIN(center_element) ? EL_MCDUFFIN : + center_element); MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; @@ -2657,7 +2705,6 @@ static void Explode_MM(int x, int y, int phase, int mode) InitLaser(); Bang_MM(laser.start_edge.x, laser.start_edge.y); - Store[x][y] = EL_EMPTY; GameOver_MM(GAME_OVER_DELAYED); @@ -2665,12 +2712,11 @@ static void Explode_MM(int x, int y, int phase, int mode) } else if (IS_MCDUFFIN(Store[x][y])) { - Store[x][y] = EL_EMPTY; - GameOver_MM(GAME_OVER_BOMB); } - Tile[x][y] = Store[x][y]; + Tile[x][y] = EL_EMPTY; + Store[x][y] = Store2[x][y] = 0; MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0; @@ -2978,6 +3024,12 @@ boolean ClickElement(int x, int y, int button) element_clicked = TRUE; } + else if (IS_ENVELOPE(element)) + { + Tile[x][y] = EL_ENVELOPE_1_OPENING + ENVELOPE_NR(element); + + element_clicked = TRUE; + } click_delay.value = (new_button ? CLICK_DELAY_FIRST : CLICK_DELAY); new_button = FALSE; @@ -3234,6 +3286,8 @@ static void GameActions_MM_Ext(void) OpenExit(x, y); else if (element == EL_GRAY_BALL_OPENING) OpenSurpriseBall(x, y); + else if (IS_ENVELOPE_OPENING(element)) + OpenEnvelope(x, y); else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_ICE) MeltIce(x, y); else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA) @@ -3436,7 +3490,11 @@ static void GameActions_MM_Ext(void) int new_element = native_mm_level.ball_content[element_pos]; - Store[ELX][ELY] = new_element + RND(get_num_elements(new_element)); + // randomly rotate newly created game element, if needed + if (native_mm_level.rotate_ball_content) + new_element = get_rotated_element(new_element, RND(16)); + + Store[ELX][ELY] = new_element; Store2[ELX][ELY] = TRUE; }