rnd-20060226-1-src
[rocksndiamonds.git] / src / libgame / setup.c
index d78e3c70f6b2addf7174478c7a8dda4859bb779f..f952cab57be96ae62f207eb4958afff2c6652c56 100644 (file)
@@ -799,7 +799,7 @@ void InitLevelSetupDirectory(char *level_subdir)
 
 
 /* ------------------------------------------------------------------------- */
-/* some functions to handle lists of level directories                       */
+/* some functions to handle lists of level and artwork directories           */
 /* ------------------------------------------------------------------------- */
 
 TreeInfo *newTreeInfo()
@@ -927,6 +927,43 @@ TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier)
   return NULL;
 }
 
+TreeInfo *cloneTreeNode(TreeInfo **node_top, TreeInfo *node_parent,
+                       TreeInfo *node, boolean skip_sets_without_levels)
+{
+  TreeInfo *node_new;
+
+  if (node == NULL)
+    return NULL;
+
+  if (!node->parent_link && !node->level_group &&
+      skip_sets_without_levels && node->levels == 0)
+    return cloneTreeNode(node_top, node_parent, node->next,
+                        skip_sets_without_levels);
+
+  node_new = newTreeInfo();
+
+  *node_new = *node;                           /* copy complete node */
+
+  node_new->node_top = node_top;               /* correct top node link */
+  node_new->node_parent = node_parent;         /* correct parent node link */
+
+  if (node->level_group)
+    node_new->node_group = cloneTreeNode(node_top, node_new, node->node_group,
+                                        skip_sets_without_levels);
+
+  node_new->next = cloneTreeNode(node_top, node_parent, node->next,
+                                skip_sets_without_levels);
+  
+  return node_new;
+}
+
+void cloneTree(TreeInfo **ti_new, TreeInfo *ti, boolean skip_empty_sets)
+{
+  TreeInfo *ti_cloned = cloneTreeNode(ti_new, NULL, ti, skip_empty_sets);
+
+  *ti_new = ti_cloned;
+}
+
 void dumpTreeInfo(TreeInfo *node, int depth)
 {
   int i;
@@ -1956,8 +1993,10 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
     leveldir_new->fullpath = getPath2(node_parent->fullpath, directory_name);
   }
 
+#if 0
   if (leveldir_new->levels < 1)
     leveldir_new->levels = 1;
+#endif
 
   leveldir_new->last_level =
     leveldir_new->first_level + leveldir_new->levels - 1;
@@ -1965,11 +2004,16 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
   leveldir_new->in_user_dir =
     (strcmp(leveldir_new->basepath, options.level_directory) != 0);
 
-  /* adjust sort priority if user's private level directory was detected */
+  /* adjust some settings if user's private level directory was detected */
   if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED &&
       leveldir_new->in_user_dir &&
-      strcmp(leveldir_new->subdir, getLoginName()) == 0)
+      (strcmp(leveldir_new->subdir, getLoginName()) == 0 ||
+       strcmp(leveldir_new->name,   getLoginName()) == 0 ||
+       strcmp(leveldir_new->author, getRealName())  == 0))
+  {
     leveldir_new->sort_priority = LEVELCLASS_PRIVATE_START;
+    leveldir_new->readonly = FALSE;
+  }
 
   leveldir_new->user_defined =
     (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new));
@@ -1982,6 +2026,22 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
     (leveldir_new->user_defined || !leveldir_new->handicap ?
      leveldir_new->last_level : leveldir_new->first_level);
 
+#if 0
+  /* !!! don't skip sets without levels (else artwork base sets are missing) */
+#if 1
+  if (leveldir_new->levels < 1 && !leveldir_new->level_group)
+  {
+    /* skip level sets without levels (which are probably artwork base sets) */
+
+    freeSetupFileHash(setup_file_hash);
+    free(directory_path);
+    free(filename);
+
+    return FALSE;
+  }
+#endif
+#endif
+
   pushTreeInfo(node_first, leveldir_new);
 
   freeSetupFileHash(setup_file_hash);
@@ -2073,6 +2133,15 @@ void LoadLevelInfo()
   LoadLevelInfoFromLevelDir(&leveldir_first, NULL, options.level_directory);
   LoadLevelInfoFromLevelDir(&leveldir_first, NULL, getUserLevelDir(NULL));
 
+#if 1
+  /* after loading all level set information, clone the level directory tree
+     and remove all level sets without levels (these may still contain artwork
+     to be offered in the setup menu as "custom artwork", and are therefore
+     checked for existing artwork in the function "LoadLevelArtworkInfo()") */
+  leveldir_first_all = leveldir_first;
+  cloneTree(&leveldir_first, leveldir_first_all, TRUE);
+#endif
+
   /* before sorting, the first entries will be from the user directory */
   leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
 
@@ -2428,9 +2497,9 @@ void LoadLevelArtworkInfo()
 {
   DrawInitText("Looking for custom level artwork:", 120, FC_GREEN);
 
-  LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first);
-  LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first);
-  LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first);
+  LoadArtworkInfoFromLevelInfo(&artwork.gfx_first, leveldir_first_all);
+  LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first_all);
+  LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first_all);
 
   /* needed for reloading level artwork not known at ealier stage */