pen_ray =
GetPixelFromRGB(window,
- (native_mm_level.laser_red ? color_max : color_up),
- (native_mm_level.laser_green ? color_down : color_min),
- (native_mm_level.laser_blue ? color_down : color_min));
+ (game_mm.laser_red ? color_max : color_up),
+ (game_mm.laser_green ? color_down : color_min),
+ (game_mm.laser_blue ? color_down : color_min));
}
static void InitMovDir_MM(int x, int y)
laser.start_edge.x = x;
laser.start_edge.y = y;
laser.start_angle = get_element_angle(element);
+
+ if (IS_MCDUFFIN(element))
+ {
+ game_mm.laser_red = native_mm_level.mm_laser_red;
+ game_mm.laser_green = native_mm_level.mm_laser_green;
+ game_mm.laser_blue = native_mm_level.mm_laser_blue;
+ }
+ else
+ {
+ game_mm.laser_red = native_mm_level.df_laser_red;
+ game_mm.laser_green = native_mm_level.df_laser_green;
+ game_mm.laser_blue = native_mm_level.df_laser_blue;
+ }
}
break;
game_mm.num_keys = 0;
game_mm.ball_choice_pos = 0;
+ game_mm.laser_red = FALSE;
+ game_mm.laser_green = FALSE;
+ game_mm.laser_blue = TRUE;
+
game_mm.level_solved = FALSE;
game_mm.game_over = FALSE;
game_mm.game_over_cause = 0;
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)
return hit_mask;
}
-void ScanLaser(void)
+static void DeactivateLaserTargetElement(void)
{
- int element;
- int end = 0, rf = laser.num_edges;
-
- // do not scan laser again after the game was lost for whatever reason
- if (game_mm.game_over)
- return;
-
if (laser.dest_element_last == EL_BOMB_ACTIVE ||
laser.dest_element_last == EL_MINE_ACTIVE ||
laser.dest_element_last == EL_GRAY_BALL_OPENING)
laser.dest_element_last_x = -1;
laser.dest_element_last_y = -1;
}
+}
+
+void ScanLaser(void)
+{
+ int element = EL_EMPTY;
+ int last_element = EL_EMPTY;
+ int end = 0, rf = laser.num_edges;
+
+ // do not scan laser again after the game was lost for whatever reason
+ if (game_mm.game_over)
+ return;
+
+ // do not scan laser if fuse is off
+ if (laser.fuse_off)
+ return;
+
+ DeactivateLaserTargetElement();
laser.overloaded = FALSE;
laser.stops_inside_element = FALSE;
hit_mask, LX, LY, ELX, ELY);
#endif
+ last_element = element;
+
element = Tile[ELX][ELY];
laser.dest_element = element;
ELX, ELY, element);
#endif
+ // special case: leaving fixed MM steel grid (upwards) with non-90° angle
+ if (element == EL_EMPTY &&
+ IS_GRID_STEEL(last_element) &&
+ laser.current_angle % 4) // angle is not 90°
+ element = last_element;
+
if (element == EL_EMPTY)
{
if (!HitOnlyAnEdge(hit_mask))
if (rf)
DrawLaser(rf - 1, DL_LASER_ENABLED);
rf = laser.num_edges;
+
+ if (!IS_DF_WALL_STEEL(element))
+ {
+ // only used for scanning DF steel walls; reset for all other elements
+ last_LX = 0;
+ last_LY = 0;
+ last_hit_mask = 0;
+ }
}
#if 0
void DrawLaser(int start_edge, int mode)
{
+ // do not draw laser if fuse is off
+ if (laser.fuse_off && mode == DL_LASER_ENABLED)
+ return;
+
+ if (mode == DL_LASER_DISABLED)
+ DeactivateLaserTargetElement();
+
if (laser.num_edges - start_edge < 0)
{
Warn("DrawLaser: laser.num_edges - start_edge < 0");
// this is more precise: check if laser would go through the center
if ((ELX * TILEX + 14 - LX) * YS != (ELY * TILEY + 14 - LY) * XS)
{
+ // prevent cutting through laser emitter with laser beam
+ if (IS_LASER(element))
+ return TRUE;
+
// skip the whole element before continuing the scan
do
{
}
static void DrawFieldAnimated_MM(int x, int y)
+{
+ DrawField_MM(x, y);
+
+ laser.redraw = TRUE;
+}
+
+static void DrawFieldAnimatedIfNeeded_MM(int x, int y)
{
int element = Tile[x][y];
+ int graphic = el2gfx(element);
- if (IS_BLOCKED(x, y))
+ if (!getGraphicInfo_NewFrame(x, y, graphic))
return;
DrawField_MM(x, y);
- if (IS_MIRROR(element) ||
- IS_MIRROR_FIXED(element) ||
- element == EL_PRISM)
+ laser.redraw = TRUE;
+}
+
+static void DrawFieldTwinkle(int x, int y)
+{
+ if (MovDelay[x][y] != 0) // wait some time before next frame
{
- if (MovDelay[x][y] != 0) // wait some time before next frame
- {
- MovDelay[x][y]--;
+ MovDelay[x][y]--;
- if (MovDelay[x][y] != 0)
- {
- int graphic = IMG_TWINKLE_WHITE;
- int frame = getGraphicAnimationFrame(graphic, 10 - MovDelay[x][y]);
+ DrawField_MM(x, y);
- DrawGraphicThruMask_MM(SCREENX(x), SCREENY(y), graphic, frame);
- }
+ if (MovDelay[x][y] != 0)
+ {
+ int graphic = IMG_TWINKLE_WHITE;
+ int frame = getGraphicAnimationFrame(graphic, 10 - MovDelay[x][y]);
+
+ DrawGraphicThruMask_MM(SCREENX(x), SCREENY(y), graphic, frame);
}
- }
- laser.redraw = TRUE;
+ laser.redraw = TRUE;
+ }
}
static void Explode_MM(int x, int y, int phase, int mode)
IS_POLAR(Tile[x][y]) ||
IS_POLAR_CROSS(Tile[x][y])) && x == ELX && y == ELY)
{
- check = 0;
-
if (IS_BEAMER(Tile[x][y]))
{
#if 0
LX, LY, laser.beamer_edge, laser.beamer[1].num);
#endif
-#if 0
- laser.num_edges--;
-#endif
+ if (check == 1)
+ laser.num_edges--;
}
ScanLaser();
+
+ check = 0;
}
if (check == 2)
MeltIce(x, y);
else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA)
GrowAmoeba(x, y);
- else
+ else if (IS_MIRROR(element) ||
+ IS_MIRROR_FIXED(element) ||
+ element == EL_PRISM)
+ DrawFieldTwinkle(x, y);
+ else if (element == EL_GRAY_BALL_OPENING ||
+ element == EL_BOMB_ACTIVE ||
+ element == EL_MINE_ACTIVE)
DrawFieldAnimated_MM(x, y);
+ else if (!IS_BLOCKED(x, y))
+ DrawFieldAnimatedIfNeeded_MM(x, y);
}
AutoRotateMirrors();