fixed bug that could cause an endless loop (freeze) in the MM engine 4.3.5.1
authorHolger Schemel <info@artsoft.org>
Sun, 19 Feb 2023 00:30:03 +0000 (01:30 +0100)
committerHolger Schemel <info@artsoft.org>
Sun, 19 Feb 2023 00:49:05 +0000 (01:49 +0100)
This is a workaround for a regression bug of commit f8aec447 (that
fixed overloading the laser due to duplicated tiles in damage list).

The problem that could cause an endless loop already existed before
the above commit, but without that commit, scanning the laser was
stopped by the damage list completely filling up, stopping the loop.
The above commit prevents adding the same tile again and again to the
damage list, therefore not stopping the endless loop anymore.

This commit should prevent the endless loop from happening at all.

The problem (and how to reproduce it) was described by Eizzoux in the
following post in the R'n'D web forum:
https://www.artsoft.org/forum/viewtopic.php?p=18214

src/game_mm/mm_game.c

index 9a7ad5e6b031563653389669f4f6690f500acdce..2805fb77d3af6f33e4bebc4ce3967b61de5bf956 100644 (file)
@@ -1496,6 +1496,8 @@ 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)
   {
+    int skip_count = 0;
+
     // prevent cutting through laser emitter with laser beam
     if (IS_LASER(element))
       return TRUE;
@@ -1505,15 +1507,18 @@ boolean HitElement(int element, int hit_mask)
     {
       LX += XS;
       LY += YS;
+
+      skip_count++;
     }
     while (ELX == LX/TILEX && ELY == LY/TILEY && LX > 0 && LY > 0);
 
-    if (LX/TILEX > ELX || LY/TILEY > ELY)
+    if ((LX/TILEX > ELX || LY/TILEY > ELY) && skip_count > 1)
     {
       /* skipping scan positions to the right and down skips one scan
         position too much, because this is only the top left scan position
         of totally four scan positions (plus one to the right, one to the
         bottom and one to the bottom right) */
+      /* ... but only roll back scan position if more than one step done */
 
       LX -= XS;
       LY -= YS;