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;
void ScanLaser(void)
{
- int element;
+ 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
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
// 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)
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();