219 #include <sys/stat.h> 220 #include <sys/types.h> 350 for (test = 0; test < list->
count; test++) {
351 if (list->
races[test] == race)
489 #define S_CONTAINER 2 518 if (item->name == item->arch->clone.name && item->title == item->arch->clone.title)
525 if (
IS_SHIELD(item) ||
IS_WEAPON(item) ||
IS_ARMOR(item) ||
IS_ARROW(item) || (item->type == ROD) || (item->type == WAND) || (item->type == RING) || (item->type == AMULET))
568 comp = special_equipment[check];
613 namepl = item->name_pl;
616 if (item->artifact != NULL) {
620 if (artifact == NULL) {
621 LOG(
llevError,
"could not find artifact %s [%d] to save data\n", item->artifact, item->type);
634 item->name = base->name;
635 item->name_pl = base->name_pl;
636 item->nrof = base->nrof;
645 object_free(base, FREE_OBJ_NO_DESTROY_CALLBACK | FREE_OBJ_FREE_INVENTORY);
652 item->name_pl = namepl;
655 if (add->
diff == NULL || strcmp(add->
diff,
"") == 0) {
660 add->
name = strdup(item->name);
661 add->
power = item->item_power;
715 for (test = 0; test < races.
count; test++) {
716 if (strcmp(races.
races[test]->
name, name) == 0) {
718 return races.
races[test];
723 item->
name = strdup(name);
743 if (monster->head && monster != monster->head)
778 const char *roads[] = {
784 const char *partial[] = {
788 for (test = 0; partial[test] != NULL; test++) {
789 if (strstr(item->arch->name, partial[test]) != NULL)
796 for (test = 0; roads[test] != NULL; test++) {
797 if (strcmp(item->arch->name, roads[test]) == 0)
812 return item->move_block ==
MOVE_ALL ? 1 : 0;
827 return gdImageColorResolve(elevationmap, 200*elevation/
elevation_max, 0, 0);
829 return gdImageColorResolve(elevationmap, 0, 0, 200*elevation/
elevation_min);
845 if (sscanf(map->
path,
"/world/world_%d_%d", &x, &y) != 2)
851 for (tx = 0; tx <
MAP_WIDTH(map); tx++) {
856 if (test->type == EXIT || test->type == TELEPORTER) {
867 }
else if (test->move_slow != 0)
872 int32_t elevation = atoi(selevation);
895 return (strcmp(*(
const char **)a, *(
const char **)b));
911 source = realloc(source, strlen(source)+strlen(add)+1);
931 if (stat(name, &info)) {
932 printf(
"Couldn't stat template %s!\n", name);
936 (*buffer) = calloc(1, info.st_size+1);
938 printf(
"Template %s calloc failed!\n", name);
942 if (info.st_size == 0) {
947 file = fopen(name,
"rb");
949 printf(
"Couldn't open template %s!\n", name);
953 if (fread(*buffer, info.st_size, 1, file) != 1) {
954 printf(
"Couldn't read template %s!\n", name);
979 static char *
do_template(
const char *
template,
const char **vars,
const char **values) {
981 const char *sharp =
template;
985 char *current_result;
988 while ((sharp = strchr(sharp,
'#')) != NULL) {
993 return strdup(
template);
995 printf(
"Malformed template, mismatched #!\n");
996 return strdup(
template);
999 while (vars[var] != NULL) {
1000 if (strlen(values[var]) > maxlen)
1001 maxlen = strlen(values[var]);
1004 result = calloc(1, strlen(
template)+maxlen*(count/2)+1);
1007 current_result = result;
1010 while ((sharp = strchr(sharp,
'#')) != NULL) {
1011 end = strchr(sharp+1,
'#');
1012 strncpy(current_result,
template, sharp-
template);
1013 if (end == sharp+1) {
1014 strcat(current_result,
"#");
1017 current_result = current_result+strlen(current_result);
1019 while (vars[var] != NULL && (strncmp(vars[var], sharp+1, end-sharp-1) || (strlen(vars[var]) != end-sharp-1)))
1022 if (vars[var] == NULL)
1023 printf(
"Wrong tag: %s\n", sharp);
1025 strcpy(current_result, values[var]);
1027 current_result = current_result+strlen(current_result);
1031 strcat(current_result,
template);
1053 fslash = strchr(from+1,
'/');
1055 strcpy(result, to+1);
1059 rslash = strchr(to+1,
'/');
1060 while (fslash && rslash && (fslash-from == rslash-to) && strncmp(from, to, fslash-from+1) == 0) {
1063 fslash = strchr(fslash+1,
'/');
1064 rslash = strchr(rslash+1,
'/');
1068 strcat(result,
"../");
1069 fslash = strchr(fslash+1,
'/');
1071 if (strlen(result) && result[strlen(result)-1] ==
'/' && *to ==
'/')
1072 result[strlen(result)-1] =
'\0';
1087 const char *l = *(
const char **)left;
1088 const char *r = *(
const char **)right;
1089 const char *sl = strrchr(l,
'/');
1090 const char *sr = strrchr(r,
'/');
1231 if (strcmp(quests[test]->name, name) == 0)
1232 return quests[test];
1240 add->
name = strdup(name);
1314 printf(
"warning, multiple quest definition for %s, found in %s and %s.\n", quest->
name, quest->
mainmap ? quest->
mainmap->
path :
"(unknown map)", mainmap->
path);
1330 char *start, *end, *next;
1332 char description[500];
1334 start = strstr(map->
lore,
"@def");
1336 description[0] =
'\0';
1338 end = strstr(start,
"\n");
1340 strncpy(name, start+5, end-start-5);
1341 name[end-start-5] =
'\0';
1343 end = strstr(next,
"@end");
1345 strncpy(description, next, end-next);
1346 description[end-next] =
'\0';
1348 memcpy(start, end+4, strlen(map->
lore)-(end-start+3));
1352 strcpy(description, next);
1357 strcpy(name, start);
1363 start = end ? strstr(end,
"@def") : NULL;
1366 start = strstr(map->
lore,
"@quest");
1368 description[0] =
'\0';
1370 end = strstr(start,
"\n");
1372 strncpy(name, start+7, end-start-7);
1373 name[end-start-7] =
'\0';
1375 end = strstr(next,
"@end");
1377 strncpy(description, next, end-next);
1378 description[end-next] =
'\0';
1380 memcpy(start, end+4, strlen(map->
lore)-(end-start+3));
1384 strcpy(description, next);
1389 strcpy(name, start);
1395 start = end ? strstr(end,
"@quest") : NULL;
1407 char mainmappath[500];
1409 const char *map_vars[] = {
"MAPPATH",
"MAPNAME",
"MAPTEXT", NULL };
1410 const char *map_vals[] = { mappath, NULL, NULL, NULL };
1411 const char *quest_vars[] = {
"QUESTNAME",
"QUESTTEXT",
"QUESTMAPS",
"QUESTID",
"MAINMAPPATH",
"MAINMAPNAME", NULL };
1412 const char *quest_vals[] = { NULL, NULL, NULL, questid, mainmappath, NULL, NULL };
1413 const char *idx_vars[] = {
"QUESTS", NULL };
1414 const char *idx_vals[] = { NULL, NULL };
1415 char *text_map = NULL;
1416 char *text_quest = NULL;
1417 char *text_idx = NULL;
1419 printf(
"Writing quest index...");
1423 for (map = 0; map < quests[quest]->
maps.
count; map++) {
1424 snprintf(mappath,
sizeof(mappath),
"%s.html", quests[quest]->maps.list[map]->map->path+1);
1430 text_map = strdup(
"");
1432 quest_vals[0] = quests[quest]->
name;
1434 quest_vals[2] = text_map;
1435 snprintf(questid,
sizeof(questid),
"quest_%d", quests[quest]->number);
1436 if (quests[quest]->mainmap) {
1437 snprintf(mainmappath,
sizeof(mainmappath),
"%s.html", quests[quest]->mainmap->path+1);
1440 snprintf(mainmappath,
sizeof(mainmappath),
"#");
1449 text_quest = strdup(
"No quest.");
1451 idx_vals[0] = text_quest;
1456 out = fopen(path,
"w+");
1457 fprintf(out,
"%s", text_idx);
1493 info->
name = strdup(npc->name);
1494 info->
message = strdup(npc->msg);
1533 for (map = 0; map < list->
count; map++)
1534 if (list->
maps[map] == info)
1576 add_map(add, &tiled_map_list);
1603 for (g = 0; g < tiled_map_list.
count; g++) {
1604 if (tiled_map_list.
maps[g] == group) {
1605 if (g < tiled_map_list.
count-1)
1606 tiled_map_list.
maps[g] = tiled_map_list.
maps[tiled_map_list.
count-1];
1607 tiled_map_list.
count--;
1612 printf(
"tiled_map not in tiled_map_list!");
1630 for (map = 0; map < maps_list.
count; map++) {
1631 if (strcmp(maps_list.
maps[map]->
path, path) == 0)
1632 return maps_list.
maps[map];
1636 add->
path = strdup(path);
1637 tmp = strrchr(path,
'/');
1663 printf(
"Map processed but not found in directory reading? %s\n", path);
1681 if (regions[test]->reg == reg)
1684 if (test == region_count) {
1691 regions[test]->
reg = reg;
1693 add_map(map, ®ions[test]->maps_list);
1694 if (sscanf(map->
path,
"/world/world_%d_%d", &x, &y) == 2) {
1695 regions[test]->
sum_x += (x-100);
1696 regions[test]->
sum_y += (y-100);
1697 regions[test]->
sum++;
1712 gdImagePng(pic, file);
1737 snprintf(entry,
sizeof(entry),
"%s -> %s [ label = \"%s\" ]\n", s->
name, d->
name, linkname);
1751 regions_link_count++;
1763 return (item->type == LOCKED_DOOR || item->type == SPECIAL_KEY || item->type == CONTAINER || item->type == CHECK_INV);
1780 if (!strcmp(slaying_info[l]->slaying, slaying))
1781 return slaying_info[l];
1789 add->
slaying = strdup(slaying);
1790 for (l = 0; l <
S_MAX; l++)
1829 if (item->type == LOCKED_DOOR)
1831 else if (item->type == SPECIAL_KEY)
1833 else if (item->type == CONTAINER)
1870 struct stat statspic;
1871 char exit_path[500];
1881 printf(
" processing map %s\n", info->
path);
1885 printf(
"couldn't load map %s\n", info->
path);
1900 isworld = (sscanf(info->
path,
"/world/world_%d_%d", &x, &y) == 2);
1917 stat(tmppath, &stats);
1918 if (stat(picpath, &statspic) || (statspic.st_mtime < stats.st_mtime))
1920 else if (stat(smallpicpath, &statspic) || (statspic.st_mtime < stats.st_mtime))
1933 for (x = 0; x < 4; x++)
1937 if (stat(tmppath, &stats)) {
1938 printf(
" map %s doesn't exist in map %s, for tile %d.\n", exit_path, info->
path, x);
1949 if (link && link != m) {
1990 if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
1994 if (!item->slaying) {
1997 printf(
" exit without any path at %d, %d on %s\n", item->x, item->y, info->
path);
2000 if (strcmp(item->slaying,
"/!"))
2004 printf(
" random map without message in %s at %d, %d\n", info->
path, item->x, item->y);
2007 start = strstr(item->msg,
"\nfinal_map ");
2008 if (!start && strncmp(item->msg,
"final_map", strlen(
"final_map")) == 0)
2012 char *end = strchr(start+1,
'\n');
2014 start += strlen(
"final_map")+2;
2015 strncpy(ep, start, end-start);
2023 if (stat(tmppath, &stats)) {
2024 printf(
" map %s doesn't exist in map %s, at %d, %d.\n", ep, info->
path, item->x, item->y);
2033 if (link && link != m) {
2059 }
else if ((item->type == SIGN || item->type == BOOK) && (item->msg != item->arch->clone.msg) && (item->msg != NULL)) {
2063 if (item->invisible)
2069 if (
gdfaces[item->face->number] == NULL) {
2075 if (item->head || item->more) {
2081 if (
gdfaces[item->face->number] != NULL && ((!item->head && !item->more) || (item->arch->clone.x+hx == 0 && item->arch->clone.y+hy == 0))) {
2082 gdImageCopy(pic,
gdfaces[item->face->number], x*32, y*32, 0, 0,
gdfaces[item->face->number]->sx,
gdfaces[item->face->number]->sy);
2090 out = fopen(picpath,
"wb+");
2097 out = fopen(smallpicpath,
"wb+");
2100 gdImageDestroy(small);
2102 gdImageDestroy(pic);
2133 const char *template_page,
const char *template_letter,
2134 const char *template_map,
const char **vars,
2135 const char **values) {
2142 char lettercount[50];
2144 const char **idx_vars;
2145 const char **idx_values;
2148 char index_path[500];
2149 char *mapstext = NULL;
2151 int basevalues, realcount = 0;
2158 for (basevalues = 0; vars[basevalues] != NULL; basevalues++)
2163 idx_vars = malloc(
sizeof(
char *)*(basevalues+
VARSADD));
2164 idx_vars[0] =
"MAPCOUNT";
2165 memcpy(&idx_vars[1], vars,
sizeof(
char *)*basevalues);
2166 idx_vars[basevalues+
VARSADD-1] = NULL;
2168 idx_values = malloc(
sizeof(
char *)*(basevalues+
VARSADD-1));
2169 memcpy(&idx_values[1], values,
sizeof(
char *)*basevalues);
2173 idx_values[0] = count;
2177 idx_vars[basevalues+1] =
"MAPNAME";
2178 idx_vars[basevalues+2] =
"MAPPATH";
2179 idx_vars[basevalues+3] =
"MAPHTML";
2180 idx_vars[basevalues+4] = NULL;
2185 str_letter[0] =
'\0';
2186 str_letter[1] =
'\0';
2188 strcpy(index_path,
"/");
2189 strcat(index_path, dest);
2192 for (map = 0; map < maps_list->
count; map++) {
2194 if (mapstext != NULL) {
2195 idx_vars[basevalues+1] =
"MAPS";
2196 idx_vars[basevalues+2] =
"LETTER";
2197 idx_vars[basevalues+3] =
"LETTERCOUNT";
2198 idx_vars[basevalues+4] = NULL;
2199 idx_values[basevalues+1] = mapstext;
2200 idx_values[basevalues+2] = str_letter;
2201 snprintf(lettercount,
sizeof(lettercount),
"%d", byletter);
2202 idx_values[basevalues+3] = lettercount;
2206 idx_values[basevalues+2] = NULL;
2209 str_letter[0] = last_letter;
2220 idx_vars[basevalues+1] =
"MAPNAME";
2221 idx_vars[basevalues+2] =
"MAPPATH";
2222 idx_vars[basevalues+3] =
"MAPHTML";
2223 idx_values[basevalues+1] = last_group ? last_group->
name : (maps_list->
maps[map]->
name ? maps_list->
maps[map]->
name : maps_list->
maps[map]->
path);
2225 strcpy(maphtml, mappath);
2226 strcat(maphtml,
".html");
2227 idx_values[basevalues+2] = mappath;
2228 idx_values[basevalues+3] = maphtml;
2232 if (last_letter !=
'\0') {
2233 idx_vars[basevalues+1] =
"MAPS";
2234 idx_vars[basevalues+2] =
"LETTER";
2235 idx_vars[basevalues+3] =
"LETTERCOUNT";
2236 idx_vars[basevalues+4] = NULL;
2237 idx_values[basevalues+1] = mapstext;
2238 idx_values[basevalues+2] = str_letter;
2239 snprintf(lettercount,
sizeof(lettercount),
"%d", byletter);
2240 idx_values[basevalues+3] = lettercount;
2244 idx_values[basevalues+2] = NULL;
2247 snprintf(count,
sizeof(count),
"%d", realcount);
2248 idx_values[basevalues+1] = string;
2249 idx_vars[basevalues+1] =
"LETTERS";
2250 idx_vars[basevalues+2] = NULL;
2251 tmp =
do_template(template_page, idx_vars, idx_values);
2271 const char *vars[] = {
"REGIONNAME",
"REGIONHTML",
"REGIONLONGNAME",
"REGIONDESC", NULL };
2272 const char *values[] = { reg->
reg->
name, html, NULL, NULL };
2274 printf(
"Generating map index for region %s...", reg->
reg->
name);
2280 strcat(html,
".html");
2287 strcat(html,
".html");
2288 index = fopen(html,
"w+");
2289 fprintf(index,
"%s",
string);
2313 char index_path[500];
2317 printf(
"Generating global map index in maps.html...");
2321 strcpy(index_path,
root);
2322 strcat(index_path,
"/maps.html");
2323 index = fopen(index_path,
"w+");
2324 fprintf(index,
"%s", tmp);
2341 const char *vars[] = {
"REGIONCOUNT",
"REGIONFILE",
"REGIONNAME", NULL };
2342 const char *values[] = { count, file, NULL };
2345 printf(
"Generating regions index in regions.html...");
2351 region = regions[reg];
2356 vars[1] =
"REGIONS";
2363 strcat(file,
"/regions.html");
2364 out = fopen(file,
"w+");
2365 fprintf(out,
"%s",
final);
2384 char mapleft[10], maptop[10], mapright[10], mapbottom[10];
2385 const char *vars[] = { NULL, NULL,
"MAPLEFT",
"MAPTOP",
"MAPRIGHT",
"MAPBOTTOM", NULL };
2386 const char *values[] = { NULL, NULL, mapleft, maptop, mapright, mapbottom, NULL };
2388 char mappath[500], mapraw[500], mapregion[500];
2397 printf(
"Generating world map in world.html...");
2400 pic = gdImageCreateTrueColor(
SIZE*30,
SIZE*30);
2403 strcat(file,
"/world.html");
2408 for (y = 0; y < 30; y++) {
2409 for (x = 0; x < 30; x++) {
2411 vars[0] =
"MAPNAME";
2412 vars[1] =
"MAPPATH";
2413 values[1] = mappath,
2414 snprintf(name,
sizeof(name),
"world_%d_%d", wx, wy);
2415 snprintf(mappath,
sizeof(mappath),
"world/%s.html", name);
2418 snprintf(mapright,
sizeof(mapright),
"%d",
SIZE*(x+1)-1);
2419 snprintf(mapbottom,
sizeof(mapbottom),
"%d",
SIZE*(y+1)-1);
2425 out = fopen(mappath,
"rb");
2427 printf(
"\n warning: large pic not found for world_%d_%d", wx, wy);
2431 if (output_format ==
OF_PNG)
2432 small = gdImageCreateFromPng(out);
2434 small = gdImageCreateFromJpeg(out);
2437 printf(
"\n warning: pic not found for world_%d_%d", wx, wy);
2441 gdImageCopyResized(pic, small,
SIZE*x,
SIZE*y, 0, 0,
SIZE,
SIZE, small->sx, small->sy);
2442 gdImageDestroy(small);
2461 values[1] = mappath;
2462 vars[1] =
"WORLDMAP";
2464 vars[2] =
"WORLDRAW";
2465 values[3] = mapregion;
2466 vars[3] =
"WORLDREGIONS";
2470 out = fopen(file,
"w+");
2471 fprintf(out,
"%s", total);
2476 out = fopen(mappath,
"wb+");
2481 small = gdImageCreateTrueColor(
SIZE*30,
SIZE*30);
2482 font = gdFontGetGiant();
2483 color = gdImageColorAllocateAlpha(pic, 255, 0, 0, 20);
2485 if (!regions[region]->is_world || regions[region]->sum == 0)
2490 gdImageString(small, font, x, y, (
unsigned char *)regions[region]->reg->name, color);
2491 gdImageString(pic, font, x, y, (
unsigned char *)regions[region]->reg->name, color);
2494 x = regions[
region]->
sum_x*50/regions[
region]->
sum+50/2-strlen(regions[region]->reg->name)*font->w/2;
2496 gdImageString(
infomap, font, x, y, (
unsigned char *)regions[region]->reg->name, color);
2500 out = fopen(mappath,
"wb+");
2503 gdImageDestroy(small);
2506 out = fopen(mappath,
"wb+");
2509 gdImageDestroy(pic);
2531 char mapsmallpic[500];
2532 char indexpath[500];
2533 char regionpath[500];
2534 char regionname[500];
2535 char regionindexpath[500];
2536 char worldmappath[500];
2537 char exit_path[500];
2538 char maplevel[5], minmonster[5], maxmonster[5];
2540 char questpath[500], questtemp[500];
2541 const char *quest_vars[] = {
"NAME",
"PATH",
"TEXT", NULL };
2542 const char *quest_vals[] = { NULL, questpath, NULL, NULL };
2543 const char *q_vars[] = {
"QUESTS", NULL };
2544 const char *q_vals[] = { NULL, NULL };
2545 const char *m_vars[] = {
"NAME", NULL };
2546 const char *m_vals[] = { NULL, NULL };
2547 const char *vars[] = {
"NAME",
"MAPPATH",
"MAPNAME",
"MAPPIC",
"MAPSMALLPIC",
"MAPEXITFROM",
"INDEXPATH",
"REGIONPATH",
"REGIONNAME",
"REGIONINDEXPATH",
"WORLDMAPPATH",
"MAPLORE",
"MAPEXITTO",
"MAPLEVEL",
"QUESTS",
"MONSTERS",
"MINMONSTER",
"MAXMONSTER", NULL, NULL, NULL };
2548 const char *values[] = { map->
path, htmlpath, map->
name, mappic, mapsmallpic,
"", indexpath, regionpath, regionname, regionindexpath, worldmappath,
"",
"", maplevel, NULL,
"", minmonster, maxmonster, NULL, NULL, NULL };
2551 while (vars[vars_count])
2563 strcpy(exit_path,
"/");
2565 strcat(exit_path,
".html");
2569 snprintf(regionname,
sizeof(regionname),
"(map was not processed)");
2581 if (map->
lore && map->
lore[0] !=
'\0') {
2582 values[11] = map->
lore;
2587 values[11] = maplore;
2590 char *one_exit = NULL;
2594 vars[vars_count] =
"EXITNAME";
2595 vars[vars_count+1] =
"EXITFILE";
2601 strcat(relative,
".html");
2602 values[vars_count+1] = relative;
2605 vars[vars_count] =
"EXIT";
2606 vars[vars_count+1] = NULL;
2607 values[vars_count] = one_exit;
2614 values[5] = exits_text;
2617 char *one_exit = NULL;
2621 vars[vars_count] =
"EXITNAME";
2622 vars[vars_count+1] =
"EXITFILE";
2628 strcat(relative,
".html");
2629 values[vars_count+1] = relative;
2632 vars[vars_count] =
"EXIT";
2633 vars[vars_count+1] = NULL;
2634 values[vars_count] = one_exit;
2640 values[12] = exits_to;
2677 values[15] = monsters;
2679 vars[vars_count] = NULL;
2680 out = fopen(htmlpath,
"w+");
2682 fprintf(out,
"%s", tmp);
2696 for (map = 0; map < maps_list.
count; map++) {
2700 printf(
"map without path!\n");
2719 for (map = 0; map < tiled_map_list.
count; map++) {
2721 printf(
"empty tiled map group!");
2725 snprintf(name,
sizeof(name),
"tiled_map_group_%d", map);
2739 printf(
"*** warning: tiled maps %s and %s not in same region (%s and %s).\n",
2754 printf(
"*** warning: tiled map without any name. First map path %s\n", tiled_map_list.
maps[map]->
tiled_maps.
maps[0]->
path);
2758 tiled_map_list.
maps[map]->
name = strdup(test);
2762 slash = strrchr(name,
'/');
2767 strncat(name, tiled_map_list.
maps[map]->
filename,
sizeof(name));
2768 tiled_map_list.
maps[map]->
path = strdup(name);
2786 max = from->
count-1;
2787 for (map = max; map >= 0; map--) {
2805 for (map = 0; map < maps_list.
count; map++) {
2812 for (map = max; map >= 0; map--) {
2819 add_map(group, ®ions[region]->maps_list);
2833 for (race = 0; race < races.
count; race++) {
2835 for (map = max; map >= 0; map--) {
2847 for (map = 0; map < maps_list.
count; map++) {
2860 printf(
"Writing map pages...");
2862 for (map = 0; map < maps_list.
count; map++)
2875 if (stat(picpath, &stats))
2879 if (stat(picpath, &stats))
2902 int xmin = 0, xmax = 0, ymin = 0, ymax = 0, tiled, count, last;
2904 gdImagePtr small, large, load;
2911 printf(
" Generating composite map for %s...", map->
name);
2915 printf(
" already uptodate.\n");
2921 printf(
"Tiled map without tiled maps?\n");
2960 if (last == count) {
2961 printf(
"do_tiled_map_picture: didn't process any map in %s (%d left)??\n", map->
path, last);
2977 large = gdImageCreateTrueColor(32*(xmax-xmin), 32*(ymax-ymin));
2983 out = fopen(picpath,
"rb");
2985 printf(
"\n do_tiled_map_picture: warning: pic file not found for %s (errno=%d)\n", map->
tiled_maps.
maps[tiled]->
path, errno);
2988 if (output_format ==
OF_PNG)
2989 load = gdImageCreateFromPng(out);
2991 load = gdImageCreateFromJpeg(out);
2994 printf(
"\n do_tiled_map_picture: warning: pic not found for %s\n", map->
tiled_maps.
maps[tiled]->
path);
2998 gdImageDestroy(load);
3001 out = fopen(picpath,
"rb");
3002 if (output_format ==
OF_PNG)
3003 load = gdImageCreateFromPng(out);
3005 load = gdImageCreateFromJpeg(out);
3008 printf(
"\n do_tiled_map_picture: warning: small pic not found for %s\n", map->
tiled_maps.
maps[tiled]->
path);
3012 gdImageDestroy(load);
3016 out = fopen(picpath,
"wb+");
3021 out = fopen(picpath,
"wb+");
3025 gdImageDestroy(small);
3026 gdImageDestroy(large);
3045 printf(
"Writing tiled map information...\n");
3047 for (map = 0; map < tiled_map_list.
count; map++)
3059 char *letters = NULL;
3065 const char *val_vars[] = {
"LEVEL",
"MAPS", NULL };
3066 const char *val_values[] = { strlevel, NULL, NULL };
3067 const char *map_vars[] = {
"MAPNAME",
"MAPPATH", NULL };
3068 const char *map_values[] = { NULL, mappath, NULL };
3069 const char *idx_vars[] = {
"COUNT",
"LEVELS", NULL };
3070 const char *idx_values[] = { strcount, NULL, NULL };
3075 printf(
"Writing map index by level...");
3077 snprintf(name,
sizeof(name),
"%s/index_by_level.html",
root);
3081 for (map = 0; map < maps_list.
count; map++) {
3082 process = maps_list.
maps[map];
3083 if (maps_list.
maps[map]->
level != lastlevel) {
3085 snprintf(strlevel,
sizeof(strlevel),
"%d", lastlevel);
3086 val_values[1] = maps;
3091 lastlevel = process->
level;
3095 if (last_tiled && last_tiled == process->
tiled_group)
3101 last_tiled = process;
3105 map_values[0] = process->
name;
3106 snprintf(mappath,
sizeof(mappath),
"%s.html", process->
path+1);
3110 snprintf(strlevel,
sizeof(strlevel),
"%d", lastlevel);
3111 val_values[1] = maps;
3116 snprintf(strcount,
sizeof(strcount),
"%d", levelcount);
3117 idx_values[1] = letters;
3121 out = fopen(name,
"w+");
3122 fprintf(out,
"%s", level);
3137 printf(
"Generating special equipment list..");
3143 out = fopen(name,
"w+");
3145 fprintf(out,
"<html><head><title>Item list</title></head><body><h1>Special items found in maps</h1>\n");
3146 fprintf(out,
"<table border=\"1\"><tr><th>Name</th><th>Map(s)</th><th>Item power</th><th>Calc item power</th><th>Description</th></tr>\n");
3149 fprintf(out,
"<tr><td>%s</td><td><ul>", special_equipment[item]->name);
3151 for (map = 0; map < special_equipment[item]->
origin.
count; map++)
3152 fprintf(out,
"<li>%s</li>\n", special_equipment[item]->origin.maps[map]->path);
3154 fprintf(out,
"</ul></td><td>%d</td><td>%d</td><td><pre>%s</pre></td></tr>\n", special_equipment[item]->power, special_equipment[item]->calc_power, special_equipment[item]->diff);
3156 fprintf(out,
"</table></body></html>\n");
3170 printf(
"Generating monster list...");
3175 snprintf(name,
sizeof(name),
"%s/monsters.html",
root);
3176 out = fopen(name,
"w+");
3178 fprintf(out,
"<html><head><title>Monster list</title></head><body><h1>Monsters found in maps</h1>\n");
3179 fprintf(out,
"<table border=\"1\"><tr><th>Name</th><th>Count</th><th>Map(s)</th></tr>\n");
3181 for (item = 0; item < races.
count; item++) {
3189 fprintf(out,
"</ul></td></tr>\n");
3191 fprintf(out,
"</table></body></html>\n");
3224 struct stat statbuf;
3226 char path[1024], full[1024];
3229 for (ignore = 0;
ignore_path[ignore] != NULL; ignore++) {
3240 for (ignore = 0;
ignore_name[ignore] != NULL; ignore++) {
3249 status = stat(full, &statbuf);
3250 if ((status != -1) && (
S_ISDIR(statbuf.st_mode))) {
3270 int index, found = 0;
3272 snprintf(path,
sizeof(path),
"%s/%s",
root,
"maps.unused");
3273 dump = fopen(path,
"w+");
3275 printf(
"Unable to open file maps.unused!\n");
3286 printf(
"%d unused maps.\n", found);
3294 gdImagePtr elevationmap;
3299 printf(
"Saving exit/blocking/road information...");
3301 file = fopen(path,
"wb+");
3309 puts(
"Error: Could not save elevation world map due to not finding any minimum or maximum elevation.");
3313 elevationmap = gdImageCreateTrueColor(30*50, 30*50);;
3315 for (x = 0; x < 30*50; x++) {
3316 for (y = 0; y < 30*50; y++) {
3321 printf(
"Saving elevation world map...");
3323 file = fopen(path,
"wb+");
3327 gdImageDestroy(elevationmap);
3328 elevationmap = NULL;
3340 printf(
"Writing regions link file...");
3341 snprintf(path,
sizeof(path),
"%s/%s",
root,
"region_links.dot");
3342 file = fopen(path,
"wb+");
3343 fprintf(file,
"digraph {\n");
3346 fprintf(file,
"}\n");
3382 fprintf(file,
"%s", without);
3388 fprintf(file,
"%s", with);
3389 fprintf(file,
"<ul>\n");
3390 for (map = 0; map < info->
maps[item].
count; map++) {
3391 fprintf(file,
"\t<li>");
3393 fprintf(file,
"</li>\n");
3395 fprintf(file,
"</ul>\n");
3424 printf(
"Writing slaying info file...");
3428 snprintf(path,
sizeof(path),
"%s/%s",
root,
"slaying_info.html");
3429 file = fopen(path,
"wb+");
3431 fprintf(file,
"<html>\n<head>\n<title>Slaying information</title>\n</head>\n<body>\n");
3432 fprintf(file,
"<p>This is a list of various slaying fields on keys, containers, doors, detectors.</p>");
3435 info = slaying_info[lock];
3436 fprintf(file,
"<h1>%s</h1>\n", info->
slaying);
3439 fprintf(file,
"No door, container or detector matching this slaying.<br />\n");
3448 fprintf(file,
"</body>\n</html>\n");
3462 printf(
"Writing NPC info file...");
3466 snprintf(path,
sizeof(path),
"%s/%s",
root,
"npc_info.html");
3467 file = fopen(path,
"wb+");
3469 fprintf(file,
"<html>\n<head>\n<title>NPCs who have a special message</title>\n</head>\n<body>\n");
3470 fprintf(file,
"<p>This is a list of NPCs having a special message.</p>");
3471 fprintf(file,
"<ul>\n");
3473 for (map = 0; map < maps_list.
count; map++) {
3476 fprintf(file,
"<li>%s</li>\n<ul>", maps_list.
maps[map]->
path);
3477 for (npc = 0; npc < maps_list.
maps[map]->
npcs.
count; npc++) {
3480 fprintf(file,
"</ul>\n</li>\n");
3483 fprintf(file,
"</ul>\n");
3484 fprintf(file,
"</body>\n</html>\n");
3498 printf(
"Writing readable info file...");
3500 snprintf(path,
sizeof(path),
"%s/%s",
root,
"readable_info.html");
3501 file = fopen(path,
"wb+");
3503 fprintf(file,
"<html>\n<head>\n<title>SIGN and BOOK with a special message</title>\n</head>\n<body>\n");
3504 fprintf(file,
"<p>This is a list of SIGN and BOOK with a special message.</p>");
3505 fprintf(file,
"<ul>\n");
3507 for (map = 0; map < maps_list.
count; map++) {
3510 fprintf(file,
"<li>%s</li>\n<ul>", maps_list.
maps[map]->
path);
3511 for (readable = 0; readable < maps_list.
maps[map]->
readable.
count; readable++) {
3514 fprintf(file,
"</ul>\n</li>\n");
3517 fprintf(file,
"</ul>\n");
3518 fprintf(file,
"</body>\n</html>\n");
3531 printf(
"Crossfire Mapper will generate pictures of maps, and create indexes for all maps and regions.\n\n");
3532 printf(
"Syntax: %s\n\n", program);
3533 printf(
"Optional arguments:\n");
3534 printf(
" -nopics don't generate pictures.\n");
3535 printf(
" -noindex don't generate global map index.\n");
3536 printf(
" -root=<path> destination path. Default 'html'.\n");
3537 printf(
" -limit=<number> stop processing after this number of maps, -1 to do all maps (default).\n");
3538 printf(
" -showmaps outputs the name of maps as they are processed.\n");
3539 printf(
" -jpg[=quality] generate jpg pictures, instead of default png. Quality should be 0-95, -1 for automatic.\n");
3540 printf(
" -forcepics force to regenerate pics, even if pics's date is after map's.\n");
3541 printf(
" -addmap=<map> adds a map to process. Path is relative to map's directory root.\n");
3542 printf(
" -rawmaps generates maps pics without items on random (shop, treasure) tiles.\n");
3543 printf(
" -warnnopath inform when an exit has no path set.\n");
3544 printf(
" -listunusedmaps finds all unused maps in the maps directory.\n");
3545 printf(
" -noworldmap don't write the world map in world.png.\n");
3546 printf(
" -noregionslink don't generate regions relation file.\n");
3547 printf(
" -regionslink generate regions relation file.\n");
3548 printf(
" -noexitmap don't generate map of exits.\n");
3549 printf(
" -exitmap generate map of exits.\n");
3550 printf(
" -tileset=<number> use specified tileset to generate the pictures. Default 0 (standard).\n");
3569 while (arg < argc) {
3570 if (strcmp(argv[arg],
"-nopics") == 0)
3572 else if (strcmp(argv[arg],
"-noindex") == 0)
3574 else if (strncmp(argv[arg],
"-root=", 6) == 0)
3575 strncpy(
root, argv[arg]+6, 500);
3576 else if (strncmp(argv[arg],
"-limit=", 7) == 0)
3578 else if (strcmp(argv[arg],
"-showmaps") == 0)
3580 else if (strcmp(argv[arg],
"-jpg") == 0) {
3582 if (argv[arg][4] ==
'=') {
3588 else if (strcmp(argv[arg],
"-forcepics") == 0)
3590 else if (strncmp(argv[arg],
"-addmap=", 8) == 0) {
3591 if (*(argv[arg]+8) ==
'/')
3592 strncpy(path, argv[arg]+8, 500);
3594 snprintf(path, 500,
"/%s", argv[arg]+8);
3597 else if (strcmp(argv[arg],
"-rawmaps") == 0)
3599 else if (strcmp(argv[arg],
"-warnnopath") == 0)
3601 else if (strcmp(argv[arg],
"-listunusedmaps") == 0)
3603 else if (strcmp(argv[arg],
"-noworldmap") == 0)
3605 else if (strcmp(argv[arg],
"-noregionslink") == 0)
3607 else if (strcmp(argv[arg],
"-regionslink") == 0)
3609 else if (strcmp(argv[arg],
"-noexitmap") == 0)
3611 else if (strcmp(argv[arg],
"-exitmap") == 0)
3613 else if (strncmp(argv[arg],
"-tileset=", 9) == 0) {
3621 strcpy(
root,
"html");
3634 strcpy(dummy,
root);
3635 strcat(dummy,
"/a");
3648 return (value ?
"yes" :
"no");
3652 int current_map = 0, i;
3663 printf(
"Initializing Crossfire data...\n");
3683 printf(
"\n\n done.\n\n");
3686 printf(
"Erreor: invalid tileset %d!\n",
tileset);
3738 strcpy(max,
"(none)");
3739 printf(
"Crossfire map browser generator\n");
3740 printf(
"-------------------------------\n\n");
3741 printf(
"Parameters:\n");
3742 printf(
" path to write files: %s\n",
root);
3743 printf(
" maximum number of maps to process: %s\n", max);
3747 if (output_format ==
OF_JPG)
3761 printf(
"listing all maps...");
3768 infomap = gdImageCreateTrueColor(30*50, 30*50);
3775 for (i = 0; i < 50*30; i++)
3780 printf(
"browsing maps...\n");
3784 while (current_map < maps_list.
count) {
3786 if (current_map%100 == 0) {
3790 printf(
" --- map limit reached, stopping ---\n");
3795 printf(
" finished map parsing, %d maps processed, %d map pictures created, %d map pictures were uptodate. Total %d faces used.\n", current_map,
created_pics,
cached_pics,
pics_allocated);
3843 while ((invtmp->stats.hp--) > 0)
3845 invtmp->randomitems = NULL;
3848 && invtmp->type != TREASURE
3849 && invtmp->type != SPELL
3850 && invtmp->type != CLASS
3856 invtmp->randomitems = NULL;
3869 if (tmp->type == WAND
3871 || tmp->type == SCROLL
3872 || tmp->type == FIREWALL
3873 || tmp->type == POTION
3874 || tmp->type == ALTAR
3875 || tmp->type == SPELLBOOK)
3876 tmp->randomitems = NULL;
3881 else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) &&
HAS_RANDOM_ITEMS(tmp)) {
3882 while ((tmp->stats.hp--) > 0)
3884 tmp->randomitems = NULL;
3885 }
else if (tmp->type == TIMED_GATE) {
3886 object *head = HEAD(tmp);
3901 && tmp->type != PLAYER
3902 && tmp->type != TREASURE
3903 && tmp->type != SPELL
3904 && tmp->type != PLAYER_CHANGER
3905 && tmp->type != CLASS
3908 tmp->randomitems = NULL;
3916 && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3921 #ifndef DOXYGEN_SHOULD_SKIP_THIS 3928 fprintf(
logfile,
"%s\n", txt);
3934 va_start(ap, format);
3935 vfprintf(
logfile, format, ap);
3940 fprintf(
logfile,
"ext_info_map: %s\n", str1);
3991 while ((tmp =
generate_treasure(op->randomitems, op->stats.exp ? (
int)op->stats.exp :
MAX(op->map->difficulty, 5))) == NULL && --i)
4010 while ((op->stats.hp--) > 0)
4011 create_treasure(op->randomitems, op, 0, op->stats.exp ? (
int)op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
4020 if (op->env && tmp->type != BOOK)
struct struct_npc_info struct_npc_info
struct_map_in_quest_list quests
struct struct_equipment struct_equipment
object * find_skill_by_number(object *who, int skillno)
static void free_equipment(struct_equipment *equip)
static void find_maps(const char *from)
static int region_allocated
static int tiled_map_need_pic(struct_map_info *map)
static char * map_exit_to_template
static int dump(const std::set< std::string > &items, const char *name)
static char * level_map_template
static void init_map_list(struct_map_list *list)
static char * map_no_exit_to_template
static char * region_template
void object_free(object *ob, int flags)
static void process_map_lore(struct_map_info *map)
static char * region_letter_template
static int generate_index
static char * world_map_template
void esrv_update_spells(player *pl)
void object_give_identified_properties(object *op)
static int sort_mapname(const void *left, const void *right)
static char * map_lore_template
static char ** regions_link
struct struct_map_in_quest ** list
static struct_equipment ** special_equipment
void make_path_to_file(const char *filename)
static int compare_map_info(const struct_map_info *left, const struct_map_info *right)
struct_race_list monsters
static void write_tiled_maps(void)
static void add_map_to_region(struct_map_info *map, region *reg)
struct_map_list maps[S_MAX]
struct_map_list tiled_maps
static char * cat_template(char *source, char *add)
archetype * find_archetype(const char *name)
static int equipment_allocated
static void add_slaying(struct_map_info *map, object *item)
static struct_equipment * ensure_unique(struct_equipment *item)
char * create_pathname(const char *name, char *buf, size_t size)
static char * map_with_exit_template
StringBuffer * stringbuffer_new(void)
mapstruct * ready_map_name(const char *name, int flags)
static void write_maps_index(void)
static char * do_template(const char *template, const char **vars, const char **values)
void dragon_ability_gain(object *ob, int x, int y)
void rod_adjust(object *rod)
static char * map_with_quests_template
const char * object_get_value(const object *op, const char *const key)
static void write_maps_by_level(void)
static struct_slaying_info ** slaying_info
void set_darkness_map(mapstruct *m)
struct_map_info * mainmap
struct_map_in_quest_list maps
static void list_map(const char *path)
region * get_region_by_map(mapstruct *m)
static char * map_no_quest_template
static void init_npc_list(struct_npc_list *list)
static gdImagePtr infomap
DIR * opendir(const char *)
static void merge_tiled_maps(struct_map_info *map, int tile, struct_map_info *tiled_map)
static const char * output_extensions[]
int is_valid_faceset(int fsn)
static void save_picture(FILE *file, gdImagePtr pic)
static char * map_no_lore_template
static const char * yesno(int value)
static void do_help(const char *program)
face_sets * find_faceset(int id)
static void relative_path(const char *from, const char *to, char *result)
static void do_parameters(int argc, char **argv)
static int sort_slaying(const void *left, const void *right)
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
static int color_unlinked_exit
static void write_npc_list(void)
static struct struct_region_info ** regions
static void write_quests_page(void)
struct struct_race_list struct_race_list
static void fix_tiled_map_monsters(void)
static void process_map(struct_map_info *info)
static struct_race_list races
static int is_special_equipment(object *item)
static int regions_link_count
int main(int argc, char **argv)
struct struct_quest * quest
static void dump_unused_maps(void)
struct artifactstruct artifact
static int slaying_allocated
static char * quest_map_template
static void init_race_list(struct_race_list *list)
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
static int color_linked_exit
static void define_quest(const char *name, struct_map_info *mainmap, const char *description)
const char * get_region_longname(const region *r)
static void add_map_to_quest(struct_map_info *map, const char *name, const char *description)
static int sort_map_info(const void *left, const void *right)
void esrv_update_item(int flags, object *pl, object *op)
void object_free_drop_inventory(object *ob)
static int sort_struct_map_in_quest(const void *left, const void *right)
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
static void add_to_struct_map_in_quest_list(struct_map_in_quest_list *list, struct_map_in_quest *item)
static void write_map_page(struct_map_info *map)
void clean_tmp_files(void)
static void fix_exits_to_tiled_maps(void)
static char * map_monster_after_template
static int list_unused_maps
static char * level_value_template
static void write_slaying_info(void)
static char * index_template
static struct_map_info * create_map_info(void)
object * object_insert_in_ob(object *op, object *where)
static struct_map_list maps_list
static char * index_letter
static int pics_allocated
object * arch_to_object(archetype *at)
static int is_road(object *item)
static void write_one_slaying_info(FILE *file, struct_slaying_info *info, int item, const char *with, const char *without)
void apply_auto_fix(mapstruct *m)
#define FLAG_UNAGGRESSIVE
struct struct_quest struct_quest
static struct_slaying_info * get_slaying_struct(const char *slaying)
static char * index_region_template
struct struct_map_info * tiled_group
static char * map_monster_before_template
const artifact * find_artifact(const object *op, const char *name)
int strcasecmp(const char *s1, const char *s2)
region * get_region_struct(void)
void emergency_save(int x)
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
struct struct_map_info * tiles[4]
static char * map_monster_between_template
static void write_readable_list(void)
static void do_tiled_map_picture(struct_map_info *map)
static char * map_monster_one_template
static void write_equipment_index(void)
static int ** elevation_info
static char * index_region_region_template
#define FLAG_IS_A_TEMPLATE
static char * level_template
struct struct_npc_list struct_npc_list
static gdImagePtr * gdfaces
static enum output_format_type output_format
static void check_slaying_inventory(struct_map_info *map, object *item)
static void add_one_item(object *item, struct_map_info *map)
static char * world_template
static void fix_map_names(void)
char d_name[_MAX_FNAME+1]
static void add_monster(object *monster, struct_map_info *map)
#define QUERY_FLAG(xyz, p)
#define CLEAR_FLAG(xyz, p)
static int sortbyname(const void *a, const void *b)
static char * index_quest_template
static void add_map_to_slaying(struct_slaying_info *info, int item, struct_map_info *map)
static int regions_link_allocated
static void add_region_link(mapstruct *source, mapstruct *dest, const char *linkname)
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
static void create_destination(void)
static int sort_race(const void *a, const void *b)
static int sort_region(const void *left, const void *right)
static char * map_exit_template
void give_artifact_abilities(object *op, const object *artifact)
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *txt)
int calc_item_power(const object *op)
struct struct_map_in_quest struct_map_in_quest
static void write_all_regions(void)
void move_firewall(object *ob)
static void write_slaying_map_name(FILE *file, struct_map_info *map)
void esrv_send_item(object *ob, object *obx)
static char * map_template
struct_map_list maps_list
static const flag_definition flags[]
static char * region_map_template
static int sort_equipment(const void *a, const void *b)
static char * map_no_monster_template
int apply_auto(object *op)
static void write_regions_link(void)
struct struct_region_info struct_region_info
struct struct_race ** races
static void init_struct_map_in_quest_list(struct_map_in_quest_list *list)
static int do_regions_link
static void write_world_info(void)
static int equipment_count
static void check_equipment(object *item, struct_map_info *map)
static void write_all_maps(void)
struct dirent * readdir(DIR *)
void delete_map(mapstruct *m)
static const char * ignore_path[]
void esrv_del_item(player *pl, object *ob)
EXTERN char first_map_path[MAX_BUF]
static void fix_tiled_map(void)
static int get_elevation_color(int elevation, gdImagePtr elevationmap)
static void do_exit_map(mapstruct *map)
static struct_map_list tiled_map_list
object * identify(object *op)
static char * do_map_index(const char *dest, struct_map_list *maps_list, const char *template_page, const char *template_letter, const char *template_map, const char **vars, const char **values)
static struct_equipment * get_equipment(void)
static void read_template(const char *name, char **buffer)
static char * world_row_template
static char * map_one_quest_template
void LOG(LogLevel logLevel, const char *format,...)
struct struct_race struct_race
static struct_race * get_race(const char *name)
static int world_exit_info
EXTERN region * first_region
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
static struct_map_info * create_tiled_map(void)
static int color_blocking
struct struct_map_info ** maps
static char * map_no_exit_template
static char * map_with_exit_to_template
int get_face_fallback(int faceset, int imageno)
static int sort_map_info_by_level(const void *left, const void *right)
object * generate_treasure(treasurelist *t, int difficulty)
static int found_maps_count
static void write_world_map(void)
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
static char ** found_maps
static struct_map_info * get_map_info(const char *path)
static void add_race_to_list(struct_race *race, struct_race_list *list, int check)
static void write_race_index(void)
void do_auto_apply(mapstruct *m)
static void write_region_page(struct_region_info *reg)
static struct_npc_info * create_npc_info(const object *npc)
struct_map_list exits_from
static int is_blocking(object *item)
static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from)
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
static void write_tiled_map_page(struct_map_info *map)
void object_update_speed(object *op)
static struct_quest ** quests
static char * quest_template
static void add_map(struct_map_info *info, struct_map_list *list)
char * stringbuffer_finish(StringBuffer *sb)
static void add_npc_to_map(struct_npc_list *list, const object *npc)
static int is_slaying(object *item)
#define HAS_RANDOM_ITEMS(op)
#define FOR_INV_PREPARE(op_, it_)
void object_remove(object *op)
const char * get_region_msg(const region *r)
static struct_quest * get_quest_info(const char *name)
static int quests_allocated
static void write_region_index(void)
struct struct_map_info struct_map_info
static const char * ignore_name[]
static int found_maps_allocated