projects
/
rocksndiamonds.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
fixed bug with re-scanning laser when rotating teleporter in MM engine
[rocksndiamonds.git]
/
src
/
game_mm
/
mm_game.c
diff --git
a/src/game_mm/mm_game.c
b/src/game_mm/mm_game.c
index 45c65634a9985556c75420f04edc463ead080198..20e27068ffa641502bc60d230642c3fe62f10563 100644
(file)
--- a/
src/game_mm/mm_game.c
+++ b/
src/game_mm/mm_game.c
@@
-644,6
+644,8
@@
void InitGameEngine_MM(void)
game_mm.laser_green = FALSE;
game_mm.laser_blue = TRUE;
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;
game_mm.level_solved = FALSE;
game_mm.game_over = FALSE;
game_mm.game_over_cause = 0;
@@
-714,6
+716,8
@@
void InitGameActions_MM(void)
InitLaser();
InitLaser();
+ game_mm.lightball_rnd = FALSE;
+
for (i = 0; i <= num_init_game_frames; i++)
{
if (i == num_init_game_frames)
for (i = 0; i <= num_init_game_frames; i++)
{
if (i == num_init_game_frames)
@@
-749,6
+753,8
@@
void InitGameActions_MM(void)
#endif
}
#endif
}
+ game_mm.lightball_rnd = TRUE;
+
ScanLaser();
if (game_mm.kettles_still_needed == 0)
ScanLaser();
if (game_mm.kettles_still_needed == 0)
@@
-958,7
+964,8
@@
static void DeactivateLaserTargetElement(void)
void ScanLaser(void)
{
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
int end = 0, rf = laser.num_edges;
// do not scan laser again after the game was lost for whatever reason
@@
-1044,6
+1051,8
@@
void ScanLaser(void)
hit_mask, LX, LY, ELX, ELY);
#endif
hit_mask, LX, LY, ELX, ELY);
#endif
+ last_element = element;
+
element = Tile[ELX][ELY];
laser.dest_element = element;
element = Tile[ELX][ELY];
laser.dest_element = element;
@@
-1062,6
+1071,12
@@
void ScanLaser(void)
ELX, ELY, element);
#endif
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 (element == EL_EMPTY)
{
if (!HitOnlyAnEdge(hit_mask))
@@
-1120,6
+1135,14
@@
void ScanLaser(void)
if (rf)
DrawLaser(rf - 1, DL_LASER_ENABLED);
rf = laser.num_edges;
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
}
#if 0
@@
-1465,6
+1488,10
@@
boolean HitElement(int element, int hit_mask)
// this is more precise: check if laser would go through the center
if ((ELX * TILEX + 14 - LX) * YS != (ELY * TILEY + 14 - LY) * XS)
{
// 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
{
// skip the whole element before continuing the scan
do
{
@@
-2532,33
+2559,43
@@
static void GrowAmoeba(int x, int y)
}
static void DrawFieldAnimated_MM(int x, int y)
}
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 element = Tile[x][y];
+ int graphic = el2gfx(element);
- if (
IS_BLOCKED(x, y
))
+ if (
!getGraphicInfo_NewFrame(x, y, graphic
))
return;
DrawField_MM(x, y);
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)
}
static void Explode_MM(int x, int y, int phase, int mode)
@@
-3023,8
+3060,6
@@
void RotateMirror(int x, int y, int button)
IS_POLAR(Tile[x][y]) ||
IS_POLAR_CROSS(Tile[x][y])) && x == ELX && y == ELY)
{
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
if (IS_BEAMER(Tile[x][y]))
{
#if 0
@@
-3032,12
+3067,13
@@
void RotateMirror(int x, int y, int button)
LX, LY, laser.beamer_edge, laser.beamer[1].num);
#endif
LX, LY, laser.beamer_edge, laser.beamer[1].num);
#endif
-#if 0
- laser.num_edges--;
-#endif
+ if (check == 1)
+ laser.num_edges--;
}
ScanLaser();
}
ScanLaser();
+
+ check = 0;
}
if (check == 2)
}
if (check == 2)
@@
-3202,8
+3238,16
@@
static void GameActions_MM_Ext(void)
MeltIce(x, y);
else if (IS_WALL_CHANGING(element) && Store[x][y] == EL_WALL_AMOEBA)
GrowAmoeba(x, y);
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);
DrawFieldAnimated_MM(x, y);
+ else if (!IS_BLOCKED(x, y))
+ DrawFieldAnimatedIfNeeded_MM(x, y);
}
AutoRotateMirrors();
}
AutoRotateMirrors();