{
if (laser.dest_element_last == EL_BOMB_ACTIVE ||
laser.dest_element_last == EL_MINE_ACTIVE ||
+ laser.dest_element_last == EL_GRAY_BALL_ACTIVE ||
laser.dest_element_last == EL_GRAY_BALL_OPENING)
{
int x = laser.dest_element_last_x;
if (Tile[x][y] == element)
Tile[x][y] = (element == EL_BOMB_ACTIVE ? EL_BOMB :
- element == EL_MINE_ACTIVE ? EL_MINE : EL_BALL_GRAY);
+ element == EL_MINE_ACTIVE ? EL_MINE : EL_GRAY_BALL);
- if (Tile[x][y] == EL_BALL_GRAY)
+ if (Tile[x][y] == EL_GRAY_BALL)
MovDelay[x][y] = 0;
laser.dest_element_last = EL_EMPTY;
#endif
}
+static void ScanLaser_FromLastMirror(void)
+{
+ int start_pos = (laser.num_damages > 0 ? laser.num_damages - 1 : 0);
+ int i;
+
+ for (i = start_pos; i >= 0; i--)
+ if (laser.damage[i].is_mirror)
+ break;
+
+ int start_edge = (i > 0 ? laser.damage[i].edge - 1 : 0);
+
+ DrawLaser(start_edge, DL_LASER_DISABLED);
+
+ ScanLaser();
+}
+
static void DrawLaserExt(int start_edge, int num_edges, int mode)
{
int element;
return TRUE;
}
- if (element == EL_BOMB || element == EL_MINE)
+ if (element == EL_BOMB || element == EL_MINE || element == EL_GRAY_BALL)
{
PlayLevelSound_MM(ELX, ELY, element, MM_ACTION_HITTING);
- Tile[ELX][ELY] = (element == EL_BOMB ? EL_BOMB_ACTIVE : EL_MINE_ACTIVE);
+ Tile[ELX][ELY] = (element == EL_BOMB ? EL_BOMB_ACTIVE :
+ element == EL_MINE ? EL_MINE_ACTIVE :
+ EL_GRAY_BALL_ACTIVE);
laser.dest_element_last = Tile[ELX][ELY];
laser.dest_element_last_x = ELX;
}
}
-static void OpenSurpriseBall(int x, int y)
+static void OpenGrayBall(int x, int y)
{
int delay = 2;
if (!MovDelay[x][y]) // next animation frame
+ {
+ if (IS_WALL(Store[x][y]))
+ {
+ DrawWalls_MM(x, y, Store[x][y]);
+
+ // copy wall tile to spare bitmap for "melting" animation
+ BlitBitmap(drawto, bitmap_db_field, cSX + x * TILEX, cSY + y * TILEY,
+ TILEX, TILEY, x * TILEX, y * TILEY);
+
+ DrawElement_MM(x, y, EL_GRAY_BALL);
+ }
+
MovDelay[x][y] = 50 * delay;
+ }
if (MovDelay[x][y]) // wait some time before next frame
{
if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
{
Bitmap *bitmap;
- int graphic = el2gfx(Store[x][y]);
int gx, gy;
int dx = RND(26), dy = RND(26);
- getGraphicSource(graphic, 0, &bitmap, &gx, &gy);
+ if (IS_WALL(Store[x][y]))
+ {
+ // copy wall tile from spare bitmap for "melting" animation
+ bitmap = bitmap_db_field;
+ gx = x * TILEX;
+ gy = y * TILEY;
+ }
+ else
+ {
+ int graphic = el2gfx(Store[x][y]);
+
+ getGraphicSource(graphic, 0, &bitmap, &gx, &gy);
+ }
BlitBitmap(bitmap, drawto, gx + dx, gy + dy, 6, 6,
cSX + x * TILEX + dx, cSY + y * TILEY + dy);
InitField(x, y, FALSE);
DrawField_MM(x, y);
- ScanLaser();
+ ScanLaser_FromLastMirror();
}
}
}
if (!MovDelay[x][y])
{
- int i;
-
Tile[x][y] = real_element & (wall_mask ^ 0xFF);
Store[x][y] = Store2[x][y] = 0;
if (Tile[x][y] == EL_WALL_ICE)
Tile[x][y] = EL_EMPTY;
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
- if (laser.damage[i].is_mirror)
- break;
-
- if (i > 0)
- DrawLaser(laser.damage[i].edge - 1, DL_LASER_DISABLED);
- else
- DrawLaser(0, DL_LASER_DISABLED);
-
- ScanLaser();
+ ScanLaser_FromLastMirror();
}
else if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(x, y))
{
else if (element == EL_EXIT_OPENING)
OpenExit(x, y);
else if (element == EL_GRAY_BALL_OPENING)
- OpenSurpriseBall(x, y);
+ OpenGrayBall(x, y);
else if (IS_ENVELOPE_OPENING(element))
OpenEnvelope(x, y);
else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_ICE)
IS_MIRROR_FIXED(element) ||
element == EL_PRISM)
DrawFieldTwinkle(x, y);
- else if (element == EL_GRAY_BALL_OPENING ||
+ else if (element == EL_GRAY_BALL_ACTIVE ||
element == EL_BOMB_ACTIVE ||
element == EL_MINE_ACTIVE)
DrawFieldAnimated_MM(x, y);
element != EL_BOMB_ACTIVE &&
element != EL_MINE &&
element != EL_MINE_ACTIVE &&
- element != EL_BALL_GRAY &&
+ element != EL_GRAY_BALL &&
+ element != EL_GRAY_BALL_ACTIVE &&
element != EL_BLOCK_STONE &&
element != EL_BLOCK_WOOD &&
element != EL_FUSE_ON &&
DrawGraphic_MM(ELX, ELY, IMG_MM_FUSE);
}
- if (element == EL_BALL_GRAY && CT > native_mm_level.time_ball)
+ if (element == EL_GRAY_BALL && CT > native_mm_level.time_ball)
{
if (!Store2[ELX][ELY]) // check if content element not yet determined
{
game_mm.ball_choice_pos++;
int new_element = native_mm_level.ball_content[element_pos];
+ int new_element_unmapped = unmap_element(new_element);
- // randomly rotate newly created game element, if needed
- if (native_mm_level.rotate_ball_content)
+ if (IS_WALL(new_element_unmapped))
+ {
+ // always use completely filled wall element
+ new_element = new_element_unmapped | 0x000f;
+ }
+ else if (native_mm_level.rotate_ball_content &&
+ get_num_elements(new_element) > 1)
+ {
+ // randomly rotate newly created game element
new_element = get_rotated_element(new_element, RND(16));
+ }
Store[ELX][ELY] = new_element;
Store2[ELX][ELY] = TRUE;
Tile[ELX][ELY] = EL_GRAY_BALL_OPENING;
- // !!! CHECK AGAIN: Laser on Polarizer !!!
- ScanLaser();
-
laser.dest_element_last = Tile[ELX][ELY];
- laser.dest_element_last_x = ELX;
- laser.dest_element_last_y = ELY;
return;
LY = laser.edge[laser.num_edges].y - cSY2;
*/
- for (i = (laser.num_damages > 0 ? laser.num_damages - 1 : 0); i >= 0; i--)
- if (laser.damage[i].is_mirror)
- break;
-
- if (i > 0)
- DrawLaser(laser.damage[i].edge - 1, DL_LASER_DISABLED);
- else
- DrawLaser(0, DL_LASER_DISABLED);
-
- ScanLaser();
+ ScanLaser_FromLastMirror();
return;
}