added setting global animation position from CE triggering that animation
[rocksndiamonds.git] / src / anim.c
index 3393d93912eef6cc0fb7e29cf1000c7cb157d8cd..219c79fd4c97b88ff074a77db45fee1052a25672 100644 (file)
@@ -631,6 +631,59 @@ static void InitGlobalAnimControls(void)
   anim_classes_last = ANIM_CLASS_NONE;
 }
 
+static void SetGlobalAnimEventsForCustomElements(int list_pos)
+{
+  int num_events = GetGlobalAnimEventValueCount(list_pos);
+  int i;
+
+  for (i = 0; i < num_events; i++)
+  {
+    int event = GetGlobalAnimEventValue(list_pos, i);
+
+    if (event & ANIM_EVENT_CE_CHANGE)
+    {
+      int nr = (event >> ANIM_EVENT_CE_BIT) & 0xff;
+
+      if (nr >= 0 && nr < NUM_CUSTOM_ELEMENTS)
+       element_info[EL_CUSTOM_START + nr].has_anim_event = TRUE;
+    }
+  }
+}
+
+void InitGlobalAnimEventsForCustomElements(void)
+{
+  int m, a, p;
+  int control;
+
+  // custom element events for global animations only relevant while playing
+  m = GAME_MODE_PLAYING;
+
+  for (a = 0; a < NUM_GLOBAL_ANIMS; a++)
+  {
+    int ctrl_id = GLOBAL_ANIM_ID_CONTROL_FIRST + a;
+
+    control = global_anim_info[ctrl_id].graphic[GLOBAL_ANIM_ID_PART_BASE][m];
+
+    // if no base animation parameters defined, use default values
+    if (control == IMG_UNDEFINED)
+      control = IMG_INTERNAL_GLOBAL_ANIM_DEFAULT;
+
+    SetGlobalAnimEventsForCustomElements(graphic_info[control].init_event);
+    SetGlobalAnimEventsForCustomElements(graphic_info[control].anim_event);
+
+    for (p = 0; p < NUM_GLOBAL_ANIM_PARTS_ALL; p++)
+    {
+      control = global_anim_info[ctrl_id].graphic[p][m];
+
+      if (control == IMG_UNDEFINED)
+       continue;
+
+      SetGlobalAnimEventsForCustomElements(graphic_info[control].init_event);
+      SetGlobalAnimEventsForCustomElements(graphic_info[control].anim_event);
+    }
+  }
+}
+
 void InitGlobalAnimations(void)
 {
   InitGlobalAnimControls();
@@ -961,7 +1014,7 @@ static boolean SetGlobalAnimPart_Viewport(struct GlobalAnimPartControlInfo *part
     viewport_width  = part->graphic_info.width;
     viewport_height = part->graphic_info.height;
 
-    part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_2;
+    part->drawing_stage = DRAW_GLOBAL_ANIM_STAGE_3;
 
     // do not use global animation mouse pointer when reloading artwork
     if (global.anim_status != GAME_MODE_LOADING)
@@ -1082,6 +1135,13 @@ static void StopGlobalAnimMusic(struct GlobalAnimPartControlInfo *part)
   if (music == MUS_UNDEFINED)
     return;
 
+  char *anim_music = getMusicInfoEntryFilename(music);
+  char *curr_music = getCurrentlyPlayingMusicFilename();
+
+  // do not stop music if global anim music differs from current music
+  if (!strEqual(curr_music, anim_music))
+    return;
+
   StopMusic();
 
 #if 0
@@ -1131,6 +1191,7 @@ static void PlayGlobalAnimSoundIfLoop(struct GlobalAnimPartControlInfo *part)
 static boolean checkGlobalAnimEvent(int anim_event, int mask)
 {
   int mask_anim_only = mask & ~ANIM_EVENT_PART_MASK;
+  int mask_ce_only   = mask & ~ANIM_EVENT_PAGE_MASK;
 
   if (mask & ANIM_EVENT_ANY)
     return (anim_event & ANIM_EVENT_ANY);
@@ -1138,6 +1199,9 @@ static boolean checkGlobalAnimEvent(int anim_event, int mask)
     return (anim_event & ANIM_EVENT_SELF);
   else if (mask & ANIM_EVENT_UNCLICK_ANY)
     return (anim_event & ANIM_EVENT_UNCLICK_ANY);
+  else if (mask & ANIM_EVENT_CE_CHANGE)
+    return (anim_event == mask ||
+           anim_event == mask_ce_only);
   else
     return (anim_event == mask ||
            anim_event == mask_anim_only);
@@ -1296,6 +1360,49 @@ static void InitGlobalAnim_Triggered(struct GlobalAnimPartControlInfo *part,
   }
 }
 
+static void InitGlobalAnim_Triggered_ByCustomElement(int nr, int page,
+                                                    int x, int y)
+{
+  struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[GAME_MODE_PLAYING];
+
+  int event_value = ANIM_EVENT_CE_CHANGE;
+  int event_bits = (nr << ANIM_EVENT_CE_BIT) | (page << ANIM_EVENT_PAGE_BIT);
+  int mask = event_value | event_bits;
+  int anim2_nr;
+
+  for (anim2_nr = 0; anim2_nr < ctrl->num_anims; anim2_nr++)
+  {
+    struct GlobalAnimMainControlInfo *anim2 = &ctrl->anim[anim2_nr];
+    int part2_nr;
+
+    for (part2_nr = 0; part2_nr < anim2->num_parts_all; part2_nr++)
+    {
+      struct GlobalAnimPartControlInfo *part2 = &anim2->part[part2_nr];
+
+      if (!(part2->state & ANIM_STATE_RUNNING))
+       continue;
+
+      if (isClickablePart(part2, mask))
+      {
+       struct GraphicInfo *c = &part2->control_info;
+
+       if (c->position == POS_CE)
+       {
+         part2->x = c->x + x;
+         part2->y = c->y + y;
+       }
+
+       part2->triggered = TRUE;
+
+#if 0
+       Debug("anim:InitGlobalAnim_Triggered_ByCustomElement",
+             "%d.%d TRIGGERED BY CE %d", anim2_nr, part2_nr, nr + 1);
+#endif
+      }
+    }
+  }
+}
+
 static void HandleGlobalAnimDelay(struct GlobalAnimPartControlInfo *part,
                                  int delay_type, char *info_text)
 {
@@ -1468,7 +1575,12 @@ static int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part,
       part->init_event_state)
   {
     if (part->initial_anim_sync_frame > 0)
-      part->initial_anim_sync_frame -= part->init_delay_counter - 1;
+    {
+      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->init_delay_counter = 1;
     part->init_event_state = FALSE;
@@ -1997,6 +2109,18 @@ static void ResetGlobalAnim_Clicked(void)
   InitGlobalAnim_Clicked(-1, -1, ANIM_CLICKED_RESET);
 }
 
+void RestartGlobalAnimsByStatus(int status)
+{
+  int anim_status_last = global.anim_status;
+
+  global.anim_status = status;
+
+  // force restarting global animations by changed global animation status
+  SDLRedrawWindow();
+
+  global.anim_status = anim_status_last;
+}
+
 boolean HandleGlobalAnimClicks(int mx, int my, int button, boolean force_click)
 {
   static boolean click_consumed = FALSE;
@@ -2032,3 +2156,13 @@ int getGlobalAnimSyncFrame(void)
 {
   return anim_sync_frame;
 }
+
+void HandleGlobalAnimEventByElementChange(int element, int page, int x, int 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);
+}