X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fgame_mm%2Fmm_game.c;h=be1bfad64051591d5fc725f781c1064269ef04b6;hb=dec5db25350278f0e64b0036dee18f58a931d31f;hp=496cc916756f878650ba455a8ce53623447b926b;hpb=c42db18f39053cf2ec85943c37a20b8caa742d09;p=rocksndiamonds.git diff --git a/src/game_mm/mm_game.c b/src/game_mm/mm_game.c index 496cc916..be1bfad6 100644 --- a/src/game_mm/mm_game.c +++ b/src/game_mm/mm_game.c @@ -828,10 +828,12 @@ static void GameOver_MM(int game_over_cause) static void AddLaserEdge(int lx, int ly) { - int clx = dSX + lx; - int cly = dSY + ly; + int full_sxsize = MAX(FULL_SXSIZE, lev_fieldx * TILEX); + int full_sysize = MAX(FULL_SYSIZE, lev_fieldy * TILEY); - if (clx < -2 || cly < -2 || clx >= SXSIZE + 2 || cly >= SYSIZE + 2) + // check if laser is still inside visible playfield area (or inside level) + if (cSX + lx < REAL_SX || cSX + lx >= REAL_SX + full_sxsize || + cSY + ly < REAL_SY || cSY + ly >= REAL_SY + full_sysize) { Warn("AddLaserEdge: out of bounds: %d, %d", lx, ly); @@ -879,11 +881,13 @@ static boolean StepBehind(void) static int getMaskFromElement(int element) { - if (IS_GRID(element)) - return MM_MASK_GRID_1 + get_element_phase(element); - else if (IS_MCDUFFIN(element)) + if (IS_MCDUFFIN(element)) return MM_MASK_MCDUFFIN_RIGHT + get_element_phase(element); - else if (IS_RECTANGLE(element) || IS_DF_GRID(element)) + else if (IS_GRID(element)) + return MM_MASK_GRID_1 + get_element_phase(element); + else if (IS_DF_GRID(element)) + return MM_MASK_RECTANGLE; + else if (IS_RECTANGLE(element)) return MM_MASK_RECTANGLE; else return MM_MASK_CIRCLE; @@ -967,6 +971,7 @@ static int ScanPixel(void) } else { + // check if laser is still inside visible playfield area pixel = (cSX + px < REAL_SX || cSX + px >= REAL_SX + FULL_SXSIZE || cSY + py < REAL_SY || cSY + py >= REAL_SY + FULL_SYSIZE); } @@ -1058,16 +1063,31 @@ static void ScanLaser(void) #endif // hit something -- check out what it was - ELX = (LX + XS) / TILEX; - ELY = (LY + YS) / TILEY; + ELX = (LX + XS + TILEX) / TILEX - 1; // ...+TILEX...-1 to get correct + ELY = (LY + YS + TILEY) / TILEY - 1; // negative values! #if 0 Debug("game:mm:ScanLaser", "hit_mask (1) == '%x' (%d, %d) (%d, %d)", hit_mask, LX, LY, ELX, ELY); #endif - if (!IN_LEV_FIELD(ELX, ELY) || !IN_PIX_FIELD(LX, LY)) + if (!IN_LEV_FIELD(ELX, ELY)) { + // laser next step position + int x = cSX + LX + XS; + int y = cSY + LY + YS; + + // check if next step of laser is still inside visible playfield area + if (x >= REAL_SX && x < REAL_SX + FULL_SXSIZE && + y >= REAL_SY && y < REAL_SY + FULL_SYSIZE) + { + // go on with another step + LX += XS; + LY += YS; + + continue; + } + element = EL_EMPTY; laser.dest_element = element; @@ -1672,6 +1692,7 @@ static boolean HitElement(int element, int hit_mask) IS_POLAR_CROSS(element) || IS_DF_MIRROR(element) || IS_DF_MIRROR_AUTO(element) || + IS_DF_MIRROR_FIXED(element) || element == EL_PRISM || element == EL_REFRACTOR) { @@ -1690,7 +1711,8 @@ static boolean HitElement(int element, int hit_mask) if (IS_MIRROR(element) || IS_MIRROR_FIXED(element) || IS_DF_MIRROR(element) || - IS_DF_MIRROR_AUTO(element)) + IS_DF_MIRROR_AUTO(element) || + IS_DF_MIRROR_FIXED(element)) laser.current_angle = get_mirrored_angle(laser.current_angle, get_element_angle(element)); @@ -3274,7 +3296,11 @@ static void AutoRotateMirrors(void) IS_GRID_WOOD_AUTO(element) || IS_GRID_STEEL_AUTO(element) || element == EL_REFRACTOR) + { RotateMirror(x, y, MB_RIGHTBUTTON); + + laser.redraw = TRUE; + } } } }