fixed ignoring clicks on global animations after executing event actions
[rocksndiamonds.git] / src / anim.c
index fa124cb6ab692e957125a060b0d8ffe0a013ef96..de1c40bff53c07c41cd9f4119c4cedfdcb1aef01 100644 (file)
@@ -1003,6 +1003,13 @@ static boolean isClickedPart(struct GlobalAnimPartControlInfo *part,
   return TRUE;
 }
 
+static boolean setPartClicked(struct GlobalAnimPartControlInfo *part)
+{
+  part->clicked = TRUE;
+
+  return (part->control_info.style & STYLE_PASSTHROUGH ? FALSE : TRUE);
+}
+
 int HandleGlobalAnim_Part(struct GlobalAnimPartControlInfo *part, int state)
 {
   struct GlobalAnimControlInfo *ctrl = &global_anim_ctrl[part->mode_nr];
@@ -1353,6 +1360,11 @@ void HandleGlobalAnim_Main(struct GlobalAnimMainControlInfo *anim, int action)
 
   part = &anim->part[anim->active_part_nr];
 
+  // first set all animation parts to "inactive", ...
+  for (i = 0; i < num_parts; i++)
+    anim->part[i].state = ANIM_STATE_INACTIVE;
+
+  // ... then set current animation parts to "running"
   part->state = ANIM_STATE_RUNNING;
 
   anim->state = HandleGlobalAnim_Part(part, anim->state);
@@ -1433,6 +1445,16 @@ static void DoAnimationExt()
 #endif
 }
 
+static boolean DoGlobalAnim_EventAction(struct GlobalAnimPartControlInfo *part)
+{
+  int anim_event_action = part->control_info.anim_event_action;
+
+  if (anim_event_action == -1)
+    return FALSE;
+
+  return DoGadgetAction(anim_event_action);
+}
+
 static void InitGlobalAnim_Clickable()
 {
   int mode_nr;
@@ -1461,6 +1483,7 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked)
 {
   boolean anything_clicked = FALSE;
   boolean any_part_clicked = FALSE;
+  boolean any_event_action = FALSE;
   int mode_nr;
 
   // check game modes in reverse draw order (to stop when clicked)
@@ -1490,9 +1513,12 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked)
        if (!part->clickable)
          continue;
 
+       if (part->state != ANIM_STATE_RUNNING)
+         continue;
+
        // always handle "any" click events (clicking anywhere on screen) ...
        if (isClickablePart(part, ANIM_EVENT_ANY))
-         anything_clicked = part->clicked = TRUE;
+         anything_clicked = setPartClicked(part);
 
        // ... but only handle the first (topmost) clickable animation
        if (any_part_clicked)
@@ -1501,13 +1527,18 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked)
        if (isClickedPart(part, mx, my, clicked))
        {
 #if 0
-         printf("::: %d.%d CLICKED\n", anim_nr, part_nr);
+         printf("::: %d.%d CLICKED [%d]\n", anim_nr, part_nr,
+                part->control_info.anim_event_action);
 #endif
 
+         // after executing event action, ignore any further actions
+         if (!any_event_action && DoGlobalAnim_EventAction(part))
+           any_event_action = TRUE;
+
          any_part_clicked = TRUE;
 
          if (isClickablePart(part, ANIM_EVENT_SELF))
-           anything_clicked = part->clicked = TRUE;
+           anything_clicked = setPartClicked(part);
 
          // check if this click is defined to trigger other animations
          int gic_anim_nr = part->old_anim_nr + 1;      // X as in "anim_X"
@@ -1528,8 +1559,22 @@ static boolean InitGlobalAnim_Clicked(int mx, int my, boolean clicked)
            {
              struct GlobalAnimPartControlInfo *part2 = &anim2->part[part2_nr];
 
+             if (part2->state != ANIM_STATE_RUNNING)
+               continue;
+
              if (isClickablePart(part2, mask))
-               anything_clicked = part2->clicked = TRUE;
+             {
+               setPartClicked(part2);
+
+#if 0
+               printf("::: %d.%d TRIGGER CLICKED [%d]\n", anim2_nr, part2_nr,
+                      part2->control_info.anim_event_action);
+#endif
+
+               // after executing event action, ignore any further actions
+               if (!any_event_action && DoGlobalAnim_EventAction(part2))
+                 any_event_action = TRUE;
+             }
 
 #if 0
              struct GraphicInfo *c = &part2->control_info;