added using author from file 'levelinfo.conf' if not defined (MM engine)
[rocksndiamonds.git] / src / files.c
index e387efc789eab8e6cfb9fedf6e033a8ab28a533f..33990a38ff52adf06fb7fe560981c012e6469188 100644 (file)
@@ -1319,6 +1319,8 @@ filetype_id_list[] =
   { LEVEL_FILE_TYPE_DX,                "DX"    },
   { LEVEL_FILE_TYPE_SB,                "SB"    },
   { LEVEL_FILE_TYPE_DC,                "DC"    },
+  { LEVEL_FILE_TYPE_MM,                "MM"    },
+  { LEVEL_FILE_TYPE_MM,                "DF"    },
   { -1,                                NULL    },
 };
 
@@ -1916,6 +1918,26 @@ static int getFileTypeFromBasename(char *basename)
   return LEVEL_FILE_TYPE_UNKNOWN;
 }
 
+static int getFileTypeFromMagicBytes(char *filename, int type)
+{
+  File *file;
+
+  if ((file = openFile(filename, MODE_READ)))
+  {
+    char chunk_name[CHUNK_ID_LEN + 1];
+
+    getFileChunkBE(file, chunk_name, NULL);
+
+    if (strEqual(chunk_name, "MMII") ||
+       strEqual(chunk_name, "MIRR"))
+      type = LEVEL_FILE_TYPE_MM;
+
+    closeFile(file);
+  }
+
+  return type;
+}
+
 static boolean checkForPackageFromBasename(char *basename)
 {
   /* !!! WON'T WORK ANYMORE IF getFileTypeFromBasename() ALSO DETECTS !!!
@@ -2120,6 +2142,16 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
     if (fileExists(lfi->filename))
       return;
   }
+  else if (leveldir_current->level_filetype != NULL)
+  {
+    int filetype = getFiletypeFromID(leveldir_current->level_filetype);
+
+    /* check for specified native level file with standard file name */
+    setLevelFileInfo_FormatLevelFilename(lfi, filetype,
+                                        "%03d.%s", nr, LEVELFILE_EXTENSION);
+    if (fileExists(lfi->filename))
+      return;
+  }
 
   /* check for native Rocks'n'Diamonds level file */
   setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
@@ -2172,6 +2204,9 @@ static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi)
 {
   if (lfi->type == LEVEL_FILE_TYPE_UNKNOWN)
     lfi->type = getFileTypeFromBasename(lfi->basename);
+
+  if (lfi->type == LEVEL_FILE_TYPE_RND)
+    lfi->type = getFileTypeFromMagicBytes(lfi->filename, lfi->type);
 }
 
 static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr)
@@ -3884,7 +3919,7 @@ void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
   level_mm->encoding_16bit_field = level->encoding_16bit_field;
 
   level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH);
-  level_mm->fieldy = MIN(level->fieldx, MM_MAX_PLAYFIELD_HEIGHT);
+  level_mm->fieldy = MIN(level->fieldy, MM_MAX_PLAYFIELD_HEIGHT);
 
   level_mm->time = level->time;
   level_mm->kettles_needed = level->gems_needed;
@@ -3903,9 +3938,10 @@ void CopyNativeLevel_RND_to_MM(struct LevelInfo *level)
   level_mm->amoeba_speed = level->amoeba_speed;
   level_mm->time_fuse = 0;
 
-  for (y = 0; y < level_mm->fieldx; y++)
-    for (x = 0; x < level_mm->fieldy; x++)
-      level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]);
+  for (x = 0; x < level->fieldx; x++)
+    for (y = 0; y < level->fieldy; y++)
+      Ur[x][y] =
+       level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]);
 }
 
 void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
@@ -3918,13 +3954,16 @@ void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
   level->encoding_16bit_field = level_mm->encoding_16bit_field;
 
   level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX);
-  level->fieldy = MIN(level_mm->fieldx, MAX_LEV_FIELDY);
+  level->fieldy = MIN(level_mm->fieldy, MAX_LEV_FIELDY);
 
   level->time = level_mm->time;
   level->gems_needed = level_mm->kettles_needed;
 
   strcpy(level->name, level_mm->name);
-  strcpy(level->author, level_mm->author);
+
+  /* only overwrite author from 'levelinfo.conf' if author defined in level */
+  if (!strEqual(level_mm->author, ANONYMOUS_NAME))
+    strcpy(level->author, level_mm->author);
 
   level->score[SC_PACMAN]     = level_mm->score[SC_PACMAN];
   level->score[SC_KEY]        = level_mm->score[SC_PACMAN];
@@ -3932,9 +3971,20 @@ void CopyNativeLevel_MM_to_RND(struct LevelInfo *level)
 
   level->amoeba_speed = level_mm->amoeba_speed;
 
-  for (y = 0; y < level->fieldx; y++)
-    for (x = 0; x < level->fieldy; x++)
+  for (x = 0; x < level->fieldx; x++)
+    for (y = 0; y < level->fieldy; y++)
       level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]);
+
+  if (level_mm->auto_count_kettles)
+  {
+    level->gems_needed = 0;
+
+    for (x = 0; x < level->fieldx; x++)
+      for (y = 0; y < level->fieldy; y++)
+       if (level->field[x][y] == EL_MM_KETTLE ||
+           level->field[x][y] == EL_DF_CELL)
+         level->gems_needed++;
+  }
 }
 
 
@@ -8331,6 +8381,8 @@ static struct TokenInfo editor_cascade_setup_tokens[] =
   { TYPE_SWITCH, &seci.el_sp,          "editor.cascade.el_sp"          },
   { TYPE_SWITCH, &seci.el_dc,          "editor.cascade.el_dc"          },
   { TYPE_SWITCH, &seci.el_dx,          "editor.cascade.el_dx"          },
+  { TYPE_SWITCH, &seci.el_mm,          "editor.cascade.el_mm"          },
+  { TYPE_SWITCH, &seci.el_df,          "editor.cascade.el_df"          },
   { TYPE_SWITCH, &seci.el_chars,       "editor.cascade.el_chars"       },
   { TYPE_SWITCH, &seci.el_steel_chars, "editor.cascade.el_steel_chars" },
   { TYPE_SWITCH, &seci.el_ce,          "editor.cascade.el_ce"          },
@@ -8524,6 +8576,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->editor.el_supaplex               = TRUE;
   si->editor.el_diamond_caves          = TRUE;
   si->editor.el_dx_boulderdash         = TRUE;
+
+  si->editor.el_mirror_magic           = TRUE;
+  si->editor.el_deflektor              = TRUE;
+
   si->editor.el_chars                  = TRUE;
   si->editor.el_steel_chars            = TRUE;
 
@@ -8659,6 +8715,9 @@ static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si)
   si->editor_cascade.el_dc             = TRUE;
   si->editor_cascade.el_dx             = TRUE;
 
+  si->editor_cascade.el_mm             = TRUE;
+  si->editor_cascade.el_df             = TRUE;
+
   si->editor_cascade.el_chars          = FALSE;
   si->editor_cascade.el_steel_chars    = FALSE;
   si->editor_cascade.el_ce             = FALSE;