--- deliantra/server/common/region.C 2007/01/27 23:59:29 1.18 +++ deliantra/server/common/region.C 2007/01/29 14:46:01 1.19 @@ -55,37 +55,6 @@ return default_region (); } -/* This might need optimising at some point. */ -region * -get_region_by_map (maptile *m) -{ - return region::find (get_name_of_region_for_map (m)); -} - -/* - * Since we won't assume all maps have a region set properly, we need an - * explicit check that it is, this is much nicer here than scattered throughout - * the map code. - */ - -const char * -get_name_of_region_for_map (const maptile *m) -{ - region *reg; - - if (m->default_region) - return m->default_region->name; - - for (reg = first_region; reg; reg = reg->next) - { - if (reg->fallback) - return reg->name; - } - - LOG (llevInfo, "map %s had no region and I couldn't find a fallback to use.\n", &m->name); - return "unknown"; -} - /* * Tries to find a region that 'name' corresponds to. * It looks, in order, for: @@ -99,7 +68,7 @@ * */ region * -get_region_from_string (const char *name) +region::find_fuzzy (const char *name) { region *reg; char *substr; @@ -107,52 +76,59 @@ if (name == NULL) { - for (reg = first_region; reg->parent != NULL; reg = reg->parent); + for (reg = first_region; reg->parent; reg = reg->parent) + ; + return reg; } + p = strchr (name, '\n'); if (p) *p = '\0'; - for (reg = first_region; reg != NULL; reg = reg->next) + + for (reg = first_region; reg; reg = reg->next) if (!strcasecmp (reg->name, name)) return reg; - for (reg = first_region; reg != NULL; reg = reg->next) - if (reg->longname != NULL) - { - if (!strcasecmp (reg->longname, name)) - return reg; - } + for (reg = first_region; reg; reg = reg->next) + if (reg->longname) + if (!strcasecmp (reg->longname, name)) + return reg; substr = NULL; - for (reg = first_region; reg != NULL; reg = reg->next) - if (reg->longname != NULL) + for (reg = first_region; reg; reg = reg->next) + if (reg->longname) { substr = strstr (reg->longname, name); - if (substr != NULL) + if (substr) return reg; } - for (reg = first_region; reg != NULL; reg = reg->next) - if (reg->longname != NULL) + + for (reg = first_region; reg; reg = reg->next) + if (reg->longname) { /* - * This is not a bug, we want the region that is most identifiably a discrete + * This is not a bug, we want the region that is most identifiably a discrete * area in the game, eg if we have 'scor', we want to return 'scorn' and not * 'scornarena', regardless of their order on the list so we only look at those * regions with a longname set. */ substr = strstr (reg->name, name); - if (substr != NULL) + if (substr) return reg; } - for (reg = first_region; reg != NULL; reg = reg->next) + + for (reg = first_region; reg; reg = reg->next) { substr = strstr (reg->name, name); - if (substr != NULL) + if (substr) return reg; } + /* if we are still here, we are going to have to give up, and give the top level region */ - for (reg = first_region; reg->parent != NULL; reg = reg->parent); + for (reg = first_region; reg->parent; reg = reg->parent) + ; + return reg; } @@ -162,59 +138,25 @@ * if passed a NULL region returns -1 */ -int +static int region_is_child_of_region (const region * child, const region * r) { if (r == NULL) return -1; + if (child == NULL) return 0; + if (!strcmp (child->name, r->name)) return 1; + else if (child->parent != NULL) return region_is_child_of_region (child->parent, r); else return 0; } -/* - * the longname of a region is not a required field, any given region - * may want to not set it and use the parent's one instead. so, we: - * 1. check if a longname is set and if so return it. - * 2. check if there is a parent and try and call the function against that - * 3. return a obviously wrong string if we can't get a longname, this should - * never happen. We also log a debug message. - */ -const char * -get_region_longname (const region * r) -{ - - if (r->longname != NULL) - return r->longname; - else if (r->parent != NULL) - return get_region_longname (r->parent); - else - { - LOG (llevDebug, "NOTICE region %s has no parent and no longname.\n", r->name); - return "no name can be found for the current region"; - } -} - -const char * -get_region_msg (const region * r) -{ - if (r->msg != NULL) - return r->msg; - else if (r->parent != NULL) - return get_region_msg (r->parent); - else - { - LOG (llevDebug, "NOTICE region %s has no parent and no msg.\n", r->name); - return "no description can be found for the current region"; - } -} - /** Returns an object which is an exit through which the player represented by op should be * sent in order to be imprisoned. If there is no suitable place to which an exit can be * constructed, then NULL will be returned. The caller is responsible for freeing the object @@ -231,8 +173,9 @@ LOG (llevError, "region.c: get_jail_exit called against non-player object.\n"); return NULL; } - reg = get_region_by_map (op->map); - while (reg != NULL) + + reg = op->region (); + while (reg) { if (reg->jailmap) { @@ -247,10 +190,32 @@ else reg = reg->parent; } - LOG (llevDebug, "No suitable jailmap for region %s was found.\n", reg->name); + + LOG (llevDebug, "No suitable jailmap for region %s was found.\n", ®->name); return NULL; } +static void +assign_region_parents (void) +{ + region *reg; + uint32 parent_count = 0; + uint32 region_count = 0; + + for (reg = first_region; reg && reg->next; reg = reg->next) + { + if (reg->parent_name) + { + reg->parent = region::find (reg->parent_name); + parent_count++; + } + + region_count++; + } + + LOG (llevDebug, "Assigned %u regions with %u parents.\n", region_count, parent_count); +} + /* * First initialises the archtype hash-table (init_archetable()). * Reads and parses the archetype file (with the first and second-pass @@ -267,6 +232,11 @@ if (first_region != NULL) /* Only do this once */ return; + // make sure one region is always available + first_region = new region; + first_region->name = ""; + first_region->longname = strdup ("Built-in Region"); + sprintf (filename, "%s/%s/%s", settings.datadir, settings.mapdir, settings.regions); LOG (llevDebug, "Reading regions from %s...\n", filename); if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) @@ -274,6 +244,7 @@ LOG (llevError, " Can't open regions file %s in init_regions.\n", filename); return; } + parse_regions (fp); assign_region_parents (); LOG (llevDebug, " done\n"); @@ -281,18 +252,6 @@ close_and_delete (fp, comp); } -/* - * Allocates and zeros a region struct, this isn't free()'d anywhere, so might - * be a memory leak, but it shouldn't matter too much since it isn't called that - * often.... - */ - -region * -get_region_struct (void) -{ - return new region; -} - /* * Reads/parses the region file, and copies into a linked list * of region structs. @@ -346,8 +305,8 @@ if (!strcmp (key, "region")) { *end = 0; - newreg = get_region_struct (); - newreg->name = strdup (value); + newreg = new region; + newreg->name = value; } else if (!strcmp (key, "parent")) { @@ -357,7 +316,7 @@ * parsed. */ *end = 0; - newreg->parent_name = strdup (value); + newreg->parent_name = value; } else if (!strcmp (key, "longname")) { @@ -433,23 +392,3 @@ LOG (llevError, "Got premature eof on regions file!\n"); } -void -assign_region_parents (void) -{ - region *reg; - uint32 parent_count = 0; - uint32 region_count = 0; - - for (reg = first_region; reg != NULL && reg->next != NULL; reg = reg->next) - { - if (reg->parent_name != NULL) - { - reg->parent = region::find (reg->parent_name); - parent_count++; - } - - region_count++; - } - - LOG (llevDebug, "Assigned %u regions with %u parents.\n", region_count, parent_count); -}