Crossfire Server, Trunk
mapper.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire map browser generator.
3  *
4  * Author: Nicolas Weeger <nicolas.weeger@laposte.net>, (C) 2006-2021.
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 
146 #include <ctype.h>
147 #include <errno.h>
148 #include <stdio.h>
149 #include <stdlib.h>
150 #include <string.h>
151 #include <strings.h>
152 #include <sys/stat.h>
153 #include <sys/types.h>
154 #include <time.h>
155 
156 extern "C" {
157 #include "global.h"
158 #include "sproto.h"
159 #include "image.h"
160 #include "quest.h"
161 
162 #include <gd.h>
163 #include <gdfonts.h>
164 #include <gdfontl.h>
165 #include <gdfontg.h>
166 }
167 
168 #include "inja.hpp"
169 #include <map>
170 #include <set>
171 
172 static gdImagePtr *gdfaces;
173 
175 typedef struct struct_npc_info {
176  const char *name;
177  const char *message;
178  int x, y;
180 
182 typedef struct struct_npc_list {
184  size_t count;
185  size_t allocated;
187 
189 typedef struct struct_race_list {
190  struct struct_race **races;
191  size_t count;
192  size_t allocated;
194 
196 typedef struct {
198  size_t count;
199  size_t allocated;
201 
203 typedef struct {
205  size_t count;
206  size_t allocated;
208 
210 typedef struct struct_map_info {
211  char *path;
212  char *name;
213  char *filename;
214  char *lore;
220 
222 
224 
227 
229  int height, width;
231  struct struct_map_info *tiles[4];
233 
236 
239 
241 typedef struct struct_equipment {
242  char *name;
243  int power;
245  char *diff;
248 
251 static size_t equipment_count = 0;
253 static size_t equipment_allocated = 0;
257 typedef struct struct_race {
258  char *name;
259  int count;
261 } struct_race;
262 
271  list->races = NULL;
272  list->count = 0;
273  list->allocated = 0;
274 }
275 
287  if (check) {
288  size_t test;
289 
290  for (test = 0; test < list->count; test++) {
291  if (list->races[test] == race)
292  return;
293  }
294  }
295 
296  if (list->allocated == list->count) {
297  list->allocated += 50;
298  list->races = (struct_race **)realloc(list->races, sizeof(struct_race *)*list->allocated);
299  }
300  list->races[list->count] = race;
301  list->count++;
302 }
303 
305 static char root[500];
306 
308 static int pics_allocated;
309 
310 /* Options */
311 static int generate_pics = 1;
312 static int force_pics = 0;
313 static int sizes[] = {32, 16, 8, 4, 2};
314 static const int num_sizes = sizeof(sizes)/sizeof(int);
315 #define size_large sizes[0]
316 #define size_small sizes[1]
317 static int map_limit = -1;
318 static int show_maps = 0;
319 static int world_map = 1;
320 static int world_exit_info = 1;
321 static int tileset = 0;
322 static bool detail_quests = false;
323 static bool list_system_quests = false;
324 static bool display_rendered_template = false;
327 static int created_pics = 0;
328 static int cached_pics = 0;
332  OF_PNG = 0,
333  OF_JPG = 1
334 };
335 
337 static const char *output_extensions[] = {
338  ".png",
339  ".jpg"
340 };
341 
344 
346 static int jpeg_quality = -1;
347 
349 static int rawmaps = 0;
350 
352 static int warn_no_path = 0;
353 
355 typedef struct struct_region_info {
358  int sum_x, sum_y, sum;
359  int is_world;
361 
362 static struct struct_region_info **regions = NULL;
363 static size_t region_count = 0;
364 static size_t region_allocated = 0;
366 static int list_unused_maps = 0;
367 static char **found_maps = NULL;
368 static int found_maps_count = 0;
369 static int found_maps_allocated = 0;
371 /* Path/exit info */
372 static gdImagePtr infomap;
374 static int color_linked_exit;
375 static int color_road;
376 static int color_blocking;
377 static int color_slowing;
379 static int **elevation_info;
380 static int elevation_min;
381 static int elevation_max;
383 /* Whether to compute links between regions or not (expensive). */
384 static bool do_regions_link = false;
385 /* Links between regions, key is source, value are destinations. */
386 static std::map<region *, std::set<region *>> region_links;
387 
389 #define S_DOOR 0
390 #define S_KEY 1
391 #define S_CONTAINER 2
392 #define S_DETECTOR 3
393 #define S_CONNECT 4
394 #define S_MAX 5
395 
397 typedef struct {
398  char *slaying;
401 
403 static size_t slaying_count = 0;
404 static size_t slaying_allocated = 0;
412  list->maps = NULL;
413  list->count = 0;
414  list->allocated = 0;
415 }
416 
417 static void add_map(struct_map_info *info, struct_map_list *list);
418 
419 static int is_special_equipment(object *item) {
420  if (item->name == item->arch->clone.name && item->title == item->arch->clone.title)
421  return 0;
423  return 0;
424  if (item->move_block == MOVE_ALL)
425  return 0;
426 
427  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))
428  return 1;
429 
430  return 0;
431 }
432 
439  struct_equipment *add = (struct_equipment *)calloc(1, sizeof(struct_equipment));
440 
441  init_map_list(&add->origin);
442  return add;
443 }
444 
451 static void free_equipment(struct_equipment *equip) {
452  free(equip->diff);
453  free(equip->name);
454  free(equip);
455 }
456 
466  struct_equipment *comp;
467 
468  for (size_t check = 0; check < equipment_count; check++) {
469  comp = special_equipment[check];
470 
471  if (strcmp(comp->name, item->name))
472  continue;
473  if (comp->power != item->power)
474  continue;
475  if (comp->calc_power != item->calc_power)
476  continue;
477  if (strcmp(comp->diff, item->diff))
478  continue;
479 
481  return comp;
482  }
483 
485  equipment_allocated += 50;
487  }
489  equipment_count++;
490 
491  return item;
492 }
493 
503 static void add_one_item(object *item, struct_map_info *map) {
506  int x, y;
507  sstring name, namepl;
508  uint32_t nrof;
509  object *base;
510 
511  x = item->x;
512  y = item->y;
513  name = item->name;
514  namepl = item->name_pl;
515  nrof = item->nrof;
516 
517  if (item->artifact != NULL) {
518  const artifact *artifact;
519 
520  artifact = find_artifact(item, item->artifact);
521  if (artifact == NULL) {
522  LOG(llevError, "could not find artifact %s [%d] to save data\n", item->artifact, item->type);
523  base = arch_to_object(item->arch);
524  } else {
525  base = arch_to_object(item->arch);
527  }
528  }
529  else {
530  base = arch_to_object(item->arch);
531  }
532 
533  item->x = base->x;
534  item->y = base->y;
535  item->name = base->name;
536  item->name_pl = base->name_pl;
537  item->nrof = base->nrof;
538 
541  SET_FLAG(base, FLAG_IDENTIFIED);
542  }
544  SET_FLAG(base, FLAG_UNPAID);
545  get_ob_diff(bf, item, base);
547 
548  add->diff = stringbuffer_finish(bf);
549 
550  item->x = x;
551  item->y = y;
552  item->name = name;
553  item->name_pl = namepl;
554  item->nrof = nrof;
555 
556  if (add->diff == NULL || strcmp(add->diff, "") == 0) {
557  free_equipment(add);
558  return;
559  }
560 
561  add->name = strdup(item->name);
562  add->power = item->item_power;
564 
565  add = ensure_unique(add);
566  add_map(map, &add->origin);
567 }
568 
577 static void check_equipment(object *item, struct_map_info *map) {
580 
583  FOR_INV_FINISH();
584 }
585 
594 static int sort_equipment(const void *a, const void *b) {
595  const struct_equipment *l = *(const struct_equipment **)a;
596  const struct_equipment *r = *(const struct_equipment **)b;
597  int c = l->power-r->power;
598 
599  if (c)
600  return c;
601  return strcasecmp(l->name, r->name);
602 }
603 
612 static struct_race *get_race(const char *name) {
613  size_t test;
614  struct_race *item;
615 
616  for (test = 0; test < races.count; test++) {
617  if (strcmp(races.races[test]->name, name) == 0) {
618  races.races[test]->count++;
619  return races.races[test];
620  }
621  }
622 
623  item = (struct_race *)calloc(1, sizeof(struct_race));
624  item->name = strdup(name);
625  item->count = 1;
626  init_map_list(&item->origin);
627 
629 
630  return item;
631 }
632 
641 static void add_monster(object *monster, struct_map_info *map) {
642  struct_race *race;
643 
644  if (monster->head && monster != monster->head)
645  return;
646 
647  map->min_monster = MIN(monster->level, map->min_monster);
648  map->max_monster = MAX(monster->level, map->max_monster);
649 
650  race = get_race(monster->name);
651  add_map(map, &race->origin);
652  add_race_to_list(race, &map->monsters, 1);
653 }
654 
663 static int sort_race(const void *a, const void *b) {
664  const struct_race *l = *(const struct_race **)a;
665  const struct_race *r = *(const struct_race **)b;
666  return strcasecmp(l->name, r->name);
667 }
668 
676 static int is_road(object *item) {
677  int test;
678  /* Archetypes used as roads. */
679  const char *roads[] = {
680  "cobblestones",
681  "flagstone",
682  "ice_stone",
683  "snow",
684  NULL };
685  const char *partial[] = {
686  "dirtroad_",
687  NULL };
688 
689  for (test = 0; partial[test] != NULL; test++) {
690  if (strstr(item->arch->name, partial[test]) != NULL)
691  return 1;
692  }
693 
695  return 0;
696 
697  for (test = 0; roads[test] != NULL; test++) {
698  if (strcmp(item->arch->name, roads[test]) == 0)
699  return 1;
700  }
701 
702  return 0;
703 }
704 
712 static int is_blocking(object *item) {
713  return item->move_block == MOVE_ALL ? 1 : 0;
714 }
715 
726 static int get_elevation_color(int elevation, gdImagePtr elevationmap) {
727  if (elevation > 0)
728  return gdImageColorResolve(elevationmap, 200*elevation/elevation_max, 0, 0);
729  else
730  return gdImageColorResolve(elevationmap, 0, 0, 200*elevation/elevation_min);
731 }
732 
741 static void do_exit_map(mapstruct *map) {
742  int tx, ty, x, y;
743  object *test;
744  sstring selevation;
745 
746  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) != 2)
747  return;
748 
749  x -= 100;
750  y -= 100;
751 
752  for (tx = 0; tx < MAP_WIDTH(map); tx++) {
753  for (ty = 0; ty < MAP_HEIGHT(map); ty++) {
754  FOR_MAP_PREPARE(map, tx, ty, item) {
755  test = HEAD(item);
756 
757  if (test->type == EXIT || test->type == TELEPORTER) {
758  if (!test->slaying)
759  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_unlinked_exit);
760  else
761  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_linked_exit);
762  } else if (is_road(test))
763  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_road);
764  else if (is_blocking(test)) {
765  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_blocking);
766  /* can't get on the spot, so no need to go on. */
767  break;
768  } else if (test->move_slow != 0)
769  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_slowing);
770 
771  selevation = object_get_value(item, "elevation");
772  if (selevation) {
773  int32_t elevation = atoi(selevation);
774  elevation_min = MIN(elevation_min, elevation);
775  elevation_max = MAX(elevation_max, elevation);
776  elevation_info[x*50+tx][y*50+ty] = elevation;
777  }
778  } FOR_MAP_FINISH();
779  }
780  }
781 }
782 
783 void do_auto_apply(mapstruct *m);
784 
795 static int sortbyname(const void *a, const void *b) {
796  return (strcmp(*(const char **)a, *(const char **)b));
797 }
798 
811 static void relative_path(const char *from, const char *to, char *result) {
812  const char *fslash;
813  const char *rslash;
814 
815  result[0] = '\0';
816 
817  fslash = strchr(from+1, '/');
818  if (!fslash) {
819  strcpy(result, to+1);
820  return;
821  }
822 
823  rslash = strchr(to+1, '/');
824  while (fslash && rslash && (fslash-from == rslash-to) && strncmp(from, to, fslash-from+1) == 0) {
825  from = fslash+1;
826  to = rslash+1;
827  fslash = strchr(fslash+1, '/');
828  rslash = strchr(rslash+1, '/');
829  }
830 
831  while (fslash) {
832  strcat(result, "../");
833  fslash = strchr(fslash+1, '/');
834  }
835  if (strlen(result) && result[strlen(result)-1] == '/' && *to == '/')
836  result[strlen(result)-1] = '\0';
837  strcat(result, to);
838 }
839 
850 static int compare_map_info(const struct_map_info *left, const struct_map_info *right) {
851  int c;
852 
853  if (left->tiled_group)
854  left = left->tiled_group;
855  if (right->tiled_group)
856  right = right->tiled_group;
857 
858  c = strcasecmp(left->name, right->name);
859  if (c)
860  return c;
861 
862  return strcasecmp(left->path, right->path);
863 }
864 
875 static int sort_map_info(const void *left, const void *right) {
876  const struct_map_info *l = *(const struct_map_info **)left;
877  const struct_map_info *r = *(const struct_map_info **)right;
878  return compare_map_info(l, r);
879 }
880 
891 static int sort_region(const void *left, const void *right) {
892  return strcmp((*((struct_region_info **)left))->reg->name, (*((struct_region_info **)right))->reg->name);
893 }
894 
895 /************************************
896  Start of quest-related definitions.
897 ************************************/
898 
900 typedef struct struct_map_in_quest {
902  char *description;
903  struct struct_quest *quest;
905 
907 typedef struct struct_quest {
908  char *name;
909  char *description;
910  int number;
913 } struct_quest;
914 
915 static struct_quest **quests = NULL;
917 static int quests_count = 0;
919 static int quests_allocated = 0;
922  list->list = NULL;
923  list->count = 0;
924  list->allocated = 0;
925 }
926 
928  if (list->count == list->allocated) {
929  list->allocated += 10;
930  list->list = (struct_map_in_quest **)realloc(list->list, sizeof(struct_map_in_quest *)*list->allocated);
931  }
932  list->list[list->count++] = item;
933 }
934 
940 static struct_quest *find_quest_info(const char *name) {
941  int test;
942  for (test = 0; test < quests_count; test++) {
943  if (strcmp(quests[test]->name, name) == 0)
944  return quests[test];
945  }
946  return NULL;
947 }
948 
957 static struct_quest *get_quest_info(const char *name) {
959  if (add) {
960  return add;
961  }
962 
964  quests_allocated += 10;
965  quests = (struct_quest **)realloc(quests, sizeof(struct_quest *)*quests_allocated);
966  }
967  add = (struct_quest *)calloc(1, sizeof(struct_quest));
968  add->name = strdup(name);
969  add->number = quests_count;
971  quests[quests_count] = add;
972  quests_count++;
973  return add;
974 }
975 
986 static void add_map_to_quest(struct_map_info *map, const char *name, const char *description) {
987  struct_map_in_quest *add;
989 
990  add = (struct_map_in_quest *)calloc(1, sizeof(struct_map_in_quest));
991  add->map = map;
992  add->quest = quest;
993  add->description = strdup(description);
994  while (strlen(add->description) && add->description[strlen(add->description)-1] == '\n')
995  add->description[strlen(add->description)-1] = '\0';
997  add_to_struct_map_in_quest_list(&map->quests, add);
998 }
999 
1008 static int sort_struct_map_in_quest(const void *left, const void *right) {
1009  int c;
1010 
1011  const struct_map_in_quest *l = *(const struct_map_in_quest **)left;
1012  const struct_map_in_quest *r = *(const struct_map_in_quest **)right;
1013  const struct_map_info *ml = l->map;
1014  const struct_map_info *mr = r->map;
1015 
1016  if (ml->tiled_group)
1017  ml = ml->tiled_group;
1018  if (mr->tiled_group)
1019  mr = mr->tiled_group;
1020 
1021  c = strcasecmp(ml->name, mr->name);
1022  if (c)
1023  return c;
1024 
1025  return strcasecmp(ml->path, mr->path);
1026 }
1027 
1036 static int sort_struct_quest(const void *left, const void *right) {
1037  const struct_quest *l = *(const struct_quest **)left;
1038  const struct_quest *r = *(const struct_quest **)right;
1039  return strcasecmp(l->name, r->name);
1040 }
1041 
1052 static void define_quest(const char *name, struct_map_info *mainmap, const char *description) {
1054 
1055  if (quest->description || quest->mainmap) {
1056  printf("warning, multiple quest definition for %s, found in %s and %s.\n", quest->name, quest->mainmap ? quest->mainmap->path : "(unknown map)", mainmap->path);
1057  return;
1058  }
1059  quest->description = strdup(description);
1060  while (strlen(quest->description) && quest->description[strlen(quest->description)-1] == '\n')
1061  quest->description[strlen(quest->description)-1] = '\0';
1062  quest->mainmap = mainmap;
1063 }
1064 
1072  char *start, *end, *next;
1073  char name[500];
1074  char description[500];
1075 
1076  start = strstr(map->lore, "@def");
1077  while (start) {
1078  description[0] = '\0';
1079  /* find name */
1080  end = strstr(start, "\n");
1081  if (end) {
1082  strncpy(name, start+5, end-start-5);
1083  name[end-start-5] = '\0';
1084  next = end+1;
1085  end = strstr(next, "@end");
1086  if (end) {
1087  strncpy(description, next, end-next);
1088  description[end-next] = '\0';
1089  /* need to erase the text. */
1090  memcpy(start, end+4, strlen(map->lore)-(end-start+3));
1091  end = start;
1092  }
1093  else {
1094  strcpy(description, next);
1095  *start = '\0';
1096  end = NULL;
1097  }
1098  } else {
1099  strcpy(name, start);
1100  *start = '\0';
1101  end = NULL;
1102  }
1103 
1104  define_quest(name, map, description);
1105  start = end ? strstr(end, "@def") : NULL;
1106  }
1107 
1108  start = strstr(map->lore, "@quest");
1109  while (start) {
1110  description[0] = '\0';
1111  /* find name */
1112  end = strstr(start, "\n");
1113  if (end) {
1114  strncpy(name, start+7, end-start-7);
1115  name[end-start-7] = '\0';
1116  next = end+1;
1117  end = strstr(next, "@end");
1118  if (end) {
1119  strncpy(description, next, end-next);
1120  description[end-next] = '\0';
1121  /* need to erase the text. */
1122  memcpy(start, end+4, strlen(map->lore)-(end-start+3));
1123  end = start;
1124  }
1125  else {
1126  strcpy(description, next);
1127  *start = '\0';
1128  end = NULL;
1129  }
1130  } else {
1131  strcpy(name, start);
1132  *start = '\0';
1133  end = NULL;
1134  }
1135 
1136  add_map_to_quest(map, name, description);
1137  start = end ? strstr(end, "@quest") : NULL;
1138  }
1139 }
1140 
1141 /************************************
1142  End of quest-related definitions.
1143 ************************************/
1144 
1145 /*********
1146 NPC-related stuff
1147 ********/
1148 
1155  list->allocated = 0;
1156  list->count = 0;
1157  list->npc = NULL;
1158 }
1159 
1167 static struct_npc_info *create_npc_info(const object *npc) {
1168  struct_npc_info *info = (struct_npc_info *)calloc(1, sizeof(struct_npc_info));
1169 
1170  info->name = strdup(npc->name);
1171  info->message = strdup(npc->msg);
1172  info->x = npc->x;
1173  info->y = npc->y;
1174 
1175  return info;
1176 }
1177 
1185 static void add_npc_to_map(struct_npc_list *list, const object *npc) {
1186  if (list->count == list->allocated) {
1187  list->allocated += 50;
1188  list->npc = (struct_npc_info **)realloc(list->npc, list->allocated*sizeof(struct_npc_info *));
1189  }
1190 
1191  list->npc[list->count] = create_npc_info(npc);
1192  list->count++;
1193 }
1194 /* end of NPC stuff */
1195 
1208  size_t map;
1209 
1210  for (map = 0; map < list->count; map++)
1211  if (list->maps[map] == info)
1212  return;
1213 
1214  if (list->count == list->allocated) {
1215  list->allocated += 50;
1216  list->maps = (struct_map_info **)realloc(list->maps, list->allocated*sizeof(struct_map_info *));
1217  }
1218  list->maps[list->count] = info;
1219  list->count++;
1220 }
1221 
1229  struct_map_info *add = (struct_map_info *)calloc(1, sizeof(struct_map_info));
1230 
1231  add->min_monster = 2000;
1232  init_map_list(&add->exits_to);
1233  init_map_list(&add->exits_from);
1234  init_map_list(&add->tiled_maps);
1236  init_race_list(&add->monsters);
1237  init_npc_list(&add->npcs);
1238  init_npc_list(&add->readable);
1239  add->tiled_group = NULL;
1240 
1241  return add;
1242 }
1243 
1252 
1253  add_map(add, &tiled_map_list);
1254  return add;
1255 }
1256 
1267  size_t g;
1268  struct_map_info *group = tiled_map->tiled_group;
1269  struct_map_info *change;
1270 
1271  while (group->tiled_maps.count > 0) {
1272  change = group->tiled_maps.maps[group->tiled_maps.count-1];
1273  change->tiled_group = map->tiled_group;
1274  add_map(change, &map->tiled_group->tiled_maps);
1275  group->tiled_maps.count--;
1276  }
1277 
1278  for (g = 0; g < tiled_map_list.count; g++) {
1279  if (tiled_map_list.maps[g] == group) {
1280  if (g < tiled_map_list.count-1)
1283  free(group);
1284  return;
1285  }
1286  }
1287  printf("tiled_map not in tiled_map_list!");
1288  abort();
1289 
1290 }
1291 
1300 static struct_map_info *get_map_info(const char *path) {
1301  struct_map_info *add;
1302  char *tmp;
1303 
1304  for (size_t map = 0; map < maps_list.count; map++) {
1305  if (strcmp(maps_list.maps[map]->path, path) == 0)
1306  return maps_list.maps[map];
1307  }
1308 
1309  add = create_map_info();
1310  add->path = strdup(path);
1311  tmp = strrchr((char *)path, '/');
1312  if (tmp)
1313  add->filename = strdup(tmp+1);
1314  else
1315  add->filename = strdup(path);
1316 
1317  add_map(add, &maps_list);
1318  return add;
1319 }
1320 
1327 static void list_map(const char *path) {
1328  int index;
1329 
1330  for (index = 0; index < found_maps_count; index++) {
1331  if (found_maps[index] && strcmp(path, found_maps[index]) == 0) {
1332  free(found_maps[index]);
1333  found_maps[index] = NULL;
1334  return;
1335  }
1336  }
1337  printf("Map processed but not found in directory reading? %s\n", path);
1338 }
1339 
1351  size_t test;
1352  int x, y;
1353 
1354  for (test = 0; test < region_count; test++) {
1355  if (regions[test]->reg == reg)
1356  break;
1357  }
1358  if (test == region_count) {
1359  if (test == region_allocated) {
1360  region_allocated++;
1362  regions[test] = (struct_region_info *)calloc(1, sizeof(struct_region_info));
1363  }
1364  region_count++;
1365  regions[test]->reg = reg;
1366  }
1367  add_map(map, &regions[test]->maps_list);
1368  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) == 2) {
1369  regions[test]->sum_x += (x-100);
1370  regions[test]->sum_y += (y-100);
1371  regions[test]->sum++;
1372  regions[test]->is_world = 1;
1373  }
1374 }
1375 
1384 static void save_picture(FILE *file, gdImagePtr pic) {
1385  if (output_format == OF_PNG)
1386  gdImagePng(pic, file);
1387  else
1388  gdImageJpeg(pic, file, jpeg_quality);
1389 }
1390 
1398 static void add_region_link(mapstruct *source, mapstruct *dest) {
1399  region *s, *d;
1400 
1401  s = get_region_by_map(source);
1402  d = get_region_by_map(dest);
1403  if (s == d)
1404  return;
1405 
1406  region_links[s].insert(d);
1407 }
1408 
1417 static int is_slaying(object *item) {
1418  return (item->type == LOCKED_DOOR || item->type == SPECIAL_KEY || item->type == CONTAINER || item->type == CHECK_INV);
1419 }
1420 
1421 
1430 static struct_slaying_info *get_slaying_struct(const char *slaying) {
1431  for (size_t l = 0; l < slaying_count; l++) {
1432  if (!strcmp(slaying_info[l]->slaying, slaying))
1433  return slaying_info[l];
1434  }
1436  slaying_allocated += 10;
1438  }
1439 
1440  struct_slaying_info *add = (struct_slaying_info *)calloc(1, sizeof(struct_slaying_info));
1441  add->slaying = strdup(slaying);
1442  for (size_t l = 0; l < S_MAX; l++)
1443  init_map_list(&add->maps[l]);
1444 
1445  slaying_info[slaying_count] = add;
1446  slaying_count++;
1447 
1448  return add;
1449 }
1450 
1462  add_map(map, &info->maps[item]);
1463 }
1464 
1473 static void add_slaying(struct_map_info *map, object *item) {
1474  struct_slaying_info *info;
1475 
1476  if (!item->slaying)
1477  /* can be undefined */
1478  return;
1479 
1480  info = get_slaying_struct(item->slaying);
1481  if (item->type == LOCKED_DOOR)
1482  add_map_to_slaying(info, S_DOOR, map);
1483  else if (item->type == SPECIAL_KEY)
1484  add_map_to_slaying(info, S_KEY, map);
1485  else if (item->type == CONTAINER)
1487  else if (item->type == DETECTOR)
1489  else
1491 }
1492 
1503  if (is_slaying(inv))
1504  add_slaying(map, inv);
1506  } FOR_INV_FINISH();
1507 }
1508 
1509 static void generate_picture_path(const char *path, size_t pic_size, char *out, size_t len) {
1510  snprintf(out, len, "%s%s.x%zu%s", root, path, pic_size + 1, output_extensions[output_format]);
1511 }
1512 
1513 static void write_pictures_from_real_size(const char *path, gdImagePtr real, int width, int height) {
1514  char picpath[MAX_BUF];
1515 
1516  generate_picture_path(path, 0, picpath, sizeof(picpath));
1517  make_path_to_file(picpath);
1518  FILE *out = fopen(picpath, "wb+");
1519  save_picture(out, real);
1520  fclose(out);
1521 
1522  for (size_t i = 1; i < num_sizes; i++) {
1523  generate_picture_path(path, i, picpath, sizeof(picpath));
1524  gdImagePtr small = gdImageCreateTrueColor(width*sizes[i], height*sizes[i]);
1525  gdImageCopyResampled(small, real, 0, 0, 0, 0, width*sizes[i], height*sizes[i], width*size_large, height*size_large);
1526  out = fopen(picpath, "wb+");
1527  save_picture(out, small);
1528  fclose(out);
1529  gdImageDestroy(small);
1530  }
1531 }
1532 
1541 static void process_map(struct_map_info *info) {
1542  mapstruct *m;
1543  int x, y, isworld;
1544  gdImagePtr pic = nullptr;
1545  struct stat stats;
1546  struct stat statspic;
1547  char exit_path[500];
1548  char tmppath[MAX_BUF];
1549  char picpath[num_sizes][MAX_BUF];
1550  int needpic = 0;
1551  struct_map_info *link;
1552 
1553  if (list_unused_maps)
1554  list_map(info->path);
1555 
1556  if (show_maps)
1557  printf(" processing map %s\n", info->path);
1558 
1559  m = ready_map_name(info->path, 0);
1560  if (!m) {
1561  printf("couldn't load map %s\n", info->path);
1562  return;
1563  }
1564 
1565  do_exit_map(m);
1566 
1567  if (!rawmaps)
1568  do_auto_apply(m);
1569 
1570  info->level = m->difficulty;
1571  if (m->maplore) {
1572  info->lore = strdup(m->maplore);
1573  process_map_lore(info);
1574  }
1575 
1576  isworld = (sscanf(info->path, "/world/world_%d_%d", &x, &y) == 2);
1577 
1578  if (m->name)
1579  info->name = strdup(m->name);
1580  else
1581  info->name = strdup(info->filename);
1582 
1583  info->cfregion = get_region_by_map(m);
1584  add_map_to_region(info, info->cfregion);
1585 
1586  for (int i = 0; i < num_sizes; i++) {
1587  generate_picture_path(info->path, i, picpath[i], sizeof(picpath[i]));
1588  }
1589 
1590  if (force_pics)
1591  needpic = 1;
1592  else if (generate_pics) {
1593  create_pathname(info->path, tmppath, MAX_BUF);
1594  stat(tmppath, &stats);
1595  if (stat(picpath[0], &statspic) || (statspic.st_mtime < stats.st_mtime))
1596  needpic = 1;
1597  }
1598  else
1599  needpic = 0;
1600 
1601  if (needpic) {
1602  pic = gdImageCreateTrueColor(MAP_WIDTH(m)*size_large, MAP_HEIGHT(m)*size_large);
1603  created_pics++;
1604  }
1605  else
1606  cached_pics++;
1607 
1608  for (x = 0; x < 4; x++)
1609  if (m->tile_path[x] != NULL) {
1610  path_combine_and_normalize(m->path, m->tile_path[x], exit_path, sizeof(exit_path));
1611  create_pathname(exit_path, tmppath, MAX_BUF);
1612  if (stat(tmppath, &stats)) {
1613  printf(" map %s doesn't exist in map %s, for tile %d.\n", exit_path, info->path, x);
1614  }
1615 
1616  if (isworld) {
1617  link = get_map_info(exit_path);
1618  add_map(link, &info->exits_from);
1619  add_map(info, &link->exits_to);
1620 
1621  if (do_regions_link) {
1622  mapstruct *link = ready_map_name(exit_path, 0);
1623 
1624  if (link && link != m) {
1625  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
1626  * want to reset it. */
1627  add_region_link(m, link);
1628  link->reset_time = 1;
1629  link->in_memory = MAP_IN_MEMORY;
1630  delete_map(link);
1631  }
1632  }
1633  } else {
1634  link = get_map_info(exit_path);
1635  info->tiles[x] = link;
1636  if (link->tiled_group) {
1637  if (info->tiled_group && link->tiled_group != info->tiled_group) {
1638  merge_tiled_maps(info, link);
1639  continue;
1640  }
1641  if (link->tiled_group == info->tiled_group) {
1642  continue;
1643  }
1644  if (!info->tiled_group) {
1645  add_map(info, &link->tiled_group->tiled_maps);
1646  continue;
1647  }
1648  }
1649 
1650  if (!info->tiled_group) {
1651  info->tiled_group = create_tiled_map();
1652  add_map(info, &info->tiled_group->tiled_maps);
1653  }
1654  link->tiled_group = info->tiled_group;
1655  add_map(link, &info->tiled_group->tiled_maps);
1656  }
1657  }
1658 
1659  info->width = MAP_WIDTH(m);
1660  info->height = MAP_HEIGHT(m);
1661 
1662  for (x = MAP_WIDTH(m)-1; x >= 0; x--)
1663  for (y = MAP_HEIGHT(m)-1; y >= 0; y--) {
1664  FOR_MAP_PREPARE(m, x, y, item) {
1665  if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
1666  char ep[500];
1667  const char *start;
1668 
1669  if (!item->slaying) {
1670  ep[0] = '\0';
1671  if (warn_no_path)
1672  printf(" exit without any path at %d, %d on %s\n", item->x, item->y, info->path);
1673  } else {
1674  memset(ep, 0, 500);
1675  if (strcmp(item->slaying, "/!"))
1676  strcpy(ep, EXIT_PATH(item));
1677  else {
1678  if (!item->msg) {
1679  printf(" random map without message in %s at %d, %d\n", info->path, item->x, item->y);
1680  } else {
1681  /* Some maps have a 'exit_on_final_map' flag, ignore it. */
1682  start = strstr(item->msg, "\nfinal_map ");
1683  if (!start && strncmp(item->msg, "final_map", strlen("final_map")) == 0)
1684  /* Message start is final_map, nice */
1685  start = item->msg;
1686  if (start) {
1687  char *end = strchr((char *)start+1, '\n');
1688 
1689  start += strlen("final_map")+2;
1690  strncpy(ep, start, end-start);
1691  }
1692  }
1693  }
1694 
1695  if (strlen(ep)) {
1696  path_combine_and_normalize(m->path, ep, exit_path, 500);
1697  create_pathname(exit_path, tmppath, MAX_BUF);
1698  if (stat(tmppath, &stats)) {
1699  printf(" map %s doesn't exist in map %s, at %d, %d.\n", ep, info->path, item->x, item->y);
1700  } else {
1701  link = get_map_info(exit_path);
1702  add_map(link, &info->exits_from);
1703  add_map(info, &link->exits_to);
1704 
1705  if (do_regions_link) {
1706  mapstruct *link = ready_map_name(exit_path, 0);
1707 
1708  if (link && link != m) {
1709  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
1710  * want to reset it. */
1711  add_region_link(m, link);
1712  link->reset_time = 1;
1713  link->in_memory = MAP_IN_MEMORY;
1714  delete_map(link);
1715  }
1716  }
1717  }
1718  }
1719  }
1720  } else if (is_slaying(item))
1721  add_slaying(info, item);
1722 
1723  check_equipment(item, info);
1724 
1726 
1727  if (QUERY_FLAG(item, FLAG_MONSTER)) {
1728  /* need to get the "real" archetype, as the item's archetype can certainly be a temporary one. */
1729  archetype *arch = find_archetype(item->arch->name);
1730 
1731  add_monster(item, info);
1732  if (arch != NULL && (QUERY_FLAG(item, FLAG_UNAGGRESSIVE) || QUERY_FLAG(item, FLAG_FRIENDLY)) && (item->msg != arch->clone.msg) && (item->msg != NULL))
1733  add_npc_to_map(&info->npcs, item);
1734  } else if ((item->type == SIGN || item->type == BOOK) && (item->msg != item->arch->clone.msg) && (item->msg != NULL)) {
1735  add_npc_to_map(&info->readable, item);
1736  }
1737 
1738  if (item->invisible)
1739  continue;
1740 
1741  if (needpic) {
1742  int sx, sy, hx, hy;
1743 
1744  if (gdfaces[item->face->number] == NULL) {
1745  face_sets *fs = find_faceset(get_face_fallback(tileset, item->face->number));
1746 
1747  gdfaces[item->face->number] = gdImageCreateFromPngPtr(fs->faces[item->face->number].datalen, fs->faces[item->face->number].data);
1748  pics_allocated++;
1749  }
1750  if (item->head || item->more) {
1751  object_get_multi_size(item, &sx, &sy, &hx, &hy);
1752  } else {
1753  hx = 0;
1754  hy = 0;
1755  }
1756  if (gdfaces[item->face->number] != NULL && ((!item->head && !item->more) || (item->arch->clone.x+hx == 0 && item->arch->clone.y+hy == 0))) {
1757  gdImageCopy(pic, gdfaces[item->face->number], x*size_large, y*size_large, 0, 0, gdfaces[item->face->number]->sx, gdfaces[item->face->number]->sy);
1758  }
1759  }
1760  } FOR_MAP_FINISH();
1761  }
1762 
1763  if (needpic) {
1765  gdImageDestroy(pic);
1766  info->pic_was_done = 1;
1767  }
1768 
1769  m->reset_time = 1;
1770  m->in_memory = MAP_IN_MEMORY;
1771  delete_map(m);
1772 }
1773 
1777 static void write_world_map(void) {
1778 #define SIZE 50
1779  int x, y;
1780  FILE *out;
1781  int wx, wy;
1782  char file[500];
1783  char mapleft[10], maptop[10], mapright[10], mapbottom[10], mappath[5000];
1784  char name[100];
1785  gdImagePtr pic;
1786  gdImagePtr small;
1787  gdFontPtr font;
1788  int color;
1789 
1790  if (!world_map)
1791  return;
1792 
1793  printf("Generating world map in world.html...");
1794  fflush(stdout);
1795 
1796  pic = gdImageCreateTrueColor(SIZE*30, SIZE*30);
1797 
1798  strcpy(file, root);
1799  strcat(file, "/world.html");
1800 
1801  wx = 100;
1802  wy = 100;
1803 
1804  for (y = 0; y < 30; y++) {
1805  for (x = 0; x < 30; x++) {
1806  snprintf(name, sizeof(name), "world_%d_%d", wx, wy);
1807  snprintf(mapleft, sizeof(mapleft), "%d", SIZE*x);
1808  snprintf(maptop, sizeof(maptop), "%d", SIZE*y);
1809  snprintf(mapright, sizeof(mapright), "%d", SIZE*(x+1)-1);
1810  snprintf(mapbottom, sizeof(mapbottom), "%d", SIZE*(y+1)-1);
1811 
1812  snprintf(mappath, sizeof(mappath), "%s/world/%s.x1%s", root, name, output_extensions[output_format]);
1813 
1814  out = fopen(mappath, "rb");
1815  if (!out) {
1816  printf("\n warning: large pic not found for world_%d_%d", wx, wy);
1817  wx++;
1818  continue;
1819  }
1820  if (output_format == OF_PNG)
1821  small = gdImageCreateFromPng(out);
1822  else
1823  small = gdImageCreateFromJpeg(out);
1824  fclose(out);
1825  if (!small) {
1826  printf("\n warning: pic not found for world_%d_%d", wx, wy);
1827  wx++;
1828  continue;
1829  }
1830  gdImageCopyResized(pic, small, SIZE*x, SIZE*y, 0, 0, SIZE, SIZE, small->sx, small->sy);
1831  gdImageDestroy(small);
1832 
1833  wx++;
1834  }
1835  wy++;
1836  wx = 100;
1837  }
1838 
1839  snprintf(mappath, sizeof(mappath), "%s/world_raw%s", root, output_extensions[output_format]);
1840  out = fopen(mappath, "wb+");
1841  save_picture(out, pic);
1842  fclose(out);
1843 
1844  /* Write region names. */
1845  small = gdImageCreateTrueColor(SIZE*30, SIZE*30);
1846  font = gdFontGetGiant();
1847  color = gdImageColorAllocateAlpha(pic, 255, 0, 0, 20);
1848  for (size_t region = 0; region < region_allocated; region++) {
1849  if (!regions[region]->is_world || regions[region]->sum == 0)
1850  continue;
1851 
1852  x = regions[region]->sum_x*SIZE/regions[region]->sum+SIZE/2-strlen(regions[region]->reg->name)*font->w/2;
1853  y = regions[region]->sum_y*SIZE/regions[region]->sum+SIZE/2-font->h/2;
1854  gdImageString(small, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1855  gdImageString(pic, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1856 
1857  /* For exit/road map, size isn't the same. */
1858  x = regions[region]->sum_x*50/regions[region]->sum+50/2-strlen(regions[region]->reg->name)*font->w/2;
1859  y = regions[region]->sum_y*50/regions[region]->sum+50/2-font->h/2;
1860  gdImageString(infomap, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1861  }
1862 
1863  snprintf(mappath, sizeof(mappath), "%s/world_regions%s", root, output_extensions[output_format]);
1864  out = fopen(mappath, "wb+");
1865  save_picture(out, small);
1866  fclose(out);
1867  gdImageDestroy(small);
1868 
1869  snprintf(mappath, sizeof(mappath), "%s/world%s", root, output_extensions[output_format]);
1870  out = fopen(mappath, "wb+");
1871  save_picture(out, pic);
1872  fclose(out);
1873  gdImageDestroy(pic);
1874 
1875  printf(" done.\n");
1876 #undef SIZE
1877 }
1878 
1880 static void fix_map_names(void) {
1881  for (size_t map = 0; map < maps_list.count; map++) {
1882  if (maps_list.maps[map]->name)
1883  continue;
1884  if (!maps_list.maps[map]->filename) {
1885  printf("map without path!\n");
1886  abort();
1887  }
1888  maps_list.maps[map]->name = strdup(maps_list.maps[map]->filename);
1889  }
1890 }
1891 
1898 static void fix_tiled_map(void) {
1899  size_t map, tile;
1900  char name[500];
1901  char *slash, *test;
1902  region *cfregion;
1903 
1904  for (map = 0; map < tiled_map_list.count; map++) {
1905  if (tiled_map_list.maps[map]->tiled_maps.count == 0) {
1906  printf("empty tiled map group!");
1907  abort();
1908  }
1909 
1910  snprintf(name, sizeof(name), "tiled_map_group_%zu", map);
1911  tiled_map_list.maps[map]->filename = strdup(name);
1912 
1913  cfregion = NULL;
1914  test = NULL;
1915 
1916  for (tile = 0; tile < tiled_map_list.maps[map]->tiled_maps.count; tile++) {
1917  if (tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion == NULL)
1918  /* map not processed, ignore it. */
1919  continue;
1920 
1921  if (!cfregion)
1922  cfregion = tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion;
1923  else if (cfregion != tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion) {
1924  printf("*** warning: tiled maps %s and %s not in same region (%s and %s).\n",
1927  cfregion = NULL;
1928  }
1929 
1931  /* map has a custom name, use it */
1932  if (!test)
1933  test = tiled_map_list.maps[map]->tiled_maps.maps[tile]->name;
1934  }
1935  }
1936 
1937  if (!test) {
1938  /* this can happen of course if only partial maps were processed, but well... */
1939  printf("*** warning: tiled map without any name. First map path %s\n", tiled_map_list.maps[map]->tiled_maps.maps[0]->path);
1940  test = name;
1941  }
1942 
1943  tiled_map_list.maps[map]->name = strdup(test);
1944  tiled_map_list.maps[map]->cfregion = cfregion;
1945 
1946  strncpy(name, tiled_map_list.maps[map]->tiled_maps.maps[0]->path, sizeof(name));
1947  slash = strrchr(name, '/');
1948  if (!slash)
1949  snprintf(name, sizeof(name), "/");
1950  else
1951  *(slash+1) = '\0';
1952  strncat(name, tiled_map_list.maps[map]->filename, sizeof(name) - strlen(name) - 1);
1953  tiled_map_list.maps[map]->path = strdup(name);
1954  }
1955 }
1956 
1967 static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from) {
1968  int map, max;
1969  struct_map_info *group;
1970 
1971  max = from->count-1;
1972  for (map = max; map >= 0; map--) {
1973  if (from->maps[map]->tiled_group) {
1974  group = from->maps[map]->tiled_group;
1975  if (map != max)
1976  from->maps[map] = from->maps[max];
1977  from->count--;
1978  max--;
1979  add_map(group, from);
1980  add_map(current->tiled_group ? current->tiled_group : current, is_from ? &group->exits_to : &group->exits_from);
1981  }
1982  }
1983 }
1984 
1986 static void fix_exits_to_tiled_maps(void) {
1987  int map, max;
1988  struct_map_info *group;
1989 
1990  for (map = 0; map < maps_list.count; map++) {
1993  }
1994 
1995  for (size_t region = 0; region < region_count; region++) {
1997  for (map = max; map >= 0; map--) {
2000  if (map != max)
2003  max--;
2004  add_map(group, &regions[region]->maps_list);
2005  }
2006  }
2007  }
2008 }
2009 
2014 static void fix_tiled_map_monsters(void) {
2015  int map, max;
2016  struct_map_info *group;
2017 
2018  for (size_t race = 0; race < races.count; race++) {
2019  max = races.races[race]->origin.count-1;
2020  for (map = max; map >= 0; map--) {
2021  if (races.races[race]->origin.maps[map]->tiled_group) {
2022  group = races.races[race]->origin.maps[map]->tiled_group;
2023  if (map != max)
2024  races.races[race]->origin.maps[map] = races.races[race]->origin.maps[max];
2025  races.races[race]->origin.count--;
2026  max--;
2027  add_map(group, &races.races[race]->origin);
2028  }
2029  }
2030  }
2031 
2032  for (map = 0; map < maps_list.count; map++) {
2033  if (maps_list.maps[map]->tiled_group) {
2034  for (size_t race = 0; race < maps_list.maps[map]->monsters.count; race++) {
2036  }
2037  }
2038  }
2039 }
2040 
2042  size_t test;
2043  char picpath[500];
2044  struct stat stats;
2045 
2046  for (size_t size = 0; size < num_sizes; size++) {
2047  generate_picture_path(map->path, size, picpath, sizeof(picpath));
2048  if (stat(picpath, &stats))
2049  return 1;
2050  }
2051 
2052  for (test = 0; test < map->tiled_maps.count; test++) {
2053  if (map->tiled_maps.maps[test]->pic_was_done)
2054  return 1;
2055  }
2056 
2057  return 0;
2058 }
2059 
2072  int xmin = 0, xmax = 0, ymin = 0, ymax = 0, count, last;
2073  size_t tiled;
2074  char picpath[500];
2075  gdImagePtr large, load;
2076  FILE *out;
2078 
2079  if (!generate_pics)
2080  return;
2081 
2082  printf(" Generating composite map for %s...", map->name);
2083  fflush(stdout);
2084 
2085  if (!tiled_map_need_pic(map)) {
2086  printf(" already uptodate.\n");
2087  return;
2088  }
2089 
2090  count = map->tiled_maps.count;
2091  if (count == 0) {
2092  printf("Tiled map without tiled maps?\n");
2093  abort();
2094  }
2095  map->tiled_maps.maps[0]->processed = 1;
2096  map->tiled_maps.maps[0]->tiled_x_from = 0;
2097  map->tiled_maps.maps[0]->tiled_y_from = 0;
2098 
2099  while (count > 0) {
2100  last = count;
2101 
2102  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2103  current = map->tiled_maps.maps[tiled];
2104  if (current->processed != 1)
2105  continue;
2106 
2107  count--;
2108 
2109  if ((current->tiles[0]) && (current->tiles[0]->processed == 0)) {
2110  current->tiles[0]->processed = 1;
2111  current->tiles[0]->tiled_x_from = current->tiled_x_from;
2112  current->tiles[0]->tiled_y_from = current->tiled_y_from-current->tiles[0]->height;
2113  }
2114  if ((current->tiles[1]) && (current->tiles[1]->processed == 0)) {
2115  current->tiles[1]->processed = 1;
2116  current->tiles[1]->tiled_x_from = current->tiled_x_from+current->width;
2117  current->tiles[1]->tiled_y_from = current->tiled_y_from;
2118  }
2119  if ((current->tiles[2]) && (current->tiles[2]->processed == 0)) {
2120  current->tiles[2]->processed = 1;
2121  current->tiles[2]->tiled_x_from = current->tiled_x_from;
2122  current->tiles[2]->tiled_y_from = current->tiled_y_from+current->height;
2123  }
2124  if ((current->tiles[3]) && (current->tiles[3]->processed == 0)) {
2125  current->tiles[3]->processed = 1;
2126  current->tiles[3]->tiled_x_from = current->tiled_x_from-current->tiles[3]->width;
2127  current->tiles[3]->tiled_y_from = current->tiled_y_from;
2128  }
2129  }
2130 
2131  if (last == count) {
2132  printf("do_tiled_map_picture: didn't process any map in %s (%d left)??\n", map->path, last);
2133  abort();
2134  }
2135  }
2136 
2137  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2138  if (map->tiled_maps.maps[tiled]->tiled_x_from < xmin)
2139  xmin = map->tiled_maps.maps[tiled]->tiled_x_from;
2140  if (map->tiled_maps.maps[tiled]->tiled_y_from < ymin)
2141  ymin = map->tiled_maps.maps[tiled]->tiled_y_from;
2142  if (map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width > xmax)
2143  xmax = map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width;
2144  if (map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height > ymax)
2145  ymax = map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height;
2146  }
2147 
2148  large = gdImageCreateTrueColor(size_large*(xmax-xmin), size_large*(ymax-ymin));
2149 
2150  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2151  generate_picture_path(map->tiled_maps.maps[tiled]->path, 0, picpath, sizeof(picpath));
2152 
2153  out = fopen(picpath, "rb");
2154  if (!out) {
2155  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);
2156  continue;
2157  }
2158  if (output_format == OF_PNG)
2159  load = gdImageCreateFromPng(out);
2160  else
2161  load = gdImageCreateFromJpeg(out);
2162  fclose(out);
2163  if (!load) {
2164  printf("\n do_tiled_map_picture: warning: pic not found for %s\n", map->tiled_maps.maps[tiled]->path);
2165  continue;
2166  }
2167  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);
2168  gdImageDestroy(load);
2169  }
2170 
2171  write_pictures_from_real_size(map->path, large, xmax-xmin, ymax-ymin);
2172 
2173  gdImageDestroy(large);
2174 
2175  printf(" done.\n");
2176 }
2177 
2180 
2182 
2185 // write_map_page(map);
2186 }
2187 
2189 static void write_tiled_maps(void) {
2190  printf("Writing tiled map information...\n");
2191 
2192  for (size_t map = 0; map < tiled_map_list.count; map++)
2194 
2195  printf(" done.\n");
2196 }
2197 
2198 static size_t system_quests_count = 0;
2199 static const quest_definition *system_quests[500];
2200 
2201 static void quest_callback(const quest_definition *quest, void *) {
2202  if (list_system_quests || !quest->quest_is_system) {
2204  }
2205 }
2206 
2207 static int sort_system_quest(const void *a, const void *b) {
2208  return strcmp((*((quest_definition **)a))->quest_code, (*((quest_definition **)b))->quest_code);
2209 }
2210 
2211 static int sort_system_quest_step(const void *a, const void *b) {
2212  return (*((quest_step_definition**)a))->step - (*((quest_step_definition**)b))->step;
2213 }
2214 
2215 static std::shared_ptr<inja::Environment> env;
2217 static std::set<std::string> rendered_templates;
2218 static std::map<struct_map_info *, std::string> reverse_maps;
2219 static std::map<region *, std::string> reverse_regions;
2226 static struct_map_info *find_map_by_key(const std::string &key) {
2227  auto found = std::find_if(reverse_maps.cbegin(), reverse_maps.cend(), [&key] (auto c) { return c.second == key; });
2228  if (found != reverse_maps.cend())
2229  return found->first;
2230  return nullptr;
2231 }
2232 
2238 static region *find_region_by_key(const std::string &key) {
2239  auto found = std::find_if(reverse_regions.cbegin(), reverse_regions.cend(), [&key] (auto c) { return c.second == key; });
2240  if (found != reverse_regions.cend())
2241  return found->first;
2242  return nullptr;
2243 }
2244 
2252  for (size_t m = 0; m < maps.count; m++) {
2253  auto map = reverse_maps.find(maps.maps[m]);
2254  if (map != reverse_maps.end()) {
2255  result.push_back(map->second);
2256  }
2257  }
2258  return result;
2259 }
2260 
2267  nlohmann::json result;
2268  for (size_t n = 0; n < list.count; n++) {
2269  auto npc = list.npc[n];
2270  result.push_back({
2271  { "name", npc->name },
2272  { "x", npc->x },
2273  { "y", npc->y },
2274  { "message", npc->message },
2275  });
2276  }
2277  return result;
2278 }
2279 
2286  nlohmann::json result;
2287  for (size_t n = 0; n < list.count; n++) {
2288  auto race = list.races[n];
2289  result.push_back({
2290  { "name", race->name },
2291  { "count", race->count },
2292  });
2293  }
2294  return result;
2295 }
2296 
2304  for (size_t m = 0; m < list.count; m++) {
2305  auto q = list.list[m];
2306  if (!q->map || !q->description)
2307  continue;
2308  ret.push_back({
2309  { "map", reverse_maps.find(q->map)->second },
2310  { "description", q->description },
2311  { "quest", q->quest->name },
2312  { "number", q->quest->number },
2313  });
2314  }
2315 
2316  return ret;
2317 }
2318 
2326  return {
2327  { "_key", key },
2328  { "name", map->name },
2329  { "path", map->path },
2330  { "region", map->cfregion ? reverse_regions[map->cfregion] : "reg_ffff" },
2331  { "level", map->level },
2332  { "lore", map->lore && map->lore[0] ? map->lore : "" },
2333  { "exits_to", create_maps_array(map->exits_to) },
2334  { "exits_from", create_maps_array(map->exits_from) },
2335  { "npcs", create_npc_array(map->npcs) },
2336  { "readables", create_npc_array(map->readable) },
2337  { "monsters", create_race_array(map->monsters) },
2338  { "quests", create_map_in_quest_array(map->quests) },
2339  };
2340 }
2341 
2349  return {
2350  { "_key", key },
2351  { "number", quest->number },
2352  { "name", quest->name ? quest->name : "" },
2353  { "description", quest->description ? quest->description : "" },
2354  { "main_map", quest->mainmap ? reverse_maps.find(quest->mainmap)->second : "" },
2355  { "maps", create_map_in_quest_array(quest->maps) },
2356  };
2357 }
2358 
2364  char buf[50];
2365  for (size_t map = 0; map < list.count; map++) {
2366  auto cur = list.maps[map];
2367  if (cur->tiled_group)
2368  continue;
2369  snprintf(buf, sizeof(buf), "map_%04lu", map);
2370  reverse_maps.insert(std::make_pair(cur, buf));
2371  qsort(cur->exits_to.maps, cur->exits_to.count, sizeof(struct_map_info *), sort_map_info);
2372  qsort(cur->exits_from.maps, cur->exits_from.count, sizeof(struct_map_info *), sort_map_info);
2373  qsort(cur->monsters.races, cur->monsters.count, sizeof(struct_race *), sort_race);
2374  }
2375 }
2376 
2383  for (size_t map = 0; map < src.count; map++)
2384  add_map(src.maps[map], &dest);
2385 }
2386 
2392 static nlohmann::json create_region_array(const std::set<region *> &regions) {
2394  for (auto reg : regions) {
2395  auto r = reverse_regions.find(reg);
2396  if (r != reverse_regions.end()) {
2397  ret.push_back((*r).second);
2398  }
2399  }
2400  return ret;
2401 }
2402 
2409  char buf[10];
2410  struct_map_list all_maps;
2411  bool need_unknown_region = false;
2412 
2413  init_map_list(&all_maps);
2414  append_map_list(all_maps, maps_list);
2415  append_map_list(all_maps, tiled_map_list);
2416  qsort(all_maps.maps, all_maps.count, sizeof(struct_map_info *), sort_map_info);
2417 
2418  fill_reverse_maps(all_maps);
2419 
2420  for (size_t reg = 0; reg < region_count; reg++) {
2421  auto region = regions[reg];
2422  snprintf(buf, sizeof(buf), "reg_%04lu", reg);
2423  reverse_regions.insert(std::make_pair(region->reg, buf));
2424  }
2425 
2426  for (size_t reg = 0; reg < region_count; reg++) {
2427  auto region = regions[reg];
2428  qsort(region->maps_list.maps, region->maps_list.count, sizeof(struct_map_info *), sort_map_info);
2429 
2430  json["regions"].push_back({
2431  { "_key", reverse_regions[region->reg] },
2432  { "name", region->reg->name },
2433  { "longname", region->reg->longname },
2434  { "description", region->reg->msg ? region->reg->msg : "" },
2435  { "maps", create_maps_array(region->maps_list) },
2436  { "links", create_region_array(region_links[region->reg]) },
2437  });
2438  }
2439 
2440  for (auto map : reverse_maps) {
2441  auto cur = map.first;
2442  if (cur->tiled_group)
2443  continue;
2444  if (cur->cfregion == nullptr)
2445  need_unknown_region = true;
2446  json["maps"].push_back(create_map_object(cur, map.second));
2447  }
2448 
2449  if (need_unknown_region) {
2450  json["regions"].push_back({
2451  { "_key", "reg_ffff" },
2452  { "name", "unknown" },
2453  { "longname", "unknown" },
2454  { "description", "unknown" },
2455  { "maps", nlohmann::json::array() },
2456  { "links", nlohmann::json::array() },
2457  });
2458  }
2459 
2460  json["items"] = nlohmann::json::array();
2461  for (size_t idx = 0; idx < equipment_count; idx++) {
2462  auto eq = special_equipment[idx];
2463  json["items"][idx] = {
2464  { "name", eq->name },
2465  { "power", eq->power },
2466  { "calc_power", eq->calc_power },
2467  { "diff", eq->diff },
2468  { "maps", create_maps_array(eq->origin) },
2469  };
2470  }
2471 
2472  json["monsters"] = nlohmann::json::array();
2473  for (size_t item = 0; item < races.count; item++) {
2474  auto race = races.races[item];
2475  qsort(race->origin.maps, race->origin.count, sizeof(struct_map_info *), sort_map_info);
2476  json["monsters"].push_back({
2477  { "name", race->name },
2478  { "count", race->count },
2479  { "maps", create_maps_array(race->origin) },
2480  });
2481  }
2482 
2483  json["system_quests"] = nlohmann::json::array();
2484  for (size_t q = 0; q < system_quests_count; q++) {
2485  auto quest = system_quests[q];
2486  nlohmann::json j({
2487  { "code", quest->quest_code },
2488  { "title", quest->quest_title },
2489  { "description", quest->quest_description ? quest->quest_description : "" },
2490  { "replayable", quest->quest_restart },
2491  { "steps", nlohmann::json::array() },
2492  { "maps", nlohmann::json::array() },
2493  });
2494 
2495  if (detail_quests) {
2496  quest_step_definition *steps[100];
2497  size_t steps_count = 0;
2498  quest_step_definition *step = quest->steps;
2499  while (step) {
2500  steps[steps_count++] = step;
2501  step = step->next;
2502  }
2503  qsort(steps, steps_count, sizeof(quest_step_definition *), sort_system_quest_step);
2504  for (size_t s = 0; s < steps_count; s++) {
2505  j["steps"].push_back({
2506  { "description", steps[s]->step_description ? steps[s]->step_description : "" },
2507  { "is_completion", steps[s]->is_completion_step ? true : false },
2508  });
2509  }
2510 
2511  auto qim = find_quest_info(quest->quest_code);
2512  if (qim) {
2513  for (size_t m = 0; m < qim->maps.count; m++) {
2514  auto map = reverse_maps.find(qim->maps.list[m]->map);
2515  assert(map != reverse_maps.end());
2516  j["maps"].push_back({
2517  { "description", qim->maps.list[m]->description },
2518  { "map", map->second },
2519  });
2520  }
2521  }
2522  }
2523  json["system_quests"].push_back(j);
2524  }
2525 
2526  json["slaying"] = nlohmann::json::array();
2527  for (size_t s = 0; s < slaying_count; s++) {
2528  auto info = slaying_info[s];
2529  json["slaying"].push_back({
2530  { "slaying", info->slaying },
2531  { "doors", create_maps_array(info->maps[S_DOOR]) },
2532  { "keys", create_maps_array(info->maps[S_KEY]) },
2533  { "containers", create_maps_array(info->maps[S_CONTAINER]) },
2534  { "detectors", create_maps_array(info->maps[S_DETECTOR]) },
2535  { "connections", create_maps_array(info->maps[S_CONNECT]) },
2536  });
2537  }
2538 
2539  json["quests"] = nlohmann::json::array();
2540  for (int quest = 0; quest < quests_count; quest++) {
2542  char buf[100];
2543  snprintf(buf, sizeof(buf), "quest_%d", quests[quest]->number);
2545  }
2546 }
2547 
2549 static std::vector<std::string> path_stack;
2550 
2551 void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string &param);
2552 
2558 static std::string path_from_current(const std::string &path) {
2559  auto p(path);
2560  char rel[1000];
2561  if (p[0] != '/')
2562  p = '/' + p;
2563  auto current(path_stack.back());
2564  if (current[0] != '/')
2565  current = '/' + current;
2566  relative_path(current.c_str(), p.c_str(), rel);
2567  return rel;
2568 }
2569 
2576  auto template_name = args.at(0)->get<std::string>();
2577  auto output_name(template_name);
2578  auto param = (args.size() > 1 ? args.at(1)->get<std::string>() : "");
2579 
2580  if (!param.empty()) {
2581  output_name = param + "_" + output_name;
2582  if (param.substr(0, 4) == "map_") {
2583  auto map = find_map_by_key(param);
2584  if (map != nullptr) {
2585  output_name = std::string(map->path + 1) + ".html";
2586  }
2587  }
2588  if (param.substr(0, 4) == "reg_") {
2589  auto reg = find_region_by_key(param);
2590  if (reg != nullptr) {
2591  output_name = std::string(reg->name) + ".html";
2592  }
2593  }
2594  }
2595 
2596  add_template_to_render(template_name, output_name, param);
2597  return path_from_current(output_name);
2598 }
2599 
2606  auto what = args.at(0)->get<std::string>();
2607  if (what.substr(0, 4) == "map_") {
2608  auto map = find_map_by_key(what);
2609  if (map == nullptr)
2610  return "";
2611  int size = 0;
2612  if (args.size() > 1) {
2613  size = args.at(1)->get<int>() - 1;
2614  }
2615  char picpath[1000];
2616  snprintf(picpath, sizeof(picpath), "%s.x%d%s", map->path, size + 1, output_extensions[output_format]);
2617  return path_from_current(picpath);
2618  }
2619  return "";
2620 }
2621 
2626 public:
2627  std::string template_name;
2628  std::string output_name;
2629  std::string param;
2630 };
2631 static std::vector<pageToRender> pages;
2639 void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string &param) {
2640  auto on(output_name);
2641  if (on[0] != '/')
2642  on = '/' + on;
2643  if (rendered_templates.find(on) != rendered_templates.end())
2644  return;
2645 
2646  rendered_templates.insert(on);
2647  pageToRender r;
2648  r.template_name = template_name;
2649  r.output_name = on;
2650  r.param = param;
2651  pages.push_back(r);
2652 }
2653 
2654 static std::string templates_root("templates/");
2655 static std::vector<std::string> templates;
2660 static void init_renderer_env() {
2661  env = std::make_shared<inja::Environment>(templates_root, std::string(root) + "/");
2662  env->add_callback("link_to_page", generate_page_and_link);
2663  env->add_callback("substr", [] (inja::Arguments &args) {
2664  std::string str = args.at(0)->get<std::string>();
2665  size_t start = args.at(1)->get<size_t>();
2666  size_t len = args.size() > 2 ? args.at(2)->get<size_t>() : std::string::npos;
2667  return str.substr(start, len);
2668  });
2669  env->add_callback("picture", generate_picture_link);
2670  env->add_callback("pad", [] (inja::Arguments &args) {
2671  char buf[50];
2672  int val = args.at(0)->get<int>(), digits = args.at(1)->get<int>();
2673  snprintf(buf, sizeof(buf), "%0*d", digits, val);
2674  return std::string(buf);
2675  });
2676  env->add_callback("path_to_root", 0, [] (inja::Arguments &) {
2677  std::string r(root);
2678  char rel[1000];
2679  auto current(path_stack.back() + '/');
2680  if (current[0] != '/')
2681  current = '/' + current;
2682  relative_path(current.c_str(), r.c_str(), rel);
2683  return std::string(rel);
2684  });
2685  env->add_callback("get_by_field", 3, [] (inja::Arguments &args) {
2686  const auto &src = args.at(0);
2687  auto field = args.at(1)->get<std::string>();
2688  const auto &value = args.at(2);
2689  auto found = std::find_if(src->begin(), src->end(), [&field, &value] (auto item) {
2690  return item[field] == *value;
2691  });
2692  if (found == src->end()) {
2693  return nlohmann::json();
2694  }
2695  return *found;
2696  });
2697  env->add_callback("get_list_by_field", 3, [] (inja::Arguments &args) {
2698  const auto &src = args.at(0);
2699  auto field = args.at(1)->get<std::string>();
2700  const auto &list = args.at(2);
2702  std::copy_if(src->begin(), src->end(), std::back_inserter(ret), [&] (auto &item) {
2703  auto val = item[field];
2704  return std::find_if(list->begin(), list->end(), [&] (auto li) { return val == li; }) != list->end();
2705  });
2706  return ret;
2707  });
2708  env->add_callback("sort", [] (inja::Arguments &args) {
2709  const auto &src = args.at(0);
2710  std::vector<nlohmann::json> ret;
2711  for (auto i : *src) {
2712  ret.push_back(i);
2713  }
2714  auto field = args.at(1)->get<std::string>();
2715  bool invert = args.size() > 2 ? args.at(2)->get<bool>() : false;
2716  bool ignore_case = args.size() > 3 ? args.at(3)->get<bool>() : true;
2717  std::sort(ret.begin(), ret.end(), [&field, &invert, &ignore_case] (auto left, auto right) {
2718  nlohmann::json l = left[field], r = right[field];
2719  if (ignore_case && l.is_string() && r.is_string()) {
2720  std::string ls(l.get<std::string>()), rs(r.get<std::string>());
2721  std::transform(ls.begin(), ls.end(), ls.begin(), [](unsigned char c){ return std::tolower(c); });
2722  std::transform(rs.begin(), rs.end(), rs.begin(), [](unsigned char c){ return std::tolower(c); });
2723  return invert ? (rs < ls) : (ls < rs);
2724  }
2725  return invert ? (r < l) : (l < r);
2726  });
2727  return ret;
2728  });
2729 
2730  env->set_trim_blocks(true);
2731  env->set_lstrip_blocks(true);
2732 }
2733 
2735 static const char *ignore_path[] = {
2736  "/Info",
2737  "/editor",
2738  "/python",
2739  "/styles",
2740  "/templates",
2741  "/test",
2742  "/unlinked",
2743  NULL };
2744 
2746 static const char *ignore_name[] = {
2747  ".",
2748  "..",
2749  ".svn",
2750  "README",
2751  NULL };
2752 
2759 static void find_maps(const char *from) {
2760  struct dirent *file;
2761  struct stat statbuf;
2762  int status, ignore;
2763  char path[1024], full[1024];
2764  DIR *dir;
2765 
2766  for (ignore = 0; ignore_path[ignore] != NULL; ignore++) {
2767  if (strcmp(from, ignore_path[ignore]) == 0)
2768  return;
2769  }
2770 
2771  snprintf(path, sizeof(path), "%s/%s%s", settings.datadir, settings.mapdir, from);
2772  dir = opendir(path);
2773 
2774  if (dir) {
2775  for (file = readdir(dir); file; file = readdir(dir)) {
2776 
2777  for (ignore = 0; ignore_name[ignore] != NULL; ignore++) {
2778  if (strcmp(file->d_name, ignore_name[ignore]) == 0)
2779  break;
2780  }
2781  if (ignore_name[ignore] != NULL)
2782  continue;
2783 
2784  snprintf(full, sizeof(full), "%s/%s", path, file->d_name);
2785 
2786  status = stat(full, &statbuf);
2787  if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
2788  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
2789  find_maps(full);
2790  continue;
2791  }
2793  found_maps_allocated += 50;
2794  found_maps = (char **)realloc(found_maps, found_maps_allocated*sizeof(char *));
2795  }
2796  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
2797  found_maps[found_maps_count++] = strdup(full);
2798  }
2799  closedir(dir);
2800  }
2801 }
2802 
2804 static void dump_unused_maps(void) {
2805  FILE *dump;
2806  char path[1024];
2807  int index, found = 0;
2808 
2809  snprintf(path, sizeof(path), "%s/%s", root, "maps.unused");
2810  dump = fopen(path, "w+");
2811  if (dump == NULL) {
2812  printf("Unable to open file maps.unused!\n");
2813  return;
2814  }
2815  for (index = 0; index < found_maps_count; index++) {
2816  if (found_maps[index] != NULL) {
2817  fprintf(dump, "%s\n", found_maps[index]);
2818  free(found_maps[index]);
2819  found++;
2820  }
2821  }
2822  fclose(dump);
2823  printf("%d unused maps.\n", found);
2824 }
2825 
2827 static void write_world_info(void) {
2828  FILE *file;
2829  char path[MAX_BUF];
2830  int x, y;
2831  gdImagePtr elevationmap;
2832 
2833  if (!world_exit_info)
2834  return;
2835 
2836  printf("Saving exit/blocking/road information...");
2837  snprintf(path, sizeof(path), "%s/%s%s", root, "world_info", output_extensions[output_format]);
2838  file = fopen(path, "wb+");
2840  fclose(file);
2841  printf("done.\n");
2842  gdImageDestroy(infomap);
2843  infomap = NULL;
2844 
2845  if (elevation_min == 0 || elevation_max == 0) {
2846  puts("Error: Could not save elevation world map due to not finding any minimum or maximum elevation.");
2847  return;
2848  }
2849 
2850  elevationmap = gdImageCreateTrueColor(30*50, 30*50);;
2851 
2852  for (x = 0; x < 30*50; x++) {
2853  for (y = 0; y < 30*50; y++) {
2854  gdImageSetPixel(elevationmap, x, y, get_elevation_color(elevation_info[x][y], elevationmap));
2855  }
2856  }
2857 
2858  printf("Saving elevation world map...");
2859  snprintf(path, sizeof(path), "%s/%s%s", root, "world_elevation", output_extensions[output_format]);
2860  file = fopen(path, "wb+");
2861  save_picture(file, elevationmap);
2862  fclose(file);
2863  printf("done.\n");
2864  gdImageDestroy(elevationmap);
2865  elevationmap = NULL;
2866 }
2867 
2878 static int sort_slaying(const void *left, const void *right) {
2881 
2882  return strcasecmp(l->slaying, r->slaying);
2883 }
2884 
2891 static void do_help(const char *program) {
2892  printf("Crossfire Mapper will generate pictures of maps, and create indexes for all maps and regions.\n\n");
2893  printf("Syntax: %s\n\n", program);
2894  printf("Optional arguments:\n");
2895  printf(" -nopics don't generate pictures.\n");
2896  printf(" -root=<path> destination path. Default 'html'.\n");
2897  printf(" -limit=<number> stop processing after this number of maps, -1 to do all maps (default).\n");
2898  printf(" -showmaps outputs the name of maps as they are processed.\n");
2899  printf(" -jpg[=quality] generate jpg pictures, instead of default png. Quality should be 0-95, -1 for automatic.\n");
2900  printf(" -forcepics force to regenerate pics, even if pics's date is after map's.\n");
2901  printf(" -addmap=<map> adds a map to process. Path is relative to map's directory root.\n");
2902  printf(" -rawmaps generates maps pics without items on random (shop, treasure) tiles.\n");
2903  printf(" -warnnopath inform when an exit has no path set.\n");
2904  printf(" -listunusedmaps finds all unused maps in the maps directory.\n");
2905  printf(" -noworldmap don't write the world map in world.png.\n");
2906  printf(" -noregionslink don't generate regions relation file.\n");
2907  printf(" -regionslink generate regions relation file.\n");
2908  printf(" -noexitmap don't generate map of exits.\n");
2909  printf(" -exitmap generate map of exits.\n");
2910  printf(" -tileset=<number> use specified tileset to generate the pictures. Default 0 (standard).\n");
2911  printf(" -details-quests list all quests steps. Default no.\n");
2912  printf(" -list-system-quests include 'system' quests in quest list. Default no.\n");
2913  printf(" -templates-dir=[dir] set the directory to get templates from. Default 'templates/'.\n");
2914  printf(" -add-template=[file] add a template to process. May be specified multiple times. If empty, 'index.html' is used.\n");
2915  printf(" -list-template-to-process display the name of the template about to be rendered. Useful for debugging.");
2916  printf("\n\n");
2917  exit(0);
2918 }
2919 
2928 static void do_parameters(int argc, char **argv) {
2929  int arg = 1;
2930  char path[500];
2931 
2932  root[0] = '\0';
2933 
2934  while (arg < argc) {
2935  if (strcmp(argv[arg], "-nopics") == 0)
2936  generate_pics = 0;
2937  else if (strncmp(argv[arg], "-root=", 6) == 0)
2938  strncpy(root, argv[arg]+6, 500);
2939  else if (strncmp(argv[arg], "-limit=", 7) == 0)
2940  map_limit = atoi(argv[arg]+7);
2941  else if (strcmp(argv[arg], "-showmaps") == 0)
2942  show_maps = 1;
2943  else if (strcmp(argv[arg], "-jpg") == 0) {
2945  if (argv[arg][4] == '=') {
2946  jpeg_quality = atoi(argv[arg]+5);
2947  if (jpeg_quality < 0)
2948  jpeg_quality = -1;
2949  }
2950  }
2951  else if (strcmp(argv[arg], "-forcepics") == 0)
2952  force_pics = 1;
2953  else if (strncmp(argv[arg], "-addmap=", 8) == 0) {
2954  if (*(argv[arg]+8) == '/')
2955  strncpy(path, argv[arg]+8, 500);
2956  else
2957  snprintf(path, 500, "/%s", argv[arg]+8);
2959  }
2960  else if (strcmp(argv[arg], "-rawmaps") == 0)
2961  rawmaps = 1;
2962  else if (strcmp(argv[arg], "-warnnopath") == 0)
2963  warn_no_path = 1;
2964  else if (strcmp(argv[arg], "-listunusedmaps") == 0)
2965  list_unused_maps = 1;
2966  else if (strcmp(argv[arg], "-noworldmap") == 0)
2967  world_map = 0;
2968  else if (strcmp(argv[arg], "-noregionslink") == 0)
2969  do_regions_link = false;
2970  else if (strcmp(argv[arg], "-regionslink") == 0)
2971  do_regions_link = true;
2972  else if (strcmp(argv[arg], "-noexitmap") == 0)
2973  world_exit_info = 0;
2974  else if (strcmp(argv[arg], "-exitmap") == 0)
2975  world_exit_info = 1;
2976  else if (strncmp(argv[arg], "-tileset=", 9) == 0) {
2977  tileset = atoi(argv[arg]+9);
2978  /* check of validity is done in main() as we need to actually have the sets loaded. */
2979  } else if (strcmp(argv[arg], "-detail-quests") == 0) {
2980  detail_quests = 1;
2981  } else if (strcmp(argv[arg], "-list-system-quests") == 0) {
2982  list_system_quests = 1;
2983  } else if (strncmp(argv[arg], "-templates-dir=", 15) == 0) {
2984  templates_root = argv[arg] + 15;
2985  } else if (strncmp(argv[arg], "-add-template=", 14) == 0) {
2986  templates.push_back(argv[arg] + 14);
2987  } else if (strcmp(argv[arg], "-list-template-to-process") == 0) {
2989  } else
2990  do_help(argv[0]);
2991  arg++;
2992  }
2993  if (!strlen(root))
2994  strcpy(root, "html");
2995  if (root[strlen(root)-1] == '/')
2996  root[strlen(root)-1] = '\0';
2997  if (map_limit < -1)
2998  map_limit = -1;
2999 
3000  if (templates_root.empty()) {
3001  templates_root = "templates/";
3002  } else if (templates_root[templates_root.length() - 1] != '/') {
3003  templates_root.append("/");
3004  }
3005 }
3006 
3010 static void create_destination(void) {
3011  char dummy[502];
3012 
3013  strcpy(dummy, root);
3014  strcat(dummy, "/a");
3015  make_path_to_file(dummy);
3016 }
3017 
3026 static const char *yesno(int value) {
3027  return (value ? "yes" : "no");
3028 }
3029 
3031 static inja::Template get_template(const std::string &filename) {
3032  auto find = templateCache.find(filename);
3033  if (find != templateCache.end()) {
3034  return find->second;
3035  }
3036  inja::Template parsed = env->parse_template(filename);
3037  templateCache[filename] = parsed;
3038  return parsed;
3039 }
3040 
3041 int main(int argc, char **argv) {
3042  size_t current_map = 0, i;
3043  char max[50];
3044  region *dummy;
3045 
3049  pics_allocated = 0;
3050 
3051  do_parameters(argc, argv);
3052 
3053  printf("Initializing Crossfire data...\n");
3054 
3056 
3057  init_globals();
3058  init_library();
3059  init_readable();
3060  init_regions();
3061 
3062  init_gods();
3063 
3064  /* Add a dummy region so unlinked maps can be identified. */
3065  dummy = get_region_struct();
3066  dummy->fallback = 1;
3067  dummy->name = strdup_local("unlinked");
3068  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3069  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3070  dummy->next = first_region;
3071  first_region = dummy;
3072 
3073  printf("\n\n done.\n\n");
3074 
3075  if (!is_valid_faceset(tileset)) {
3076  printf("Erreor: invalid tileset %d!\n", tileset);
3077  exit(1);
3078  }
3079 
3080  if (templates.empty()) {
3081  templates.push_back("index.html");
3082  }
3083 
3085  gdfaces = (gdImagePtr *)calloc(get_faces_count(), sizeof(gdImagePtr));
3086 
3087  if (map_limit != -1)
3088  snprintf(max, sizeof(max), "%d", map_limit);
3089  else
3090  strcpy(max, "(none)");
3091  printf("Crossfire map browser generator\n");
3092  printf("-------------------------------\n\n");
3093  printf("Parameters:\n");
3094  printf(" path to write files: %s\n", root);
3095  printf(" maximum number of maps to process: %s\n", max);
3096  printf(" will generate map picture: %s\n", yesno(generate_pics));
3097  printf(" will always generate map picture: %s\n", yesno(force_pics));
3098  printf(" picture output format: %s\n", output_extensions[output_format]);
3099  if (output_format == OF_JPG)
3100  printf(" JPEG quality: %d\n", jpeg_quality);
3101  printf(" show map being processed: %s\n", yesno(show_maps));
3102  printf(" generate raw maps: %s\n", yesno(rawmaps));
3103  printf(" warn of exit without path: %s\n", yesno(warn_no_path));
3104  printf(" list unused maps: %s\n", yesno(list_unused_maps));
3105  printf(" generate world map: %s\n", yesno(world_map));
3106  printf(" generate exit map: %s\n", yesno(world_exit_info));
3107  printf(" generate regions link file: %s\n", yesno(do_regions_link));
3108  printf(" tileset: %s\n", find_faceset(tileset)->fullname);
3109  printf(" detail quest steps: %s\n", yesno(detail_quests));
3110  printf(" list system quests: %s\n", yesno(list_system_quests));
3111  printf(" templates directory: %s\n", templates_root.c_str());
3112  printf(" templates to process: ");
3113  const char *sep = "";
3114  for (auto f : templates) {
3115  printf("%s%s", sep, f.c_str());
3116  sep = ", ";
3117  }
3118  printf("\n");
3119  printf(" display template to process: %s\n", yesno(display_rendered_template));
3120  printf("\n");
3121 
3122  if (list_unused_maps) {
3123  printf("listing all maps...");
3124  find_maps("");
3125  printf("done, %d maps found.\n", found_maps_count);
3126  qsort(found_maps, found_maps_count, sizeof(char *), sortbyname);
3127  }
3128 
3129  /* exit/blocking information. */
3130  infomap = gdImageCreateTrueColor(30*50, 30*50);
3131  color_unlinked_exit = gdImageColorResolve(infomap, 255, 0, 0);
3132  color_linked_exit = gdImageColorResolve(infomap, 255, 255, 255);
3133  color_road = gdImageColorResolve(infomap, 0, 255, 0);
3134  color_blocking = gdImageColorResolve(infomap, 0, 0, 255);
3135  color_slowing = gdImageColorResolve(infomap, 0, 0, 127);
3136  elevation_info = (int **)calloc(50*30, sizeof(int *));
3137  for (i = 0; i < 50*30; i++)
3138  elevation_info[i] = (int *)calloc(50*30, sizeof(int));
3139  elevation_min = 0;
3140  elevation_max = 0;
3141 
3142  printf("browsing maps...\n");
3143 
3145 
3146  while (current_map < maps_list.count) {
3147  process_map(maps_list.maps[current_map++]);
3148  if (current_map%100 == 0) {
3149  printf(" %zu maps processed, %d map pictures created, %d map pictures were uptodate. %d faces used.\n", current_map, created_pics, cached_pics, pics_allocated);
3150  }
3151  if ((map_limit != -1) && (current_map == map_limit)) {
3152  printf(" --- map limit reached, stopping ---\n");
3153  break;
3154  }
3155  }
3156 
3157  printf(" finished map parsing, %zu maps processed, %d map pictures created, %d map pictures were uptodate. Total %d faces used.\n", current_map, created_pics, cached_pics, pics_allocated);
3158 
3159  if (list_unused_maps)
3160  dump_unused_maps();
3161 
3163  fix_map_names();
3164  fix_tiled_map();
3166  write_tiled_maps();
3167 
3168  write_world_map();
3169  write_world_info();
3170 
3172  qsort(regions, region_count, sizeof(struct_region_info *), sort_region);
3175  qsort(races.races, races.count, sizeof(struct_race *), sort_race);
3176  qsort(quests, quests_count, sizeof(struct_quest *), sort_struct_quest);
3177 
3180 
3182 
3184 
3185  for (auto file : templates) {
3186  if (!file.empty()) {
3188  }
3189  }
3190 
3191  const auto fullStart = time(nullptr);
3192  printf("rendering pages...");
3194  printf("\n");
3195  fflush(stdout);
3196 
3197  while (!pages.empty()) {
3198  auto p = pages.back();
3199  pages.pop_back();
3200  if (p.param.empty())
3201  all_data.erase("param");
3202  else
3203  all_data["param"] = p.param;
3204  const auto start = time(nullptr);
3206  printf(" rendering page %s (%s)... ", p.template_name.c_str(), p.param.c_str());
3207  fflush(stdout);
3208  }
3209  path_stack.push_back(p.output_name);
3210  inja::Template temp = get_template(p.template_name);
3211  env->write(temp, all_data, p.output_name);
3212  path_stack.pop_back();
3213  const auto elapsed = time(nullptr) - start;
3215  printf("took %ld seconds\n", elapsed);
3216  }
3217  }
3218 
3219  const auto elapsed = time(nullptr) - fullStart;
3220  printf(" done, took %ld seconds\n", elapsed);
3221 
3222  return 0;
3223 }
3224 
3226  int x, y;
3227 
3228  if (m == NULL)
3229  return;
3230 
3231  for (x = 0; x < MAP_WIDTH(m); x++)
3232  for (y = 0; y < MAP_HEIGHT(m); y++)
3233  FOR_MAP_PREPARE(m, x, y, tmp) {
3234  if (tmp->inv) {
3235  FOR_INV_PREPARE(tmp, invtmp) {
3236  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
3237  apply_auto(invtmp);
3238  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
3239  while ((invtmp->stats.hp--) > 0)
3240  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3241  invtmp->randomitems = NULL;
3242  } else if (invtmp
3243  && invtmp->arch
3244  && invtmp->type != TREASURE
3245  && invtmp->type != SPELL
3246  && invtmp->type != CLASS
3247  && HAS_RANDOM_ITEMS(invtmp)) {
3248  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3249  /* Need to clear this so that we never try to create
3250  * treasure again for this object
3251  */
3252  invtmp->randomitems = NULL;
3253  }
3254  } FOR_INV_FINISH();
3255  /* This is really temporary - the code at the bottom will
3256  * also set randomitems to null. The problem is there are bunches
3257  * of maps/players already out there with items that have spells
3258  * which haven't had the randomitems set to null yet.
3259  * MSW 2004-05-13
3260  *
3261  * And if it's a spellbook, it's better to set randomitems to NULL too,
3262  * else you get two spells in the book ^_-
3263  * Ryo 2004-08-16
3264  */
3265  if (tmp->type == WAND
3266  || tmp->type == ROD
3267  || tmp->type == SCROLL
3268  || tmp->type == FIREWALL
3269  || tmp->type == POTION
3270  || tmp->type == ALTAR
3271  || tmp->type == SPELLBOOK)
3272  tmp->randomitems = NULL;
3273  }
3274 
3276  apply_auto(tmp);
3277  else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS(tmp)) {
3278  while ((tmp->stats.hp--) > 0)
3279  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
3280  tmp->randomitems = NULL;
3281  } else if (tmp->type == TIMED_GATE) {
3282  object *head = HEAD(tmp);
3283 
3284  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
3285  tmp->speed = 0;
3287  }
3288  /* This function can be called everytime a map is loaded, even when
3289  * swapping back in. As such, we don't want to create the treasure
3290  * over and ove again, so after we generate the treasure, blank out
3291  * randomitems so if it is swapped in again, it won't make anything.
3292  * This is a problem for the above objects, because they have counters
3293  * which say how many times to make the treasure.
3294  */
3295  } else if (tmp
3296  && tmp->arch
3297  && tmp->type != PLAYER
3298  && tmp->type != TREASURE
3299  && tmp->type != SPELL
3300  && tmp->type != PLAYER_CHANGER
3301  && tmp->type != CLASS
3302  && HAS_RANDOM_ITEMS(tmp)) {
3303  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
3304  tmp->randomitems = NULL;
3305  }
3306  } FOR_MAP_FINISH();
3307 
3308  for (x = 0; x < MAP_WIDTH(m); x++)
3309  for (y = 0; y < MAP_HEIGHT(m); y++)
3310  FOR_MAP_PREPARE(m, x, y, tmp) {
3311  if (tmp->above
3312  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3313  check_trigger(tmp, tmp->above);
3314  } FOR_MAP_FINISH();
3315 }
3316 
3317 #ifndef DOXYGEN_SHOULD_SKIP_THIS
3318 
3323 void draw_ext_info(int, int, const object *, uint8_t, uint8_t, const char *txt) {
3324  fprintf(logfile, "%s\n", txt);
3325 }
3326 
3327 void draw_ext_info_format(int, int, const object *, uint8_t, uint8_t, const char *format, ...) {
3328  va_list ap;
3329 
3330  va_start(ap, format);
3331  vfprintf(logfile, format, ap);
3332  va_end(ap);
3333 }
3334 
3335 void ext_info_map(int, const mapstruct *, uint8_t, uint8_t, const char *str1) {
3336  fprintf(logfile, "ext_info_map: %s\n", str1);
3337 }
3338 
3339 void move_firewall(object *) {
3340 }
3341 
3342 void emergency_save(int) {
3343 }
3344 
3345 void clean_tmp_files(void) {
3346 }
3347 
3348 void esrv_send_item(object *, object *) {
3349 }
3350 
3351 void dragon_ability_gain(object *, int, int) {
3352 }
3353 
3355 }
3356 
3357 object *find_skill_by_number(object *, int) {
3358  return NULL;
3359 }
3360 
3361 void esrv_del_item(player *, object *) {
3362 }
3363 
3364 void esrv_update_item(int, object *, object *) {
3365 }
3366 
3368 }
3369 
3370 void rod_adjust(object *) {
3371 }
3372 
3373 /*
3374  * This a modified version of apply_auto: BOOK are not generated, so they don't pollute
3375  * the readable list.
3376  */
3377 int apply_auto(object *op) {
3378  object *tmp = NULL;
3379  int i;
3380 
3381  switch (op->type) {
3382  case SHOP_FLOOR:
3383  if (!HAS_RANDOM_ITEMS(op))
3384  return 0;
3385  do {
3386  i = 10; /* let's give it 10 tries */
3387  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL && --i)
3388  ;
3389  if (tmp == NULL)
3390  return 0;
3391  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED) || tmp->type == BOOK) {
3393  tmp = NULL;
3394  }
3395  } while (!tmp);
3397  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
3399  tmp = identify(tmp);
3400  break;
3401 
3402  case TREASURE:
3404  return 0;
3405 
3406  while ((op->stats.hp--) > 0)
3407  create_treasure(op->randomitems, op, 0, op->stats.exp ? (int)op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3408 
3409  /* If we generated an object and put it in this object inventory,
3410  * move it to the parent object as the current object is about
3411  * to disappear. An example of this item is the random_ *stuff
3412  * that is put inside other objects.
3413  */
3414  FOR_INV_PREPARE(op, tmp) {
3415  object_remove(tmp);
3416  if (op->env && tmp->type != BOOK)
3417  object_insert_in_ob(tmp, op->env);
3418  else
3420  }
3421  FOR_INV_FINISH();
3422  object_remove(op);
3424  break;
3425  }
3426  return tmp ? 1 : 0;
3427 }
3428 
3430 }
3431 
3433  return NULL;
3434 }
3435 
3437  return NULL;
3438 }
3439 
3441  return NULL;
3442 }
3443 
3444 void account_char_save(const char *, Account_Char *) {
3445 }
3446 
3448 }
3449 
3450 void command_help(object *, const char *) {
3451 }
3452 
3453 #endif /* dummy DOXYGEN_SHOULD_SKIP_THIS */
get_race
static struct_race * get_race(const char *name)
Definition: mapper.cpp:612
struct_map_info::tiles
struct struct_map_info * tiles[4]
Definition: mapper.cpp:231
CLASS
@ CLASS
Definition: object.h:138
struct_region_info::sum_x
int sum_x
Definition: mapper.cpp:358
give.next
def next
Definition: give.py:44
move_firewall
void move_firewall(object *)
Definition: mapper.cpp:3339
write_tiled_map_page
static void write_tiled_map_page(struct_map_info *map)
Definition: mapper.cpp:2179
fix_tiled_map_monsters
static void fix_tiled_map_monsters(void)
Definition: mapper.cpp:2014
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.c:1768
do_auto_apply
void do_auto_apply(mapstruct *m)
Definition: mapper.cpp:3225
add_map
static void add_map(struct_map_info *info, struct_map_list *list)
Definition: mapper.cpp:1207
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:184
PLAYER
@ PLAYER
Definition: object.h:107
artifact
struct artifactstruct artifact
Settings::mapdir
const char * mapdir
Definition: global.h:247
struct_map_in_quest
struct struct_map_in_quest struct_map_in_quest
global.h
FREE_OBJ_NO_DESTROY_CALLBACK
#define FREE_OBJ_NO_DESTROY_CALLBACK
Definition: object.h:532
object_free
void object_free(object *ob, int flags)
Definition: object.c:1565
ignore_name
static const char * ignore_name[]
Definition: mapper.cpp:2746
struct_npc_info
struct struct_npc_info struct_npc_info
struct_equipment::diff
char * diff
Definition: mapper.cpp:245
banquet.l
l
Definition: banquet.py:164
get_quest_info
static struct_quest * get_quest_info(const char *name)
Definition: mapper.cpp:957
find_region_by_key
static region * find_region_by_key(const std::string &key)
Definition: mapper.cpp:2238
object_remove
void object_remove(object *op)
Definition: object.c:1806
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:728
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.c:57
found_maps_allocated
static int found_maps_allocated
Definition: mapper.cpp:369
process_map_lore
static void process_map_lore(struct_map_info *map)
Definition: mapper.cpp:1071
llevError
@ llevError
Definition: logger.h:11
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.c:194
maps
static std::unordered_map< std::string, mapzone * > maps
Definition: citylife.cpp:93
compare_map_info
static int compare_map_info(const struct_map_info *left, const struct_map_info *right)
Definition: mapper.cpp:850
path_from_current
static std::string path_from_current(const std::string &path)
Definition: mapper.cpp:2558
MOVE_ALL
#define MOVE_ALL
Definition: define.h:398
WAND
@ WAND
Definition: object.h:220
quest_for_each
void quest_for_each(quest_op op, void *user)
Definition: assets.cpp:703
struct_region_info::is_world
int is_world
Definition: mapper.cpp:359
SET_FLAG
#define SET_FLAG(xyz, p)
Definition: define.h:224
generate_picture_link
static nlohmann::json generate_picture_link(inja::Arguments &args)
Definition: mapper.cpp:2605
struct_map_info::tiled_group
struct struct_map_info * tiled_group
Definition: mapper.cpp:228
struct_map_info::filename
char * filename
Definition: mapper.cpp:213
num_sizes
static const int num_sizes
Definition: mapper.cpp:314
add_slaying
static void add_slaying(struct_map_info *map, object *item)
Definition: mapper.cpp:1473
strdup_local
#define strdup_local
Definition: compat.h:29
diamondslots.x
x
Definition: diamondslots.py:15
write_tiled_maps
static void write_tiled_maps(void)
Definition: mapper.cpp:2189
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
struct_quest::maps
struct_map_in_quest_list maps
Definition: mapper.cpp:912
archininventory.arch
arch
DIALOGCHECK MINARGS 1 MAXARGS 1
Definition: archininventory.py:16
create_quest_object
static nlohmann::json create_quest_object(struct_quest *quest, const std::string &key)
Definition: mapper.cpp:2348
create_map_info
static struct_map_info * create_map_info(void)
Definition: mapper.cpp:1228
struct_race::count
int count
Definition: mapper.cpp:259
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:134
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:3404
struct_map_in_quest::map
struct_map_info * map
Definition: mapper.cpp:903
esrv_del_item
void esrv_del_item(player *, object *)
Definition: mapper.cpp:3361
pageToRender::param
std::string param
Definition: mapper.cpp:2629
S_CONNECT
#define S_CONNECT
Definition: mapper.cpp:393
write_pictures_from_real_size
static void write_pictures_from_real_size(const char *path, gdImagePtr real, int width, int height)
Definition: mapper.cpp:1513
region_links
static std::map< region *, std::set< region * > > region_links
Definition: mapper.cpp:386
struct_npc_list
struct struct_npc_list struct_npc_list
calc_item_power
int calc_item_power(const object *op)
Definition: item.c:238
Settings::datadir
const char * datadir
Definition: global.h:244
c
static event_registration c
Definition: citylife.cpp:425
disinfect.a
a
Definition: disinfect.py:13
output_format
static enum output_format_type output_format
Definition: mapper.cpp:343
quests_count
static int quests_count
Definition: mapper.cpp:917
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:183
Ice.g
def g
Definition: Ice.py:63
pl
Definition: player.h:92
get_map_info
static struct_map_info * get_map_info(const char *path)
Definition: mapper.cpp:1300
EXIT_PATH
#define EXIT_PATH(xyz)
Definition: define.h:439
fix_exits_to_tiled_maps
static void fix_exits_to_tiled_maps(void)
Definition: mapper.cpp:1986
reverse_maps
static std::map< struct_map_info *, std::string > reverse_maps
Definition: mapper.cpp:2218
dump
static int dump(const std::set< std::string > &items, const char *name)
Definition: AssetsManager.cpp:55
get_ob_diff
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Definition: object.c:4952
guildoracle.list
list
Definition: guildoracle.py:87
struct_map_in_quest
Definition: mapper.cpp:900
slaying_allocated
static size_t slaying_allocated
Definition: mapper.cpp:404
get_equipment
static struct_equipment * get_equipment(void)
Definition: mapper.cpp:438
is_special_equipment
static int is_special_equipment(object *item)
Definition: mapper.cpp:419
TIMED_GATE
@ TIMED_GATE
Definition: object.h:128
region_allocated
static size_t region_allocated
Definition: mapper.cpp:364
struct_map_list
Definition: mapper.cpp:203
generate_page_and_link
static nlohmann::json generate_page_and_link(inja::Arguments &args)
Definition: mapper.cpp:2575
struct_equipment::origin
struct_map_list origin
Definition: mapper.cpp:246
find_faceset
face_sets * find_faceset(int id)
Definition: assets.cpp:364
python_event.path
path
Definition: python_event.py:11
commongive.inv
inv
Definition: commongive.py:28
root
static char root[500]
Definition: mapper.cpp:305
create_map_in_quest_array
static nlohmann::json create_map_in_quest_array(struct_map_in_quest_list &list)
Definition: mapper.cpp:2302
yesno
static const char * yesno(int value)
Definition: mapper.cpp:3026
AMULET
@ AMULET
Definition: object.h:139
CHECK_INV
@ CHECK_INV
Definition: object.h:169
mapdef::in_memory
uint32_t in_memory
Definition: map.h:344
struct_map_info::name
char * name
Definition: mapper.cpp:212
fix_map_names
static void fix_map_names(void)
Definition: mapper.cpp:1880
account_char_free
void account_char_free(Account_Char *)
Definition: mapper.cpp:3447
struct_slaying_info::maps
struct_map_list maps[S_MAX]
Definition: mapper.cpp:399
mad_mage_user.file
file
Definition: mad_mage_user.py:15
MIN
#define MIN(x, y)
Definition: compat.h:21
SIZE
#define SIZE
maps_list
static struct_map_list maps_list
Definition: mapper.cpp:235
TREASURE
@ TREASURE
Definition: object.h:110
color_unlinked_exit
static int color_unlinked_exit
Definition: mapper.cpp:373
struct_region_info::sum_y
int sum_y
Definition: mapper.cpp:358
create_pathname
char * create_pathname(const char *name, char *buf, size_t size)
Definition: map.c:103
init_regions
int init_regions(void)
Definition: region.c:293
pages
static std::vector< pageToRender > pages
Definition: mapper.cpp:2631
list_unused_maps
static int list_unused_maps
Definition: mapper.cpp:366
struct_map_info
Definition: mapper.cpp:210
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Definition: path.c:172
draw_ext_info_format
void draw_ext_info_format(int, int, const object *, uint8_t, uint8_t, const char *format,...)
Definition: mapper.cpp:3327
esrv_send_item
void esrv_send_item(object *, object *)
Definition: mapper.cpp:3348
struct_map_info::min_monster
int min_monster
Definition: mapper.cpp:216
Ice.tmp
int tmp
Definition: Ice.py:207
nlohmann::basic_json::push_back
void push_back(basic_json &&val)
add an object to an array
Definition: json.hpp:22807
create_region_array
static nlohmann::json create_region_array(const std::set< region * > &regions)
Definition: mapper.cpp:2392
struct_region_info
Definition: mapper.cpp:355
clean_tmp_files
void clean_tmp_files(void)
Definition: mapper.cpp:3345
inja::Template
The main inja Template.
Definition: inja.hpp:2836
nlohmann::basic_json::diff
static JSON_HEDLEY_WARN_UNUSED_RESULT basic_json diff(const basic_json &source, const basic_json &target, const std::string &path="")
creates a diff as a JSON patch
Definition: json.hpp:26097
SIGN
@ SIGN
Definition: object.h:211
first_map_path
EXTERN char first_map_path[MAX_BUF]
Definition: global.h:143
struct_equipment::name
char * name
Definition: mapper.cpp:242
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:132
npc_dialog.filename
filename
Definition: npc_dialog.py:99
smoking_pipe.color
color
Definition: smoking_pipe.py:5
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.c:242
struct_map_info::max_monster
int max_monster
Definition: mapper.cpp:216
is_valid_faceset
int is_valid_faceset(int fsn)
Definition: image.c:116
struct_slaying_info
Definition: mapper.cpp:397
account_char_struct
Definition: account_char.h:12
struct_equipment::calc_power
int calc_power
Definition: mapper.cpp:244
make_path_to_file
void make_path_to_file(const char *filename)
Definition: porting.c:162
quest_step_definition
Definition: quest.h:33
MAX
#define MAX(x, y)
Definition: compat.h:24
apply_auto_fix
void apply_auto_fix(mapstruct *)
Definition: mapper.cpp:3429
obj::nrof
uint32_t nrof
Definition: object.h:335
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
account_char_load
Account_Char * account_char_load(const char *)
Definition: mapper.cpp:3440
force_pics
static int force_pics
Definition: mapper.cpp:312
reputation_trigger_connect.check
def check()
Definition: reputation_trigger_connect.py:18
world_exit_info
static int world_exit_info
Definition: mapper.cpp:320
sort_struct_quest
static int sort_struct_quest(const void *left, const void *right)
Definition: mapper.cpp:1036
struct_quest
Definition: mapper.cpp:907
archt
Definition: object.h:468
settings
struct Settings settings
Definition: init.c:39
struct_map_in_quest_list
Definition: mapper.cpp:196
struct_region_info::reg
region * reg
Definition: mapper.cpp:356
init_readable
void init_readable(void)
Definition: readable.c:899
struct_map_in_quest::quest
struct struct_quest * quest
Definition: mapper.cpp:905
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.c:4354
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Definition: define.h:366
obj::slaying
sstring slaying
Definition: object.h:320
identify
object * identify(object *op)
Definition: item.c:1408
init_renderer_env
static void init_renderer_env()
Definition: mapper.cpp:2660
struct_quest::description
char * description
Definition: mapper.cpp:909
regiondef::next
struct regiondef * next
Definition: map.h:276
m
static event_registration m
Definition: citylife.cpp:425
quest
Definition: quest.py:1
MAP_IN_MEMORY
#define MAP_IN_MEMORY
Definition: map.h:131
S_CONTAINER
#define S_CONTAINER
Definition: mapper.cpp:391
struct_race
struct struct_race struct_race
item.q
q
Definition: item.py:32
opendir
DIR * opendir(const char *)
quest_step_definition::next
struct quest_step_definition * next
Definition: quest.h:37
templateCache
static inja::TemplateStorage templateCache
Definition: mapper.cpp:3030
disinfect.map
map
Definition: disinfect.py:4
regions
static struct struct_region_info ** regions
Definition: mapper.cpp:362
struct_npc_info::y
int y
Definition: mapper.cpp:178
struct_map_info::exits_from
struct_map_list exits_from
Definition: mapper.cpp:217
Settings::debug
LogLevel debug
Definition: global.h:240
detail_quests
static bool detail_quests
Definition: mapper.cpp:322
ensure_unique
static struct_equipment * ensure_unique(struct_equipment *item)
Definition: mapper.cpp:465
struct_npc_info::message
const char * message
Definition: mapper.cpp:177
special_equipment
static struct_equipment ** special_equipment
Definition: mapper.cpp:249
obj::name
sstring name
Definition: object.h:312
quest_step_definition::is_completion_step
int is_completion_step
Definition: quest.h:36
get_slaying_struct
static struct_slaying_info * get_slaying_struct(const char *slaying)
Definition: mapper.cpp:1430
generate_picture_path
static void generate_picture_path(const char *path, size_t pic_size, char *out, size_t len)
Definition: mapper.cpp:1509
make_face_from_files.args
args
Definition: make_face_from_files.py:31
OF_JPG
@ OF_JPG
Definition: mapper.cpp:333
struct_npc_list::count
size_t count
Definition: mapper.cpp:184
elevation_max
static int elevation_max
Definition: mapper.cpp:381
struct_map_info::pic_was_done
int pic_was_done
Definition: mapper.cpp:216
add_npc_to_map
static void add_npc_to_map(struct_npc_list *list, const object *npc)
Definition: mapper.cpp:1185
struct_map_info
struct struct_map_info struct_map_info
set_darkness_map
void set_darkness_map(mapstruct *)
Definition: mapper.cpp:3354
system_quests_count
static size_t system_quests_count
Definition: mapper.cpp:2198
POTION
@ POTION
Definition: object.h:111
struct_npc_info
Definition: mapper.cpp:175
define_quest
static void define_quest(const char *name, struct_map_info *mainmap, const char *description)
Definition: mapper.cpp:1052
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.cpp:927
do_tiled_map_picture
static void do_tiled_map_picture(struct_map_info *map)
Definition: mapper.cpp:2071
slaying_info
static struct_slaying_info ** slaying_info
Definition: mapper.cpp:402
obj::name_pl
sstring name_pl
Definition: object.h:316
races
static struct_race_list races
Definition: mapper.cpp:263
main
int main(int argc, char **argv)
Definition: mapper.cpp:3041
HEAD
#define HEAD(op)
Definition: object.h:594
output_extensions
static const char * output_extensions[]
Definition: mapper.cpp:337
create_maps_array
static nlohmann::json create_maps_array(struct_map_list &maps)
Definition: mapper.cpp:2250
ROD
@ ROD
Definition: object.h:109
init_gods
void init_gods(void)
Definition: holy.c:86
show_maps
static int show_maps
Definition: mapper.cpp:318
CONTAINER
@ CONTAINER
Definition: object.h:231
get_elevation_color
static int get_elevation_color(int elevation, gdImagePtr elevationmap)
Definition: mapper.cpp:726
make_face_from_files.str
str
Definition: make_face_from_files.py:24
S_MAX
#define S_MAX
Definition: mapper.cpp:394
quest_callback
static void quest_callback(const quest_definition *quest, void *)
Definition: mapper.cpp:2201
readdir
struct dirent * readdir(DIR *)
LOCKED_DOOR
@ LOCKED_DOOR
Definition: object.h:123
struct_race::name
char * name
Definition: mapper.cpp:258
dump
Definition: quest.c:859
is_slaying
static int is_slaying(object *item)
Definition: mapper.cpp:1417
struct_equipment::power
int power
Definition: mapper.cpp:243
create_race_array
static nlohmann::json create_race_array(struct_race_list &list)
Definition: mapper.cpp:2285
dragon_ability_gain
void dragon_ability_gain(object *, int, int)
Definition: mapper.cpp:3351
nlohmann::basic_json::array
array_t * array
array (stored with pointer to save storage)
Definition: json.hpp:18360
SPECIAL_KEY
@ SPECIAL_KEY
Definition: object.h:124
inja::json
nlohmann::json json
Definition: inja.hpp:1565
struct_race::origin
struct_map_list origin
Definition: mapper.cpp:260
color_slowing
static int color_slowing
Definition: mapper.cpp:377
Ice.b
b
Definition: Ice.py:48
regiondef::name
char * name
Definition: map.h:277
obj::x
int16_t x
Definition: object.h:328
system_quests
static const quest_definition * system_quests[500]
Definition: mapper.cpp:2199
struct_map_info::quests
struct_map_in_quest_list quests
Definition: mapper.cpp:219
write_world_map
static void write_world_map(void)
Definition: mapper.cpp:1777
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
struct_map_info::width
int width
Definition: mapper.cpp:229
add_map_to_quest
static void add_map_to_quest(struct_map_info *map, const char *name, const char *description)
Definition: mapper.cpp:986
create_npc_info
static struct_npc_info * create_npc_info(const object *npc)
Definition: mapper.cpp:1167
struct_quest
struct struct_quest struct_quest
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.c:76
face_info::data
uint8_t * data
Definition: image.h:11
color_road
static int color_road
Definition: mapper.cpp:375
tileset
static int tileset
Definition: mapper.cpp:321
esrv_update_item
void esrv_update_item(int, object *, object *)
Definition: mapper.cpp:3364
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:675
is_blocking
static int is_blocking(object *item)
Definition: mapper.cpp:712
do_exit_map
static void do_exit_map(mapstruct *map)
Definition: mapper.cpp:741
create_destination
static void create_destination(void)
Definition: mapper.cpp:3010
struct_map_info::tiled_y_from
int tiled_y_from
Definition: mapper.cpp:230
struct_race_list::races
struct struct_race ** races
Definition: mapper.cpp:190
sstring
const typedef char * sstring
Definition: global.h:40
disinfect.count
int count
Definition: disinfect.py:7
FLAG_UNAGGRESSIVE
#define FLAG_UNAGGRESSIVE
Definition: define.h:272
check_slaying_inventory
static void check_slaying_inventory(struct_map_info *map, object *item)
Definition: mapper.cpp:1501
say.max
dictionary max
Definition: say.py:148
object_give_identified_properties
void object_give_identified_properties(object *op)
Definition: item.c:1343
jpeg_quality
static int jpeg_quality
Definition: mapper.cpp:346
sort_system_quest_step
static int sort_system_quest_step(const void *a, const void *b)
Definition: mapper.cpp:2211
sproto.h
append_map_list
static void append_map_list(struct_map_list &dest, struct_map_list &src)
Definition: mapper.cpp:2382
IS_SHIELD
#define IS_SHIELD(op)
Definition: define.h:170
mapdef
Definition: map.h:324
BOOK
@ BOOK
Definition: object.h:114
rawmaps
static int rawmaps
Definition: mapper.cpp:349
init_struct_map_in_quest_list
static void init_struct_map_in_quest_list(struct_map_in_quest_list *list)
Definition: mapper.cpp:921
struct_race_list
Definition: mapper.cpp:189
struct_race
Definition: mapper.cpp:257
emergency_save
void emergency_save(int)
Definition: mapper.cpp:3342
logfile
EXTERN FILE * logfile
Definition: global.h:136
struct_race_list::allocated
size_t allocated
Definition: mapper.cpp:192
struct_map_list::maps
struct struct_map_info ** maps
Definition: mapper.cpp:204
RING
@ RING
Definition: object.h:185
delete_map
void delete_map(mapstruct *m)
Definition: map.c:1706
account_char_save
void account_char_save(const char *, Account_Char *)
Definition: mapper.cpp:3444
struct_race_list::count
size_t count
Definition: mapper.cpp:191
fill_json
static void fill_json(nlohmann::json &json)
Definition: mapper.cpp:2407
add_map_to_region
static void add_map_to_region(struct_map_info *map, region *reg)
Definition: mapper.cpp:1350
init_globals
void init_globals(void)
Definition: init.c:271
image.h
struct_map_info::level
int level
Definition: mapper.cpp:216
found_maps_count
static int found_maps_count
Definition: mapper.cpp:368
struct_equipment
struct struct_equipment struct_equipment
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
list_system_quests
static bool list_system_quests
Definition: mapper.cpp:323
generate_pics
static int generate_pics
Definition: mapper.cpp:311
MAP_WIDTH
#define MAP_WIDTH(m)
Definition: map.h:78
create_map_object
static nlohmann::json create_map_object(struct_map_info *map, const std::string &key)
Definition: mapper.cpp:2325
struct_quest::mainmap
struct_map_info * mainmap
Definition: mapper.cpp:911
env
static std::shared_ptr< inja::Environment > env
Definition: mapper.cpp:2215
MAX_BUF
#define MAX_BUF
Definition: define.h:35
S_KEY
#define S_KEY
Definition: mapper.cpp:390
object_get_multi_size
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
Definition: object.c:4731
artifactstruct
Definition: artifact.h:14
sort_map_info
static int sort_map_info(const void *left, const void *right)
Definition: mapper.cpp:875
fill_reverse_maps
static void fill_reverse_maps(struct_map_list &list)
Definition: mapper.cpp:2363
struct_map_info::tiled_x_from
int tiled_x_from
Definition: mapper.cpp:230
pageToRender
Definition: mapper.cpp:2625
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.c:518
sort_slaying
static int sort_slaying(const void *left, const void *right)
Definition: mapper.cpp:2878
tiled_map_list
static struct_map_list tiled_map_list
Definition: mapper.cpp:238
add_race_to_list
static void add_race_to_list(struct_race *race, struct_race_list *list, int check)
Definition: mapper.cpp:286
StringBuffer
Definition: stringbuffer.c:25
equipment_count
static size_t equipment_count
Definition: mapper.cpp:251
struct_race_list
struct struct_race_list struct_race_list
is_valid_types_gen.found
found
Definition: is_valid_types_gen.py:39
check_equipment
static void check_equipment(object *item, struct_map_info *map)
Definition: mapper.cpp:577
sort_system_quest
static int sort_system_quest(const void *a, const void *b)
Definition: mapper.cpp:2207
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:721
EXIT
@ EXIT
Definition: object.h:181
obj::y
int16_t y
Definition: object.h:328
sortbyname
static int sortbyname(const void *a, const void *b)
Definition: mapper.cpp:795
path_stack
static std::vector< std::string > path_stack
Definition: mapper.cpp:2549
create_npc_array
static nlohmann::json create_npc_array(struct_npc_list &list)
Definition: mapper.cpp:2266
merge_tiled_maps
static void merge_tiled_maps(struct_map_info *map, struct_map_info *tiled_map)
Definition: mapper.cpp:1266
cached_pics
static int cached_pics
Definition: mapper.cpp:328
struct_map_list::allocated
size_t allocated
Definition: mapper.cpp:206
list_map
static void list_map(const char *path)
Definition: mapper.cpp:1327
struct_map_info::exits_to
struct_map_list exits_to
Definition: mapper.cpp:218
struct_map_info::lore
char * lore
Definition: mapper.cpp:214
rendered_templates
static std::set< std::string > rendered_templates
Definition: mapper.cpp:2217
apply_auto
int apply_auto(object *op)
Definition: mapper.cpp:3377
make_face_from_files.out
out
Definition: make_face_from_files.py:75
quest.h
obj::type
uint8_t type
Definition: object.h:341
dirent
#define dirent
Definition: xdir.h:12
S_DETECTOR
#define S_DETECTOR
Definition: mapper.cpp:392
struct_map_info::path
char * path
Definition: mapper.cpp:211
struct_map_in_quest_list::count
size_t count
Definition: mapper.cpp:198
init_map_list
static void init_map_list(struct_map_list *list)
Definition: mapper.cpp:411
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.c:74
add_region_link
static void add_region_link(mapstruct *source, mapstruct *dest)
Definition: mapper.cpp:1398
FLAG_FRIENDLY
#define FLAG_FRIENDLY
Definition: define.h:246
struct_region_info
struct struct_region_info struct_region_info
obj::move_slow
MoveType move_slow
Definition: object.h:433
free_equipment
static void free_equipment(struct_equipment *equip)
Definition: mapper.cpp:451
esrv_update_spells
void esrv_update_spells(player *)
Definition: mapper.cpp:3367
created_pics
static int created_pics
Definition: mapper.cpp:327
size_large
#define size_large
Definition: mapper.cpp:315
add_map_to_slaying
static void add_map_to_slaying(struct_slaying_info *info, int item, struct_map_info *map)
Definition: mapper.cpp:1461
struct_region_info::sum
int sum
Definition: mapper.cpp:358
inja::TemplateStorage
std::map< std::string, Template > TemplateStorage
Definition: inja.hpp:2852
IS_ARMOR
#define IS_ARMOR(op)
Definition: define.h:166
OF_PNG
@ OF_PNG
Definition: mapper.cpp:332
struct_region_info::maps_list
struct_map_list maps_list
Definition: mapper.cpp:357
init_npc_list
static void init_npc_list(struct_npc_list *list)
Definition: mapper.cpp:1154
item
Definition: item.py:1
struct_map_info::processed
int processed
Definition: mapper.cpp:230
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
FIREWALL
@ FIREWALL
Definition: object.h:168
PLAYER_CHANGER
@ PLAYER_CHANGER
Definition: object.h:162
get_face_fallback
int get_face_fallback(int faceset, uint16_t imageno)
Definition: image.c:132
inja::Arguments
std::vector< const json * > Arguments
Definition: inja.hpp:1567
nlohmann::basic_json
a class to store JSON values
Definition: json.hpp:3380
give.op
op
Definition: give.py:33
autojail.value
value
Definition: autojail.py:6
save_picture
static void save_picture(FILE *file, gdImagePtr pic)
Definition: mapper.cpp:1384
display_rendered_template
static bool display_rendered_template
Definition: mapper.cpp:324
templates_root
static std::string templates_root("templates/")
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Definition: define.h:250
quest_definition
Definition: quest.h:42
struct_map_info::monsters
struct_race_list monsters
Definition: mapper.cpp:223
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:282
elevation_info
static int ** elevation_info
Definition: mapper.cpp:379
color_blocking
static int color_blocking
Definition: mapper.cpp:376
get_region_struct
region * get_region_struct(void)
Definition: region.c:326
struct_map_in_quest::description
char * description
Definition: mapper.cpp:904
get_template
static inja::Template get_template(const std::string &filename)
Definition: mapper.cpp:3031
convert.dest
dest
Definition: convert.py:25
struct_map_info::tiled_maps
struct_map_list tiled_maps
Definition: mapper.cpp:221
inja.hpp
diamondslots.y
y
Definition: diamondslots.py:16
ext_info_map
void ext_info_map(int, const mapstruct *, uint8_t, uint8_t, const char *str1)
Definition: mapper.cpp:3335
region_count
static size_t region_count
Definition: mapper.cpp:363
command_help
void command_help(object *, const char *)
Definition: mapper.cpp:3450
do_parameters
static void do_parameters(int argc, char **argv)
Definition: mapper.cpp:2928
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
buf
StringBuffer * buf
Definition: readable.c:1606
all_data
static nlohmann::json all_data
Definition: mapper.cpp:2216
face_info::datalen
uint16_t datalen
Definition: image.h:12
add_monster
static void add_monster(object *monster, struct_map_info *map)
Definition: mapper.cpp:641
struct_map_in_quest_list::list
struct struct_map_in_quest ** list
Definition: mapper.cpp:197
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:80
struct_quest::number
int number
Definition: mapper.cpp:910
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.c:2820
pageToRender::template_name
std::string template_name
Definition: mapper.cpp:2627
struct_map_info::cfregion
region * cfregion
Definition: mapper.cpp:215
object_update_speed
void object_update_speed(object *op)
Definition: object.c:1317
sort_race
static int sort_race(const void *a, const void *b)
Definition: mapper.cpp:663
obj::head
struct obj * head
Definition: object.h:297
do_regions_link
static bool do_regions_link
Definition: mapper.cpp:384
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:232
init_race_list
static void init_race_list(struct_race_list *list)
Definition: mapper.cpp:270
process_map
static void process_map(struct_map_info *info)
Definition: mapper.cpp:1541
quests_allocated
static int quests_allocated
Definition: mapper.cpp:919
region
struct regiondef region
strcasecmp
int strcasecmp(const char *s1, const char *s2)
artifactstruct::item
object * item
Definition: artifact.h:15
castle_read.key
key
Definition: castle_read.py:64
npc_dialog.npc
npc
Definition: npc_dialog.py:95
found_maps
static char ** found_maps
Definition: mapper.cpp:367
find_skill_by_number
object * find_skill_by_number(object *, int)
Definition: mapper.cpp:3357
sizes
static int sizes[]
Definition: mapper.cpp:313
reverse_regions
static std::map< region *, std::string > reverse_regions
Definition: mapper.cpp:2219
S_DOOR
#define S_DOOR
Definition: mapper.cpp:389
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:2067
create_tiled_map
static struct_map_info * create_tiled_map(void)
Definition: mapper.cpp:1250
world_map
static int world_map
Definition: mapper.cpp:319
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.c:1533
templates
static std::vector< std::string > templates
Definition: mapper.cpp:2655
ignore_path
static const char * ignore_path[]
Definition: mapper.cpp:2735
sort_equipment
static int sort_equipment(const void *a, const void *b)
Definition: mapper.cpp:594
struct_map_list::count
size_t count
Definition: mapper.cpp:205
slaying_count
static size_t slaying_count
Definition: mapper.cpp:403
player_get_delayed_buffer
SockList * player_get_delayed_buffer(player *)
Definition: mapper.cpp:3432
add_template_to_render
void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string &param)
Definition: mapper.cpp:2639
struct_npc_list::allocated
size_t allocated
Definition: mapper.cpp:185
regiondef::fallback
int8_t fallback
Definition: map.h:294
infomap
static gdImagePtr infomap
Definition: mapper.cpp:372
sort_struct_map_in_quest
static int sort_struct_map_in_quest(const void *left, const void *right)
Definition: mapper.cpp:1008
struct_map_info::height
int height
Definition: mapper.cpp:229
ALTAR
@ ALTAR
Definition: object.h:122
struct_npc_info::x
int x
Definition: mapper.cpp:178
relative_path
static void relative_path(const char *from, const char *to, char *result)
Definition: mapper.cpp:811
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
dump_unused_maps
static void dump_unused_maps(void)
Definition: mapper.cpp:2804
struct_npc_list::npc
struct_npc_info ** npc
Definition: mapper.cpp:183
rod_adjust
void rod_adjust(object *)
Definition: mapper.cpp:3370
struct_map_info::readable
struct_npc_list readable
Definition: mapper.cpp:226
sort_region
static int sort_region(const void *left, const void *right)
Definition: mapper.cpp:891
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.c:274
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:531
fix_exits_for_map
static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from)
Definition: mapper.cpp:1967
struct_npc_list
Definition: mapper.cpp:182
quest_step_definition::step_description
sstring step_description
Definition: quest.h:35
SCROLL
@ SCROLL
Definition: object.h:221
FLAG_IS_LINKED
#define FLAG_IS_LINKED
Definition: define.h:315
struct_npc_info::name
const char * name
Definition: mapper.cpp:176
draw_ext_info
void draw_ext_info(int, int, const object *, uint8_t, uint8_t, const char *txt)
Definition: mapper.cpp:3323
say.item
dictionary item
Definition: say.py:149
do_help
static void do_help(const char *program)
Definition: mapper.cpp:2891
struct_quest::name
char * name
Definition: mapper.cpp:908
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21582
init_library
void init_library(void)
Definition: init.c:192
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:317
write_world_info
static void write_world_info(void)
Definition: mapper.cpp:2827
struct_map_in_quest_list::allocated
size_t allocated
Definition: mapper.cpp:199
tiled_map_need_pic
static int tiled_map_need_pic(struct_map_info *map)
Definition: mapper.cpp:2041
regiondef::msg
char * msg
Definition: map.h:292
face_sets
Definition: image.h:17
equipment_allocated
static size_t equipment_allocated
Definition: mapper.cpp:253
SPELL
@ SPELL
Definition: object.h:214
map_limit
static int map_limit
Definition: mapper.cpp:317
replace.current
current
Definition: replace.py:64
closedir
int closedir(DIR *)
quests
static struct_quest ** quests
Definition: mapper.cpp:915
guildbuy.temp
def temp
Definition: guildbuy.py:26
fix_tiled_map
static void fix_tiled_map(void)
Definition: mapper.cpp:1898
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
first_region
EXTERN region * first_region
Definition: global.h:117
output_format_type
output_format_type
Definition: mapper.cpp:331
TELEPORTER
@ TELEPORTER
Definition: object.h:141
regiondef::longname
char * longname
Definition: map.h:290
gdfaces
static gdImagePtr * gdfaces
Definition: mapper.cpp:172
pics_allocated
static int pics_allocated
Definition: mapper.cpp:308
struct_equipment
Definition: mapper.cpp:241
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
SPELLBOOK
@ SPELLBOOK
Definition: object.h:203
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:668
takeitem.status
status
Definition: takeitem.py:35
find_player_partial_name
player * find_player_partial_name(const char *)
Definition: mapper.cpp:3436
find_map_by_key
static struct_map_info * find_map_by_key(const std::string &key)
Definition: mapper.cpp:2226
warn_no_path
static int warn_no_path
Definition: mapper.cpp:352
find_quest_info
static struct_quest * find_quest_info(const char *name)
Definition: mapper.cpp:940
DETECTOR
@ DETECTOR
Definition: object.h:149
find_maps
static void find_maps(const char *from)
Definition: mapper.cpp:2759
struct_slaying_info::slaying
char * slaying
Definition: mapper.cpp:398
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
is_road
static int is_road(object *item)
Definition: mapper.cpp:676
obj::level
int16_t level
Definition: object.h:354
elevation_min
static int elevation_min
Definition: mapper.cpp:380
struct_map_info::npcs
struct_npc_list npcs
Definition: mapper.cpp:225
color_linked_exit
static int color_linked_exit
Definition: mapper.cpp:374
FLAG_IS_FLOOR
#define FLAG_IS_FLOOR
Definition: define.h:302
add_one_item
static void add_one_item(object *item, struct_map_info *map)
Definition: mapper.cpp:503
FLAG_IDENTIFIED
#define FLAG_IDENTIFIED
Definition: define.h:261
give.name
name
Definition: give.py:27
pageToRender::output_name
std::string output_name
Definition: mapper.cpp:2628
regiondef
Definition: map.h:275