fixed bug with events defined to start and stop global animations
[rocksndiamonds.git] / src / anim.c
index c457936bcd7582b48c65f3c0c2143ea7753e993b..4f1034eb35d43b4251d97332dafced2b574f0823 100644 (file)
@@ -115,7 +115,7 @@ struct GlobalAnimPartControlInfo
   struct GraphicInfo graphic_info;
   struct GraphicInfo control_info;
 
-  boolean class_playfield;
+  boolean class_playfield_or_door;
 
   int viewport_x;
   int viewport_y;
@@ -381,9 +381,9 @@ static int compareGlobalAnimMainControlInfo(const void *obj1, const void *obj2)
   return compare_result;
 }
 
-static boolean isPausedOnPlayfield(struct GlobalAnimPartControlInfo *part)
+static boolean isPausedOnPlayfieldOrDoor(struct GlobalAnimPartControlInfo *part)
 {
-  // only pause playfield animations when playing
+  // only pause playfield and door animations when playing
   if (game_status != GAME_MODE_PLAYING)
     return FALSE;
 
@@ -391,8 +391,8 @@ static boolean isPausedOnPlayfield(struct GlobalAnimPartControlInfo *part)
   if (checkGameEnded())
     return FALSE;
 
-  // only pause animations on playfield
-  if (!part->class_playfield)
+  // only pause animations on playfield and doors
+  if (!part->class_playfield_or_door)
     return FALSE;
 
   // only pause animations when engine is paused or request dialog is open(ing)
@@ -951,8 +951,8 @@ static void DrawGlobalAnimationsExt(int drawing_target, int drawing_stage)
        if (part->drawing_stage != drawing_stage)
          continue;
 
-       // if game is paused, also pause playfield animations
-       if (isPausedOnPlayfield(part))
+       // if game is paused, also pause playfield and door animations
+       if (isPausedOnPlayfieldOrDoor(part))
          part->initial_anim_sync_frame++;
 
        sync_frame = anim_sync_frame - part->initial_anim_sync_frame;
@@ -1028,7 +1028,7 @@ static boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part
 
   part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_1;
 
-  part->class_playfield = FALSE;
+  part->class_playfield_or_door = FALSE;
 
   if (part->control_info.class == get_hash_from_key("window") ||
       part->control_info.class == get_hash_from_key("border"))
@@ -1067,6 +1067,8 @@ static boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part
     viewport_y = DY;
     viewport_width  = DXSIZE;
     viewport_height = DYSIZE;
+
+    part->class_playfield_or_door = TRUE;
   }
   else if (part->control_info.class == get_hash_from_key("door_2"))
   {
@@ -1084,6 +1086,8 @@ static boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part
       viewport_width  = VXSIZE;
       viewport_height = VYSIZE;
     }
+
+    part->class_playfield_or_door = TRUE;
   }
   else         // default: "playfield"
   {
@@ -1092,7 +1096,7 @@ static boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part
     viewport_width  = FULL_SXSIZE;
     viewport_height = FULL_SYSIZE;
 
-    part->class_playfield = TRUE;
+    part->class_playfield_or_door = TRUE;
   }
 
   if (viewport_x != part->viewport_x ||
@@ -1267,8 +1271,7 @@ static boolean isClickablePart(struct GlobalAnimPartControlInfo *part, int mask)
        return TRUE;
     }
   }
-
-  if (part->anim_event_state)
+  else if (part->anim_event_state)
   {
     int num_anim_events = GetGlobalAnimEventValueCount(c->anim_event);
 
@@ -1434,7 +1437,9 @@ static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part,
 }
 
 static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page,
-                                                    int x, int y)
+                                                    int x, int y,
+                                                    int trigger_x,
+                                                    int trigger_y)
 {
   struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_PLAYING];
 
@@ -1459,16 +1464,19 @@ static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page,
       {
        struct GraphicInfo *c = &part2->control_info;
 
-       if (c->position == POS_CE)
+       if (c->position == POS_CE ||
+           c->position == POS_CE_TRIGGER)
        {
          // store CE tile and offset position to handle scrolling
-         part2->tile_x = x;
-         part2->tile_y = y;
+         part2->tile_x = (c->position == POS_CE_TRIGGER ? trigger_x : x);
+         part2->tile_y = (c->position == POS_CE_TRIGGER ? trigger_y : y);
          part2->tile_xoffset = c->x;
          part2->tile_yoffset = c->y;
 
          // set resulting animation position relative to CE tile position
-         SetGlobalAnimPartTileXY(part2);
+         // (but only for ".init_event", not ".anim_event" type events)
+         if (part2->init_event_state)
+           SetGlobalAnimPartTileXY(part2);
 
          // restart animation (by using current sync frame)
          part2->initial_anim_sync_frame = anim_sync_frame;
@@ -1528,8 +1536,8 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
   struct GraphicInfo *c = &part->control_info;
   boolean viewport_changed = SetGlobalAnimPart_Viewport(part);
 
-  // if game is paused, also pause playfield animations
-  if (isPausedOnPlayfield(part))
+  // if game is paused, also pause playfield and door animations
+  if (isPausedOnPlayfieldOrDoor(part))
     return state;
 
   if (viewport_changed)
@@ -1794,7 +1802,8 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
   }
 #endif
 
-  if (c->position == POS_CE)
+  if (c->position == POS_CE ||
+      c->position == POS_CE_TRIGGER)
   {
     SetGlobalAnimPartTileXY(part);
   }
@@ -2258,12 +2267,13 @@ int getGlobalAnimSyncFrame(void)
   return anim_sync_frame;
 }
 
-void HandleGlobalAnimEventByElementChange(int element, int page, int x, int y)
+void HandleGlobalAnimEventByElementChange(int element, int page, int x, int y,
+                                         int trigger_x, int trigger_y)
 {
   if (!IS_CUSTOM_ELEMENT(element))
     return;
 
   // custom element stored as 0 to 255, change page stored as 1 to 32
   InitGlobalAnim_Triggered_ByCustomElement(element - EL_CUSTOM_START, page + 1,
-                                          x, y);
+                                          x, y, trigger_x, trigger_y);
 }