fixed bug with forced restart of global animations when restarting game
[rocksndiamonds.git] / src / anim.c
index a20ee4a3153c7881e9235b6c852f448a2ff83976..bd1847a9a72cb3cef58bb53bba49d8ba44129004 100644 (file)
@@ -122,6 +122,9 @@ struct GlobalAnimPartControlInfo
   int x, y;
   int step_xoffset, step_yoffset;
 
+  int tile_x, tile_y;
+  int tile_xoffset, tile_yoffset;
+
   unsigned int initial_anim_sync_frame;
   unsigned int anim_random_frame;
 
@@ -854,6 +857,10 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
     }
   }
 
+  // when restarting global animations, do not redraw them, but stop here
+  if (drawing_stage == DRAW_GLOBAL_ANIM_STAGE_RESTART)
+    return;
+
   if (global.anim_status == GAME_MODE_LOADING)
     return;
 
@@ -1390,18 +1397,28 @@ static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page,
       if (!(part2->state & ANIM_STATE_RUNNING))
        continue;
 
-      if (isClickablePart(part2, mask))
+      if (isClickablePart(part2, mask) && !part2->triggered)
       {
        struct GraphicInfo *c = &part2->control_info;
 
        if (c->position == POS_CE)
        {
-         part2->x = c->x + x;
-         part2->y = c->y + y;
+         // store CE tile and offset position to handle scrolling
+         part2->tile_x = x;
+         part2->tile_y = y;
+         part2->tile_xoffset = c->x;
+         part2->tile_yoffset = c->y;
+
+         // restart animation (by using current sync frame)
+         part2->initial_anim_sync_frame = anim_sync_frame;
        }
 
        part2->triggered = TRUE;
 
+       // do not trigger any other animation if CE change event was consumed
+       if (c->style == STYLE_CONSUME_CE_EVENT)
+         return;
+
 #if 0
        Debug("anim:InitGlobalAnim_Triggered_ByCustomElement",
              "%d.%d TRIGGERED BY CE %d", anim2_nr, part2_nr, nr + 1);
@@ -1583,12 +1600,7 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
       part->init_event_state)
   {
     if (part->initial_anim_sync_frame > 0)
-    {
-      if (part->init_delay_counter > 0)
-       part->initial_anim_sync_frame -= part->init_delay_counter - 1;
-      else
-       part->initial_anim_sync_frame = anim_sync_frame;
-    }
+      part->initial_anim_sync_frame = anim_sync_frame;
 
     part->init_delay_counter = 1;
     part->init_event_state = FALSE;
@@ -1617,9 +1629,13 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
 
       HandleGlobalAnimDelay(part, ANIM_DELAY_INIT,  "START [INIT_DELAY]");
       HandleGlobalAnimEvent(part, ANIM_EVENT_START, "START [ANIM]");
-    }
 
-    return ANIM_STATE_WAITING;
+      // continue with state ANIM_STATE_RUNNING (set below)
+    }
+    else
+    {
+      return ANIM_STATE_WAITING;
+    }
   }
 
   if (part->init_event_state)
@@ -1713,8 +1729,27 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
   }
 #endif
 
-  part->x += part->step_xoffset;
-  part->y += part->step_yoffset;
+  if (c->position == POS_CE)
+  {
+    // calculate playfield position (with scrolling) for related CE tile
+    int fx = getFieldbufferOffsetX_RND(ScreenMovDir, ScreenGfxPos);
+    int fy = getFieldbufferOffsetY_RND(ScreenMovDir, ScreenGfxPos);
+    int sx = FX + SCREENX(part->tile_x) * TILEX_VAR;
+    int sy = FY + SCREENY(part->tile_y) * TILEY_VAR;
+    int x = sx - fx;
+    int y = sy - fy;
+
+    part->tile_xoffset += part->step_xoffset;
+    part->tile_yoffset += part->step_yoffset;
+
+    part->x = x + part->tile_xoffset;
+    part->y = y + part->tile_yoffset;
+  }
+  else
+  {
+    part->x += part->step_xoffset;
+    part->y += part->step_yoffset;
+  }
 
   anim->last_x = part->x;
   anim->last_y = part->y;
@@ -2124,11 +2159,16 @@ void RestartGlobalAnimsByStatus(int status)
   global.anim_status = status;
 
   // force restarting global animations by changed global animation status
-  SDLRedrawWindow();
+  DrawGlobalAnimationsExt(DRAW_TO_SCREEN, DRAW_GLOBAL_ANIM_STAGE_RESTART);
 
   global.anim_status = anim_status_last;
 }
 
+void SetAnimStatusBeforeFading(int status)
+{
+  anim_status_last_before_fading = status;
+}
+
 boolean HandleGlobalAnimClicks(int mx, int my, int button, boolean force_click)
 {
   static boolean click_consumed = FALSE;