rnd-20040112-3-src
[rocksndiamonds.git] / src / game.c
index 20c68e41f7edfbfec10ecab5b223aa8f8e9fb799..f29584b4be06e36a1a0807689abb5dc35555826b 100644 (file)
@@ -787,6 +787,108 @@ void DrawGameDoorValues()
           int2str(TimeLeft, 3), FONT_TEXT_2);
 }
 
+#if 1
+
+static void resolve_group_element(int group_element, int recursion_depth)
+{
+  static struct ElementGroupInfo *group;
+  struct ElementGroupInfo *actual_group = element_info[group_element].group;
+  int i;
+
+  if (recursion_depth > NUM_GROUP_ELEMENTS)    /* recursion too deep */
+  {
+    Error(ERR_WARN, "recursion too deep when resolving group element %d",
+         group_element - EL_GROUP_START + 1);
+
+    /* replace element which caused too deep recursion by question mark */
+    group->element_resolved[group->num_elements_resolved++] = EL_CHAR_QUESTION;
+
+    return;
+  }
+
+  if (recursion_depth == 0)                    /* initialization */
+  {
+    group = element_info[group_element].group;
+    group->num_elements_resolved = 0;
+  }
+
+  for (i = 0; i < actual_group->num_elements; i++)
+  {
+    int element = actual_group->element[i];
+
+    if (group->num_elements_resolved == NUM_FILE_ELEMENTS)
+      break;
+
+    if (IS_GROUP_ELEMENT(element))
+      resolve_group_element(element, recursion_depth + 1);
+    else
+      group->element_resolved[group->num_elements_resolved++] = element;
+  }
+
+#if 1
+  if (recursion_depth == 0 && group_element <= EL_GROUP_4)
+  {
+    printf("::: group %d: %d resolved elements\n",
+          group_element - EL_GROUP_START, group->num_elements_resolved);
+    for (i = 0; i < group->num_elements_resolved; i++)
+      printf("::: - %d ['%s']\n", group->element_resolved[i],
+            element_info[group->element_resolved[i]].token_name);
+  }
+#endif
+}
+
+#else
+
+static void resolve_group_element(int group_element, int recursion_depth)
+{
+  static short element_list_count[NUM_FILE_ELEMENTS];
+  struct ElementGroupInfo *group = element_info[group_element].group;
+  int i, j;
+
+  if (group == NULL)
+    return;
+
+  if (recursion_depth > NUM_GROUP_ELEMENTS)    /* recursion too deep */
+    return;
+
+  if (recursion_depth == 0)                    /* initialization */
+    for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+      element_list_count[i] = 0;
+
+  for (i = 0; i < group->num_elements; i++)
+  {
+    int element = group->element[i];
+
+    if (IS_GROUP_ELEMENT(element))
+      resolve_group_element(element, recursion_depth + 1);
+    else if (element < NUM_FILE_ELEMENTS)
+      element_list_count[group->element[i]]++;
+  }
+
+  if (recursion_depth == 0)                    /* finalization */
+  {
+    group->num_elements_resolved = 0;
+
+    for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+      for (j = 0; j < element_list_count[i]; j++)
+       if (group->num_elements_resolved < NUM_FILE_ELEMENTS)
+         group->element_resolved[group->num_elements_resolved++] = i;
+
+#if 1
+    if (group_element <= EL_GROUP_8)
+    {
+      printf("::: group %d: %d resolved elements\n",
+            group_element - EL_GROUP_START, group->num_elements_resolved);
+      for (i = 0; i < group->num_elements_resolved; i++)
+       printf("::: - %d ['%s']\n", group->element_resolved[i],
+              element_info[group->element_resolved[i]].token_name);
+    }
+#endif
+  }
+}
+
+#endif
+
 
 /*
   =============================================================================
@@ -815,6 +917,11 @@ static void InitGameEngine()
   printf("       => game.engine_version == %06d\n", game.engine_version);
 #endif
 
+  /* ---------- recursively resolve group elements ------------------------- */
+
+  for (i = 0; i < NUM_GROUP_ELEMENTS; i++)
+    resolve_group_element(EL_GROUP_START + i, 0);
+
   /* ---------- initialize player's initial move delay --------------------- */
 
   /* dynamically adjust player properties according to game engine version */
@@ -6484,6 +6591,11 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
   if (!player->active || tape.pausing)
     return 0;
 
+#if 0
+  printf("::: [%d %d %d %d] [%d %d]\n",
+        left, right, up, down, button1, button2);
+#endif
+
   if (player_action)
   {
 #if 0
@@ -8526,7 +8638,7 @@ int DigField(struct PlayerInfo *player,
 
       /* automatically move to the next field with double speed */
       player->programmed_action = move_direction;
-#if 0
+#if 1
       if (player->move_delay_reset_counter == 0)
       {
        player->move_delay_reset_counter = 2;   /* two double speed steps */
@@ -8534,9 +8646,9 @@ int DigField(struct PlayerInfo *player,
        DOUBLE_PLAYER_SPEED(player);
       }
 #else
-      DOUBLE_PLAYER_SPEED(player);
-
       player->move_delay_reset_counter = 2;
+
+      DOUBLE_PLAYER_SPEED(player);
 #endif
 
       PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
@@ -8651,9 +8763,9 @@ int DigField(struct PlayerInfo *player,
          DOUBLE_PLAYER_SPEED(player);
        }
 #else
-       DOUBLE_PLAYER_SPEED(player);
-
        player->move_delay_reset_counter = 2;
+
+       DOUBLE_PLAYER_SPEED(player);
 #endif
 
        PlayLevelSoundAction(x, y, ACTION_PASSING);
@@ -9100,9 +9212,14 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 
   player->MovDir = snap_direction;
 
-  player->is_moving = FALSE;
-  player->is_digging = FALSE;
-  player->is_collecting = FALSE;
+#if 1
+  if (player->MovPos == 0)
+#endif
+  {
+    player->is_moving = FALSE;
+    player->is_digging = FALSE;
+    player->is_collecting = FALSE;
+  }
 
   player->is_dropping = FALSE;
 
@@ -9111,9 +9228,14 @@ boolean SnapField(struct PlayerInfo *player, int dx, int dy)
 
   player->is_snapping = TRUE;
 
-  player->is_moving = FALSE;
-  player->is_digging = FALSE;
-  player->is_collecting = FALSE;
+#if 1
+  if (player->MovPos == 0)
+#endif
+  {
+    player->is_moving = FALSE;
+    player->is_digging = FALSE;
+    player->is_collecting = FALSE;
+  }
 
   DrawLevelField(x, y);
   BackToFront();