rnd-20040222-1-src
[rocksndiamonds.git] / src / files.c
index c7af57d1ed923d0b4daec8c864b9b47a09e3221f..c8580105cfcef25a13b193902a9c8fa8d0732c9c 100644 (file)
@@ -29,7 +29,7 @@
 #define CHUNK_SIZE_NONE                -1      /* do not write chunk size    */
 #define FILE_VERS_CHUNK_SIZE   8       /* size of file version chunk */
 #define LEVEL_HEADER_SIZE      80      /* size of level file header  */
-#define LEVEL_HEADER_UNUSED    11      /* unused level header bytes  */
+#define LEVEL_HEADER_UNUSED          /* unused level header bytes  */
 #define LEVEL_CHUNK_CNT2_SIZE  160     /* size of level CNT2 chunk   */
 #define LEVEL_CHUNK_CNT2_UNUSED        11      /* unused CNT2 chunk bytes    */
 #define LEVEL_CHUNK_CNT3_HEADER        16      /* size of level CNT3 header  */
@@ -141,18 +141,26 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
   level->time = 100;
   level->gems_needed = 0;
+
   level->amoeba_speed = 10;
+
   level->time_magic_wall = 10;
   level->time_wheel = 10;
   level->time_light = 10;
   level->time_timegate = 10;
+
   level->amoeba_content = EL_DIAMOND;
+
   level->double_speed = FALSE;
   level->initial_gravity = FALSE;
   level->em_slippery_gems = FALSE;
   level->block_last_field = FALSE;
   level->sp_block_last_field = TRUE;
 
+  level->use_spring_bug = FALSE;
+
+  level->can_move_into_acid = ~0;      /* everything can move into acid */
+
   level->use_custom_template = FALSE;
 
   for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
@@ -252,6 +260,9 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
       for (j = 0; j < NUM_EP_BITFIELDS; j++)
        Properties[element][j] = EP_BITMASK_DEFAULT;
 
+      /* now set default properties */
+      SET_PROPERTY(element, EP_CAN_MOVE_INTO_ACID, TRUE);
+
       element_info[element].modified_settings = FALSE;
     }
     else if (IS_GROUP_ELEMENT(element) || element == EL_INTERNAL_EDITOR)
@@ -639,6 +650,10 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level)
   level->block_last_field      = (getFile8Bit(file) == 1 ? TRUE : FALSE);
   level->sp_block_last_field   = (getFile8Bit(file) == 1 ? TRUE : FALSE);
 
+  level->use_spring_bug                = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+
+  level->can_move_into_acid    = getFile16BitBE(file);
+
   ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
 
   return chunk_size;
@@ -1011,8 +1026,13 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
   ei->move_pattern |= (getFile16BitBE(file) << 16);
 
+  ei->access_direction = getFile8Bit(file);
+
+  ei->explosion_delay = getFile8Bit(file);
+  ei->ignition_delay = getFile8Bit(file);
+
   /* some free bytes for future custom property values and padding */
-  ReadUnusedBytesFromFile(file, 5);
+  ReadUnusedBytesFromFile(file, 2);
 
   /* read change property values */
 
@@ -2016,6 +2036,24 @@ static void LoadLevel_InitVersion(struct LevelInfo *level, char *filename)
     /* Default behaviour for EM style gems was "slippery" only in 2.0.1 */
     if (level->game_version == VERSION_IDENT(2,0,1,0))
       level->em_slippery_gems = TRUE;
+
+    if (level->game_version < VERSION_IDENT(2,2,0,0))
+      level->use_spring_bug = TRUE;
+
+    if (level->game_version < VERSION_IDENT(3,0,9,0))
+    {
+      int i;
+
+      level->can_move_into_acid = 0;   /* nothing can move into acid */
+
+      setMoveIntoAcidProperty(level, EL_ROBOT,     TRUE);
+      setMoveIntoAcidProperty(level, EL_SATELLITE, TRUE);
+      setMoveIntoAcidProperty(level, EL_PENGUIN,   TRUE);
+      setMoveIntoAcidProperty(level, EL_BALLOON,   TRUE);
+
+      for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+       SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE);
+    }
   }
   else
   {
@@ -2120,6 +2158,15 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
     }
   }
 
+  /* correct field access direction (for old levels without this option) */
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+  {
+    int element = EL_CUSTOM_START + i;
+
+    if (element_info[element].access_direction == MV_NO_MOVING)
+      element_info[element].access_direction = MV_ALL_DIRECTIONS;
+  }
+
 #if 0
   /* set default push delay values (corrected since version 3.0.7-1) */
   if (level->game_version < VERSION_IDENT(3,0,7,1))
@@ -2282,6 +2329,10 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
   putFile8Bit(file, (level->block_last_field ? 1 : 0));
   putFile8Bit(file, (level->sp_block_last_field ? 1 : 0));
 
+  putFile8Bit(file, (level->use_spring_bug ? 1 : 0));
+
+  putFile16BitBE(file, level->can_move_into_acid);
+
   WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
 }
 
@@ -2582,8 +2633,13 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
   /* ... bits 16 - 31 of "move_pattern" (not nice, but downward compatible) */
   putFile16BitBE(file, (ei->move_pattern >> 16) & 0xffff);
 
+  putFile8Bit(file, ei->access_direction);
+
+  putFile8Bit(file, ei->explosion_delay);
+  putFile8Bit(file, ei->ignition_delay);
+
   /* some free bytes for future custom property values and padding */
-  WriteUnusedBytesToFile(file, 5);
+  WriteUnusedBytesToFile(file, 2);
 
   /* write change property values */
 
@@ -2804,6 +2860,7 @@ void DumpLevel(struct LevelInfo *level)
   printf("EM style slippery gems:      %s\n", (level->em_slippery_gems ? "yes" : "no"));
   printf("Player blocks last field:    %s\n", (level->block_last_field ? "yes" : "no"));
   printf("SP player blocks last field: %s\n", (level->sp_block_last_field ? "yes" : "no"));
+  printf("use spring bug: %s\n", (level->use_spring_bug ? "yes" : "no"));
 
   printf_line("-", 79);
 }