00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00036 #include <global.h>
00037
00038 #ifndef WIN32
00039 #include <unistd.h>
00040 #endif
00041
00042 static void parse_regions(FILE *fp);
00043 static void assign_region_parents(void);
00044
00057 region *get_region_by_name(const char *region_name) {
00058 region *reg;
00059
00060 for (reg = first_region; reg != NULL; reg = reg->next)
00061 if (!strcmp(reg->name, region_name))
00062 return reg;
00063
00064 for (reg = first_region; reg != NULL; reg = reg->next) {
00065 if (reg->fallback) {
00066 LOG(llevDebug, "region called %s requested, but not found, fallback used.\n", region_name);
00067 return reg;
00068 }
00069 }
00070 LOG(llevInfo, "Got no region or fallback for region %s.\n", region_name);
00071 return NULL;
00072 }
00073
00085 region *get_region_by_map(mapstruct *m) {
00086 return get_region_by_name(get_name_of_region_for_map(m));
00087 }
00088
00103 const char *get_name_of_region_for_map(const mapstruct *m) {
00104 region *reg;
00105
00106 if (m->region != NULL)
00107 return m->region->name;
00108 for (reg = first_region; reg != NULL; reg = reg->next) {
00109 if (reg->fallback)
00110 return reg->name;
00111 }
00112 LOG(llevInfo, "map %s had no region and I couldn't find a fallback to use.\n", m->name);
00113 return "unknown";
00114 }
00115
00132 region *get_region_from_string(const char *name) {
00133 region *reg;
00134 char *substr;
00135 char *p;
00136
00137 if (first_region == NULL) {
00138 return NULL;
00139 }
00140
00141 if (name == NULL) {
00142 for (reg = first_region; reg->parent != NULL; reg = reg->parent)
00143 ;
00144 return reg;
00145 }
00146 p = strchr(name, '\n');
00147 if (p)
00148 *p = '\0';
00149 for (reg = first_region; reg != NULL; reg = reg->next)
00150 if (!strcasecmp(reg->name, name))
00151 return reg;
00152
00153 for (reg = first_region; reg != NULL; reg = reg->next)
00154 if (reg->longname != NULL) {
00155 if (!strcasecmp(reg->longname, name))
00156 return reg;
00157 }
00158
00159 substr = NULL;
00160 for (reg = first_region; reg != NULL; reg = reg->next)
00161 if (reg->longname != NULL) {
00162 substr = strstr(reg->longname, name);
00163 if (substr != NULL)
00164 return reg;
00165 }
00166 for (reg = first_region; reg != NULL; reg = reg->next)
00167 if (reg->longname != NULL) {
00168
00169
00170
00171
00172
00173
00174 substr = strstr(reg->name, name);
00175 if (substr != NULL)
00176 return reg;
00177 }
00178 for (reg = first_region; reg != NULL; reg = reg->next) {
00179 substr = strstr(reg->name, name);
00180 if (substr != NULL)
00181 return reg;
00182 }
00183
00184 for (reg = first_region; reg->parent != NULL; reg = reg->parent)
00185 ;
00186 return reg;
00187 }
00188
00201 int region_is_child_of_region(const region *child, const region *r) {
00202
00203 if (r == NULL)
00204 return -1;
00205 if (child == NULL)
00206 return 0;
00207 if (!strcmp(child->name, r->name))
00208 return 1;
00209 else if (child->parent != NULL)
00210 return region_is_child_of_region(child->parent, r);
00211 else
00212 return 0;
00213 }
00214
00229 const char *get_region_longname(const region *r) {
00230 if (r->longname != NULL)
00231 return r->longname;
00232 else if (r->parent != NULL)
00233 return get_region_longname(r->parent);
00234 else {
00235 LOG(llevDebug, "NOTICE region %s has no parent and no longname.\n", r->name);
00236 return "no name can be found for the current region";
00237 }
00238 }
00239
00250 const char *get_region_msg(const region *r) {
00251 if (r->msg != NULL)
00252 return r->msg;
00253 else if (r->parent != NULL)
00254 return get_region_msg(r->parent);
00255 else {
00256 LOG(llevDebug, "NOTICE region %s has no parent and no msg.\n", r->name);
00257 return "no description can be found for the current region";
00258 }
00259 }
00260
00272 object *get_jail_exit(object *op) {
00273 region *reg;
00274 object *exit;
00275
00276 if (op->type != PLAYER) {
00277 LOG(llevError, "region.c: get_jail_exit called against non-player object.\n");
00278 return NULL;
00279 }
00280
00281 reg = get_region_by_map(op->map);
00282 while (reg != NULL) {
00283 if (reg->jailmap) {
00284 exit = get_object();
00285 EXIT_PATH(exit) = add_string(reg->jailmap);
00286
00287 SET_FLAG(exit, FLAG_DAMNED);
00288 EXIT_X(exit) = reg->jailx;
00289 EXIT_Y(exit) = reg->jaily;
00290 return exit;
00291 } else
00292 reg = reg->parent;
00293 }
00294 LOG(llevDebug, "No suitable jailmap for region %s was found.\n", reg->name);
00295 return NULL;
00296 }
00297
00301 void init_regions(void) {
00302 FILE *fp;
00303 char filename[MAX_BUF];
00304 int comp;
00305
00306 if (first_region != NULL)
00307 return;
00308
00309 snprintf(filename, sizeof(filename), "%s/%s/%s", settings.datadir, settings.mapdir, settings.regions);
00310 LOG(llevDebug, "Reading regions from %s...\n", filename);
00311 if ((fp = open_and_uncompress(filename, 0, &comp)) == NULL) {
00312 LOG(llevError, " Can't open regions file %s in init_regions.\n", filename);
00313 return;
00314 }
00315 parse_regions(fp);
00316 assign_region_parents();
00317 LOG(llevDebug, " done\n");
00318
00319 close_and_delete(fp, comp);
00320 }
00321
00336 region *get_region_struct(void) {
00337 region *new;
00338
00339 new = (region *)CALLOC(1, sizeof(region));
00340 if (new == NULL)
00341 fatal(OUT_OF_MEMORY);
00342
00343 memset(new, '\0', sizeof(region));
00344
00345 return new;
00346 }
00347
00355 static void parse_regions(FILE *fp) {
00356 region *new;
00357 region *reg;
00358
00359 char buf[HUGE_BUF], msgbuf[HUGE_BUF], *key = NULL, *value, *end;
00360 int msgpos = 0;
00361
00362 new = NULL;
00363 while (fgets(buf, HUGE_BUF-1, fp) != NULL) {
00364 buf[HUGE_BUF-1] = 0;
00365 key = buf;
00366 while (isspace(*key))
00367 key++;
00368 if (*key == 0)
00369 continue;
00370 value = strchr(key, ' ');
00371 if (!value) {
00372 end = strchr(key, '\n');
00373 *end = 0;
00374 } else {
00375 *value = 0;
00376 value++;
00377 while (isspace(*value))
00378 value++;
00379 end = strchr(value, '\n');
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 if (!strcmp(key, "region")) {
00396 *end = 0;
00397 new = get_region_struct();
00398 new->name = strdup_local(value);
00399 } else if (!strcmp(key, "parent")) {
00400
00401
00402
00403
00404
00405 *end = 0;
00406 new->parent_name = strdup_local(value);
00407 } else if (!strcmp(key, "longname")) {
00408 *end = 0;
00409 new->longname = strdup_local(value);
00410 } else if (!strcmp(key, "jail")) {
00411
00412 char path[MAX_BUF];
00413 int x, y;
00414
00415 if (sscanf(value, "%[^ ] %d %d\n", path, &x, &y) != 3) {
00416 LOG(llevError, "region.c: malformated regions entry: jail %s\n", value);
00417 continue;
00418 }
00419 new->jailmap = strdup_local(path);
00420 new->jailx = x;
00421 new->jaily = y;
00422 } else if (!strcmp(key, "msg")) {
00423 while (fgets(buf, HUGE_BUF-1, fp) != NULL) {
00424 if (!strcmp(buf, "endmsg\n"))
00425 break;
00426 else {
00427 strcpy(msgbuf+msgpos, buf);
00428 msgpos += strlen(buf);
00429 }
00430 }
00431
00432
00433
00434
00435
00436 if (msgpos != 0)
00437 new->msg = strdup_local(msgbuf);
00438
00439
00440 msgpos = 0;
00441 } else if (!strcmp(key, "fallback")) {
00442 *end = 0;
00443 new->fallback = atoi(value);
00444 } else if (!strcmp(key, "end")) {
00445
00446 for (reg = first_region; reg != NULL && reg->next != NULL; reg = reg->next)
00447 ;
00448
00449 if (reg == NULL)
00450 first_region = new;
00451 else
00452 reg->next = new;
00453 new = NULL;
00454 } else if (!strcmp(key, "nomore")) {
00455
00456 break;
00457 } else {
00458
00459 LOG(llevError, "Got unknown value in region file: %s %s\n", key, value);
00460 }
00461 }
00462 if (!key || strcmp(key, "nomore"))
00463 LOG(llevError, "Got premature eof on regions file!\n");
00464 }
00465
00469 static void assign_region_parents(void) {
00470 region *reg;
00471 uint32 parent_count = 0;
00472 uint32 region_count = 0;
00473
00474 for (reg = first_region; reg != NULL && reg->next != NULL; reg = reg->next) {
00475 if (reg->parent_name != NULL) {
00476 reg->parent = get_region_by_name(reg->parent_name);
00477 parent_count++;
00478 }
00479 region_count++;
00480 }
00481 LOG(llevDebug, "Assigned %u regions with %u parents.\n", region_count, parent_count);
00482 }