--- deliantra/server/random_maps/style.C 2006/08/29 08:01:36 1.2 +++ deliantra/server/random_maps/style.C 2006/09/10 16:06:37 1.3 @@ -1,6 +1,7 @@ + /* * static char *rcsid_style_c = - * "$Id: style.C,v 1.2 2006/08/29 08:01:36 root Exp $"; + * "$Id: style.C,v 1.3 2006/09/10 16:06:37 root Exp $"; */ /* @@ -29,20 +30,21 @@ #include #include -#ifndef WIN32 /* ---win32 exclude headers */ -#include -#include -#include -#include "../include/autoconf.h" +#ifndef WIN32 /* ---win32 exclude headers */ +# include +# include +# include +# include "../include/autoconf.h" #endif /* win32 */ -static int pointer_strcmp(const void *p1, const void *p2) +static int +pointer_strcmp (const void *p1, const void *p2) { - const char *s1 = *(const char **)p1; - const char *s2 = *(const char **)p2; + const char *s1 = *(const char **) p1; + const char *s2 = *(const char **) p2; - return(strcmp(s1, s2)); + return (strcmp (s1, s2)); } /* This is our own version of scandir/select_regular_files/sort. @@ -59,47 +61,52 @@ * since there are cases where we want to choose a random * directory. */ -int load_dir (const char *dir, char ***namelist, int skip_dirs) +int +load_dir (const char *dir, char ***namelist, int skip_dirs) { - DIR *dp; - struct dirent *d; - int entries=0, entry_size=0; - char name[NAME_MAX+1], **rn=NULL; - struct stat sb; - - dp = opendir (dir); - if (dp == NULL) - return -1; - - while ((d = readdir (dp)) != NULL) { - sprintf(name, "%s/%s", dir, d->d_name); - if (skip_dirs) { - stat(name, &sb); - if (S_ISDIR(sb.st_mode)) { - continue; + DIR *dp; + struct dirent *d; + int entries = 0, entry_size = 0; + char name[NAME_MAX + 1], **rn = NULL; + struct stat sb; + + dp = opendir (dir); + if (dp == NULL) + return -1; + + while ((d = readdir (dp)) != NULL) + { + sprintf (name, "%s/%s", dir, d->d_name); + if (skip_dirs) + { + stat (name, &sb); + if (S_ISDIR (sb.st_mode)) + { + continue; } } - if (entries == entry_size) { - entry_size+=10; - rn = (char **) realloc(rn, sizeof(char*) * entry_size); + if (entries == entry_size) + { + entry_size += 10; + rn = (char **) realloc (rn, sizeof (char *) * entry_size); } - rn[entries] = strdup_local(d->d_name); - entries++; + rn[entries] = strdup_local (d->d_name); + entries++; } - (void) closedir (dp); + (void) closedir (dp); - qsort(rn, entries, sizeof(char*), pointer_strcmp); + qsort (rn, entries, sizeof (char *), pointer_strcmp); - *namelist = rn; - return entries; + *namelist = rn; + return entries; } - + /* this function loads and returns the map requested. * dirname, for example, is "/styles/wallstyles", stylename, is, * for example, "castle", difficulty is -1 when difficulty is @@ -110,122 +117,139 @@ */ /* remove extern, so visible to command_style_map_info function */ -mapstruct *styles=NULL; +mapstruct *styles = NULL; -mapstruct *load_style_map(char *style_name) +mapstruct * +load_style_map (char *style_name) { - mapstruct *style_map; + mapstruct *style_map; - /* Given a file. See if its in memory */ - for (style_map = styles; style_map!=NULL; style_map=style_map->next) { - if (!strcmp(style_name, style_map->path)) return style_map; + /* Given a file. See if its in memory */ + for (style_map = styles; style_map != NULL; style_map = style_map->next) + { + if (!strcmp (style_name, style_map->path)) + return style_map; } - style_map = load_original_map(style_name,MAP_STYLE); - /* Remove it from global list, put it on our local list */ - if (style_map) { - mapstruct *tmp; - - if (style_map == first_map) - first_map = style_map->next; - else { - for (tmp = first_map; tmp && tmp->next != style_map; tmp = tmp->next); - if(tmp) - tmp->next = style_map->next; + style_map = load_original_map (style_name, MAP_STYLE); + /* Remove it from global list, put it on our local list */ + if (style_map) + { + mapstruct *tmp; + + if (style_map == first_map) + first_map = style_map->next; + else + { + for (tmp = first_map; tmp && tmp->next != style_map; tmp = tmp->next); + if (tmp) + tmp->next = style_map->next; } - style_map->next = styles; - styles = style_map; + style_map->next = styles; + styles = style_map; } - return style_map; + return style_map; } -mapstruct *find_style(const char *dirname,const char *stylename,int difficulty) { - char style_file_path[256]; - char style_file_full_path[256]; - mapstruct *style_map = NULL; - struct stat file_stat; - int i, only_subdirs=0; - - /* if stylename exists, set style_file_path to that file.*/ - if(stylename && strlen(stylename)>0) - sprintf(style_file_path,"%s/%s",dirname,stylename); - else /* otherwise, just use the dirname. We'll pick a random stylefile.*/ - sprintf(style_file_path,"%s",dirname); - - /* is what we were given a directory, or a file? */ - sprintf(style_file_full_path,"%s/maps%s",settings.datadir,style_file_path); - if (stat(style_file_full_path, &file_stat) == 0 - && !S_ISDIR(file_stat.st_mode)) { - style_map=load_style_map(style_file_path); +mapstruct * +find_style (const char *dirname, const char *stylename, int difficulty) +{ + char style_file_path[256]; + char style_file_full_path[256]; + mapstruct *style_map = NULL; + struct stat file_stat; + int i, only_subdirs = 0; + + /* if stylename exists, set style_file_path to that file. */ + if (stylename && strlen (stylename) > 0) + sprintf (style_file_path, "%s/%s", dirname, stylename); + else /* otherwise, just use the dirname. We'll pick a random stylefile. */ + sprintf (style_file_path, "%s", dirname); + + /* is what we were given a directory, or a file? */ + sprintf (style_file_full_path, "%s/maps%s", settings.datadir, style_file_path); + if (stat (style_file_full_path, &file_stat) == 0 && !S_ISDIR (file_stat.st_mode)) + { + style_map = load_style_map (style_file_path); } - if(style_map == NULL) /* maybe we were given a directory! */ + if (style_map == NULL) /* maybe we were given a directory! */ { - char **namelist; - int n; - char style_dir_full_path[256]; - - /* get the names of all the files in that directory */ - sprintf(style_dir_full_path,"%s/maps%s",settings.datadir,style_file_path); - - /* First, skip subdirectories. If we don't find anything, then try again - * without skipping subdirs. - */ - n = load_dir(style_dir_full_path, &namelist, 1); - - if (n<=0) { - n = load_dir(style_dir_full_path, &namelist, 0); - only_subdirs=1; + char **namelist; + int n; + char style_dir_full_path[256]; + + /* get the names of all the files in that directory */ + sprintf (style_dir_full_path, "%s/maps%s", settings.datadir, style_file_path); + + /* First, skip subdirectories. If we don't find anything, then try again + * without skipping subdirs. + */ + n = load_dir (style_dir_full_path, &namelist, 1); + + if (n <= 0) + { + n = load_dir (style_dir_full_path, &namelist, 0); + only_subdirs = 1; } - if (n<=0) return 0; /* nothing to load. Bye. */ + if (n <= 0) + return 0; /* nothing to load. Bye. */ - /* Picks a random map. Note that if this is all directories, - * we know it won't be able to load, so save a few ticks. - * the door handling checks for this failure and handles - * it properly. - */ - if(difficulty==-1) { /* pick a random style from this dir. */ - if (only_subdirs) - style_map=NULL; - else { - strcat(style_file_path,"/"); - strcat(style_file_path,namelist[RANDOM()%n]); - style_map = load_style_map(style_file_path); + /* Picks a random map. Note that if this is all directories, + * we know it won't be able to load, so save a few ticks. + * the door handling checks for this failure and handles + * it properly. + */ + if (difficulty == -1) + { /* pick a random style from this dir. */ + if (only_subdirs) + style_map = NULL; + else + { + strcat (style_file_path, "/"); + strcat (style_file_path, namelist[RANDOM () % n]); + style_map = load_style_map (style_file_path); } } - else { /* find the map closest in difficulty */ - int min_dist=32000,min_index=-1; - - for(i=0;ihead) return new_obj->head; - else return new_obj; +object * +pick_random_object (mapstruct *style) +{ + int x, y, limit = 0; + object *new_obj; + + /* while returning a null object will result in a crash, that + * is actually preferable to an infinite loop. That is because + * most servers will automatically restart in case of crash. + * Change the logic on getting the random space - shouldn't make + * any difference, but this seems clearer to me. + */ + do + { + limit++; + x = RANDOM () % MAP_WIDTH (style); + y = RANDOM () % MAP_HEIGHT (style); + new_obj = get_map_ob (style, x, y); + } + while (new_obj == NULL && limit < 1000); + if (new_obj->head) + return new_obj->head; + else + return new_obj; } - -void free_style_maps(void) + +void +free_style_maps (void) { - mapstruct *next; - int style_maps=0; + mapstruct *next; + int style_maps = 0; - /* delete_map will try to free it from the linked list, - * but won't find it, so we need to do it ourselves - */ - while (styles) { - next = styles->next; - delete_map(styles); - styles=next; - style_maps++; + /* delete_map will try to free it from the linked list, + * but won't find it, so we need to do it ourselves + */ + while (styles) + { + next = styles->next; + delete_map (styles); + styles = next; + style_maps++; } - LOG(llevDebug,"free_style_maps: Freed %d maps\n", style_maps); + LOG (llevDebug, "free_style_maps: Freed %d maps\n", style_maps); } -