rnd-20051125-1-src
[rocksndiamonds.git] / src / files.c
index 94fa3088686ebeaecb8ba3fcaa6baf07fd9e76c8..f5275728156c3e921462a8cf5d030149262672b1 100644 (file)
@@ -88,11 +88,12 @@ void setElementChangePages(struct ElementInfo *ei, int change_pages)
 
 void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
 {
-  int x, y;
+  int i, x, y;
 
   change->can_change = FALSE;
 
-  change->events = CE_BITMASK_DEFAULT;
+  for (i = 0; i < NUM_CHANGE_EVENTS; i++)
+    change->has_event[i] = FALSE;
 
   change->trigger_player = CH_PLAYER_ANY;
   change->trigger_side = CH_SIDE_ANY;
@@ -113,6 +114,11 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
   change->random_percentage = 100;
   change->replace_when = CP_WHEN_EMPTY;
 
+  change->has_action = FALSE;
+  change->action_type = CA_NO_ACTION;
+  change->action_mode = CA_MODE_UNDEFINED;
+  change->action_arg = CA_ARG_UNDEFINED;
+
   for (x = 0; x < 3; x++)
     for (y = 0; y < 3; y++)
       change->target_content[x][y] = EL_EMPTY_SPACE;
@@ -292,6 +298,9 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
       element_info[element].explosion_delay = 16;
       element_info[element].ignition_delay = 8;
 
+      element_info[element].counter_initial = 0;
+      element_info[element].counter = 0;
+
       for (x = 0; x < 3; x++)
        for (y = 0; y < 3; y++)
          element_info[element].content[x][y] = EL_EMPTY_SPACE;
@@ -1090,6 +1099,7 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
   for (i = 0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
+    unsigned long event_bits;
 
     if (!IS_CUSTOM_ELEMENT(element))
     {
@@ -1128,7 +1138,10 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
        element_info[element].content[x][y] =
          getMappedElement(getFile16BitBE(file));
 
-    element_info[element].change->events = getFile32BitBE(file);
+    event_bits = getFile32BitBE(file);
+    for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+      if (event_bits & (1 << j))
+       element_info[element].change->has_event[j] = TRUE;
 
     element_info[element].change->target_element =
       getMappedElement(getFile16BitBE(file));
@@ -1170,7 +1183,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   struct ElementInfo *ei;
   int chunk_size_expected;
   int element;
-  int i, x, y;
+  int i, j, x, y;
 
   element = getFile16BitBE(file);
 
@@ -1252,11 +1265,15 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   for (i = 0; i < ei->num_change_pages; i++)
   {
     struct ElementChangeInfo *change = &ei->change_page[i];
+    unsigned long event_bits;
 
     /* always start with reliable default values */
     setElementChangeInfoToDefaults(change);
 
-    change->events = getFile32BitBE(file);
+    event_bits = getFile32BitBE(file);
+    for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+      if (event_bits & (1 << j))
+       change->has_event[j] = TRUE;
 
     change->target_element = getMappedElement(getFile16BitBE(file));
 
@@ -1289,8 +1306,18 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
     change->trigger_page = (change->trigger_page == CH_PAGE_ANY_FILE ?
                            CH_PAGE_ANY : (1 << change->trigger_page));
 
+#if 1
+    change->has_action = getFile8Bit(file);
+    change->action_type = getFile8Bit(file);
+    change->action_mode = getFile8Bit(file);
+    change->action_arg = getFile16BitBE(file);
+
+    /* some free bytes for future change property values and padding */
+    ReadUnusedBytesFromFile(file, 1);
+#else
     /* some free bytes for future change property values and padding */
     ReadUnusedBytesFromFile(file, 6);
+#endif
 
 #else
 
@@ -2694,7 +2721,8 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   int i, j, x, y;
 
   /* map custom element change events that have changed in newer versions
-     (these following values were accidentally changed in version 3.0.1) */
+     (these following values were accidentally changed in version 3.0.1)
+     (this seems to be needed only for 'ab_levelset3' and 'ab_levelset4') */
   if (level->game_version <= VERSION_IDENT(3,0,0,0))
   {
     for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
@@ -2702,7 +2730,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       int element = EL_CUSTOM_START + i;
 
       /* order of checking and copying events to be mapped is important */
-      for (j = CE_BY_OTHER_ACTION; j >= CE_BY_PLAYER_OBSOLETE; j--)
+      for (j = CE_BY_OTHER_ACTION; j >= CE_COUNT_AT_ZERO; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 2))
        {
@@ -2712,7 +2740,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       }
 
       /* order of checking and copying events to be mapped is important */
-      for (j = CE_OTHER_GETS_COLLECTED; j >= CE_HITTING_SOMETHING; j--)
+      for (j = CE_PLAYER_COLLECTS_X; j >= CE_HITTING_SOMETHING; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 1))
        {
@@ -2723,20 +2751,30 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
+#if 0
+  /* !!! TESTS SHOWED THAT THIS CODE SEGMENT IS NOT NEEDED FOR ANY LEVEL !!! */
+
   /* some custom element change events get mapped since version 3.0.3 */
-  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+#if 1
+  if (level->game_version >= VERSION_IDENT(3,0,3,0) &&
+      level->game_version <= VERSION_IDENT(3,2,0,3))
+#endif
   {
-    int element = EL_CUSTOM_START + i;
-
-    if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) ||
-       HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE))
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
-      SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE);
-      SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE);
+      int element = EL_CUSTOM_START + i;
+
+      if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) ||
+         HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE))
+      {
+       SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE);
+       SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE);
 
-      SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE);
+       SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE);
+      }
     }
   }
+#endif
 
   /* initialize "can_change" field for old levels with only one change page */
   if (level->game_version <= VERSION_IDENT(3,0,2,0))
@@ -2751,20 +2789,23 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   }
 
   /* correct custom element values (for old levels without these options) */
-  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+  if (level->game_version < VERSION_IDENT(3,1,1,0))
   {
-    int element = EL_CUSTOM_START + i;
-    struct ElementInfo *ei = &element_info[element];
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+    {
+      int element = EL_CUSTOM_START + i;
+      struct ElementInfo *ei = &element_info[element];
 
-    if (ei->access_direction == MV_NO_MOVING)
-      ei->access_direction = MV_ALL_DIRECTIONS;
+      if (ei->access_direction == MV_NO_MOVING)
+       ei->access_direction = MV_ALL_DIRECTIONS;
 
-    for (j = 0; j < ei->num_change_pages; j++)
-    {
-      struct ElementChangeInfo *change = &ei->change_page[j];
+      for (j = 0; j < ei->num_change_pages; j++)
+      {
+       struct ElementChangeInfo *change = &ei->change_page[j];
 
-      if (change->trigger_side == CH_SIDE_NONE)
-       change->trigger_side = CH_SIDE_ANY;
+       if (change->trigger_side == CH_SIDE_NONE)
+         change->trigger_side = CH_SIDE_ANY;
+      }
     }
   }
 
@@ -3269,7 +3310,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
 static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 {
   struct ElementInfo *ei = &element_info[element];
-  int i, x, y;
+  int i, j, x, y;
 
   putFile16BitBE(file, element);
 
@@ -3331,8 +3372,13 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   for (i = 0; i < ei->num_change_pages; i++)
   {
     struct ElementChangeInfo *change = &ei->change_page[i];
+    unsigned long event_bits = 0;
 
-    putFile32BitBE(file, change->events);
+    for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+      if (change->has_event[j])
+       event_bits |= (1 << j);
+
+    putFile32BitBE(file, event_bits);
 
     putFile16BitBE(file, change->target_element);
 
@@ -3363,8 +3409,19 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
     putFile8Bit(file, (change->trigger_page == CH_PAGE_ANY ? CH_PAGE_ANY_FILE :
                       log_2(change->trigger_page)));
 
+#if 1
+
+    putFile8Bit(file, change->has_action);
+    putFile8Bit(file, change->action_type);
+    putFile8Bit(file, change->action_mode);
+    putFile16BitBE(file, change->action_arg);
+
+    /* some free bytes for future change property values and padding */
+    WriteUnusedBytesToFile(file, 1);
+#else
     /* some free bytes for future change property values and padding */
     WriteUnusedBytesToFile(file, 6);
+#endif
 
 #else
 
@@ -3681,7 +3738,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
 
   for (i = 0; i < tape->length; i++)
   {
-    if (i >= MAX_TAPELEN)
+    if (i >= MAX_TAPE_LEN)
       break;
 
     for (j = 0; j < MAX_PLAYERS; j++)
@@ -4049,7 +4106,7 @@ void DumpTape(struct TapeInfo *tape)
 
   for (i = 0; i < tape->length; i++)
   {
-    if (i >= MAX_TAPELEN)
+    if (i >= MAX_TAPE_LEN)
       break;
 
     printf("%03d: ", i);