Crossfire Server, Trunk
mapper.c
Go to the documentation of this file.
1 /*
2  * Crossfire map browser generator.
3  *
4  * Author: Nicolas Weeger <nicolas.weeger@laposte.net>, (C) 2006, 2007, 2008.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
213 #include <ctype.h>
214 #include <errno.h>
215 #include <stdio.h>
216 #include <stdlib.h>
217 #include <string.h>
218 #include <strings.h>
219 #include <sys/stat.h>
220 #include <sys/types.h>
221 #include <time.h>
222 
223 #include "global.h"
224 #include "sproto.h"
225 #include "image.h"
226 #include "quest.h"
227 
228 #include <gd.h>
229 #include <gdfonts.h>
230 #include <gdfontl.h>
231 #include <gdfontg.h>
232 
233 static gdImagePtr *gdfaces;
234 
236 typedef struct struct_npc_info {
237  const char *name;
238  const char *message;
239  int x, y;
241 
243 typedef struct struct_npc_list {
245  int count;
248 
250 typedef struct struct_race_list {
251  struct struct_race **races;
252  int count;
253  int allocated;
255 
257 typedef struct {
259  int count;
262 
264 typedef struct {
266  int count;
269 
271 typedef struct struct_map_info {
272  char *path;
273  char *name;
274  char *filename;
275  char *lore;
281 
283 
285 
288 
290  int height, width;
292  struct struct_map_info *tiles[4];
294 
297 
300 
302 typedef struct struct_equipment {
303  char *name;
304  int power;
306  char *diff;
309 
312 static int equipment_count = 0;
314 static int equipment_allocated = 0;
318 typedef struct struct_race {
319  char *name;
320  int count;
322 } struct_race;
323 
332  list->races = NULL;
333  list->count = 0;
334  list->allocated = 0;
335 }
336 
348  if (check) {
349  int test;
350 
351  for (test = 0; test < list->count; test++) {
352  if (list->races[test] == race)
353  return;
354  }
355  }
356 
357  if (list->allocated == list->count) {
358  list->allocated += 50;
359  list->races = realloc(list->races, sizeof(struct_race *)*list->allocated);
360  }
361  list->races[list->count] = race;
362  list->count++;
363 }
364 
366 static char root[500];
367 
369 static int pics_allocated;
370 
371 /* Options */
372 static int generate_pics = 1;
373 static int force_pics = 0;
374 static int generate_index = 1;
375 static int sizes[] = {32, 16, 8, 4, 2};
376 static const int num_sizes = sizeof(sizes)/sizeof(int);
377 #define size_large sizes[0]
378 #define size_small sizes[1]
379 static int map_limit = -1;
380 static int show_maps = 0;
381 static int world_map = 1;
382 static int world_exit_info = 1;
383 static int tileset = 0;
384 static bool detail_quests = false;
385 static bool list_system_quests = false;
387 static char *world_template;
388 static char *world_row_template;
389 static char *world_map_template;
391 static char *map_template;
392 static char *map_no_exit_template;
394 static char *map_exit_template;
397 static char *map_exit_to_template;
398 static char *map_lore_template;
399 static char *map_no_lore_template;
406 static char *index_template;
407 static char *index_letter;
408 static char *index_map;
410 static char *region_template;
412 static char *region_map_template;
414 static char *index_region_template;
417 static char *level_template;
418 static char *level_value_template;
419 static char *level_map_template;
420 
421 static char *index_quest_template;
422 static char *quest_template;
423 static char *quest_map_template;
424 
428 
430 static int created_pics = 0;
431 static int cached_pics = 0;
435  OF_PNG = 0,
436  OF_JPG = 1
437 };
438 
440 static const char *output_extensions[] = {
441  ".png",
442  ".jpg"
443 };
444 
447 
449 static int jpeg_quality = -1;
450 
452 static int rawmaps = 0;
453 
455 static int warn_no_path = 0;
456 
458 typedef struct struct_region_info {
461  int sum_x, sum_y, sum;
462  int is_world;
464 
465 static struct struct_region_info **regions = NULL;
466 static int region_count = 0;
467 static int region_allocated = 0;
469 static int list_unused_maps = 0;
470 static char **found_maps = NULL;
471 static int found_maps_count = 0;
472 static int found_maps_allocated = 0;
474 /* Path/exit info */
475 static gdImagePtr infomap;
477 static int color_linked_exit;
478 static int color_road;
479 static int color_blocking;
480 static int color_slowing;
482 static int **elevation_info;
483 static int elevation_min;
484 static int elevation_max;
486 /* Links between regions */
487 static int do_regions_link = 0;
488 static char **regions_link;
489 static int regions_link_count = 0;
490 static int regions_link_allocated = 0;
491 
493 #define S_DOOR 0
494 #define S_KEY 1
495 #define S_CONTAINER 2
496 #define S_DETECTOR 3
497 #define S_CONNECT 4
498 #define S_MAX 5
499 
501 typedef struct {
502  char *slaying;
505 
507 static int slaying_count = 0;
508 static int slaying_allocated = 0;
516  list->maps = NULL;
517  list->count = 0;
518  list->allocated = 0;
519 }
520 
521 static void add_map(struct_map_info *info, struct_map_list *list);
522 
523 static int is_special_equipment(object *item) {
524  if (item->name == item->arch->clone.name && item->title == item->arch->clone.title)
525  return 0;
527  return 0;
528  if (item->move_block == MOVE_ALL)
529  return 0;
530 
531  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))
532  return 1;
533 
534  return 0;
535 }
536 
543  struct_equipment *add = calloc(1, sizeof(struct_equipment));
544 
545  init_map_list(&add->origin);
546  return add;
547 }
548 
555 static void free_equipment(struct_equipment *equip) {
556  free(equip->diff);
557  free(equip->name);
558  free(equip);
559 }
560 
570  int check;
571  struct_equipment *comp;
572 
573  for (check = 0; check < equipment_count; check++) {
574  comp = special_equipment[check];
575 
576  if (strcmp(comp->name, item->name))
577  continue;
578  if (comp->power != item->power)
579  continue;
580  if (comp->calc_power != item->calc_power)
581  continue;
582  if (strcmp(comp->diff, item->diff))
583  continue;
584 
586  return comp;
587  }
588 
590  equipment_allocated += 50;
592  }
594  equipment_count++;
595 
596  return item;
597 }
598 
608 static void add_one_item(object *item, struct_map_info *map) {
611  int x, y;
612  sstring name, namepl;
613  uint32_t nrof;
614  object *base;
615 
616  x = item->x;
617  y = item->y;
618  name = item->name;
619  namepl = item->name_pl;
620  nrof = item->nrof;
621 
622  if (item->artifact != NULL) {
623  const artifact *artifact;
624 
625  artifact = find_artifact(item, item->artifact);
626  if (artifact == NULL) {
627  LOG(llevError, "could not find artifact %s [%d] to save data\n", item->artifact, item->type);
628  base = arch_to_object(item->arch);
629  } else {
630  base = arch_to_object(item->arch);
632  }
633  }
634  else {
635  base = arch_to_object(item->arch);
636  }
637 
638  item->x = base->x;
639  item->y = base->y;
640  item->name = base->name;
641  item->name_pl = base->name_pl;
642  item->nrof = base->nrof;
643 
646  SET_FLAG(base, FLAG_IDENTIFIED);
647  }
649  SET_FLAG(base, FLAG_UNPAID);
650  get_ob_diff(bf, item, base);
651  object_free(base, FREE_OBJ_NO_DESTROY_CALLBACK | FREE_OBJ_FREE_INVENTORY);
652 
653  add->diff = stringbuffer_finish(bf);
654 
655  item->x = x;
656  item->y = y;
657  item->name = name;
658  item->name_pl = namepl;
659  item->nrof = nrof;
660 
661  if (add->diff == NULL || strcmp(add->diff, "") == 0) {
662  free_equipment(add);
663  return;
664  }
665 
666  add->name = strdup(item->name);
667  add->power = item->item_power;
669 
670  add = ensure_unique(add);
671  add_map(map, &add->origin);
672 }
673 
682 static void check_equipment(object *item, struct_map_info *map) {
685 
688  FOR_INV_FINISH();
689 }
690 
699 static int sort_equipment(const void *a, const void *b) {
700  const struct_equipment *l = *(const struct_equipment **)a;
701  const struct_equipment *r = *(const struct_equipment **)b;
702  int c = l->power-r->power;
703 
704  if (c)
705  return c;
706  return strcasecmp(l->name, r->name);
707 }
708 
717 static struct_race *get_race(const char *name) {
718  int test;
719  struct_race *item;
720 
721  for (test = 0; test < races.count; test++) {
722  if (strcmp(races.races[test]->name, name) == 0) {
723  races.races[test]->count++;
724  return races.races[test];
725  }
726  }
727 
728  item = calloc(1, sizeof(struct_race));
729  item->name = strdup(name);
730  item->count = 1;
731  init_map_list(&item->origin);
732 
734 
735  return item;
736 }
737 
746 static void add_monster(object *monster, struct_map_info *map) {
747  struct_race *race;
748 
749  if (monster->head && monster != monster->head)
750  return;
751 
752  map->min_monster = MIN(monster->level, map->min_monster);
753  map->max_monster = MAX(monster->level, map->max_monster);
754 
755  race = get_race(monster->name);
756  add_map(map, &race->origin);
757  add_race_to_list(race, &map->monsters, 1);
758 }
759 
768 static int sort_race(const void *a, const void *b) {
769  const struct_race *l = *(const struct_race **)a;
770  const struct_race *r = *(const struct_race **)b;
771  return strcasecmp(l->name, r->name);
772 }
773 
781 static int is_road(object *item) {
782  int test;
783  /* Archetypes used as roads. */
784  const char *roads[] = {
785  "cobblestones",
786  "flagstone",
787  "ice_stone",
788  "snow",
789  NULL };
790  const char *partial[] = {
791  "dirtroad_",
792  NULL };
793 
794  for (test = 0; partial[test] != NULL; test++) {
795  if (strstr(item->arch->name, partial[test]) != NULL)
796  return 1;
797  }
798 
800  return 0;
801 
802  for (test = 0; roads[test] != NULL; test++) {
803  if (strcmp(item->arch->name, roads[test]) == 0)
804  return 1;
805  }
806 
807  return 0;
808 }
809 
817 static int is_blocking(object *item) {
818  return item->move_block == MOVE_ALL ? 1 : 0;
819 }
820 
831 static int get_elevation_color(int elevation, gdImagePtr elevationmap) {
832  if (elevation > 0)
833  return gdImageColorResolve(elevationmap, 200*elevation/elevation_max, 0, 0);
834  else
835  return gdImageColorResolve(elevationmap, 0, 0, 200*elevation/elevation_min);
836 }
837 
846 static void do_exit_map(mapstruct *map) {
847  int tx, ty, x, y;
848  object *test;
849  sstring selevation;
850 
851  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) != 2)
852  return;
853 
854  x -= 100;
855  y -= 100;
856 
857  for (tx = 0; tx < MAP_WIDTH(map); tx++) {
858  for (ty = 0; ty < MAP_HEIGHT(map); ty++) {
859  FOR_MAP_PREPARE(map, tx, ty, item) {
860  test = HEAD(item);
861 
862  if (test->type == EXIT || test->type == TELEPORTER) {
863  if (!test->slaying)
864  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_unlinked_exit);
865  else
866  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_linked_exit);
867  } else if (is_road(test))
868  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_road);
869  else if (is_blocking(test)) {
870  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_blocking);
871  /* can't get on the spot, so no need to go on. */
872  break;
873  } else if (test->move_slow != 0)
874  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_slowing);
875 
876  selevation = object_get_value(item, "elevation");
877  if (selevation) {
878  int32_t elevation = atoi(selevation);
879  elevation_min = MIN(elevation_min, elevation);
880  elevation_max = MAX(elevation_max, elevation);
881  elevation_info[x*50+tx][y*50+ty] = elevation;
882  }
883  } FOR_MAP_FINISH();
884  }
885  }
886 }
887 
888 void do_auto_apply(mapstruct *m);
889 
900 static int sortbyname(const void *a, const void *b) {
901  return (strcmp(*(const char **)a, *(const char **)b));
902 }
903 
914 static char *cat_template(char *source, char *add) {
915  if (!source)
916  return add;
917  source = realloc(source, strlen(source)+strlen(add)+1);
918  strcat(source, add);
919  free(add);
920  return source;
921 }
922 
933 static void read_template(const char *name, char **buffer) {
934  FILE *file;
935  struct stat info;
936 
937  if (stat(name, &info)) {
938  printf("Couldn't stat template %s!\n", name);
939  exit(1);
940  }
941 
942  (*buffer) = calloc(1, info.st_size+1);
943  if (!(*buffer)) {
944  printf("Template %s calloc failed!\n", name);
945  exit(1);
946  }
947 
948  if (info.st_size == 0) {
949  (*buffer)[0] = '\0';
950  return;
951  }
952 
953  file = fopen(name, "rb");
954  if (!file) {
955  printf("Couldn't open template %s!\n", name);
956  free(*buffer);
957  exit(1);
958  }
959  if (fread(*buffer, info.st_size, 1, file) != 1) {
960  printf("Couldn't read template %s!\n", name);
961  free(*buffer);
962  fclose(file);
963  exit(1);
964  }
965  fclose(file);
966 }
967 
985 static char *do_template(const char *template, const char **vars, const char **values) {
986  int count = 0;
987  const char *sharp = template;
988  int maxlen = 0;
989  int var = 0;
990  char *result;
991  char *current_result;
992  const char *end;
993 
994  while ((sharp = strchr(sharp, '#')) != NULL) {
995  sharp++;
996  count++;
997  }
998  if (!count)
999  return strdup(template);
1000  if (count%2) {
1001  printf("Malformed template, mismatched #!\n");
1002  return strdup(template);
1003  }
1004 
1005  while (vars[var] != NULL) {
1006  if (strlen(values[var]) > maxlen)
1007  maxlen = strlen(values[var]);
1008  var++;
1009  }
1010  result = calloc(1, strlen(template)+maxlen*(count/2)+1);
1011  if (!result)
1012  return NULL;
1013  current_result = result;
1014 
1015  sharp = template;
1016  while ((sharp = strchr(sharp, '#')) != NULL) {
1017  end = strchr(sharp+1, '#');
1018  strncpy(current_result, template, sharp-template);
1019  if (end == sharp+1) {
1020  strcat(current_result, "#");
1021  }
1022  else {
1023  current_result = current_result+strlen(current_result);
1024  var = 0;
1025  while (vars[var] != NULL && (strncmp(vars[var], sharp+1, end-sharp-1) || (strlen(vars[var]) != end-sharp-1)))
1026  /* tag must be the same length, else can take a wrong tag */
1027  var++;
1028  if (vars[var] == NULL)
1029  printf("Wrong tag: %s\n", sharp);
1030  else
1031  strcpy(current_result, values[var]);
1032  }
1033  current_result = current_result+strlen(current_result);
1034  sharp = end+1;
1035  template = sharp;
1036  }
1037  strcat(current_result, template);
1038  return result;
1039 }
1040 
1053 static void relative_path(const char *from, const char *to, char *result) {
1054  const char *fslash;
1055  const char *rslash;
1056 
1057  result[0] = '\0';
1058 
1059  fslash = strchr(from+1, '/');
1060  if (!fslash) {
1061  strcpy(result, to+1);
1062  return;
1063  }
1064 
1065  rslash = strchr(to+1, '/');
1066  while (fslash && rslash && (fslash-from == rslash-to) && strncmp(from, to, fslash-from+1) == 0) {
1067  from = fslash+1;
1068  to = rslash+1;
1069  fslash = strchr(fslash+1, '/');
1070  rslash = strchr(rslash+1, '/');
1071  }
1072 
1073  while (fslash) {
1074  strcat(result, "../");
1075  fslash = strchr(fslash+1, '/');
1076  }
1077  if (strlen(result) && result[strlen(result)-1] == '/' && *to == '/')
1078  result[strlen(result)-1] = '\0';
1079  strcat(result, to);
1080 }
1081 
1092 static int sort_mapname(const void *left, const void *right) {
1093  const char *l = *(const char **)left;
1094  const char *r = *(const char **)right;
1095  const char *sl = strrchr(l, '/');
1096  const char *sr = strrchr(r, '/');
1097  int c;
1098 
1099  if (!sl)
1100  sl = l;
1101  if (!sr)
1102  sr = r;
1103  c = strcasecmp(sl, sr);
1104  if (c)
1105  return c;
1106 
1107  return strcasecmp(l, r);
1108 }
1109 
1120 static int compare_map_info(const struct_map_info *left, const struct_map_info *right) {
1121  int c;
1122 
1123  if (left->tiled_group)
1124  left = left->tiled_group;
1125  if (right->tiled_group)
1126  right = right->tiled_group;
1127 
1128  c = strcasecmp(left->name, right->name);
1129  if (c)
1130  return c;
1131 
1132  return strcasecmp(left->path, right->path);
1133 }
1134 
1145 static int sort_map_info(const void *left, const void *right) {
1146  const struct_map_info *l = *(const struct_map_info **)left;
1147  const struct_map_info *r = *(const struct_map_info **)right;
1148  return compare_map_info(l, r);
1149 }
1150 
1161 static int sort_map_info_by_level(const void *left, const void *right) {
1162  const struct_map_info *l = *(const struct_map_info **)left;
1163  const struct_map_info *r = *(const struct_map_info **)right;
1164  int c = l->level-r->level;
1165  if (c)
1166  return c;
1167  return compare_map_info(l, r);
1168 }
1169 
1180 static int sort_region(const void *left, const void *right) {
1181  return strcmp((*((struct_region_info **)left))->reg->name, (*((struct_region_info **)right))->reg->name);
1182 }
1183 
1184 /************************************
1185  Start of quest-related definitions.
1186 ************************************/
1187 
1189 typedef struct struct_map_in_quest {
1190  struct_map_info *map;
1191  char *description;
1196 typedef struct struct_quest {
1197  char *name;
1198  char *description;
1199  int number;
1202 } struct_quest;
1203 
1204 static struct_quest **quests = NULL;
1206 static int quests_count = 0;
1208 static int quests_allocated = 0;
1211  list->list = NULL;
1212  list->count = 0;
1213  list->allocated = 0;
1214 }
1215 
1217  if (list->count == list->allocated) {
1218  list->allocated += 10;
1219  list->list = realloc(list->list, sizeof(struct_map_in_quest *)*list->allocated);
1220  }
1221  list->list[list->count++] = item;
1222 }
1223 
1229 static struct_quest *find_quest_info(const char *name) {
1230  int test;
1231  for (test = 0; test < quests_count; test++) {
1232  if (strcmp(quests[test]->name, name) == 0)
1233  return quests[test];
1234  }
1235  return NULL;
1236 }
1237 
1246 static struct_quest *get_quest_info(const char *name) {
1248  if (add) {
1249  return add;
1250  }
1251 
1252  if (quests_count == quests_allocated) {
1253  quests_allocated += 10;
1254  quests = realloc(quests, sizeof(struct_quest *)*quests_allocated);
1255  }
1256  add = calloc(1, sizeof(struct_quest));
1257  add->name = strdup(name);
1258  add->number = quests_count;
1260  quests[quests_count] = add;
1261  quests_count++;
1262  return add;
1263 }
1264 
1275 static void add_map_to_quest(struct_map_info *map, const char *name, const char *description) {
1276  struct_map_in_quest *add;
1278 
1279  add = calloc(1, sizeof(struct_map_in_quest));
1280  add->map = map;
1281  add->quest = quest;
1282  add->description = strdup(description);
1283  while (strlen(add->description) && add->description[strlen(add->description)-1] == '\n')
1284  add->description[strlen(add->description)-1] = '\0';
1286  add_to_struct_map_in_quest_list(&map->quests, add);
1287 }
1288 
1297 static int sort_struct_map_in_quest(const void *left, const void *right) {
1298  int c;
1299 
1300  const struct_map_in_quest *l = *(const struct_map_in_quest **)left;
1301  const struct_map_in_quest *r = *(const struct_map_in_quest **)right;
1302  const struct_map_info *ml = l->map;
1303  const struct_map_info *mr = r->map;
1304 
1305  if (ml->tiled_group)
1306  ml = ml->tiled_group;
1307  if (mr->tiled_group)
1308  mr = mr->tiled_group;
1309 
1310  c = strcasecmp(ml->name, mr->name);
1311  if (c)
1312  return c;
1313 
1314  return strcasecmp(ml->path, mr->path);
1315 }
1316 
1327 static void define_quest(const char *name, struct_map_info *mainmap, const char *description) {
1329 
1330  if (quest->description || quest->mainmap) {
1331  printf("warning, multiple quest definition for %s, found in %s and %s.\n", quest->name, quest->mainmap ? quest->mainmap->path : "(unknown map)", mainmap->path);
1332  return;
1333  }
1334  quest->description = strdup(description);
1335  while (strlen(quest->description) && quest->description[strlen(quest->description)-1] == '\n')
1336  quest->description[strlen(quest->description)-1] = '\0';
1337  quest->mainmap = mainmap;
1338 }
1339 
1347  char *start, *end, *next;
1348  char name[500];
1349  char description[500];
1350 
1351  start = strstr(map->lore, "@def");
1352  while (start) {
1353  description[0] = '\0';
1354  /* find name */
1355  end = strstr(start, "\n");
1356  if (end) {
1357  strncpy(name, start+5, end-start-5);
1358  name[end-start-5] = '\0';
1359  next = end+1;
1360  end = strstr(next, "@end");
1361  if (end) {
1362  strncpy(description, next, end-next);
1363  description[end-next] = '\0';
1364  /* need to erase the text. */
1365  memcpy(start, end+4, strlen(map->lore)-(end-start+3));
1366  end = start;
1367  }
1368  else {
1369  strcpy(description, next);
1370  *start = '\0';
1371  end = NULL;
1372  }
1373  } else {
1374  strcpy(name, start);
1375  *start = '\0';
1376  end = NULL;
1377  }
1378 
1379  define_quest(name, map, description);
1380  start = end ? strstr(end, "@def") : NULL;
1381  }
1382 
1383  start = strstr(map->lore, "@quest");
1384  while (start) {
1385  description[0] = '\0';
1386  /* find name */
1387  end = strstr(start, "\n");
1388  if (end) {
1389  strncpy(name, start+7, end-start-7);
1390  name[end-start-7] = '\0';
1391  next = end+1;
1392  end = strstr(next, "@end");
1393  if (end) {
1394  strncpy(description, next, end-next);
1395  description[end-next] = '\0';
1396  /* need to erase the text. */
1397  memcpy(start, end+4, strlen(map->lore)-(end-start+3));
1398  end = start;
1399  }
1400  else {
1401  strcpy(description, next);
1402  *start = '\0';
1403  end = NULL;
1404  }
1405  } else {
1406  strcpy(name, start);
1407  *start = '\0';
1408  end = NULL;
1409  }
1410 
1411  add_map_to_quest(map, name, description);
1412  start = end ? strstr(end, "@quest") : NULL;
1413  }
1414 }
1415 
1419 static void write_quests_page(void) {
1420  int quest, map;
1421  FILE *out;
1422  char path[500];
1423  char mappath[500];
1424  char mainmappath[500];
1425  char questid[500];
1426  const char *map_vars[] = { "MAPPATH", "MAPNAME", "MAPTEXT", NULL };
1427  const char *map_vals[] = { mappath, NULL, NULL, NULL };
1428  const char *quest_vars[] = { "QUESTNAME", "QUESTTEXT", "QUESTMAPS", "QUESTID", "MAINMAPPATH", "MAINMAPNAME", NULL };
1429  const char *quest_vals[] = { NULL, NULL, NULL, questid, mainmappath, NULL, NULL };
1430  const char *idx_vars[] = { "QUESTS", NULL };
1431  const char *idx_vals[] = { NULL, NULL };
1432  char *text_map = NULL;
1433  char *text_quest = NULL;
1434  char *text_idx = NULL;
1435 
1436  printf("Writing quest index...");
1437 
1438  for (quest = 0; quest < quests_count; quest++) {
1440  for (map = 0; map < quests[quest]->maps.count; map++) {
1441  snprintf(mappath, sizeof(mappath), "%s.html", quests[quest]->maps.list[map]->map->path+1);
1442  map_vals[1] = quests[quest]->maps.list[map]->map->name;
1443  map_vals[2] = quests[quest]->maps.list[map]->description ? quests[quest]->maps.list[map]->description : "(no description)";
1444  text_map = cat_template(text_map, do_template(quest_map_template, map_vars, map_vals));
1445  }
1446  if (!text_map)
1447  text_map = strdup("");
1448 
1449  quest_vals[0] = quests[quest]->name;
1450  quest_vals[1] = quests[quest]->description ? quests[quest]->description : "(main map not processed)";
1451  quest_vals[2] = text_map;
1452  snprintf(questid, sizeof(questid), "quest_%d", quests[quest]->number);
1453  if (quests[quest]->mainmap) {
1454  snprintf(mainmappath, sizeof(mainmappath), "%s.html", quests[quest]->mainmap->path+1);
1455  quest_vals[5] = quests[quest]->mainmap->name;
1456  } else {
1457  snprintf(mainmappath, sizeof(mainmappath), "#");
1458  quest_vals[5] = "";
1459  }
1460  text_quest = cat_template(text_quest, do_template(quest_template, quest_vars, quest_vals));
1461  free(text_map);
1462  text_map = NULL;
1463  }
1464 
1465  if (!text_quest)
1466  text_quest = strdup("No quest.");
1467 
1468  idx_vals[0] = text_quest;
1469  text_idx = do_template(index_quest_template, idx_vars, idx_vals);
1470  free(text_quest);
1471 
1472  snprintf(path, sizeof(path), "%s/quests.html", root);
1473  out = fopen(path, "w+");
1474  fprintf(out, "%s", text_idx);
1475  fclose(out);
1476  free(text_idx);
1477 
1478  printf(" done.\n");
1479 }
1480 
1481 /************************************
1482  End of quest-related definitions.
1483 ************************************/
1484 
1485 /*********
1486 NPC-related stuff
1487 ********/
1488 
1495  list->allocated = 0;
1496  list->count = 0;
1497  list->npc = NULL;
1498 }
1499 
1507 static struct_npc_info *create_npc_info(const object *npc) {
1508  struct_npc_info *info = calloc(1, sizeof(struct_npc_info));
1509 
1510  info->name = strdup(npc->name);
1511  info->message = strdup(npc->msg);
1512  info->x = npc->x;
1513  info->y = npc->y;
1514 
1515  return info;
1516 }
1517 
1525 static void add_npc_to_map(struct_npc_list *list, const object *npc) {
1526  if (list->count == list->allocated) {
1527  list->allocated += 50;
1528  list->npc = realloc(list->npc, list->allocated*sizeof(struct_npc_info *));
1529  }
1530 
1531  list->npc[list->count] = create_npc_info(npc);
1532  list->count++;
1533 }
1534 /* end of NPC stuff */
1535 
1548  int map;
1549 
1550  for (map = 0; map < list->count; map++)
1551  if (list->maps[map] == info)
1552  return;
1553 
1554  if (list->count == list->allocated) {
1555  list->allocated += 50;
1556  list->maps = realloc(list->maps, list->allocated*sizeof(struct_map_info *));
1557  }
1558  list->maps[list->count] = info;
1559  list->count++;
1560 }
1561 
1569  struct_map_info *add = calloc(1, sizeof(struct_map_info));
1570 
1571  add->min_monster = 2000;
1572  init_map_list(&add->exits_to);
1573  init_map_list(&add->exits_from);
1574  init_map_list(&add->tiled_maps);
1576  init_race_list(&add->monsters);
1577  init_npc_list(&add->npcs);
1578  init_npc_list(&add->readable);
1579  add->tiled_group = NULL;
1580 
1581  return add;
1582 }
1583 
1592 
1593  add_map(add, &tiled_map_list);
1594  return add;
1595 }
1596 
1608 static void merge_tiled_maps(struct_map_info *map, int tile, struct_map_info *tiled_map) {
1609  int g;
1610  struct_map_info *group = tiled_map->tiled_group;
1611  struct_map_info *change;
1612 
1613  while (group->tiled_maps.count > 0) {
1614  change = group->tiled_maps.maps[group->tiled_maps.count-1];
1615  change->tiled_group = map->tiled_group;
1616  add_map(change, &map->tiled_group->tiled_maps);
1617  group->tiled_maps.count--;
1618  }
1619 
1620  for (g = 0; g < tiled_map_list.count; g++) {
1621  if (tiled_map_list.maps[g] == group) {
1622  if (g < tiled_map_list.count-1)
1625  free(group);
1626  return;
1627  }
1628  }
1629  printf("tiled_map not in tiled_map_list!");
1630  abort();
1631 
1632 }
1633 
1642 static struct_map_info *get_map_info(const char *path) {
1643  int map;
1644  struct_map_info *add;
1645  char *tmp;
1646 
1647  for (map = 0; map < maps_list.count; map++) {
1648  if (strcmp(maps_list.maps[map]->path, path) == 0)
1649  return maps_list.maps[map];
1650  }
1651 
1652  add = create_map_info();
1653  add->path = strdup(path);
1654  tmp = strrchr(path, '/');
1655  if (tmp)
1656  add->filename = strdup(tmp+1);
1657  else
1658  add->filename = strdup(path);
1659 
1660  add_map(add, &maps_list);
1661  return add;
1662 }
1663 
1670 static void list_map(const char *path) {
1671  int index;
1672 
1673  for (index = 0; index < found_maps_count; index++) {
1674  if (found_maps[index] && strcmp(path, found_maps[index]) == 0) {
1675  free(found_maps[index]);
1676  found_maps[index] = NULL;
1677  return;
1678  }
1679  }
1680  printf("Map processed but not found in directory reading? %s\n", path);
1681 }
1682 
1694  int test;
1695  int x, y;
1696 
1697  for (test = 0; test < region_count; test++) {
1698  if (regions[test]->reg == reg)
1699  break;
1700  }
1701  if (test == region_count) {
1702  if (test == region_allocated) {
1703  region_allocated++;
1704  regions = realloc(regions, sizeof(struct_region_info *)*region_allocated);
1705  regions[test] = calloc(1, sizeof(struct_region_info));
1706  }
1707  region_count++;
1708  regions[test]->reg = reg;
1709  }
1710  add_map(map, &regions[test]->maps_list);
1711  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) == 2) {
1712  regions[test]->sum_x += (x-100);
1713  regions[test]->sum_y += (y-100);
1714  regions[test]->sum++;
1715  regions[test]->is_world = 1;
1716  }
1717 }
1718 
1727 static void save_picture(FILE *file, gdImagePtr pic) {
1728  if (output_format == OF_PNG)
1729  gdImagePng(pic, file);
1730  else
1731  gdImageJpeg(pic, file, jpeg_quality);
1732 }
1733 
1743 static void add_region_link(mapstruct *source, mapstruct *dest, const char *linkname) {
1744  int search = 0;
1745  char entry[500];
1746  region *s, *d;
1747 
1748  s = get_region_by_map(source);
1749  d = get_region_by_map(dest);
1750  if (s == d)
1751  return;
1752 
1753  if (linkname && 0)
1754  snprintf(entry, sizeof(entry), "%s -> %s [ label = \"%s\" ]\n", s->name, d->name, linkname);
1755  else
1756  snprintf(entry, sizeof(entry), "%s -> %s\n", s->name, d->name);
1757 
1758  for (search = 0; search < regions_link_count; search++) {
1759  if (strcmp(regions_link[search], entry) == 0)
1760  return;
1761  }
1762 
1764  regions_link_allocated += 10;
1765  regions_link = realloc(regions_link, sizeof(const char *)*regions_link_allocated);
1766  }
1769 }
1770 
1779 static int is_slaying(object *item) {
1780  return (item->type == LOCKED_DOOR || item->type == SPECIAL_KEY || item->type == CONTAINER || item->type == CHECK_INV);
1781 }
1782 
1783 
1792 static struct_slaying_info *get_slaying_struct(const char *slaying) {
1793  struct_slaying_info *add;
1794  int l;
1795 
1796  for (l = 0; l < slaying_count; l++) {
1797  if (!strcmp(slaying_info[l]->slaying, slaying))
1798  return slaying_info[l];
1799  }
1801  slaying_allocated += 10;
1803  }
1804 
1805  add = (struct_slaying_info *)calloc(1, sizeof(struct_slaying_info));
1806  add->slaying = strdup(slaying);
1807  for (l = 0; l < S_MAX; l++)
1808  init_map_list(&add->maps[l]);
1809 
1810  slaying_info[slaying_count] = add;
1811  slaying_count++;
1812 
1813  return add;
1814 }
1815 
1827  add_map(map, &info->maps[item]);
1828 }
1829 
1838 static void add_slaying(struct_map_info *map, object *item) {
1839  struct_slaying_info *info;
1840 
1841  if (!item->slaying)
1842  /* can be undefined */
1843  return;
1844 
1845  info = get_slaying_struct(item->slaying);
1846  if (item->type == LOCKED_DOOR)
1847  add_map_to_slaying(info, S_DOOR, map);
1848  else if (item->type == SPECIAL_KEY)
1849  add_map_to_slaying(info, S_KEY, map);
1850  else if (item->type == CONTAINER)
1852  else
1854 }
1855 
1866  if (is_slaying(inv))
1867  add_slaying(map, inv);
1869  } FOR_INV_FINISH();
1870 }
1871 
1880 static void process_map(struct_map_info *info) {
1881  mapstruct *m;
1882  int x, y, isworld;
1883  FILE *out;
1884  gdImagePtr pic;
1885  gdImagePtr small;
1886  struct stat stats;
1887  struct stat statspic;
1888  char exit_path[500];
1889  char tmppath[MAX_BUF];
1890  char picpath[num_sizes][MAX_BUF];
1891  int needpic = 0;
1892  struct_map_info *link;
1893 
1894  if (list_unused_maps)
1895  list_map(info->path);
1896 
1897  if (show_maps)
1898  printf(" processing map %s\n", info->path);
1899 
1900  m = ready_map_name(info->path, 0);
1901  if (!m) {
1902  printf("couldn't load map %s\n", info->path);
1903  return;
1904  }
1905 
1906  do_exit_map(m);
1907 
1908  if (!rawmaps)
1909  do_auto_apply(m);
1910 
1911  info->level = m->difficulty;
1912  if (m->maplore) {
1913  info->lore = strdup(m->maplore);
1914  process_map_lore(info);
1915  }
1916 
1917  isworld = (sscanf(info->path, "/world/world_%d_%d", &x, &y) == 2);
1918 
1919  if (m->name)
1920  info->name = strdup(m->name);
1921  else
1922  info->name = strdup(info->filename);
1923 
1924  info->cfregion = get_region_by_map(m);
1925  add_map_to_region(info, info->cfregion);
1926 
1927  for (int i = 0; i < num_sizes; i++) {
1928  snprintf(picpath[i], sizeof(picpath[i]), "%s%s.x%d%s", root, info->path, i+1, output_extensions[output_format]);
1929  }
1930 
1931  if (force_pics)
1932  needpic = 1;
1933  else if (generate_pics) {
1934  create_pathname(info->path, tmppath, MAX_BUF);
1935  stat(tmppath, &stats);
1936  if (stat(picpath[0], &statspic) || (statspic.st_mtime < stats.st_mtime))
1937  needpic = 1;
1938  }
1939  else
1940  needpic = 0;
1941 
1942  if (needpic) {
1943  pic = gdImageCreateTrueColor(MAP_WIDTH(m)*size_large, MAP_HEIGHT(m)*size_large);
1944  created_pics++;
1945  }
1946  else
1947  cached_pics++;
1948 
1949  for (x = 0; x < 4; x++)
1950  if (m->tile_path[x] != NULL) {
1951  path_combine_and_normalize(m->path, m->tile_path[x], exit_path, sizeof(exit_path));
1952  create_pathname(exit_path, tmppath, MAX_BUF);
1953  if (stat(tmppath, &stats)) {
1954  printf(" map %s doesn't exist in map %s, for tile %d.\n", exit_path, info->path, x);
1955  }
1956 
1957  if (isworld) {
1958  link = get_map_info(exit_path);
1959  add_map(link, &info->exits_from);
1960  add_map(info, &link->exits_to);
1961 
1962  if (do_regions_link) {
1963  mapstruct *link = ready_map_name(exit_path, 0);
1964 
1965  if (link && link != m) {
1966  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
1967  * want to reset it. */
1968  add_region_link(m, link, NULL);
1969  link->reset_time = 1;
1970  link->in_memory = MAP_IN_MEMORY;
1971  delete_map(link);
1972  }
1973  }
1974  } else {
1975  link = get_map_info(exit_path);
1976  info->tiles[x] = link;
1977  if (link->tiled_group) {
1978  if (info->tiled_group && link->tiled_group != info->tiled_group) {
1979  merge_tiled_maps(info, x, link);
1980  continue;
1981  }
1982  if (link->tiled_group == info->tiled_group) {
1983  continue;
1984  }
1985  if (!info->tiled_group) {
1986  add_map(info, &link->tiled_group->tiled_maps);
1987  continue;
1988  }
1989  }
1990 
1991  if (!info->tiled_group) {
1992  info->tiled_group = create_tiled_map();
1993  add_map(info, &info->tiled_group->tiled_maps);
1994  }
1995  link->tiled_group = info->tiled_group;
1996  add_map(link, &info->tiled_group->tiled_maps);
1997  }
1998  }
1999 
2000  info->width = MAP_WIDTH(m);
2001  info->height = MAP_HEIGHT(m);
2002 
2003  for (x = MAP_WIDTH(m)-1; x >= 0; x--)
2004  for (y = MAP_HEIGHT(m)-1; y >= 0; y--) {
2005  FOR_MAP_PREPARE(m, x, y, item) {
2006  if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
2007  char ep[500];
2008  const char *start;
2009 
2010  if (!item->slaying) {
2011  ep[0] = '\0';
2012  if (warn_no_path)
2013  printf(" exit without any path at %d, %d on %s\n", item->x, item->y, info->path);
2014  } else {
2015  memset(ep, 0, 500);
2016  if (strcmp(item->slaying, "/!"))
2017  strcpy(ep, EXIT_PATH(item));
2018  else {
2019  if (!item->msg) {
2020  printf(" random map without message in %s at %d, %d\n", info->path, item->x, item->y);
2021  } else {
2022  /* Some maps have a 'exit_on_final_map' flag, ignore it. */
2023  start = strstr(item->msg, "\nfinal_map ");
2024  if (!start && strncmp(item->msg, "final_map", strlen("final_map")) == 0)
2025  /* Message start is final_map, nice */
2026  start = item->msg;
2027  if (start) {
2028  char *end = strchr(start+1, '\n');
2029 
2030  start += strlen("final_map")+2;
2031  strncpy(ep, start, end-start);
2032  }
2033  }
2034  }
2035 
2036  if (strlen(ep)) {
2037  path_combine_and_normalize(m->path, ep, exit_path, 500);
2038  create_pathname(exit_path, tmppath, MAX_BUF);
2039  if (stat(tmppath, &stats)) {
2040  printf(" map %s doesn't exist in map %s, at %d, %d.\n", ep, info->path, item->x, item->y);
2041  } else {
2042  link = get_map_info(exit_path);
2043  add_map(link, &info->exits_from);
2044  add_map(info, &link->exits_to);
2045 
2046  if (do_regions_link) {
2047  mapstruct *link = ready_map_name(exit_path, 0);
2048 
2049  if (link && link != m) {
2050  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
2051  * want to reset it. */
2052  add_region_link(m, link, item->arch->clone.name);
2053  link->reset_time = 1;
2054  link->in_memory = MAP_IN_MEMORY;
2055  delete_map(link);
2056  }
2057  }
2058  }
2059  }
2060  }
2061  } else if (is_slaying(item))
2062  add_slaying(info, item);
2063 
2064  check_equipment(item, info);
2065 
2067 
2068  if (QUERY_FLAG(item, FLAG_MONSTER)) {
2069  /* need to get the "real" archetype, as the item's archetype can certainly be a temporary one. */
2070  archetype *arch = find_archetype(item->arch->name);
2071 
2072  add_monster(item, info);
2073  if (arch != NULL && (QUERY_FLAG(item, FLAG_UNAGGRESSIVE) || QUERY_FLAG(item, FLAG_FRIENDLY)) && (item->msg != arch->clone.msg) && (item->msg != NULL))
2074  add_npc_to_map(&info->npcs, item);
2075  } else if ((item->type == SIGN || item->type == BOOK) && (item->msg != item->arch->clone.msg) && (item->msg != NULL)) {
2076  add_npc_to_map(&info->readable, item);
2077  }
2078 
2079  if (item->invisible)
2080  continue;
2081 
2082  if (needpic) {
2083  int sx, sy, hx, hy;
2084 
2085  if (gdfaces[item->face->number] == NULL) {
2086  face_sets *fs = find_faceset(get_face_fallback(tileset, item->face->number));
2087 
2088  gdfaces[item->face->number] = gdImageCreateFromPngPtr(fs->faces[item->face->number].datalen, fs->faces[item->face->number].data);
2089  pics_allocated++;
2090  }
2091  if (item->head || item->more) {
2092  object_get_multi_size(item, &sx, &sy, &hx, &hy);
2093  } else {
2094  hx = 0;
2095  hy = 0;
2096  }
2097  if (gdfaces[item->face->number] != NULL && ((!item->head && !item->more) || (item->arch->clone.x+hx == 0 && item->arch->clone.y+hy == 0))) {
2098  gdImageCopy(pic, gdfaces[item->face->number], x*size_large, y*size_large, 0, 0, gdfaces[item->face->number]->sx, gdfaces[item->face->number]->sy);
2099  }
2100  }
2101  } FOR_MAP_FINISH();
2102  }
2103 
2104  if (needpic) {
2105  make_path_to_file(picpath[0]);
2106  out = fopen(picpath[0], "wb+");
2107  save_picture(out, pic);
2108  fclose(out);
2109 
2110  for (int i = 1; i < num_sizes; i++) {
2111  small = gdImageCreateTrueColor(MAP_WIDTH(m)*sizes[i], MAP_HEIGHT(m)*sizes[i]);
2112  gdImageCopyResampled(small, pic, 0, 0, 0, 0, MAP_WIDTH(m)*sizes[i], MAP_HEIGHT(m)*sizes[i], MAP_WIDTH(m)*size_large, MAP_HEIGHT(m)*size_large);
2113  out = fopen(picpath[i], "wb+");
2114  save_picture(out, small);
2115  fclose(out);
2116  gdImageDestroy(small);
2117  }
2118 
2119  gdImageDestroy(pic);
2120  info->pic_was_done = 1;
2121  }
2122 
2123  m->reset_time = 1;
2124  m->in_memory = MAP_IN_MEMORY;
2125  delete_map(m);
2126 }
2127 
2148 static char *do_map_index(const char *dest, struct_map_list *maps_list,
2149  const char *template_page, const char *template_letter,
2150  const char *template_map, const char **vars,
2151  const char **values) {
2152 #define VARSADD 6
2153  int map;
2154  char *string;
2155  char mappath[500];
2156  char maphtml[500];
2157  char count[50];
2158  char lettercount[50];
2159  char *tmp;
2160  const char **idx_vars;
2161  const char **idx_values;
2162  char str_letter[2];
2163  char last_letter;
2164  char index_path[500];
2165  char *mapstext = NULL;
2166  int byletter;
2167  int basevalues, realcount = 0;
2168  struct_map_info *last_group = NULL;
2169 
2170  if (!generate_index)
2171  return strdup("");
2172 
2173  if (vars)
2174  for (basevalues = 0; vars[basevalues] != NULL; basevalues++)
2175  ;
2176  else
2177  basevalues = 0;
2178 
2179  idx_vars = malloc(sizeof(char *)*(basevalues+VARSADD));
2180  idx_vars[0] = "MAPCOUNT";
2181  memcpy(&idx_vars[1], vars, sizeof(char *)*basevalues);
2182  idx_vars[basevalues+VARSADD-1] = NULL;
2183 
2184  idx_values = malloc(sizeof(char *)*(basevalues+VARSADD-1));
2185  memcpy(&idx_values[1], values, sizeof(char *)*basevalues);
2186 
2187  string = NULL;
2188 
2189  idx_values[0] = count;
2190  /* wrong value, but in case the template needs to display something... */
2191  snprintf(count, sizeof(count), "%d", maps_list->count);
2192 
2193  idx_vars[basevalues+1] = "MAPNAME";
2194  idx_vars[basevalues+2] = "MAPPATH";
2195  idx_vars[basevalues+3] = "MAPHTML";
2196  idx_vars[basevalues+4] = NULL;
2197 
2198  qsort(maps_list->maps, maps_list->count, sizeof(const char *), sort_map_info);
2199 
2200  last_letter = '\0';
2201  str_letter[0] = '\0';
2202  str_letter[1] = '\0';
2203 
2204  strcpy(index_path, "/");
2205  strcat(index_path, dest);
2206 
2207  string = NULL;
2208  for (map = 0; map < maps_list->count; map++) {
2209  if (tolower(maps_list->maps[map]->name[0]) != last_letter) {
2210  if (mapstext != NULL) {
2211  idx_vars[basevalues+1] = "MAPS";
2212  idx_vars[basevalues+2] = "LETTER";
2213  idx_vars[basevalues+3] = "LETTERCOUNT";
2214  idx_vars[basevalues+4] = NULL;
2215  idx_values[basevalues+1] = mapstext;
2216  idx_values[basevalues+2] = str_letter;
2217  snprintf(lettercount, sizeof(lettercount), "%d", byletter);
2218  idx_values[basevalues+3] = lettercount;
2219  string = cat_template(string, do_template(template_letter, idx_vars, idx_values));
2220  free(mapstext);
2221  mapstext = NULL;
2222  idx_values[basevalues+2] = NULL;
2223  }
2224  last_letter = tolower(maps_list->maps[map]->name[0]);
2225  str_letter[0] = last_letter;
2226  byletter = 0;
2227  last_group = NULL;
2228  }
2229 
2230  if (last_group && last_group == maps_list->maps[map]->tiled_group)
2231  continue;
2232  else
2233  last_group = maps_list->maps[map]->tiled_group;
2234 
2235  realcount++;
2236  idx_vars[basevalues+1] = "MAPNAME";
2237  idx_vars[basevalues+2] = "MAPPATH";
2238  idx_vars[basevalues+3] = "MAPHTML";
2239  idx_values[basevalues+1] = last_group ? last_group->name : (maps_list->maps[map]->name ? maps_list->maps[map]->name : maps_list->maps[map]->path);
2240  relative_path(index_path, last_group ? last_group->path : maps_list->maps[map]->path, mappath);
2241  strcpy(maphtml, mappath);
2242  strcat(maphtml, ".html");
2243  idx_values[basevalues+2] = mappath;
2244  idx_values[basevalues+3] = maphtml;
2245  mapstext = cat_template(mapstext, do_template(template_map, idx_vars, idx_values));
2246  byletter++;
2247  }
2248  if (last_letter != '\0') {
2249  idx_vars[basevalues+1] = "MAPS";
2250  idx_vars[basevalues+2] = "LETTER";
2251  idx_vars[basevalues+3] = "LETTERCOUNT";
2252  idx_vars[basevalues+4] = NULL;
2253  idx_values[basevalues+1] = mapstext;
2254  idx_values[basevalues+2] = str_letter;
2255  snprintf(lettercount, sizeof(lettercount), "%d", byletter);
2256  idx_values[basevalues+3] = lettercount;
2257  string = cat_template(string, do_template(template_letter, idx_vars, idx_values));
2258  free(mapstext);
2259  mapstext = NULL;
2260  idx_values[basevalues+2] = NULL;
2261  }
2262 
2263  snprintf(count, sizeof(count), "%d", realcount);
2264  idx_values[basevalues+1] = string;
2265  idx_vars[basevalues+1] = "LETTERS";
2266  idx_vars[basevalues+2] = NULL;
2267  tmp = do_template(template_page, idx_vars, idx_values);
2268  free(string);
2269  free(idx_vars);
2270  free(idx_values);
2271  return tmp;
2272 }
2273 
2284  char *string;
2285  FILE *index;
2286  char html[500];
2287  const char *vars[] = { "REGIONNAME", "REGIONHTML", "REGIONLONGNAME", "REGIONDESC", NULL };
2288  const char *values[] = { reg->reg->name, html, NULL, NULL };
2289 
2290  printf("Generating map index for region %s...", reg->reg->name);
2291 
2292  values[2] = get_region_longname(reg->reg);
2293  values[3] = get_region_msg(reg->reg);
2294 
2295  strcpy(html, reg->reg->name);
2296  strcat(html, ".html");
2297 
2298  string = do_map_index(html, &reg->maps_list, region_template, region_letter_template, region_map_template, vars, values);
2299 
2300  strcpy(html, root);
2301  strcat(html, "/");
2302  strcat(html, reg->reg->name);
2303  strcat(html, ".html");
2304  index = fopen(html, "w+");
2305  fprintf(index, "%s", string);
2306  fclose(index);
2307  free(string);
2308 
2309  printf(" done.\n");
2310 
2311 }
2312 
2316 static void write_all_regions(void) {
2317  int reg;
2318 
2319  qsort(regions, region_count, sizeof(struct_region_info *), sort_region);
2320 
2321  for (reg = 0; reg < region_count; reg++)
2322  write_region_page(regions[reg]);
2323 }
2324 
2328 static void write_maps_index(void) {
2329  char index_path[500];
2330  char *tmp;
2331  FILE *index;
2332 
2333  printf("Generating global map index in maps.html...");
2334 
2335  tmp = do_map_index("maps.html", &maps_list, index_template, index_letter, index_map, NULL, NULL);
2336 
2337  strcpy(index_path, root);
2338  strcat(index_path, "/maps.html");
2339  index = fopen(index_path, "w+");
2340  fprintf(index, "%s", tmp);
2341  fclose(index);
2342  free(tmp);
2343 
2344  printf(" done.\n");
2345 }
2346 
2350 static void write_region_index(void) {
2351  char *txt;
2352  char *final;
2353  char count[10];
2355  int reg;
2356  char file[500];
2357  const char *vars[] = { "REGIONCOUNT", "REGIONFILE", "REGIONNAME", NULL };
2358  const char *values[] = { count, file, NULL };
2359  FILE *out;
2360 
2361  printf("Generating regions index in regions.html...");
2362 
2363  snprintf(count, sizeof(count), "%d", region_count);
2364  txt = NULL;
2365 
2366  for (reg = 0; reg < region_count; reg++) {
2367  region = regions[reg];
2368  snprintf(file, sizeof(file), "%s.html", region->reg->name);
2369  values[2] = get_region_longname(region->reg);
2370  txt = cat_template(txt, do_template(index_region_region_template, vars, values));
2371  }
2372  vars[1] = "REGIONS";
2373  values[1] = txt;
2374  vars[2] = NULL;
2375  final = do_template(index_region_template, vars, values);
2376  free(txt);
2377 
2378  strcpy(file, root);
2379  strcat(file, "/regions.html");
2380  out = fopen(file, "w+");
2381  fprintf(out, "%s", final);
2382  fclose(out);
2383  free(final);
2384 
2385  printf(" done.\n");
2386 }
2387 
2391 static void write_world_map(void) {
2392 #define SIZE 50
2393  int x, y;
2394  FILE *out;
2395  int wx, wy;
2396  char file[500];
2397  char *map = NULL;
2398  char *total;
2399  char *row = NULL;
2400  char mapleft[10], maptop[10], mapright[10], mapbottom[10];
2401  const char *vars[] = { NULL, NULL, "MAPLEFT", "MAPTOP", "MAPRIGHT", "MAPBOTTOM", NULL };
2402  const char *values[] = { NULL, NULL, mapleft, maptop, mapright, mapbottom, NULL };
2403  char name[100];
2404  char mappath[500], mapraw[500], mapregion[500];
2405  gdImagePtr pic;
2406  gdImagePtr small;
2407  gdFontPtr font;
2408  int region, color;
2409 
2410  if (!world_map)
2411  return;
2412 
2413  printf("Generating world map in world.html...");
2414  fflush(stdout);
2415 
2416  pic = gdImageCreateTrueColor(SIZE*30, SIZE*30);
2417 
2418  strcpy(file, root);
2419  strcat(file, "/world.html");
2420 
2421  wx = 100;
2422  wy = 100;
2423 
2424  for (y = 0; y < 30; y++) {
2425  for (x = 0; x < 30; x++) {
2426  values[0] = name;
2427  vars[0] = "MAPNAME";
2428  vars[1] = "MAPPATH";
2429  values[1] = mappath,
2430  snprintf(name, sizeof(name), "world_%d_%d", wx, wy);
2431  snprintf(mappath, sizeof(mappath), "world/%s.html", name);
2432  snprintf(mapleft, sizeof(mapleft), "%d", SIZE*x);
2433  snprintf(maptop, sizeof(maptop), "%d", SIZE*y);
2434  snprintf(mapright, sizeof(mapright), "%d", SIZE*(x+1)-1);
2435  snprintf(mapbottom, sizeof(mapbottom), "%d", SIZE*(y+1)-1);
2436 
2437  map = cat_template(map, do_template(world_map_template, vars, values));
2438 
2439  snprintf(mappath, sizeof(mappath), "%s/world/%s.x1%s", root, name, output_extensions[output_format]);
2440 
2441  out = fopen(mappath, "rb");
2442  if (!out) {
2443  printf("\n warning: large pic not found for world_%d_%d", wx, wy);
2444  wx++;
2445  continue;
2446  }
2447  if (output_format == OF_PNG)
2448  small = gdImageCreateFromPng(out);
2449  else
2450  small = gdImageCreateFromJpeg(out);
2451  fclose(out);
2452  if (!small) {
2453  printf("\n warning: pic not found for world_%d_%d", wx, wy);
2454  wx++;
2455  continue;
2456  }
2457  gdImageCopyResized(pic, small, SIZE*x, SIZE*y, 0, 0, SIZE, SIZE, small->sx, small->sy);
2458  gdImageDestroy(small);
2459 
2460  wx++;
2461  }
2462  wy++;
2463  wx = 100;
2464  values[0] = map;
2465  vars[0] = "MAPS";
2466  vars[1] = NULL;
2467  row = cat_template(row, do_template(world_row_template, vars, values));
2468  free(map);
2469  map = NULL;
2470  }
2471  snprintf(mappath, sizeof(mappath), "world%s", output_extensions[output_format]);
2472  snprintf(mapraw, sizeof(mapraw), "world_raw%s", output_extensions[output_format]);
2473  snprintf(mapregion, sizeof(mapregion), "world_regions%s", output_extensions[output_format]);
2474 
2475  values[0] = row;
2476  vars[0] = "MAPS";
2477  values[1] = mappath;
2478  vars[1] = "WORLDMAP";
2479  values[2] = mapraw;
2480  vars[2] = "WORLDRAW";
2481  values[3] = mapregion;
2482  vars[3] = "WORLDREGIONS";
2483  vars[4] = NULL;
2484  total = do_template(world_template, vars, values);
2485  free(row);
2486  out = fopen(file, "w+");
2487  fprintf(out, "%s", total);
2488  free(total);
2489  fclose(out);
2490 
2491  snprintf(mappath, sizeof(mappath), "%s/world_raw%s", root, output_extensions[output_format]);
2492  out = fopen(mappath, "wb+");
2493  save_picture(out, pic);
2494  fclose(out);
2495 
2496  /* Write region names. */
2497  small = gdImageCreateTrueColor(SIZE*30, SIZE*30);
2498  font = gdFontGetGiant();
2499  color = gdImageColorAllocateAlpha(pic, 255, 0, 0, 20);
2500  for (region = 0; region < region_allocated; region++) {
2501  if (!regions[region]->is_world || regions[region]->sum == 0)
2502  continue;
2503 
2504  x = regions[region]->sum_x*SIZE/regions[region]->sum+SIZE/2-strlen(regions[region]->reg->name)*font->w/2;
2505  y = regions[region]->sum_y*SIZE/regions[region]->sum+SIZE/2-font->h/2;
2506  gdImageString(small, font, x, y, (unsigned char *)regions[region]->reg->name, color);
2507  gdImageString(pic, font, x, y, (unsigned char *)regions[region]->reg->name, color);
2508 
2509  /* For exit/road map, size isn't the same. */
2510  x = regions[region]->sum_x*50/regions[region]->sum+50/2-strlen(regions[region]->reg->name)*font->w/2;
2511  y = regions[region]->sum_y*50/regions[region]->sum+50/2-font->h/2;
2512  gdImageString(infomap, font, x, y, (unsigned char *)regions[region]->reg->name, color);
2513  }
2514 
2515  snprintf(mappath, sizeof(mappath), "%s/world_regions%s", root, output_extensions[output_format]);
2516  out = fopen(mappath, "wb+");
2517  save_picture(out, small);
2518  fclose(out);
2519  gdImageDestroy(small);
2520 
2521  snprintf(mappath, sizeof(mappath), "%s/world%s", root, output_extensions[output_format]);
2522  out = fopen(mappath, "wb+");
2523  save_picture(out, pic);
2524  fclose(out);
2525  gdImageDestroy(pic);
2526 
2527  printf(" done.\n");
2528 #undef SIZE
2529 }
2530 
2538  char *exits_text;
2539  char *exits_to;
2540  char *maplore;
2541  char *tmp;
2542  char *quests, *quest;
2543  char *monsters;
2544 
2545  char htmlpath[500]; /* Map file path. */
2546  char mappic[500]; /* Name of map's full size picture. */
2547  char mapsmallpic[500]; /* Name of map's small size picture. */
2548  char indexpath[500]; /* Relative path of full index. */
2549  char regionpath[500]; /* Path to region's filename. */
2550  char regionname[500]; /* Name of map's region. */
2551  char regionindexpath[500]; /* Path to region index file. */
2552  char worldmappath[500]; /* Path to world map. */
2553  char exit_path[500];
2554  char maplevel[5], minmonster[5], maxmonster[5];
2555  FILE *out;
2556  char questpath[500], questtemp[500];
2557  const char *quest_vars[] = { "NAME", "PATH", "TEXT", NULL };
2558  const char *quest_vals[] = { NULL, questpath, NULL, NULL };
2559  const char *q_vars[] = { "QUESTS", NULL };
2560  const char *q_vals[] = { NULL, NULL };
2561  const char *m_vars[] = { "NAME", NULL };
2562  const char *m_vals[] = { NULL, NULL };
2563  const char *vars[] = { "NAME", "MAPPATH", "MAPNAME", "MAPPIC", "MAPSMALLPIC", "MAPEXITFROM", "INDEXPATH", "REGIONPATH", "REGIONNAME", "REGIONINDEXPATH", "WORLDMAPPATH", "MAPLORE", "MAPEXITTO", "MAPLEVEL", "QUESTS", "MONSTERS", "MINMONSTER", "MAXMONSTER", NULL, NULL, NULL };
2564  const char *values[] = { map->path, htmlpath, map->name, mappic, mapsmallpic, "", indexpath, regionpath, regionname, regionindexpath, worldmappath, "", "", maplevel, NULL, "", minmonster, maxmonster, NULL, NULL, NULL };
2565  int vars_count = 0;
2566 
2567  while (vars[vars_count])
2568  vars_count++;
2569 
2570  snprintf(minmonster, sizeof(minmonster), "%d", map->min_monster);
2571  snprintf(maxmonster, sizeof(maxmonster), "%d", map->max_monster);
2572 
2573  relative_path(map->path, "/maps.html", indexpath);
2574  relative_path(map->path, "/world.html", worldmappath);
2575  relative_path(map->path, "/regions.html", regionindexpath);
2576 
2577  if (map->cfregion) {
2578  strcpy(regionname, get_region_longname(map->cfregion));
2579  strcpy(exit_path, "/");
2580  strcat(exit_path, map->cfregion->name);
2581  strcat(exit_path, ".html");
2582  relative_path(map->path, exit_path, regionpath);
2583  } else {
2584  regionpath[0]='\0';
2585  snprintf(regionname, sizeof(regionname), "(map was not processed)");
2586  }
2587 
2588  snprintf(mappic, sizeof(mappic), "%s%s", map->filename, output_extensions[output_format]);
2589  snprintf(mapsmallpic, sizeof(mapsmallpic), "%s.x2%s", map->filename, output_extensions[output_format]);
2590 
2591  snprintf(htmlpath, sizeof(htmlpath), "%s%s.html", root, map->path);
2592  make_path_to_file(htmlpath);
2593 
2594  values[14] = "";
2595 
2596  snprintf(maplevel, sizeof(maplevel), "%d", map->level);
2597  if (map->lore && map->lore[0] != '\0') {
2598  values[11] = map->lore;
2599  maplore = do_template(map_lore_template, vars, values);
2600  } else {
2601  maplore = do_template(map_no_lore_template, vars, values);
2602  }
2603  values[11] = maplore;
2604 
2605  if (map->exits_from.count) {
2606  char *one_exit = NULL;
2607  int exit;
2608  char relative[500];
2609 
2610  vars[vars_count] = "EXITNAME";
2611  vars[vars_count+1] = "EXITFILE";
2612 
2613  qsort(map->exits_from.maps, map->exits_from.count, sizeof(const char *), sort_map_info);
2614  for (exit = 0; exit < map->exits_from.count; exit++) {
2615  relative_path(map->path, map->exits_from.maps[exit]->path, relative);
2616  values[vars_count] = map->exits_from.maps[exit]->name;
2617  strcat(relative, ".html");
2618  values[vars_count+1] = relative;
2619  one_exit = cat_template(one_exit, do_template(map_exit_template, vars, values));
2620  }
2621  vars[vars_count] = "EXIT";
2622  vars[vars_count+1] = NULL;
2623  values[vars_count] = one_exit;
2624  exits_text = do_template(map_with_exit_template, vars, values);
2625  free(one_exit);
2626  }
2627  else
2628  exits_text = do_template(map_no_exit_template, vars, values);
2629 
2630  values[5] = exits_text;
2631 
2632  if (map->exits_to.count) {
2633  char *one_exit = NULL;
2634  int exit;
2635  char relative[500];
2636 
2637  vars[vars_count] = "EXITNAME";
2638  vars[vars_count+1] = "EXITFILE";
2639 
2640  qsort(map->exits_to.maps, map->exits_to.count, sizeof(struct_map_info *), sort_map_info);
2641  for (exit = 0; exit < map->exits_to.count; exit++) {
2642  relative_path(map->path, map->exits_to.maps[exit]->path, relative);
2643  values[vars_count] = map->exits_to.maps[exit]->name;
2644  strcat(relative, ".html");
2645  values[vars_count+1] = relative;
2646  one_exit = cat_template(one_exit, do_template(map_exit_to_template, vars, values));
2647  }
2648  vars[vars_count] = "EXIT";
2649  vars[vars_count+1] = NULL;
2650  values[vars_count] = one_exit;
2651  exits_to = do_template(map_with_exit_to_template, vars, values);
2652  free(one_exit);
2653  } else
2654  exits_to = do_template(map_no_exit_to_template, vars, values);
2655 
2656  values[12] = exits_to;
2657 
2658  if (map->quests.count) {
2659  int q;
2660 
2661  quest = NULL;
2662  for (q = 0; q < map->quests.count; q++) {
2663  quest_vals[0] = map->quests.list[q]->quest->name;
2664  relative_path(map->path, "/quests.html", questtemp);
2665  snprintf(questpath, sizeof(questpath), "%s#quest_%d", questtemp, map->quests.list[q]->quest->number);
2666  quest_vals[2] = map->quests.list[q]->description;
2667  quest = cat_template(quest, do_template(map_one_quest_template, quest_vars, quest_vals));
2668  }
2669 
2670  q_vals[0] = quest;
2671  quests = do_template(map_with_quests_template, q_vars, q_vals);
2672  free(quest);
2673  quest = NULL;
2674  } else
2675  quests = strdup(map_no_quest_template);
2676  values[14] = quests;
2677 
2678  if (map->monsters.count) {
2679  int m;
2680 
2681  qsort(map->monsters.races, map->monsters.count, sizeof(struct_race *), sort_race);
2682 
2683  monsters = do_template(map_monster_before_template, vars, values);
2684  for (m = 0; m < map->monsters.count; m++) {
2685  m_vals[0] = map->monsters.races[m]->name;
2686  monsters = cat_template(monsters, do_template(map_monster_one_template, m_vars, m_vals));
2687  if (m != map->monsters.count-1)
2688  monsters = cat_template(monsters, do_template(map_monster_between_template, vars, values));
2689  }
2690  monsters = cat_template(monsters, do_template(map_monster_after_template, vars, values));
2691  } else
2692  monsters = do_template(map_no_monster_template, vars, values);
2693  values[15] = monsters;
2694 
2695  vars[vars_count] = NULL;
2696  out = fopen(htmlpath, "w+");
2697  tmp = do_template(map_template, vars, values);
2698  fprintf(out, "%s", tmp);
2699  fclose(out);
2700  free(tmp);
2701  free(exits_text);
2702  free(exits_to);
2703  free(maplore);
2704  free(quests);
2705  free(monsters);
2706 }
2707 
2709 static void fix_map_names(void) {
2710  int map;
2711 
2712  for (map = 0; map < maps_list.count; map++) {
2713  if (maps_list.maps[map]->name)
2714  continue;
2715  if (!maps_list.maps[map]->filename) {
2716  printf("map without path!\n");
2717  abort();
2718  }
2719  maps_list.maps[map]->name = strdup(maps_list.maps[map]->filename);
2720  }
2721 }
2722 
2729 static void fix_tiled_map(void) {
2730  int map, tile;
2731  char name[500];
2732  char *slash, *test;
2733  region *cfregion;
2734 
2735  for (map = 0; map < tiled_map_list.count; map++) {
2736  if (tiled_map_list.maps[map]->tiled_maps.count == 0) {
2737  printf("empty tiled map group!");
2738  abort();
2739  }
2740 
2741  snprintf(name, sizeof(name), "tiled_map_group_%d", map);
2742  tiled_map_list.maps[map]->filename = strdup(name);
2743 
2744  cfregion = NULL;
2745  test = NULL;
2746 
2747  for (tile = 0; tile < tiled_map_list.maps[map]->tiled_maps.count; tile++) {
2748  if (tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion == NULL)
2749  /* map not processed, ignore it. */
2750  continue;
2751 
2752  if (!cfregion)
2753  cfregion = tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion;
2754  else if (cfregion != tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion) {
2755  printf("*** warning: tiled maps %s and %s not in same region (%s and %s).\n",
2758  cfregion = NULL;
2759  }
2760 
2762  /* map has a custom name, use it */
2763  if (!test)
2764  test = tiled_map_list.maps[map]->tiled_maps.maps[tile]->name;
2765  }
2766  }
2767 
2768  if (!test) {
2769  /* this can happen of course if only partial maps were processed, but well... */
2770  printf("*** warning: tiled map without any name. First map path %s\n", tiled_map_list.maps[map]->tiled_maps.maps[0]->path);
2771  test = name;
2772  }
2773 
2774  tiled_map_list.maps[map]->name = strdup(test);
2775  tiled_map_list.maps[map]->cfregion = cfregion;
2776 
2777  strncpy(name, tiled_map_list.maps[map]->tiled_maps.maps[0]->path, sizeof(name));
2778  slash = strrchr(name, '/');
2779  if (!slash)
2780  snprintf(name, sizeof(name), "/");
2781  else
2782  *(slash+1) = '\0';
2783  strncat(name, tiled_map_list.maps[map]->filename, sizeof(name) - strlen(name) - 1);
2784  tiled_map_list.maps[map]->path = strdup(name);
2785  }
2786 }
2787 
2798 static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from) {
2799  int map, max;
2800  struct_map_info *group;
2801 
2802  max = from->count-1;
2803  for (map = max; map >= 0; map--) {
2804  if (from->maps[map]->tiled_group) {
2805  group = from->maps[map]->tiled_group;
2806  if (map != max)
2807  from->maps[map] = from->maps[max];
2808  from->count--;
2809  max--;
2810  add_map(group, from);
2811  add_map(current->tiled_group ? current->tiled_group : current, is_from ? &group->exits_to : &group->exits_from);
2812  }
2813  }
2814 }
2815 
2817 static void fix_exits_to_tiled_maps(void) {
2818  int map, region, max;
2819  struct_map_info *group;
2820 
2821  for (map = 0; map < maps_list.count; map++) {
2824  }
2825 
2826  for (region = 0; region < region_count; region++) {
2828  for (map = max; map >= 0; map--) {
2831  if (map != max)
2834  max--;
2835  add_map(group, &regions[region]->maps_list);
2836  }
2837  }
2838  }
2839 }
2840 
2845 static void fix_tiled_map_monsters(void) {
2846  int map, race, max;
2847  struct_map_info *group;
2848 
2849  for (race = 0; race < races.count; race++) {
2850  max = races.races[race]->origin.count-1;
2851  for (map = max; map >= 0; map--) {
2852  if (races.races[race]->origin.maps[map]->tiled_group) {
2853  group = races.races[race]->origin.maps[map]->tiled_group;
2854  if (map != max)
2855  races.races[race]->origin.maps[map] = races.races[race]->origin.maps[max];
2856  races.races[race]->origin.count--;
2857  max--;
2858  add_map(group, &races.races[race]->origin);
2859  }
2860  }
2861  }
2862 
2863  for (map = 0; map < maps_list.count; map++) {
2864  if (maps_list.maps[map]->tiled_group) {
2865  for (race = 0; race < maps_list.maps[map]->monsters.count; race++) {
2867  }
2868  }
2869  }
2870 }
2871 
2873 static void write_all_maps(void) {
2874  int map;
2875 
2876  printf("Writing map pages...");
2877 
2878  for (map = 0; map < maps_list.count; map++)
2879  if (!maps_list.maps[map]->tiled_group)
2881 
2882  printf(" done.\n");
2883 }
2884 
2886  int test;
2887  char picpath[500];
2888  struct stat stats;
2889 
2890  snprintf(picpath, sizeof(picpath), "%s%s%s", root, map->path, output_extensions[output_format]);
2891  if (stat(picpath, &stats))
2892  return 1;
2893 
2894  snprintf(picpath, sizeof(picpath), "%s%s.x2%s", root, map->path, output_extensions[output_format]);
2895  if (stat(picpath, &stats))
2896  return 1;
2897 
2898  for (test = 0; test < map->tiled_maps.count; test++) {
2899  if (map->tiled_maps.maps[test]->pic_was_done)
2900  return 1;
2901  }
2902 
2903  return 0;
2904 }
2905 
2918  int xmin = 0, xmax = 0, ymin = 0, ymax = 0, tiled, count, last;
2919  char picpath[500];
2920  gdImagePtr small, large, load;
2921  FILE *out;
2923 
2924  if (!generate_pics)
2925  return;
2926 
2927  printf(" Generating composite map for %s...", map->name);
2928  fflush(stdout);
2929 
2930  if (!tiled_map_need_pic(map)) {
2931  printf(" already uptodate.\n");
2932  return;
2933  }
2934 
2935  count = map->tiled_maps.count;
2936  if (count == 0) {
2937  printf("Tiled map without tiled maps?\n");
2938  abort();
2939  }
2940  map->tiled_maps.maps[0]->processed = 1;
2941  map->tiled_maps.maps[0]->tiled_x_from = 0;
2942  map->tiled_maps.maps[0]->tiled_y_from = 0;
2943 
2944  while (count > 0) {
2945  last = count;
2946 
2947  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2948  current = map->tiled_maps.maps[tiled];
2949  if (current->processed != 1)
2950  continue;
2951 
2952  count--;
2953 
2954  if ((current->tiles[0]) && (current->tiles[0]->processed == 0)) {
2955  current->tiles[0]->processed = 1;
2956  current->tiles[0]->tiled_x_from = current->tiled_x_from;
2957  current->tiles[0]->tiled_y_from = current->tiled_y_from-current->tiles[0]->height;
2958  }
2959  if ((current->tiles[1]) && (current->tiles[1]->processed == 0)) {
2960  current->tiles[1]->processed = 1;
2961  current->tiles[1]->tiled_x_from = current->tiled_x_from+current->width;
2962  current->tiles[1]->tiled_y_from = current->tiled_y_from;
2963  }
2964  if ((current->tiles[2]) && (current->tiles[2]->processed == 0)) {
2965  current->tiles[2]->processed = 1;
2966  current->tiles[2]->tiled_x_from = current->tiled_x_from;
2967  current->tiles[2]->tiled_y_from = current->tiled_y_from+current->height;
2968  }
2969  if ((current->tiles[3]) && (current->tiles[3]->processed == 0)) {
2970  current->tiles[3]->processed = 1;
2971  current->tiles[3]->tiled_x_from = current->tiled_x_from-current->tiles[3]->width;
2972  current->tiles[3]->tiled_y_from = current->tiled_y_from;
2973  }
2974  }
2975 
2976  if (last == count) {
2977  printf("do_tiled_map_picture: didn't process any map in %s (%d left)??\n", map->path, last);
2978  abort();
2979  }
2980  }
2981 
2982  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2983  if (map->tiled_maps.maps[tiled]->tiled_x_from < xmin)
2984  xmin = map->tiled_maps.maps[tiled]->tiled_x_from;
2985  if (map->tiled_maps.maps[tiled]->tiled_y_from < ymin)
2986  ymin = map->tiled_maps.maps[tiled]->tiled_y_from;
2987  if (map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width > xmax)
2988  xmax = map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width;
2989  if (map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height > ymax)
2990  ymax = map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height;
2991  }
2992 
2993  large = gdImageCreateTrueColor(size_large*(xmax-xmin), size_large*(ymax-ymin));
2994  small = gdImageCreateTrueColor(size_small*(xmax-xmin), size_small*(ymax-ymin));
2995 
2996  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2997  snprintf(picpath, sizeof(picpath), "%s%s.x1%s", root, map->tiled_maps.maps[tiled]->path, output_extensions[output_format]);
2998 
2999  out = fopen(picpath, "rb");
3000  if (!out) {
3001  printf("\n do_tiled_map_picture: warning: pic file %s not found for %s (errno=%d)\n", picpath, map->tiled_maps.maps[tiled]->path, errno);
3002  continue;
3003  }
3004  if (output_format == OF_PNG)
3005  load = gdImageCreateFromPng(out);
3006  else
3007  load = gdImageCreateFromJpeg(out);
3008  fclose(out);
3009  if (!load) {
3010  printf("\n do_tiled_map_picture: warning: pic not found for %s\n", map->tiled_maps.maps[tiled]->path);
3011  continue;
3012  }
3013  gdImageCopy(large, load, size_large*(map->tiled_maps.maps[tiled]->tiled_x_from-xmin), size_large*(map->tiled_maps.maps[tiled]->tiled_y_from-ymin), 0, 0, load->sx, load->sy);
3014  gdImageDestroy(load);
3015 
3016  snprintf(picpath, sizeof(picpath), "%s%s.x2%s", root, map->tiled_maps.maps[tiled]->path, output_extensions[output_format]);
3017  out = fopen(picpath, "rb");
3018  if (output_format == OF_PNG)
3019  load = gdImageCreateFromPng(out);
3020  else
3021  load = gdImageCreateFromJpeg(out);
3022  fclose(out);
3023  if (!load) {
3024  printf("\n do_tiled_map_picture: warning: small pic not found for %s\n", map->tiled_maps.maps[tiled]->path);
3025  continue;
3026  }
3027  gdImageCopy(small, load, size_small*(map->tiled_maps.maps[tiled]->tiled_x_from-xmin), size_small*(map->tiled_maps.maps[tiled]->tiled_y_from-ymin), 0, 0, load->sx, load->sy);
3028  gdImageDestroy(load);
3029  }
3030 
3031  snprintf(picpath, sizeof(picpath), "%s%s%s", root, map->path, output_extensions[output_format]);
3032  out = fopen(picpath, "wb+");
3033  save_picture(out, large);
3034  fclose(out);
3035 
3036  snprintf(picpath, sizeof(picpath), "%s%s.x2%s", root, map->path, output_extensions[output_format]);
3037  out = fopen(picpath, "wb+");
3038  save_picture(out, small);
3039  fclose(out);
3040 
3041  gdImageDestroy(small);
3042  gdImageDestroy(large);
3043 
3044  printf(" done.\n");
3045 }
3046 
3049 
3051 
3055 }
3056 
3058 static void write_tiled_maps(void) {
3059  int map;
3060 
3061  printf("Writing tiled map information...\n");
3062 
3063  for (map = 0; map < tiled_map_list.count; map++)
3065 
3066  printf(" done.\n");
3067 }
3068 
3070 static void write_maps_by_level(void) {
3071  int map;
3072  FILE *out;
3073  char name[500];
3074  char mappath[500];
3075  char *letters = NULL;
3076  char *maps = NULL;
3077  char *level = NULL;
3078  int lastlevel = -1;
3079  char strlevel[10];
3080  char strcount[10];
3081  const char *val_vars[] = { "LEVEL", "MAPS", NULL };
3082  const char *val_values[] = { strlevel, NULL, NULL };
3083  const char *map_vars[] = { "MAPNAME", "MAPPATH", NULL };
3084  const char *map_values[] = { NULL, mappath, NULL };
3085  const char *idx_vars[] = { "COUNT", "LEVELS", NULL };
3086  const char *idx_values[] = { strcount, NULL, NULL };
3087  int levelcount = 0;
3088  struct_map_info *last_tiled = NULL;
3090 
3091  printf("Writing map index by level...");
3092 
3093  snprintf(name, sizeof(name), "%s/index_by_level.html", root);
3094 
3096 
3097  for (map = 0; map < maps_list.count; map++) {
3099  if (maps_list.maps[map]->level != lastlevel) {
3100  if (maps) {
3101  snprintf(strlevel, sizeof(strlevel), "%d", lastlevel);
3102  val_values[1] = maps;
3103  letters = cat_template(letters, do_template(level_value_template, val_vars, val_values));
3104  free(maps);
3105  maps = NULL;
3106  }
3107  lastlevel = process->level;
3108  levelcount++;
3109  last_tiled = NULL;
3110  } else
3111  if (last_tiled && last_tiled == process->tiled_group)
3112  /* Group maps of same tiled group and level, but make them appear in different levels if applicable. */
3113  continue;
3114 
3115  if (process->tiled_group) {
3116  process = process->tiled_group;
3117  last_tiled = process;
3118  } else
3119  last_tiled = process->tiled_group;
3120 
3121  map_values[0] = process->name;
3122  snprintf(mappath, sizeof(mappath), "%s.html", process->path+1); /* don't want the leading / */
3123  maps = cat_template(maps, do_template(level_map_template, map_vars, map_values));
3124  }
3125 
3126  snprintf(strlevel, sizeof(strlevel), "%d", lastlevel);
3127  val_values[1] = maps;
3128  letters = cat_template(letters, do_template(level_value_template, val_vars, val_values));
3129  free(maps);
3130  maps = NULL;
3131 
3132  snprintf(strcount, sizeof(strcount), "%d", levelcount);
3133  idx_values[1] = letters;
3134  level = do_template(level_template, idx_vars, idx_values);
3135  free(letters);
3136 
3137  out = fopen(name, "w+");
3138  fprintf(out, "%s", level);
3139  fclose(out);
3140  free(level);
3141 
3142  printf(" done.\n");
3143 }
3144 
3148 static void write_equipment_index(void) {
3149  int item, map;
3150  FILE *out;
3151  char name[500];
3152 
3153  printf("Generating special equipment list..");
3154  fflush(stdout);
3155 
3157 
3158  snprintf(name, sizeof(name), "%s/items.html", root);
3159  out = fopen(name, "w+");
3160 
3161  fprintf(out, "<html><head><title>Item list</title></head><body><h1>Special items found in maps</h1>\n");
3162  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");
3163 
3164  for (item = 0; item < equipment_count; item++) {
3165  fprintf(out, "<tr><td>%s</td><td><ul>", special_equipment[item]->name);
3166 
3167  for (map = 0; map < special_equipment[item]->origin.count; map++)
3168  fprintf(out, "<li>%s</li>\n", special_equipment[item]->origin.maps[map]->path);
3169 
3170  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);
3171  }
3172  fprintf(out, "</table></body></html>\n");
3173  fclose(out);
3174 
3175  printf(" done.\n");
3176 }
3177 
3181 static void write_race_index(void) {
3182  int item, map;
3183  FILE *out;
3184  char name[500];
3185 
3186  printf("Generating monster list...");
3187  fflush(stdout);
3188 
3189  qsort(races.races, races.count, sizeof(struct_race *), sort_race);
3190 
3191  snprintf(name, sizeof(name), "%s/monsters.html", root);
3192  out = fopen(name, "w+");
3193 
3194  fprintf(out, "<html><head><title>Monster list</title></head><body><h1>Monsters found in maps</h1>\n");
3195  fprintf(out, "<table border=\"1\"><tr><th>Name</th><th>Count</th><th>Map(s)</th></tr>\n");
3196 
3197  for (item = 0; item < races.count; item++) {
3198  fprintf(out, "<tr><td>%s</td><td>%d</td><td>Found on %d maps:<ul>", races.races[item]->name, races.races[item]->count, races.races[item]->origin.count);
3199 
3201 
3202  for (map = 0; map < races.races[item]->origin.count; map++)
3203  fprintf(out, "<li>%s</li>\n", races.races[item]->origin.maps[map]->path);
3204 
3205  fprintf(out, "</ul></td></tr>\n");
3206  }
3207  fprintf(out, "</table></body></html>\n");
3208  fclose(out);
3209 
3210  printf(" done.\n");
3211 }
3212 
3214 static const char *ignore_path[] = {
3215  "/Info",
3216  "/editor",
3217  "/python",
3218  "/styles",
3219  "/templates",
3220  "/test",
3221  "/unlinked",
3222  NULL };
3223 
3225 static const char *ignore_name[] = {
3226  ".",
3227  "..",
3228  ".svn",
3229  "README",
3230  NULL };
3231 
3238 static void find_maps(const char *from) {
3239  struct dirent *file;
3240  struct stat statbuf;
3241  int status, ignore;
3242  char path[1024], full[1024];
3243  DIR *dir;
3244 
3245  for (ignore = 0; ignore_path[ignore] != NULL; ignore++) {
3246  if (strcmp(from, ignore_path[ignore]) == 0)
3247  return;
3248  }
3249 
3250  snprintf(path, sizeof(path), "%s/%s%s", settings.datadir, settings.mapdir, from);
3251  dir = opendir(path);
3252 
3253  if (dir) {
3254  for (file = readdir(dir); file; file = readdir(dir)) {
3255 
3256  for (ignore = 0; ignore_name[ignore] != NULL; ignore++) {
3257  if (strcmp(file->d_name, ignore_name[ignore]) == 0)
3258  break;
3259  }
3260  if (ignore_name[ignore] != NULL)
3261  continue;
3262 
3263  snprintf(full, sizeof(full), "%s/%s", path, file->d_name);
3264 
3265  status = stat(full, &statbuf);
3266  if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
3267  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
3268  find_maps(full);
3269  continue;
3270  }
3272  found_maps_allocated += 50;
3273  found_maps = realloc(found_maps, found_maps_allocated*sizeof(char *));
3274  }
3275  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
3276  found_maps[found_maps_count++] = strdup(full);
3277  }
3278  closedir(dir);
3279  }
3280 }
3281 
3283 static void dump_unused_maps(void) {
3284  FILE *dump;
3285  char path[1024];
3286  int index, found = 0;
3287 
3288  snprintf(path, sizeof(path), "%s/%s", root, "maps.unused");
3289  dump = fopen(path, "w+");
3290  if (dump == NULL) {
3291  printf("Unable to open file maps.unused!\n");
3292  return;
3293  }
3294  for (index = 0; index < found_maps_count; index++) {
3295  if (found_maps[index] != NULL) {
3296  fprintf(dump, "%s\n", found_maps[index]);
3297  free(found_maps[index]);
3298  found++;
3299  }
3300  }
3301  fclose(dump);
3302  printf("%d unused maps.\n", found);
3303 }
3304 
3306 static void write_world_info(void) {
3307  FILE *file;
3308  char path[MAX_BUF];
3309  int x, y;
3310  gdImagePtr elevationmap;
3311 
3312  if (!world_exit_info)
3313  return;
3314 
3315  printf("Saving exit/blocking/road information...");
3316  snprintf(path, sizeof(path), "%s/%s%s", root, "world_info", output_extensions[output_format]);
3317  file = fopen(path, "wb+");
3319  fclose(file);
3320  printf("done.\n");
3321  gdImageDestroy(infomap);
3322  infomap = NULL;
3323 
3324  if (elevation_min == 0 || elevation_max == 0) {
3325  puts("Error: Could not save elevation world map due to not finding any minimum or maximum elevation.");
3326  return;
3327  }
3328 
3329  elevationmap = gdImageCreateTrueColor(30*50, 30*50);;
3330 
3331  for (x = 0; x < 30*50; x++) {
3332  for (y = 0; y < 30*50; y++) {
3333  gdImageSetPixel(elevationmap, x, y, get_elevation_color(elevation_info[x][y], elevationmap));
3334  }
3335  }
3336 
3337  printf("Saving elevation world map...");
3338  snprintf(path, sizeof(path), "%s/%s%s", root, "world_elevation", output_extensions[output_format]);
3339  file = fopen(path, "wb+");
3340  save_picture(file, elevationmap);
3341  fclose(file);
3342  printf("done.\n");
3343  gdImageDestroy(elevationmap);
3344  elevationmap = NULL;
3345 }
3346 
3348 static void write_regions_link(void) {
3349  FILE *file;
3350  char path[MAX_BUF];
3351  int link;
3352 
3353  if (!do_regions_link)
3354  return;
3355 
3356  printf("Writing regions link file...");
3357  snprintf(path, sizeof(path), "%s/%s", root, "region_links.dot");
3358  file = fopen(path, "wb+");
3359  fprintf(file, "digraph {\n");
3360  for (link = 0; link < regions_link_count; link++)
3361  fprintf(file, "%s", regions_link[link]);
3362  fprintf(file, "}\n");
3363  fclose(file);
3364  printf("done.\n");
3365 }
3366 
3376  fprintf(file, "<a href=\"%s.html\">%s</a> (full map path: %s)", map->tiled_group ? map->tiled_group->path+1 : map->path+1, map->name, map->path);
3377 }
3378 
3393 static void write_one_slaying_info(FILE *file, struct_slaying_info *info, int item, const char *with, const char *without) {
3394  int map;
3395 
3396  if (info->maps[item].count == 0) {
3397  if (without)
3398  fprintf(file, "%s", without);
3399  return;
3400  }
3401 
3402  qsort(info->maps[item].maps, info->maps[item].count, sizeof(const char *), sort_mapname);
3403 
3404  fprintf(file, "%s", with);
3405  fprintf(file, "<ul>\n");
3406  for (map = 0; map < info->maps[item].count; map++) {
3407  fprintf(file, "\t<li>");
3409  fprintf(file, "</li>\n");
3410  }
3411  fprintf(file, "</ul>\n");
3412 }
3413 
3424 static int sort_slaying(const void *left, const void *right) {
3427 
3428  return strcasecmp(l->slaying, r->slaying);
3429 }
3430 
3434 static void write_slaying_info(void) {
3435  FILE *file;
3436  char path[MAX_BUF];
3437  int lock;
3438  struct_slaying_info *info;
3439 
3440  printf("Writing slaying info file...");
3441 
3443 
3444  snprintf(path, sizeof(path), "%s/%s", root, "slaying_info.html");
3445  file = fopen(path, "wb+");
3446 
3447  fprintf(file, "<html>\n<head>\n<title>Slaying information</title>\n</head>\n<body>\n");
3448  fprintf(file, "<p>This is a list of various slaying fields on keys, containers, doors, detectors.</p>");
3449 
3450  for (lock = 0; lock < slaying_count; lock++) {
3451  info = slaying_info[lock];
3452  fprintf(file, "<h1>%s</h1>\n", info->slaying);
3453 
3454  if (info->maps[S_DOOR].count == 0 && info->maps[S_CONTAINER].count == 0 && info->maps[S_CONNECT].count == 0) {
3455  fprintf(file, "No door, container or detector matching this slaying.<br />\n");
3456  } else {
3457  write_one_slaying_info(file, info, S_DOOR, "Connected doors:\n", NULL);
3458  write_one_slaying_info(file, info, S_CONTAINER, "Matching containers:\n", NULL);
3459  write_one_slaying_info(file, info, S_CONNECT, "Detectors and such:\n", NULL);
3460  }
3461  write_one_slaying_info(file, info, S_KEY, "Matching keys:\n", "No key with this slaying.<br />\n");
3462  }
3463 
3464  fprintf(file, "</body>\n</html>\n");
3465 
3466  fclose(file);
3467  printf("done.\n");
3468 }
3469 
3473 static void write_npc_list(void) {
3474  FILE *file;
3475  char path[MAX_BUF];
3476  int map, npc;
3477 
3478  printf("Writing NPC info file...");
3479 
3481 
3482  snprintf(path, sizeof(path), "%s/%s", root, "npc_info.html");
3483  file = fopen(path, "wb+");
3484 
3485  fprintf(file, "<html>\n<head>\n<title>NPCs who have a special message</title>\n</head>\n<body>\n");
3486  fprintf(file, "<p>This is a list of NPCs having a special message.</p>");
3487  fprintf(file, "<ul>\n");
3488 
3489  for (map = 0; map < maps_list.count; map++) {
3490  if (maps_list.maps[map]->npcs.count == 0)
3491  continue;
3492  fprintf(file, "<li>%s</li>\n<ul>", maps_list.maps[map]->path);
3493  for (npc = 0; npc < maps_list.maps[map]->npcs.count; npc++) {
3494  fprintf(file, "<li>%s (%d,%d): <br /><pre>%s</pre></li>\n", maps_list.maps[map]->npcs.npc[npc]->name, maps_list.maps[map]->npcs.npc[npc]->x, maps_list.maps[map]->npcs.npc[npc]->y, maps_list.maps[map]->npcs.npc[npc]->message);
3495  }
3496  fprintf(file, "</ul>\n</li>\n");
3497  }
3498 
3499  fprintf(file, "</ul>\n");
3500  fprintf(file, "</body>\n</html>\n");
3501 
3502  fclose(file);
3503  printf("done.\n");
3504 }
3505 
3509 static void write_readable_list(void) {
3510  FILE *file;
3511  char path[MAX_BUF];
3512  int map, readable;
3513 
3514  printf("Writing readable info file...");
3515 
3516  snprintf(path, sizeof(path), "%s/%s", root, "readable_info.html");
3517  file = fopen(path, "wb+");
3518 
3519  fprintf(file, "<html>\n<head>\n<title>SIGN and BOOK with a special message</title>\n</head>\n<body>\n");
3520  fprintf(file, "<p>This is a list of SIGN and BOOK with a special message.</p>");
3521  fprintf(file, "<ul>\n");
3522 
3523  for (map = 0; map < maps_list.count; map++) {
3524  if (maps_list.maps[map]->readable.count == 0)
3525  continue;
3526  fprintf(file, "<li>%s</li>\n<ul>", maps_list.maps[map]->path);
3527  for (readable = 0; readable < maps_list.maps[map]->readable.count; readable++) {
3528  fprintf(file, "<li>%s (%d,%d): <br /><pre>%s</pre></li>\n", maps_list.maps[map]->readable.npc[readable]->name, maps_list.maps[map]->readable.npc[readable]->x, maps_list.maps[map]->readable.npc[readable]->y, maps_list.maps[map]->readable.npc[readable]->message);
3529  }
3530  fprintf(file, "</ul>\n</li>\n");
3531  }
3532 
3533  fprintf(file, "</ul>\n");
3534  fprintf(file, "</body>\n</html>\n");
3535 
3536  fclose(file);
3537  printf("done.\n");
3538 }
3539 
3540 static size_t system_quests_count = 0;
3541 static const quest_definition *system_quests[500];
3542 
3543 static void quest_callback(const quest_definition *quest, void *user) {
3544  if (list_system_quests || !quest->quest_is_system) {
3546  }
3547 }
3548 
3549 static int sort_system_quest(const void *a, const void *b) {
3550  return strcmp((*((quest_definition **)a))->quest_code, (*((quest_definition **)b))->quest_code);
3551 }
3552 
3553 static int sort_system_quest_step(const void *a, const void *b) {
3554  return (*((quest_step_definition**)a))->step - (*((quest_step_definition**)b))->step;
3555 }
3556 
3557 static void do_quest_item(const quest_definition *quest, FILE *file) {
3558  fprintf(file, "<li>%s (%s)%s\n", quest->quest_title, quest->quest_code, quest->quest_is_system ? " (system quest)": "");
3559  if (quest->quest_description)
3560  fprintf(file, "<p>%s</p>\n", quest->quest_description);
3561 
3562  if (detail_quests && quest->steps) {
3563  quest_step_definition *steps[100];
3564  size_t steps_count = 0;
3565  quest_step_definition *step = quest->steps;
3566  while (step) {
3567  steps[steps_count++] = step;
3568  step = step->next;
3569  }
3570  qsort(steps, steps_count, sizeof(quest_step_definition *), sort_system_quest_step);
3571 
3572  fprintf(file, "<ul>\n");
3573  for (size_t s = 0; s < steps_count; s++)
3574  fprintf(file, "<li>%s%s</li>\n", steps[s]->step_description, steps[s]->is_completion_step ? "(end)" : "");
3575  fprintf(file, "</ul>\n");
3576 
3577  struct_quest *sq = find_quest_info(quest->quest_code);
3578  if (sq && sq->maps.count > 0) {
3579  fprintf(file, "<p>Linked maps:</p>\n");
3580  fprintf(file, "<ul>\n");
3581  for (size_t i = 0; i < sq->maps.count; i++) {
3582  const struct_map_in_quest *miq = sq->maps.list[i];
3583  fprintf(file, "<li>%s (%s)</li>\n", miq->map->name, miq->description);
3584  }
3585  fprintf(file, "</ul>\n");
3586  }
3587  }
3588 
3589  fprintf(file, "</li>\n");
3590 }
3591 
3595 static void write_quests_list(void) {
3596  FILE *file;
3597  char path[MAX_BUF];
3598 
3601 
3602  printf("Writing defined quests info file...");
3603 
3604  snprintf(path, sizeof(path), "%s/%s", root, "quests_list.html");
3605  file = fopen(path, "wb+");
3606 
3607  fprintf(file, "<html>\n<head>\n<title>Defined quests</title>\n</head>\n<body>\n");
3608  fprintf(file, "<p>%lu quests are defined%s.</p>\n", system_quests_count, list_system_quests ? " (including system quests)" : "");
3609  fprintf(file, "<ul>\n");
3610 
3611  for (size_t q = 0; q < system_quests_count; q++) {
3613  }
3614 
3615  fprintf(file, "</ul>\n");
3616  fprintf(file, "</body>\n</html>\n");
3617 
3618  fclose(file);
3619  printf("done.\n");
3620 }
3621 
3628 static void do_help(const char *program) {
3629  printf("Crossfire Mapper will generate pictures of maps, and create indexes for all maps and regions.\n\n");
3630  printf("Syntax: %s\n\n", program);
3631  printf("Optional arguments:\n");
3632  printf(" -nopics don't generate pictures.\n");
3633  printf(" -noindex don't generate global map index.\n");
3634  printf(" -root=<path> destination path. Default 'html'.\n");
3635  printf(" -limit=<number> stop processing after this number of maps, -1 to do all maps (default).\n");
3636  printf(" -showmaps outputs the name of maps as they are processed.\n");
3637  printf(" -jpg[=quality] generate jpg pictures, instead of default png. Quality should be 0-95, -1 for automatic.\n");
3638  printf(" -forcepics force to regenerate pics, even if pics's date is after map's.\n");
3639  printf(" -addmap=<map> adds a map to process. Path is relative to map's directory root.\n");
3640  printf(" -rawmaps generates maps pics without items on random (shop, treasure) tiles.\n");
3641  printf(" -warnnopath inform when an exit has no path set.\n");
3642  printf(" -listunusedmaps finds all unused maps in the maps directory.\n");
3643  printf(" -noworldmap don't write the world map in world.png.\n");
3644  printf(" -noregionslink don't generate regions relation file.\n");
3645  printf(" -regionslink generate regions relation file.\n");
3646  printf(" -noexitmap don't generate map of exits.\n");
3647  printf(" -exitmap generate map of exits.\n");
3648  printf(" -tileset=<number> use specified tileset to generate the pictures. Default 0 (standard).\n");
3649  printf(" -details-quests list all quests steps. Default no.\n");
3650  printf(" -list-system-quests include 'system' quests in quest list. Default no.\n");
3651  printf("\n\n");
3652  exit(0);
3653 }
3654 
3663 static void do_parameters(int argc, char **argv) {
3664  int arg = 1;
3665  char path[500];
3666 
3667  root[0] = '\0';
3668 
3669  while (arg < argc) {
3670  if (strcmp(argv[arg], "-nopics") == 0)
3671  generate_pics = 0;
3672  else if (strcmp(argv[arg], "-noindex") == 0)
3673  generate_index = 0;
3674  else if (strncmp(argv[arg], "-root=", 6) == 0)
3675  strncpy(root, argv[arg]+6, 500);
3676  else if (strncmp(argv[arg], "-limit=", 7) == 0)
3677  map_limit = atoi(argv[arg]+7);
3678  else if (strcmp(argv[arg], "-showmaps") == 0)
3679  show_maps = 1;
3680  else if (strcmp(argv[arg], "-jpg") == 0) {
3682  if (argv[arg][4] == '=') {
3683  jpeg_quality = atoi(argv[arg]+5);
3684  if (jpeg_quality < 0)
3685  jpeg_quality = -1;
3686  }
3687  }
3688  else if (strcmp(argv[arg], "-forcepics") == 0)
3689  force_pics = 1;
3690  else if (strncmp(argv[arg], "-addmap=", 8) == 0) {
3691  if (*(argv[arg]+8) == '/')
3692  strncpy(path, argv[arg]+8, 500);
3693  else
3694  snprintf(path, 500, "/%s", argv[arg]+8);
3696  }
3697  else if (strcmp(argv[arg], "-rawmaps") == 0)
3698  rawmaps = 1;
3699  else if (strcmp(argv[arg], "-warnnopath") == 0)
3700  warn_no_path = 1;
3701  else if (strcmp(argv[arg], "-listunusedmaps") == 0)
3702  list_unused_maps = 1;
3703  else if (strcmp(argv[arg], "-noworldmap") == 0)
3704  world_map = 0;
3705  else if (strcmp(argv[arg], "-noregionslink") == 0)
3706  do_regions_link = 0;
3707  else if (strcmp(argv[arg], "-regionslink") == 0)
3708  do_regions_link = 1;
3709  else if (strcmp(argv[arg], "-noexitmap") == 0)
3710  world_exit_info = 0;
3711  else if (strcmp(argv[arg], "-exitmap") == 0)
3712  world_exit_info = 1;
3713  else if (strncmp(argv[arg], "-tileset=", 9) == 0) {
3714  tileset = atoi(argv[arg]+9);
3715  /* check of validity is done in main() as we need to actually have the sets loaded. */
3716  } else if (strcmp(argv[arg], "-detail-quests") == 0) {
3717  detail_quests = 1;
3718  } else if (strcmp(argv[arg], "-list-system-quests") == 0) {
3719  list_system_quests = 1;
3720  } else
3721  do_help(argv[0]);
3722  arg++;
3723  }
3724  if (!strlen(root))
3725  strcpy(root, "html");
3726  if (root[strlen(root)-1] == '/')
3727  root[strlen(root)-1] = '\0';
3728  if (map_limit < -1)
3729  map_limit = -1;
3730 }
3731 
3735 static void create_destination(void) {
3736  char dummy[502];
3737 
3738  strcpy(dummy, root);
3739  strcat(dummy, "/a");
3740  make_path_to_file(dummy);
3741 }
3742 
3751 static const char *yesno(int value) {
3752  return (value ? "yes" : "no");
3753 }
3754 
3755 int main(int argc, char **argv) {
3756  int current_map = 0, i;
3757  char max[50];
3758  region *dummy;
3759 
3763  pics_allocated = 0;
3764 
3765  do_parameters(argc, argv);
3766 
3767  printf("Initializing Crossfire data...\n");
3768 
3769  settings.debug = 0;
3770 
3771  init_globals();
3772  init_library();
3773  init_readable();
3774  init_regions();
3775 
3776  init_gods();
3777 
3778  /* Add a dummy region so unlinked maps can be identified. */
3779  dummy = get_region_struct();
3780  dummy->fallback = 1;
3781  dummy->name = strdup_local("unlinked");
3782  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3783  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3784  dummy->next = first_region;
3785  first_region = dummy;
3786 
3787  printf("\n\n done.\n\n");
3788 
3789  if (!is_valid_faceset(tileset)) {
3790  printf("Erreor: invalid tileset %d!\n", tileset);
3791  exit(1);
3792  }
3793 
3795  gdfaces = calloc(get_faces_count(), sizeof(gdImagePtr));
3796 
3797  read_template("templates/map.template", &map_template);
3798  read_template("templates/map_no_exit.template", &map_no_exit_template);
3799  read_template("templates/map_with_exit.template", &map_with_exit_template);
3800  read_template("templates/map_exit.template", &map_exit_template);
3801  read_template("templates/map_no_exit_to.template", &map_no_exit_to_template);
3802  read_template("templates/map_with_exit_to.template", &map_with_exit_to_template);
3803  read_template("templates/map_exit_to.template", &map_exit_to_template);
3804  read_template("templates/map_lore.template", &map_lore_template);
3805  read_template("templates/map_no_lore.template", &map_no_lore_template);
3806  read_template("templates/map_no_monster.template", &map_no_monster_template);
3807  read_template("templates/map_monster_before.template", &map_monster_before_template);
3808  read_template("templates/map_monster_between.template", &map_monster_between_template);
3809  read_template("templates/map_monster_one.template", &map_monster_one_template);
3810  read_template("templates/map_monster_after.template", &map_monster_after_template);
3811 
3812  read_template("templates/index.template", &index_template);
3813  read_template("templates/index_letter.template", &index_letter);
3814  read_template("templates/index_map.template", &index_map);
3815 
3816  read_template("templates/region.template", &region_template);
3817  read_template("templates/region_letter.template", &region_letter_template);
3818  read_template("templates/region_map.template", &region_map_template);
3819 
3820  read_template("templates/index_region.template", &index_region_template);
3821  read_template("templates/index_region_region.template", &index_region_region_template);
3822 
3823  read_template("templates/world.template", &world_template);
3824  read_template("templates/world_row.template", &world_row_template);
3825  read_template("templates/world_map.template", &world_map_template);
3826 
3827  read_template("templates/level.template", &level_template);
3828  read_template("templates/level_value.template", &level_value_template);
3829  read_template("templates/level_map.template", &level_map_template);
3830 
3831  read_template("templates/quests.template", &index_quest_template);
3832  read_template("templates/quests_quest.template", &quest_template);
3833  read_template("templates/quests_map.template", &quest_map_template);
3834 
3835  read_template("templates/map_with_quests.template", &map_with_quests_template);
3836  read_template("templates/map_one_quest.template", &map_one_quest_template);
3837  read_template("templates/map_no_quest.template", &map_no_quest_template);
3838 
3839  if (map_limit != -1)
3840  snprintf(max, sizeof(max), "%d", map_limit);
3841  else
3842  strcpy(max, "(none)");
3843  printf("Crossfire map browser generator\n");
3844  printf("-------------------------------\n\n");
3845  printf("Parameters:\n");
3846  printf(" path to write files: %s\n", root);
3847  printf(" maximum number of maps to process: %s\n", max);
3848  printf(" will generate map picture: %s\n", yesno(generate_pics));
3849  printf(" will always generate map picture: %s\n", yesno(force_pics));
3850  printf(" picture output format: %s\n", output_extensions[output_format]);
3851  if (output_format == OF_JPG)
3852  printf(" JPEG quality: %d\n", jpeg_quality);
3853  printf(" will generate map index: %s\n", yesno(generate_index));
3854  printf(" show map being processed: %s\n", yesno(show_maps));
3855  printf(" generate raw maps: %s\n", yesno(rawmaps));
3856  printf(" warn of exit without path: %s\n", yesno(warn_no_path));
3857  printf(" list unused maps: %s\n", yesno(list_unused_maps));
3858  printf(" generate world map: %s\n", yesno(world_map));
3859  printf(" generate exit map: %s\n", yesno(world_exit_info));
3860  printf(" generate regions link file: %s\n", yesno(do_regions_link));
3861  printf(" tileset: %s\n", find_faceset(tileset)->fullname);
3862  printf(" detail quest steps: %s\n", yesno(detail_quests));
3863  printf(" list system quests: %s\n", yesno(list_system_quests));
3864  printf("\n");
3865 
3866  if (list_unused_maps) {
3867  printf("listing all maps...");
3868  find_maps("");
3869  printf("done, %d maps found.\n", found_maps_count);
3870  qsort(found_maps, found_maps_count, sizeof(char *), sortbyname);
3871  }
3872 
3873  /* exit/blocking information. */
3874  infomap = gdImageCreateTrueColor(30*50, 30*50);
3875  color_unlinked_exit = gdImageColorResolve(infomap, 255, 0, 0);
3876  color_linked_exit = gdImageColorResolve(infomap, 255, 255, 255);
3877  color_road = gdImageColorResolve(infomap, 0, 255, 0);
3878  color_blocking = gdImageColorResolve(infomap, 0, 0, 255);
3879  color_slowing = gdImageColorResolve(infomap, 0, 0, 127);
3880  elevation_info = calloc(50*30, sizeof(int *));
3881  for (i = 0; i < 50*30; i++)
3882  elevation_info[i] = calloc(50*30, sizeof(int));
3883  elevation_min = 0;
3884  elevation_max = 0;
3885 
3886  printf("browsing maps...\n");
3887 
3889 
3890  while (current_map < maps_list.count) {
3891  process_map(maps_list.maps[current_map++]);
3892  if (current_map%100 == 0) {
3893  printf(" %d maps processed, %d map pictures created, %d map pictures were uptodate. %d faces used.\n", current_map, created_pics, cached_pics, pics_allocated);
3894  }
3895  if ((map_limit != -1) && (current_map == map_limit)) {
3896  printf(" --- map limit reached, stopping ---\n");
3897  break;
3898  }
3899  }
3900 
3901  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);
3902 
3903  if (list_unused_maps)
3904  dump_unused_maps();
3905 
3907  fix_map_names();
3908  fix_tiled_map();
3910 
3911  write_all_maps();
3912  write_maps_index();
3914  write_tiled_maps();
3915 
3918 
3919  write_world_map();
3920  write_world_info();
3921 
3924 
3926 
3928  write_race_index();
3929  write_npc_list();
3932 
3933  return 0;
3934 }
3935 
3937  int x, y;
3938 
3939  if (m == NULL)
3940  return;
3941 
3942  for (x = 0; x < MAP_WIDTH(m); x++)
3943  for (y = 0; y < MAP_HEIGHT(m); y++)
3944  FOR_MAP_PREPARE(m, x, y, tmp) {
3945  if (tmp->inv) {
3946  FOR_INV_PREPARE(tmp, invtmp) {
3947  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
3948  apply_auto(invtmp);
3949  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
3950  while ((invtmp->stats.hp--) > 0)
3951  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3952  invtmp->randomitems = NULL;
3953  } else if (invtmp
3954  && invtmp->arch
3955  && invtmp->type != TREASURE
3956  && invtmp->type != SPELL
3957  && invtmp->type != CLASS
3958  && HAS_RANDOM_ITEMS(invtmp)) {
3959  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3960  /* Need to clear this so that we never try to create
3961  * treasure again for this object
3962  */
3963  invtmp->randomitems = NULL;
3964  }
3965  } FOR_INV_FINISH();
3966  /* This is really temporary - the code at the bottom will
3967  * also set randomitems to null. The problem is there are bunches
3968  * of maps/players already out there with items that have spells
3969  * which haven't had the randomitems set to null yet.
3970  * MSW 2004-05-13
3971  *
3972  * And if it's a spellbook, it's better to set randomitems to NULL too,
3973  * else you get two spells in the book ^_-
3974  * Ryo 2004-08-16
3975  */
3976  if (tmp->type == WAND
3977  || tmp->type == ROD
3978  || tmp->type == SCROLL
3979  || tmp->type == FIREWALL
3980  || tmp->type == POTION
3981  || tmp->type == ALTAR
3982  || tmp->type == SPELLBOOK)
3983  tmp->randomitems = NULL;
3984  }
3985 
3987  apply_auto(tmp);
3988  else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS(tmp)) {
3989  while ((tmp->stats.hp--) > 0)
3990  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
3991  tmp->randomitems = NULL;
3992  } else if (tmp->type == TIMED_GATE) {
3993  object *head = HEAD(tmp);
3994 
3995  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
3996  tmp->speed = 0;
3998  }
3999  /* This function can be called everytime a map is loaded, even when
4000  * swapping back in. As such, we don't want to create the treasure
4001  * over and ove again, so after we generate the treasure, blank out
4002  * randomitems so if it is swapped in again, it won't make anything.
4003  * This is a problem for the above objects, because they have counters
4004  * which say how many times to make the treasure.
4005  */
4006  } else if (tmp
4007  && tmp->arch
4008  && tmp->type != PLAYER
4009  && tmp->type != TREASURE
4010  && tmp->type != SPELL
4011  && tmp->type != PLAYER_CHANGER
4012  && tmp->type != CLASS
4013  && HAS_RANDOM_ITEMS(tmp)) {
4014  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
4015  tmp->randomitems = NULL;
4016  }
4017  } FOR_MAP_FINISH();
4018 
4019  for (x = 0; x < MAP_WIDTH(m); x++)
4020  for (y = 0; y < MAP_HEIGHT(m); y++)
4021  FOR_MAP_PREPARE(m, x, y, tmp) {
4022  if (tmp->above
4023  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
4024  check_trigger(tmp, tmp->above);
4025  } FOR_MAP_FINISH();
4026 }
4027 
4028 #ifndef DOXYGEN_SHOULD_SKIP_THIS
4029 
4034 void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *txt) {
4035  fprintf(logfile, "%s\n", txt);
4036 }
4037 
4038 void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format, ...) {
4039  va_list ap;
4040 
4041  va_start(ap, format);
4042  vfprintf(logfile, format, ap);
4043  va_end(ap);
4044 }
4045 
4046 void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1) {
4047  fprintf(logfile, "ext_info_map: %s\n", str1);
4048 }
4049 
4050 void move_firewall(object *ob) {
4051 }
4052 
4053 void emergency_save(int x) {
4054 }
4055 
4056 void clean_tmp_files(void) {
4057 }
4058 
4059 void esrv_send_item(object *ob, object *obx) {
4060 }
4061 
4062 void dragon_ability_gain(object *ob, int x, int y) {
4063 }
4064 
4066 }
4067 
4068 object *find_skill_by_number(object *who, int skillno) {
4069  return NULL;
4070 }
4071 
4072 void esrv_del_item(player *pl, object *ob) {
4073 }
4074 
4075 void esrv_update_item(int flags, object *pl, object *op) {
4076 }
4077 
4079 }
4080 
4081 void rod_adjust(object *rod) {
4082 }
4083 
4084 /*
4085  * This a modified version of apply_auto: BOOK are not generated, so they don't pollute
4086  * the readable list.
4087  */
4088 int apply_auto(object *op) {
4089  object *tmp = NULL;
4090  int i;
4091 
4092  switch (op->type) {
4093  case SHOP_FLOOR:
4094  if (!HAS_RANDOM_ITEMS(op))
4095  return 0;
4096  do {
4097  i = 10; /* let's give it 10 tries */
4098  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL && --i)
4099  ;
4100  if (tmp == NULL)
4101  return 0;
4102  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED) || tmp->type == BOOK) {
4104  tmp = NULL;
4105  }
4106  } while (!tmp);
4108  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
4110  tmp = identify(tmp);
4111  break;
4112 
4113  case TREASURE:
4115  return 0;
4116 
4117  while ((op->stats.hp--) > 0)
4118  create_treasure(op->randomitems, op, 0, op->stats.exp ? (int)op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
4119 
4120  /* If we generated an object and put it in this object inventory,
4121  * move it to the parent object as the current object is about
4122  * to disappear. An example of this item is the random_ *stuff
4123  * that is put inside other objects.
4124  */
4125  FOR_INV_PREPARE(op, tmp) {
4126  object_remove(tmp);
4127  if (op->env && tmp->type != BOOK)
4128  object_insert_in_ob(tmp, op->env);
4129  else
4131  }
4132  FOR_INV_FINISH();
4133  object_remove(op);
4135  break;
4136  }
4137  return tmp ? 1 : 0;
4138 }
4139 
4141 }
4142 
4144  return NULL;
4145 }
4146 
4148  return NULL;
4149 }
4150 
4151 Account_Char *account_char_load(const char *account_name) {
4152  return NULL;
4153 }
4154 
4155 void account_char_save(const char *account, Account_Char *chars) {
4156 }
4157 
4159 }
4160 
4161 void command_help(object* ob, const char *params) {
4162 }
4163 
4164 #endif /* dummy DOXYGEN_SHOULD_SKIP_THIS */
struct_map_info::tiles
struct struct_map_info * tiles[4]
Definition: mapper.c:292
struct_region_info::sum_x
int sum_x
Definition: mapper.c:461
write_maps_index
static void write_maps_index(void)
Definition: mapper.c:2328
give.next
def next
Definition: give.py:44
color_slowing
static int color_slowing
Definition: mapper.c:480
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1778
do_regions_link
static int do_regions_link
Definition: mapper.c:487
sort_map_info
static int sort_map_info(const void *left, const void *right)
Definition: mapper.c:1145
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:184
move_firewall
void move_firewall(object *ob)
Definition: mapper.c:4050
races
static struct_race_list races
Definition: mapper.c:324
map_one_quest_template
static char * map_one_quest_template
Definition: mapper.c:427
Settings::mapdir
const char * mapdir
Definition: global.h:246
global.h
tolower
#define tolower(C)
Definition: c_new.c:30
quest_for_each
void quest_for_each(quest_op op, void *user)
Definition: quest.c:1408
is_special_equipment
static int is_special_equipment(object *item)
Definition: mapper.c:523
world_map
static int world_map
Definition: mapper.c:381
object_free
void object_free(object *ob, int flags)
Definition: object.c:1573
struct_equipment::diff
char * diff
Definition: mapper.c:306
banquet.l
l
Definition: banquet.py:164
spell_arrow.archetype
archetype
Definition: spell_arrow.py:11
object_remove
void object_remove(object *op)
Definition: object.c:1814
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:728
map_monster_after_template
static char * map_monster_after_template
Definition: mapper.c:404
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
add_monster
static void add_monster(object *monster, struct_map_info *map)
Definition: mapper.c:746
sort_map_info_by_level
static int sort_map_info_by_level(const void *left, const void *right)
Definition: mapper.c:1161
llevError
@ llevError
Definition: logger.h:11
regions_link_allocated
static int regions_link_allocated
Definition: mapper.c:490
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:194
ignore_path
static const char * ignore_path[]
Definition: mapper.c:3214
maps
static std::unordered_map< std::string, mapzone * > maps
Definition: citylife.cpp:93
MOVE_ALL
#define MOVE_ALL
Definition: define.h:398
output_extensions
static const char * output_extensions[]
Definition: mapper.c:440
index_region_region_template
static char * index_region_region_template
Definition: mapper.c:415
struct_region_info::is_world
int is_world
Definition: mapper.c:462
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
struct_map_info::tiled_group
struct struct_map_info * tiled_group
Definition: mapper.c:289
struct_race_list
struct struct_race_list struct_race_list
struct_map_info::filename
char * filename
Definition: mapper.c:274
do_quest_item
static void do_quest_item(const quest_definition *quest, FILE *file)
Definition: mapper.c:3557
strdup_local
#define strdup_local
Definition: compat.h:29
do_exit_map
static void do_exit_map(mapstruct *map)
Definition: mapper.c:846
diamondslots.x
x
Definition: diamondslots.py:15
write_race_index
static void write_race_index(void)
Definition: mapper.c:3181
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
struct_quest::maps
struct_map_in_quest_list maps
Definition: mapper.c:1201
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
struct_race::count
int count
Definition: mapper.c:320
slaying_count
static int slaying_count
Definition: mapper.c:507
struct_map_in_quest::map
struct_map_info * map
Definition: mapper.c:1192
S_KEY
#define S_KEY
Definition: mapper.c:494
clean_tmp_files
void clean_tmp_files(void)
Definition: mapper.c:4056
fix_map_names
static void fix_map_names(void)
Definition: mapper.c:2709
struct_npc_info
struct struct_npc_info struct_npc_info
make_face_from_files.type
type
Definition: make_face_from_files.py:24
force_pics
static int force_pics
Definition: mapper.c:373
color_blocking
static int color_blocking
Definition: mapper.c:479
sizes
static int sizes[]
Definition: mapper.c:375
calc_item_power
int calc_item_power(const object *op)
Definition: item.c:238
Settings::datadir
const char * datadir
Definition: global.h:243
c
static event_registration c
Definition: citylife.cpp:410
disinfect.a
a
Definition: disinfect.py:13
entry
Definition: entry.py:1
manor.params
params
Definition: manor.py:295
Ice.g
def g
Definition: Ice.py:63
quest_map_template
static char * quest_map_template
Definition: mapper.c:423
pl
Definition: player.h:92
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:439
map_monster_one_template
static char * map_monster_one_template
Definition: mapper.c:403
dump
static int dump(const std::set< std::string > &items, const char *name)
Definition: AssetsManager.cpp:54
struct_map_in_quest_list::allocated
int allocated
Definition: mapper.c:260
get_ob_diff
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Definition: object.c:4960
guildoracle.list
list
Definition: guildoracle.py:87
struct_map_in_quest
Definition: mapper.c:1189
map_exit_template
static char * map_exit_template
Definition: mapper.c:394
region_allocated
static int region_allocated
Definition: mapper.c:467
struct_map_list::count
int count
Definition: mapper.c:266
created_pics
static int created_pics
Definition: mapper.c:430
struct_race_list::count
int count
Definition: mapper.c:252
do_auto_apply
void do_auto_apply(mapstruct *m)
Definition: mapper.c:3936
struct_map_list
Definition: mapper.c:264
guildjoin.ob
ob
Definition: guildjoin.py:42
struct_equipment::origin
struct_map_list origin
Definition: mapper.c:307
find_faceset
face_sets * find_faceset(int id)
Definition: assets.cpp:348
python_event.path
path
Definition: python_event.py:11
system_quests
static const quest_definition * system_quests[500]
Definition: mapper.c:3541
init_struct_map_in_quest_list
static void init_struct_map_in_quest_list(struct_map_in_quest_list *list)
Definition: mapper.c:1210
get_region_longname
const char * get_region_longname(const region *r)
Definition: region.c:217
S_DOOR
#define S_DOOR
Definition: mapper.c:493
mail_login.total
total
Definition: mail_login.py:30
commongive.inv
inv
Definition: commongive.py:28
account_char_save
void account_char_save(const char *account, Account_Char *chars)
Definition: mapper.c:4155
S_MAX
#define S_MAX
Definition: mapper.c:498
write_region_page
static void write_region_page(struct_region_info *reg)
Definition: mapper.c:2283
mapdef::in_memory
uint32_t in_memory
Definition: map.h:344
index_region_template
static char * index_region_template
Definition: mapper.c:414
struct_map_info::name
char * name
Definition: mapper.c:273
world_row_template
static char * world_row_template
Definition: mapper.c:388
struct_slaying_info::maps
struct_map_list maps[S_MAX]
Definition: mapper.c:503
mad_mage_user.file
file
Definition: mad_mage_user.py:15
MIN
#define MIN(x, y)
Definition: compat.h:21
write_slaying_map_name
static void write_slaying_map_name(FILE *file, struct_map_info *map)
Definition: mapper.c:3375
map_template
static char * map_template
Definition: mapper.c:391
write_world_info
static void write_world_info(void)
Definition: mapper.c:3306
map_limit
static int map_limit
Definition: mapper.c:379
emergency_save
void emergency_save(int x)
Definition: mapper.c:4053
struct_region_info::sum_y
int sum_y
Definition: mapper.c:461
create_pathname
char * create_pathname(const char *name, char *buf, size_t size)
Definition: map.c:113
init_regions
int init_regions(void)
Definition: region.c:293
write_all_regions
static void write_all_regions(void)
Definition: mapper.c:2316
write_map_page
static void write_map_page(struct_map_info *map)
Definition: mapper.c:2537
region_map_template
static char * region_map_template
Definition: mapper.c:412
struct_map_info
Definition: mapper.c:271
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Definition: path.c:172
struct_map_info::min_monster
int min_monster
Definition: mapper.c:277
do_tiled_map_picture
static void do_tiled_map_picture(struct_map_info *map)
Definition: mapper.c:2917
world_template
static char * world_template
Definition: mapper.c:387
Ice.tmp
int tmp
Definition: Ice.py:207
sort_equipment
static int sort_equipment(const void *a, const void *b)
Definition: mapper.c:699
struct_npc_list::allocated
int allocated
Definition: mapper.c:246
struct_region_info
Definition: mapper.c:458
write_slaying_info
static void write_slaying_info(void)
Definition: mapper.c:3434
map_no_monster_template
static char * map_no_monster_template
Definition: mapper.c:400
OF_PNG
@ OF_PNG
Definition: mapper.c:435
find_player_partial_name
player * find_player_partial_name(const char *name)
Definition: mapper.c:4147
create_map_info
static struct_map_info * create_map_info(void)
Definition: mapper.c:1568
found_maps_allocated
static int found_maps_allocated
Definition: mapper.c:472
flags
static const flag_definition flags[]
Definition: gridarta-types-convert.c:101
first_map_path
EXTERN char first_map_path[MAX_BUF]
Definition: global.h:143
struct_equipment::name
char * name
Definition: mapper.c:303
found_maps
static char ** found_maps
Definition: mapper.c:470
get_map_info
static struct_map_info * get_map_info(const char *path)
Definition: mapper.c:1642
struct_region_info
struct struct_region_info struct_region_info
smoking_pipe.color
color
Definition: smoking_pipe.py:5
detail_quests
static bool detail_quests
Definition: mapper.c:384
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:242
add_race_to_list
static void add_race_to_list(struct_race *race, struct_race_list *list, int check)
Definition: mapper.c:347
account_char_free
void account_char_free(Account_Char *chars)
Definition: mapper.c:4158
find_maps
static void find_maps(const char *from)
Definition: mapper.c:3238
struct_map_info::max_monster
int max_monster
Definition: mapper.c:277
apply_auto_fix
void apply_auto_fix(mapstruct *m)
Definition: mapper.c:4140
is_valid_faceset
int is_valid_faceset(int fsn)
Definition: image.c:116
is_road
static int is_road(object *item)
Definition: mapper.c:781
fix_exits_for_map
static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from)
Definition: mapper.c:2798
struct_slaying_info
Definition: mapper.c:501
account_char_struct
Definition: account_char.h:12
get_equipment
static struct_equipment * get_equipment(void)
Definition: mapper.c:542
struct_equipment::calc_power
int calc_power
Definition: mapper.c:305
is_blocking
static int is_blocking(object *item)
Definition: mapper.c:817
draw_ext_info
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *txt)
Definition: mapper.c:4034
make_path_to_file
void make_path_to_file(const char *filename)
Definition: porting.c:162
quest_step_definition
Definition: quest.h:33
sort_system_quest_step
static int sort_system_quest_step(const void *a, const void *b)
Definition: mapper.c:3553
MAX
#define MAX(x, y)
Definition: compat.h:24
struct_map_in_quest
struct struct_map_in_quest struct_map_in_quest
S_CONTAINER
#define S_CONTAINER
Definition: mapper.c:495
FLAG_NO_PICK
#define FLAG_NO_PICK
Definition: define.h:239
find_artifact
const artifact * find_artifact(const object *op, const char *name)
Definition: artifact.c:657
process_map_lore
static void process_map_lore(struct_map_info *map)
Definition: mapper.c:1346
reputation_trigger_connect.check
def check()
Definition: reputation_trigger_connect.py:18
struct_quest
Definition: mapper.c:1196
create_tiled_map
static struct_map_info * create_tiled_map(void)
Definition: mapper.c:1590
settings
struct Settings settings
Definition: init.c:39
struct_map_in_quest_list
Definition: mapper.c:257
struct_region_info::reg
region * reg
Definition: mapper.c:459
init_readable
void init_readable(void)
Definition: readable.c:899
is_slaying
static int is_slaying(object *item)
Definition: mapper.c:1779
struct_map_in_quest::quest
struct struct_quest * quest
Definition: mapper.c:1194
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4362
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Definition: define.h:366
identify
object * identify(object *op)
Definition: item.c:1398
map_with_quests_template
static char * map_with_quests_template
Definition: mapper.c:426
struct_quest::description
char * description
Definition: mapper.c:1198
generate_index
static int generate_index
Definition: mapper.c:374
do_template
static char * do_template(const char *template, const char **vars, const char **values)
Definition: mapper.c:985
regiondef::next
struct regiondef * next
Definition: map.h:276
m
static event_registration m
Definition: citylife.cpp:410
quest
Definition: quest.py:1
autojail.who
who
Definition: autojail.py:3
esrv_del_item
void esrv_del_item(player *pl, object *ob)
Definition: mapper.c:4072
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Definition: map.h:131
ignore_name
static const char * ignore_name[]
Definition: mapper.c:3225
item.q
q
Definition: item.py:32
opendir
DIR * opendir(const char *)
write_regions_link
static void write_regions_link(void)
Definition: mapper.c:3348
quest_step_definition::next
struct quest_step_definition * next
Definition: quest.h:37
regions_link
static char ** regions_link
Definition: mapper.c:488
disinfect.map
map
Definition: disinfect.py:4
set_darkness_map
void set_darkness_map(mapstruct *m)
Definition: mapper.c:4065
sort_race
static int sort_race(const void *a, const void *b)
Definition: mapper.c:768
do_map_index
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)
Definition: mapper.c:2148
struct_npc_info::y
int y
Definition: mapper.c:239
struct_map_info::exits_from
struct_map_list exits_from
Definition: mapper.c:278
Settings::debug
LogLevel debug
Definition: global.h:239
artifact
struct artifactstruct artifact
struct_npc_info::message
const char * message
Definition: mapper.c:238
infomap
static gdImagePtr infomap
Definition: mapper.c:475
equipment_allocated
static int equipment_allocated
Definition: mapper.c:314
equipment_count
static int equipment_count
Definition: mapper.c:312
struct_map_info::pic_was_done
int pic_was_done
Definition: mapper.c:277
show_maps
static int show_maps
Definition: mapper.c:380
map_no_exit_to_template
static char * map_no_exit_to_template
Definition: mapper.c:395
struct_map_info
struct struct_map_info struct_map_info
do_parameters
static void do_parameters(int argc, char **argv)
Definition: mapper.c:3663
cached_pics
static int cached_pics
Definition: mapper.c:431
warn_no_path
static int warn_no_path
Definition: mapper.c:455
struct_npc_info
Definition: mapper.c:236
quest_template
static char * quest_template
Definition: mapper.c:422
add_map
static void add_map(struct_map_info *info, struct_map_list *list)
Definition: mapper.c:1547
struct_race_list::allocated
int allocated
Definition: mapper.c:253
sort_slaying
static int sort_slaying(const void *left, const void *right)
Definition: mapper.c:3424
struct_npc_list::count
int count
Definition: mapper.c:245
OF_JPG
@ OF_JPG
Definition: mapper.c:436
num_sizes
static const int num_sizes
Definition: mapper.c:376
world_map_template
static char * world_map_template
Definition: mapper.c:389
sortbyname
static int sortbyname(const void *a, const void *b)
Definition: mapper.c:900
color_unlinked_exit
static int color_unlinked_exit
Definition: mapper.c:476
rod_adjust
void rod_adjust(object *rod)
Definition: mapper.c:4081
init_gods
void init_gods(void)
Definition: holy.c:86
player_get_delayed_buffer
SockList * player_get_delayed_buffer(player *pl)
Definition: mapper.c:4143
readdir
struct dirent * readdir(DIR *)
struct_race::name
char * name
Definition: mapper.c:319
regions_link_count
static int regions_link_count
Definition: mapper.c:489
struct_equipment::power
int power
Definition: mapper.c:304
find_skill_by_number
object * find_skill_by_number(object *who, int skillno)
Definition: mapper.c:4068
get_elevation_color
static int get_elevation_color(int elevation, gdImagePtr elevationmap)
Definition: mapper.c:831
tiled_map_list
static struct_map_list tiled_map_list
Definition: mapper.c:299
struct_race::origin
struct_map_list origin
Definition: mapper.c:321
Ice.b
b
Definition: Ice.py:48
regiondef::name
char * name
Definition: map.h:277
struct_map_info::quests
struct_map_in_quest_list quests
Definition: mapper.c:280
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
struct_map_info::width
int width
Definition: mapper.c:290
command_help
void command_help(object *ob, const char *params)
Definition: mapper.c:4161
write_tiled_map_page
static void write_tiled_map_page(struct_map_info *map)
Definition: mapper.c:3048
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
check_equipment
static void check_equipment(object *item, struct_map_info *map)
Definition: mapper.c:682
face_info::data
uint8_t * data
Definition: image.h:11
index_map
static char * index_map
Definition: mapper.c:408
size_small
#define size_small
Definition: mapper.c:378
color_linked_exit
static int color_linked_exit
Definition: mapper.c:477
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:675
map_with_exit_template
static char * map_with_exit_template
Definition: mapper.c:393
struct_map_info::tiled_y_from
int tiled_y_from
Definition: mapper.c:291
get_race
static struct_race * get_race(const char *name)
Definition: mapper.c:717
struct_race_list::races
struct struct_race ** races
Definition: mapper.c:251
add_npc_to_map
static void add_npc_to_map(struct_npc_list *list, const object *npc)
Definition: mapper.c:1525
sstring
const typedef char * sstring
Definition: global.h:40
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Definition: define.h:272
disinfect.count
int count
Definition: disinfect.py:7
say.max
dictionary max
Definition: say.py:148
get_quest_info
static struct_quest * get_quest_info(const char *name)
Definition: mapper.c:1246
object_give_identified_properties
void object_give_identified_properties(object *op)
Definition: item.c:1333
esrv_update_spells
void esrv_update_spells(player *pl)
Definition: mapper.c:4078
write_quests_page
static void write_quests_page(void)
Definition: mapper.c:1419
doors_galore.process
def process()
Definition: doors_galore.py:72
add_to_struct_map_in_quest_list
static void add_to_struct_map_in_quest_list(struct_map_in_quest_list *list, struct_map_in_quest *item)
Definition: mapper.c:1216
sproto.h
IS_SHIELD
#define IS_SHIELD(op)
Definition: define.h:170
apply_auto
int apply_auto(object *op)
Definition: mapper.c:4088
mapdef
Definition: map.h:324
write_world_map
static void write_world_map(void)
Definition: mapper.c:2391
write_maps_by_level
static void write_maps_by_level(void)
Definition: mapper.c:3070
struct_race_list
Definition: mapper.c:250
struct_race
Definition: mapper.c:318
logfile
EXTERN FILE * logfile
Definition: global.h:136
struct_map_list::maps
struct struct_map_info ** maps
Definition: mapper.c:265
delete_map
void delete_map(mapstruct *m)
Definition: map.c:1716
struct_equipment
struct struct_equipment struct_equipment
dump_unused_maps
static void dump_unused_maps(void)
Definition: mapper.c:3283
init_globals
void init_globals(void)
Definition: init.c:267
map_no_quest_template
static char * map_no_quest_template
Definition: mapper.c:425
image.h
struct_map_info::level
int level
Definition: mapper.c:277
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
level_map_template
static char * level_map_template
Definition: mapper.c:419
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:78
cat_template
static char * cat_template(char *source, char *add)
Definition: mapper.c:914
struct_quest::mainmap
struct_map_info * mainmap
Definition: mapper.c:1200
read_template
static void read_template(const char *name, char **buffer)
Definition: mapper.c:933
quests
static struct_quest ** quests
Definition: mapper.c:1204
MAX_BUF
#define MAX_BUF
Definition: define.h:35
object_get_multi_size
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
Definition: object.c:4739
artifactstruct
Definition: artifact.h:14
map_no_lore_template
static char * map_no_lore_template
Definition: mapper.c:399
ensure_unique
static struct_equipment * ensure_unique(struct_equipment *item)
Definition: mapper.c:569
color_road
static int color_road
Definition: mapper.c:478
root
static char root[500]
Definition: mapper.c:366
output_format_type
output_format_type
Definition: mapper.c:434
pics_allocated
static int pics_allocated
Definition: mapper.c:369
struct_map_info::tiled_x_from
int tiled_x_from
Definition: mapper.c:291
define_quest
static void define_quest(const char *name, struct_map_info *mainmap, const char *description)
Definition: mapper.c:1327
region_template
static char * region_template
Definition: mapper.c:410
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.c:518
world_exit_info
static int world_exit_info
Definition: mapper.c:382
StringBuffer
Definition: stringbuffer.c:25
size_large
#define size_large
Definition: mapper.c:377
list_system_quests
static bool list_system_quests
Definition: mapper.c:385
write_region_index
static void write_region_index(void)
Definition: mapper.c:2350
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:721
map_no_exit_template
static char * map_no_exit_template
Definition: mapper.c:392
process_map
static void process_map(struct_map_info *info)
Definition: mapper.c:1880
struct_map_info::exits_to
struct_map_list exits_to
Definition: mapper.c:279
struct_map_info::lore
char * lore
Definition: mapper.c:275
quest_callback
static void quest_callback(const quest_definition *quest, void *user)
Definition: mapper.c:3543
map_with_exit_to_template
static char * map_with_exit_to_template
Definition: mapper.c:396
list_map
static void list_map(const char *path)
Definition: mapper.c:1670
struct_quest
struct struct_quest struct_quest
make_face_from_files.out
out
Definition: make_face_from_files.py:74
main
int main(int argc, char **argv)
Definition: mapper.c:3755
quest.h
dirent
#define dirent
Definition: xdir.h:12
struct_map_info::path
char * path
Definition: mapper.c:272
special_equipment
static struct_equipment ** special_equipment
Definition: mapper.c:310
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.c:74
create_npc_info
static struct_npc_info * create_npc_info(const object *npc)
Definition: mapper.c:1507
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Definition: define.h:246
struct_map_in_quest_list::count
int count
Definition: mapper.c:259
tiled_map_need_pic
static int tiled_map_need_pic(struct_map_info *map)
Definition: mapper.c:2885
jpeg_quality
static int jpeg_quality
Definition: mapper.c:449
struct_region_info::sum
int sum
Definition: mapper.c:461
do_help
static void do_help(const char *program)
Definition: mapper.c:3628
ext_info_map
void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Definition: mapper.c:4046
struct_race
struct struct_race struct_race
init_map_list
static void init_map_list(struct_map_list *list)
Definition: mapper.c:515
IS_ARMOR
#define IS_ARMOR(op)
Definition: define.h:166
save_picture
static void save_picture(FILE *file, gdImagePtr pic)
Definition: mapper.c:1727
relative_path
static void relative_path(const char *from, const char *to, char *result)
Definition: mapper.c:1053
struct_region_info::maps_list
struct_map_list maps_list
Definition: mapper.c:460
VARSADD
#define VARSADD
item
Definition: item.py:1
struct_map_info::processed
int processed
Definition: mapper.c:291
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
get_face_fallback
int get_face_fallback(int faceset, uint16_t imageno)
Definition: image.c:132
generate_pics
static int generate_pics
Definition: mapper.c:372
write_npc_list
static void write_npc_list(void)
Definition: mapper.c:3473
give.op
op
Definition: give.py:33
autojail.value
value
Definition: autojail.py:6
add_map_to_quest
static void add_map_to_quest(struct_map_info *map, const char *name, const char *description)
Definition: mapper.c:1275
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Definition: define.h:250
esrv_update_item
void esrv_update_item(int flags, object *pl, object *op)
Definition: mapper.c:4075
regions
static struct struct_region_info ** regions
Definition: mapper.c:465
quest_definition
Definition: quest.h:42
struct_map_info::monsters
struct_race_list monsters
Definition: mapper.c:284
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:266
add_one_item
static void add_one_item(object *item, struct_map_info *map)
Definition: mapper.c:608
get_region_struct
region * get_region_struct(void)
Definition: region.c:326
found_maps_count
static int found_maps_count
Definition: mapper.c:471
struct_map_in_quest::description
char * description
Definition: mapper.c:1193
slaying_info
static struct_slaying_info ** slaying_info
Definition: mapper.c:506
quests_allocated
static int quests_allocated
Definition: mapper.c:1208
convert.dest
dest
Definition: convert.py:25
struct_map_list::allocated
int allocated
Definition: mapper.c:267
free_equipment
static void free_equipment(struct_equipment *equip)
Definition: mapper.c:555
output_format
static enum output_format_type output_format
Definition: mapper.c:446
struct_map_info::tiled_maps
struct_map_list tiled_maps
Definition: mapper.c:282
map_monster_between_template
static char * map_monster_between_template
Definition: mapper.c:402
guild_entry.found
int found
Definition: guild_entry.py:46
diamondslots.y
y
Definition: diamondslots.py:16
CLEAR_FLAG
#define CLEAR_FLAG(xyz, p)
Definition: define.h:225
npc_dialog.index
int index
Definition: npc_dialog.py:102
mapdef::reset_time
uint32_t reset_time
Definition: map.h:331
merge_tiled_maps
static void merge_tiled_maps(struct_map_info *map, int tile, struct_map_info *tiled_map)
Definition: mapper.c:1608
face_info::datalen
uint16_t datalen
Definition: image.h:12
struct_map_in_quest_list::list
struct struct_map_in_quest ** list
Definition: mapper.c:258
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:80
add_map_to_slaying
static void add_map_to_slaying(struct_slaying_info *info, int item, struct_map_info *map)
Definition: mapper.c:1826
struct_quest::number
int number
Definition: mapper.c:1199
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2828
quests_count
static int quests_count
Definition: mapper.c:1206
struct_map_info::cfregion
region * cfregion
Definition: mapper.c:276
elevation_max
static int elevation_max
Definition: mapper.c:484
object_update_speed
void object_update_speed(object *op)
Definition: object.c:1311
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
region_count
static int region_count
Definition: mapper.c:466
region
struct regiondef region
strcasecmp
int strcasecmp(const char *s1, const char *s2)
artifactstruct::item
object * item
Definition: artifact.h:15
write_quests_list
static void write_quests_list(void)
Definition: mapper.c:3595
npc_dialog.npc
npc
Definition: npc_dialog.py:95
sort_region
static int sort_region(const void *left, const void *right)
Definition: mapper.c:1180
region_letter_template
static char * region_letter_template
Definition: mapper.c:411
sort_struct_map_in_quest
static int sort_struct_map_in_quest(const void *left, const void *right)
Definition: mapper.c:1297
get_region_msg
const char * get_region_msg(const region *r)
Definition: region.c:238
object_insert_in_map_at
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Definition: object.c:2075
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1541
esrv_send_item
void esrv_send_item(object *ob, object *obx)
Definition: mapper.c:4059
gdfaces
static gdImagePtr * gdfaces
Definition: mapper.c:233
map_monster_before_template
static char * map_monster_before_template
Definition: mapper.c:401
dragon_ability_gain
void dragon_ability_gain(object *ob, int x, int y)
Definition: mapper.c:4062
regiondef::fallback
int8_t fallback
Definition: map.h:294
SIZE
#define SIZE
struct_map_info::height
int height
Definition: mapper.c:290
sort_mapname
static int sort_mapname(const void *left, const void *right)
Definition: mapper.c:1092
struct_npc_info::x
int x
Definition: mapper.c:239
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
struct_npc_list::npc
struct_npc_info ** npc
Definition: mapper.c:244
struct_map_info::readable
struct_npc_list readable
Definition: mapper.c:287
map_exit_to_template
static char * map_exit_to_template
Definition: mapper.c:397
write_readable_list
static void write_readable_list(void)
Definition: mapper.c:3509
compare_map_info
static int compare_map_info(const struct_map_info *left, const struct_map_info *right)
Definition: mapper.c:1120
sort_system_quest
static int sort_system_quest(const void *a, const void *b)
Definition: mapper.c:3549
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:274
list_unused_maps
static int list_unused_maps
Definition: mapper.c:469
struct_npc_list
Definition: mapper.c:243
index_template
static char * index_template
Definition: mapper.c:406
system_quests_count
static size_t system_quests_count
Definition: mapper.c:3540
FLAG_IS_LINKED
#define FLAG_IS_LINKED
Definition: define.h:315
struct_npc_info::name
const char * name
Definition: mapper.c:237
add_region_link
static void add_region_link(mapstruct *source, mapstruct *dest, const char *linkname)
Definition: mapper.c:1743
elevation_min
static int elevation_min
Definition: mapper.c:483
S_CONNECT
#define S_CONNECT
Definition: mapper.c:497
say.item
dictionary item
Definition: say.py:149
write_equipment_index
static void write_equipment_index(void)
Definition: mapper.c:3148
init_race_list
static void init_race_list(struct_race_list *list)
Definition: mapper.c:331
struct_quest::name
char * name
Definition: mapper.c:1197
yesno
static const char * yesno(int value)
Definition: mapper.c:3751
init_library
void init_library(void)
Definition: init.c:187
index_letter
static char * index_letter
Definition: mapper.c:407
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:301
draw_ext_info_format
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: mapper.c:4038
write_one_slaying_info
static void write_one_slaying_info(FILE *file, struct_slaying_info *info, int item, const char *with, const char *without)
Definition: mapper.c:3393
face_sets
Definition: image.h:17
replace.current
current
Definition: replace.py:64
get_slaying_struct
static struct_slaying_info * get_slaying_struct(const char *slaying)
Definition: mapper.c:1792
closedir
int closedir(DIR *)
check_slaying_inventory
static void check_slaying_inventory(struct_map_info *map, object *item)
Definition: mapper.c:1864
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
first_region
EXTERN region * first_region
Definition: global.h:117
fix_tiled_map_monsters
static void fix_tiled_map_monsters(void)
Definition: mapper.c:2845
write_all_maps
static void write_all_maps(void)
Definition: mapper.c:2873
regiondef::longname
char * longname
Definition: map.h:290
fix_exits_to_tiled_maps
static void fix_exits_to_tiled_maps(void)
Definition: mapper.c:2817
map_lore_template
static char * map_lore_template
Definition: mapper.c:398
struct_equipment
Definition: mapper.c:302
face_sets::faces
face_info * faces
Definition: image.h:26
SockList
Definition: newclient.h:681
IS_ARROW
#define IS_ARROW(op)
Definition: define.h:178
level_value_template
static char * level_value_template
Definition: mapper.c:418
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:668
init_npc_list
static void init_npc_list(struct_npc_list *list)
Definition: mapper.c:1494
takeitem.status
status
Definition: takeitem.py:35
tileset
static int tileset
Definition: mapper.c:383
index_quest_template
static char * index_quest_template
Definition: mapper.c:421
write_tiled_maps
static void write_tiled_maps(void)
Definition: mapper.c:3058
add_map_to_region
static void add_map_to_region(struct_map_info *map, region *reg)
Definition: mapper.c:1693
maps_list
static struct_map_list maps_list
Definition: mapper.c:296
slaying_allocated
static int slaying_allocated
Definition: mapper.c:508
struct_slaying_info::slaying
char * slaying
Definition: mapper.c:502
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
fix_tiled_map
static void fix_tiled_map(void)
Definition: mapper.c:2729
struct_npc_list
struct struct_npc_list struct_npc_list
account_char_load
Account_Char * account_char_load(const char *account_name)
Definition: mapper.c:4151
elevation_info
static int ** elevation_info
Definition: mapper.c:482
struct_map_info::npcs
struct_npc_list npcs
Definition: mapper.c:286
FLAG_IS_FLOOR
#define FLAG_IS_FLOOR
Definition: define.h:302
create_destination
static void create_destination(void)
Definition: mapper.c:3735
add_slaying
static void add_slaying(struct_map_info *map, object *item)
Definition: mapper.c:1838
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261
find_quest_info
static struct_quest * find_quest_info(const char *name)
Definition: mapper.c:1229
give.name
name
Definition: give.py:27
level_template
static char * level_template
Definition: mapper.c:417
level
Definition: level.py:1
rawmaps
static int rawmaps
Definition: mapper.c:452
regiondef
Definition: map.h:275