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 
150 #include <ctype.h>
151 #include <errno.h>
152 #include <stdio.h>
153 #include <stdlib.h>
154 #include <string.h>
155 #include <strings.h>
156 #include <sys/stat.h>
157 #include <sys/types.h>
158 #include <time.h>
159 
160 #include "global.h"
161 #include "sproto.h"
162 #include "image.h"
163 #include "quest.h"
164 
165 extern "C" {
166 #include <gd.h>
167 #include <gdfonts.h>
168 #include <gdfontl.h>
169 #include <gdfontg.h>
170 }
171 
172 #include "inja.hpp"
173 #include <map>
174 #include <set>
175 
176 static gdImagePtr *gdfaces;
177 
179 typedef struct struct_npc_info {
180  const char *name;
181  const char *message;
182  int x, y;
184 
186 typedef struct struct_npc_list {
188  size_t count;
189  size_t allocated;
191 
193 typedef struct struct_race_list {
194  struct struct_race **races;
195  size_t count;
196  size_t allocated;
198 
200 typedef struct {
202  size_t count;
203  size_t allocated;
205 
207 typedef struct {
209  size_t count;
210  size_t allocated;
212 
214 typedef struct struct_map_info {
215  char *path;
216  char *name;
217  char *filename;
218  char *lore;
225 
227 
229 
232 
234  int height, width;
236  struct struct_map_info *tiles[4];
238 
241 
244 
246 typedef struct struct_equipment {
247  char *name;
248  int power;
250  char *diff;
253 
256 static size_t equipment_count = 0;
258 static size_t equipment_allocated = 0;
262 typedef struct struct_race {
263  char *name;
264  int count;
266 } struct_race;
267 
270 static std::set<std::string> reset_groups;
278  list->races = NULL;
279  list->count = 0;
280  list->allocated = 0;
281 }
282 
294  if (check) {
295  size_t test;
296 
297  for (test = 0; test < list->count; test++) {
298  if (list->races[test] == race)
299  return;
300  }
301  }
302 
303  if (list->allocated == list->count) {
304  list->allocated += 50;
305  list->races = (struct_race **)realloc(list->races, sizeof(struct_race *)*list->allocated);
306  }
307  list->races[list->count] = race;
308  list->count++;
309 }
310 
312 static char root[500];
313 
315 static int pics_allocated;
316 
317 /* Options */
318 static int generate_pics = 1;
319 static int force_pics = 0;
320 static int sizes[] = {32, 16, 8, 4, 2};
321 static const int num_sizes = sizeof(sizes)/sizeof(int);
322 #define size_large sizes[0]
323 #define size_small sizes[1]
324 static int map_limit = -1;
325 static int show_maps = 0;
326 static int world_map = 1;
327 static int world_exit_info = 1;
328 static int tileset = 0;
329 static bool detail_quests = false;
330 static bool list_system_quests = false;
331 static bool display_rendered_template = false;
334 static int created_pics = 0;
335 static int cached_pics = 0;
339  OF_PNG = 0,
340  OF_JPG = 1
341 };
342 
344 static const char *output_extensions[] = {
345  ".png",
346  ".jpg"
347 };
348 
351 
353 static int jpeg_quality = -1;
354 
356 static int rawmaps = 0;
357 
359 static int warn_no_path = 0;
360 
362 typedef struct struct_region_info {
365  int sum_x, sum_y, sum;
366  int is_world;
368 
369 static struct struct_region_info **regions = NULL;
370 static size_t region_count = 0;
371 static size_t region_allocated = 0;
373 static int list_unused_maps = 0;
374 static char **found_maps = NULL;
375 static int found_maps_count = 0;
376 static int found_maps_allocated = 0;
378 /* Path/exit info */
379 static gdImagePtr infomap;
381 static int color_linked_exit;
382 static int color_road;
383 static int color_blocking;
384 static int color_slowing;
386 static int **elevation_info;
387 static int elevation_min;
388 static int elevation_max;
390 /* Whether to compute links between regions or not (expensive). */
391 static bool do_regions_link = false;
392 /* Links between regions, key is source, value are destinations. */
393 static std::map<region *, std::set<region *>> region_links;
394 
396 #define S_DOOR 0
397 #define S_KEY 1
398 #define S_CONTAINER 2
399 #define S_DETECTOR 3
400 #define S_CONNECT 4
401 #define S_MAX 5
402 
404 typedef struct {
405  char *slaying;
408 
410 static size_t slaying_count = 0;
411 static size_t slaying_allocated = 0;
419  list->maps = NULL;
420  list->count = 0;
421  list->allocated = 0;
422 }
423 
424 static void add_map(struct_map_info *info, struct_map_list *list);
425 
426 static int is_special_equipment(object *item) {
427  if (item->name == item->arch->clone.name && item->title == item->arch->clone.title)
428  return 0;
430  return 0;
431  if (item->move_block == MOVE_ALL)
432  return 0;
433 
434  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))
435  return 1;
436 
437  return 0;
438 }
439 
446  struct_equipment *add = (struct_equipment *)calloc(1, sizeof(struct_equipment));
447 
448  init_map_list(&add->origin);
449  return add;
450 }
451 
458 static void free_equipment(struct_equipment *equip) {
459  free(equip->diff);
460  free(equip->name);
461  free(equip);
462 }
463 
473  struct_equipment *comp;
474 
475  for (size_t check = 0; check < equipment_count; check++) {
476  comp = special_equipment[check];
477 
478  if (strcmp(comp->name, item->name))
479  continue;
480  if (comp->power != item->power)
481  continue;
482  if (comp->calc_power != item->calc_power)
483  continue;
484  if (strcmp(comp->diff, item->diff))
485  continue;
486 
488  return comp;
489  }
490 
492  equipment_allocated += 50;
494  }
496  equipment_count++;
497 
498  return item;
499 }
500 
510 static void add_one_item(object *item, struct_map_info *map) {
513  int x, y;
514  sstring name, namepl;
515  uint32_t nrof;
516  object *base;
517 
518  x = item->x;
519  y = item->y;
520  name = item->name;
521  namepl = item->name_pl;
522  nrof = item->nrof;
523 
524  if (item->artifact != NULL) {
525  const artifact *artifact;
526 
527  artifact = find_artifact(item, item->artifact);
528  if (artifact == NULL) {
529  LOG(llevError, "could not find artifact %s [%d] to save data\n", item->artifact, item->type);
530  base = arch_to_object(item->arch);
531  } else {
532  base = arch_to_object(item->arch);
534  }
535  }
536  else {
537  base = arch_to_object(item->arch);
538  }
539 
540  item->x = base->x;
541  item->y = base->y;
542  item->name = base->name;
543  item->name_pl = base->name_pl;
544  item->nrof = base->nrof;
545 
548  SET_FLAG(base, FLAG_IDENTIFIED);
549  }
551  SET_FLAG(base, FLAG_UNPAID);
552  get_ob_diff(bf, item, base);
554 
555  add->diff = stringbuffer_finish(bf);
556 
557  item->x = x;
558  item->y = y;
559  item->name = name;
560  item->name_pl = namepl;
561  item->nrof = nrof;
562 
563  if (add->diff == NULL || strcmp(add->diff, "") == 0) {
564  free_equipment(add);
565  return;
566  }
567 
568  add->name = strdup(item->name);
569  add->power = item->item_power;
571 
572  add = ensure_unique(add);
573  add_map(map, &add->origin);
574 }
575 
584 static void check_equipment(object *item, struct_map_info *map) {
587 
590  FOR_INV_FINISH();
591 }
592 
601 static int sort_equipment(const void *a, const void *b) {
602  const struct_equipment *l = *(const struct_equipment **)a;
603  const struct_equipment *r = *(const struct_equipment **)b;
604  int c = l->power-r->power;
605 
606  if (c)
607  return c;
608  return strcasecmp(l->name, r->name);
609 }
610 
619 static struct_race *get_race(const char *name) {
620  size_t test;
621  struct_race *item;
622 
623  for (test = 0; test < races.count; test++) {
624  if (strcmp(races.races[test]->name, name) == 0) {
625  races.races[test]->count++;
626  return races.races[test];
627  }
628  }
629 
630  item = (struct_race *)calloc(1, sizeof(struct_race));
631  item->name = strdup(name);
632  item->count = 1;
633  init_map_list(&item->origin);
634 
636 
637  return item;
638 }
639 
648 static void add_monster(object *monster, struct_map_info *map) {
649  struct_race *race;
650 
651  if (monster->head && monster != monster->head)
652  return;
653 
654  map->min_monster = MIN(monster->level, map->min_monster);
655  map->max_monster = MAX(monster->level, map->max_monster);
656 
657  race = get_race(monster->name);
658  add_map(map, &race->origin);
659  add_race_to_list(race, &map->monsters, 1);
660 }
661 
670 static int sort_race(const void *a, const void *b) {
671  const struct_race *l = *(const struct_race **)a;
672  const struct_race *r = *(const struct_race **)b;
673  return strcasecmp(l->name, r->name);
674 }
675 
683 static int is_road(object *item) {
684  int test;
685  /* Archetypes used as roads. */
686  const char *roads[] = {
687  "cobblestones",
688  "flagstone",
689  "ice_stone",
690  "snow",
691  NULL };
692  const char *partial[] = {
693  "dirtroad_",
694  NULL };
695 
696  for (test = 0; partial[test] != NULL; test++) {
697  if (strstr(item->arch->name, partial[test]) != NULL)
698  return 1;
699  }
700 
702  return 0;
703 
704  for (test = 0; roads[test] != NULL; test++) {
705  if (strcmp(item->arch->name, roads[test]) == 0)
706  return 1;
707  }
708 
709  return 0;
710 }
711 
719 static int is_blocking(object *item) {
720  return item->move_block == MOVE_ALL ? 1 : 0;
721 }
722 
733 static int get_elevation_color(int elevation, gdImagePtr elevationmap) {
734  if (elevation > 0)
735  return gdImageColorResolve(elevationmap, 200*elevation/elevation_max, 0, 0);
736  else
737  return gdImageColorResolve(elevationmap, 0, 0, 200*elevation/elevation_min);
738 }
739 
748 static void do_exit_map(mapstruct *map) {
749  int tx, ty, x, y;
750  object *test;
751  sstring selevation;
752 
753  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) != 2)
754  return;
755 
756  x -= 100;
757  y -= 100;
758 
759  for (tx = 0; tx < MAP_WIDTH(map); tx++) {
760  for (ty = 0; ty < MAP_HEIGHT(map); ty++) {
761  FOR_MAP_PREPARE(map, tx, ty, item) {
762  test = HEAD(item);
763 
764  if (test->type == EXIT || test->type == TELEPORTER) {
765  if (!test->slaying)
766  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_unlinked_exit);
767  else
768  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_linked_exit);
769  } else if (is_road(test))
770  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_road);
771  else if (is_blocking(test)) {
772  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_blocking);
773  /* can't get on the spot, so no need to go on. */
774  break;
775  } else if (test->move_slow != 0)
776  gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_slowing);
777 
778  selevation = object_get_value(item, "elevation");
779  if (selevation) {
780  int32_t elevation = atoi(selevation);
781  elevation_min = MIN(elevation_min, elevation);
782  elevation_max = MAX(elevation_max, elevation);
783  elevation_info[x*50+tx][y*50+ty] = elevation;
784  }
785  } FOR_MAP_FINISH();
786  }
787  }
788 }
789 
790 void do_auto_apply(mapstruct *m);
791 
802 static int sortbyname(const void *a, const void *b) {
803  return (strcmp(*(const char **)a, *(const char **)b));
804 }
805 
818 static void relative_path(const char *from, const char *to, char *result) {
819  const char *fslash;
820  const char *rslash;
821 
822  result[0] = '\0';
823 
824  fslash = strchr(from+1, '/');
825  if (!fslash) {
826  strcpy(result, to+1);
827  return;
828  }
829 
830  rslash = strchr(to+1, '/');
831  while (fslash && rslash && (fslash-from == rslash-to) && strncmp(from, to, fslash-from+1) == 0) {
832  from = fslash+1;
833  to = rslash+1;
834  fslash = strchr(fslash+1, '/');
835  rslash = strchr(rslash+1, '/');
836  }
837 
838  while (fslash) {
839  strcat(result, "../");
840  fslash = strchr(fslash+1, '/');
841  }
842  if (strlen(result) && result[strlen(result)-1] == '/' && *to == '/')
843  result[strlen(result)-1] = '\0';
844  strcat(result, to);
845 }
846 
857 static int compare_map_info(const struct_map_info *left, const struct_map_info *right) {
858  int c;
859 
860  if (left->tiled_group)
861  left = left->tiled_group;
862  if (right->tiled_group)
863  right = right->tiled_group;
864 
865  c = strcasecmp(left->name, right->name);
866  if (c)
867  return c;
868 
869  return strcasecmp(left->path, right->path);
870 }
871 
882 static int sort_map_info(const void *left, const void *right) {
883  const struct_map_info *l = *(const struct_map_info **)left;
884  const struct_map_info *r = *(const struct_map_info **)right;
885  return compare_map_info(l, r);
886 }
887 
898 static int sort_region(const void *left, const void *right) {
899  return strcmp((*((struct_region_info **)left))->reg->name, (*((struct_region_info **)right))->reg->name);
900 }
901 
902 /************************************
903  Start of quest-related definitions.
904 ************************************/
905 
907 typedef struct struct_map_in_quest {
909  char *description;
910  struct struct_quest *quest;
912 
914 typedef struct struct_quest {
915  char *name;
916  char *description;
917  int number;
920 } struct_quest;
921 
922 static struct_quest **quests = NULL;
924 static int quests_count = 0;
926 static int quests_allocated = 0;
929  list->list = NULL;
930  list->count = 0;
931  list->allocated = 0;
932 }
933 
935  if (list->count == list->allocated) {
936  list->allocated += 10;
937  list->list = (struct_map_in_quest **)realloc(list->list, sizeof(struct_map_in_quest *)*list->allocated);
938  }
939  list->list[list->count++] = item;
940 }
941 
947 static struct_quest *find_quest_info(const char *name) {
948  int test;
949  for (test = 0; test < quests_count; test++) {
950  if (strcmp(quests[test]->name, name) == 0)
951  return quests[test];
952  }
953  return NULL;
954 }
955 
964 static struct_quest *get_quest_info(const char *name) {
966  if (add) {
967  return add;
968  }
969 
971  quests_allocated += 10;
972  quests = (struct_quest **)realloc(quests, sizeof(struct_quest *)*quests_allocated);
973  }
974  add = (struct_quest *)calloc(1, sizeof(struct_quest));
975  add->name = strdup(name);
976  add->number = quests_count;
978  quests[quests_count] = add;
979  quests_count++;
980  return add;
981 }
982 
993 static void add_map_to_quest(struct_map_info *map, const char *name, const char *description) {
994  struct_map_in_quest *add;
996 
997  add = (struct_map_in_quest *)calloc(1, sizeof(struct_map_in_quest));
998  add->map = map;
999  add->quest = quest;
1000  add->description = strdup(description);
1001  while (strlen(add->description) && add->description[strlen(add->description)-1] == '\n')
1002  add->description[strlen(add->description)-1] = '\0';
1004  add_to_struct_map_in_quest_list(&map->quests, add);
1005 }
1006 
1015 static int sort_struct_map_in_quest(const void *left, const void *right) {
1016  int c;
1017 
1018  const struct_map_in_quest *l = *(const struct_map_in_quest **)left;
1019  const struct_map_in_quest *r = *(const struct_map_in_quest **)right;
1020  const struct_map_info *ml = l->map;
1021  const struct_map_info *mr = r->map;
1022 
1023  if (ml->tiled_group)
1024  ml = ml->tiled_group;
1025  if (mr->tiled_group)
1026  mr = mr->tiled_group;
1027 
1028  c = strcasecmp(ml->name, mr->name);
1029  if (c)
1030  return c;
1031 
1032  return strcasecmp(ml->path, mr->path);
1033 }
1034 
1043 static int sort_struct_quest(const void *left, const void *right) {
1044  const struct_quest *l = *(const struct_quest **)left;
1045  const struct_quest *r = *(const struct_quest **)right;
1046  return strcasecmp(l->name, r->name);
1047 }
1048 
1059 static void define_quest(const char *name, struct_map_info *mainmap, const char *description) {
1061 
1062  if (quest->description || quest->mainmap) {
1063  printf("warning, multiple quest definition for %s, found in %s and %s.\n", quest->name, quest->mainmap ? quest->mainmap->path : "(unknown map)", mainmap->path);
1064  return;
1065  }
1066  quest->description = strdup(description);
1067  while (strlen(quest->description) && quest->description[strlen(quest->description)-1] == '\n')
1068  quest->description[strlen(quest->description)-1] = '\0';
1069  quest->mainmap = mainmap;
1070 }
1071 
1079  char *start, *end, *next;
1080  char name[500];
1081  char description[500];
1082 
1083  start = strstr(map->lore, "@def");
1084  while (start) {
1085  description[0] = '\0';
1086  /* find name */
1087  end = strstr(start, "\n");
1088  if (end) {
1089  strncpy(name, start+5, end-start-5);
1090  name[end-start-5] = '\0';
1091  next = end+1;
1092  end = strstr(next, "@end");
1093  if (end) {
1094  strncpy(description, next, end-next);
1095  description[end-next] = '\0';
1096  /* need to erase the text. */
1097  memmove(start, end+4, strlen(map->lore)-(end-start+3));
1098  end = start;
1099  }
1100  else {
1101  strcpy(description, next);
1102  *start = '\0';
1103  end = NULL;
1104  }
1105  } else {
1106  strcpy(name, start);
1107  *start = '\0';
1108  end = NULL;
1109  }
1110 
1111  define_quest(name, map, description);
1112  start = end ? strstr(end, "@def") : NULL;
1113  }
1114 
1115  start = strstr(map->lore, "@quest");
1116  while (start) {
1117  description[0] = '\0';
1118  /* find name */
1119  end = strstr(start, "\n");
1120  if (end) {
1121  strncpy(name, start+7, end-start-7);
1122  name[end-start-7] = '\0';
1123  next = end+1;
1124  end = strstr(next, "@end");
1125  if (end) {
1126  strncpy(description, next, end-next);
1127  description[end-next] = '\0';
1128  /* need to erase the text. */
1129  memmove(start, end+4, strlen(map->lore)-(end-start+3));
1130  end = start;
1131  }
1132  else {
1133  strcpy(description, next);
1134  *start = '\0';
1135  end = NULL;
1136  }
1137  } else {
1138  strcpy(name, start);
1139  *start = '\0';
1140  end = NULL;
1141  }
1142 
1143  add_map_to_quest(map, name, description);
1144  start = end ? strstr(end, "@quest") : NULL;
1145  }
1146 }
1147 
1148 /************************************
1149  End of quest-related definitions.
1150 ************************************/
1151 
1152 /*********
1153 NPC-related stuff
1154 ********/
1155 
1162  list->allocated = 0;
1163  list->count = 0;
1164  list->npc = NULL;
1165 }
1166 
1174 static struct_npc_info *create_npc_info(const object *npc) {
1175  struct_npc_info *info = (struct_npc_info *)calloc(1, sizeof(struct_npc_info));
1176 
1177  info->name = strdup(npc->name);
1178  info->message = strdup(npc->msg);
1179  info->x = npc->x;
1180  info->y = npc->y;
1181 
1182  return info;
1183 }
1184 
1192 static void add_npc_to_map(struct_npc_list *list, const object *npc) {
1193  if (list->count == list->allocated) {
1194  list->allocated += 50;
1195  list->npc = (struct_npc_info **)realloc(list->npc, list->allocated*sizeof(struct_npc_info *));
1196  }
1197 
1198  list->npc[list->count] = create_npc_info(npc);
1199  list->count++;
1200 }
1201 /* end of NPC stuff */
1202 
1215  size_t map;
1216 
1217  for (map = 0; map < list->count; map++)
1218  if (list->maps[map] == info)
1219  return;
1220 
1221  if (list->count == list->allocated) {
1222  list->allocated += 50;
1223  list->maps = (struct_map_info **)realloc(list->maps, list->allocated*sizeof(struct_map_info *));
1224  }
1225  list->maps[list->count] = info;
1226  list->count++;
1227 }
1228 
1236  struct_map_info *add = (struct_map_info *)calloc(1, sizeof(struct_map_info));
1237 
1238  add->min_monster = 2000;
1239  init_map_list(&add->exits_to);
1240  init_map_list(&add->exits_from);
1241  init_map_list(&add->tiled_maps);
1243  init_race_list(&add->monsters);
1244  init_npc_list(&add->npcs);
1245  init_npc_list(&add->readable);
1246  add->tiled_group = NULL;
1247 
1248  return add;
1249 }
1250 
1259 
1260  add_map(add, &tiled_map_list);
1261  return add;
1262 }
1263 
1274  size_t g;
1275  struct_map_info *group = tiled_map->tiled_group;
1276  struct_map_info *change;
1277 
1278  while (group->tiled_maps.count > 0) {
1279  change = group->tiled_maps.maps[group->tiled_maps.count-1];
1280  change->tiled_group = map->tiled_group;
1281  add_map(change, &map->tiled_group->tiled_maps);
1282  group->tiled_maps.count--;
1283  }
1284 
1285  for (g = 0; g < tiled_map_list.count; g++) {
1286  if (tiled_map_list.maps[g] == group) {
1287  if (g < tiled_map_list.count-1)
1290  free(group);
1291  return;
1292  }
1293  }
1294  printf("tiled_map not in tiled_map_list!");
1295  abort();
1296 
1297 }
1298 
1307 static struct_map_info *get_map_info(const char *path) {
1308  struct_map_info *add;
1309  char *tmp;
1310 
1311  for (size_t map = 0; map < maps_list.count; map++) {
1312  if (strcmp(maps_list.maps[map]->path, path) == 0)
1313  return maps_list.maps[map];
1314  }
1315 
1316  add = create_map_info();
1317  add->path = strdup(path);
1318  tmp = strrchr((char *)path, '/');
1319  if (tmp)
1320  add->filename = strdup(tmp+1);
1321  else
1322  add->filename = strdup(path);
1323 
1324  add_map(add, &maps_list);
1325  return add;
1326 }
1327 
1334 static void list_map(const char *path) {
1335  int index;
1336 
1337  for (index = 0; index < found_maps_count; index++) {
1338  if (found_maps[index] && strcmp(path, found_maps[index]) == 0) {
1339  free(found_maps[index]);
1340  found_maps[index] = NULL;
1341  return;
1342  }
1343  }
1344  printf("Map processed but not found in directory reading? %s\n", path);
1345 }
1346 
1358  size_t test;
1359  int x, y;
1360 
1361  for (test = 0; test < region_count; test++) {
1362  if (regions[test]->reg == reg)
1363  break;
1364  }
1365  if (test == region_count) {
1366  if (test == region_allocated) {
1367  region_allocated++;
1369  regions[test] = (struct_region_info *)calloc(1, sizeof(struct_region_info));
1370  }
1371  region_count++;
1372  regions[test]->reg = reg;
1373  }
1374  add_map(map, &regions[test]->maps_list);
1375  if (sscanf(map->path, "/world/world_%d_%d", &x, &y) == 2) {
1376  regions[test]->sum_x += (x-100);
1377  regions[test]->sum_y += (y-100);
1378  regions[test]->sum++;
1379  regions[test]->is_world = 1;
1380  }
1381 }
1382 
1391 static void save_picture(FILE *file, gdImagePtr pic) {
1392  if (output_format == OF_PNG)
1393  gdImagePng(pic, file);
1394  else
1395  gdImageJpeg(pic, file, jpeg_quality);
1396 }
1397 
1405 static void add_region_link(mapstruct *source, mapstruct *dest) {
1406  region *s, *d;
1407 
1408  s = get_region_by_map(source);
1409  d = get_region_by_map(dest);
1410  if (s == d)
1411  return;
1412 
1413  region_links[s].insert(d);
1414 }
1415 
1424 static int is_slaying(object *item) {
1425  return (item->type == LOCKED_DOOR || item->type == SPECIAL_KEY || item->type == CONTAINER || item->type == CHECK_INV);
1426 }
1427 
1428 
1437 static struct_slaying_info *get_slaying_struct(const char *slaying) {
1438  for (size_t l = 0; l < slaying_count; l++) {
1439  if (!strcmp(slaying_info[l]->slaying, slaying))
1440  return slaying_info[l];
1441  }
1443  slaying_allocated += 10;
1445  }
1446 
1447  struct_slaying_info *add = (struct_slaying_info *)calloc(1, sizeof(struct_slaying_info));
1448  add->slaying = strdup(slaying);
1449  for (size_t l = 0; l < S_MAX; l++)
1450  init_map_list(&add->maps[l]);
1451 
1452  slaying_info[slaying_count] = add;
1453  slaying_count++;
1454 
1455  return add;
1456 }
1457 
1469  add_map(map, &info->maps[item]);
1470 }
1471 
1480 static void add_slaying(struct_map_info *map, object *item) {
1481  struct_slaying_info *info;
1482 
1483  if (!item->slaying)
1484  /* can be undefined */
1485  return;
1486 
1487  info = get_slaying_struct(item->slaying);
1488  if (item->type == LOCKED_DOOR)
1489  add_map_to_slaying(info, S_DOOR, map);
1490  else if (item->type == SPECIAL_KEY)
1491  add_map_to_slaying(info, S_KEY, map);
1492  else if (item->type == CONTAINER)
1494  else if (item->type == DETECTOR)
1496  else
1498 }
1499 
1510  if (is_slaying(inv))
1511  add_slaying(map, inv);
1513  } FOR_INV_FINISH();
1514 }
1515 
1516 static void generate_picture_path(const char *path, size_t pic_size, char *out, size_t len) {
1517  snprintf(out, len, "%s%s.x%zu%s", root, path, pic_size + 1, output_extensions[output_format]);
1518 }
1519 
1520 static void write_pictures_from_real_size(const char *path, gdImagePtr real, int width, int height) {
1521  char picpath[MAX_BUF];
1522 
1523  generate_picture_path(path, 0, picpath, sizeof(picpath));
1524  make_path_to_file(picpath);
1525  FILE *out = fopen(picpath, "wb+");
1526  save_picture(out, real);
1527  fclose(out);
1528 
1529  for (size_t i = 1; i < num_sizes; i++) {
1530  generate_picture_path(path, i, picpath, sizeof(picpath));
1531  gdImagePtr small = gdImageCreateTrueColor(width*sizes[i], height*sizes[i]);
1532  gdImageCopyResampled(small, real, 0, 0, 0, 0, width*sizes[i], height*sizes[i], width*size_large, height*size_large);
1533  out = fopen(picpath, "wb+");
1534  save_picture(out, small);
1535  fclose(out);
1536  gdImageDestroy(small);
1537  }
1538 }
1539 
1548 static void process_map(struct_map_info *info) {
1549  mapstruct *m;
1550  int x, y, isworld;
1551  gdImagePtr pic = nullptr;
1552  struct stat stats;
1553  struct stat statspic;
1554  char exit_path[500];
1555  char tmppath[MAX_BUF];
1556  char picpath[num_sizes][MAX_BUF];
1557  int needpic = 0;
1558  struct_map_info *link;
1559 
1560  if (list_unused_maps)
1561  list_map(info->path);
1562 
1563  if (show_maps)
1564  printf(" processing map %s\n", info->path);
1565 
1566  m = ready_map_name(info->path, 0);
1567  if (!m) {
1568  printf("couldn't load map %s\n", info->path);
1569  return;
1570  }
1571 
1572  do_exit_map(m);
1573 
1574  if (!rawmaps)
1575  do_auto_apply(m);
1576 
1577  info->level = m->difficulty;
1578  if (m->maplore) {
1579  info->lore = strdup(m->maplore);
1580  process_map_lore(info);
1581  }
1582  if (m->reset_group) {
1583  info->reset_group = add_string(m->reset_group);
1584  reset_groups.insert(m->reset_group);
1585  }
1586 
1587  isworld = (sscanf(info->path, "/world/world_%d_%d", &x, &y) == 2);
1588 
1589  if (m->name)
1590  info->name = strdup(m->name);
1591  else
1592  info->name = strdup(info->filename);
1593 
1594  info->cfregion = get_region_by_map(m);
1595  add_map_to_region(info, info->cfregion);
1596 
1597  for (int i = 0; i < num_sizes; i++) {
1598  generate_picture_path(info->path, i, picpath[i], sizeof(picpath[i]));
1599  }
1600 
1601  if (force_pics)
1602  needpic = 1;
1603  else if (generate_pics) {
1604  create_pathname(info->path, tmppath, MAX_BUF);
1605  stat(tmppath, &stats);
1606  if (stat(picpath[0], &statspic) || (statspic.st_mtime < stats.st_mtime))
1607  needpic = 1;
1608  }
1609  else
1610  needpic = 0;
1611 
1612  if (needpic) {
1613  pic = gdImageCreateTrueColor(MAP_WIDTH(m)*size_large, MAP_HEIGHT(m)*size_large);
1614  created_pics++;
1615  }
1616  else
1617  cached_pics++;
1618 
1619  for (x = 0; x < 4; x++)
1620  if (m->tile_path[x] != NULL) {
1621  path_combine_and_normalize(m->path, m->tile_path[x], exit_path, sizeof(exit_path));
1622  create_pathname(exit_path, tmppath, MAX_BUF);
1623  if (stat(tmppath, &stats)) {
1624  printf(" map %s doesn't exist in map %s, for tile %d.\n", exit_path, info->path, x);
1625  }
1626 
1627  if (isworld) {
1628  link = get_map_info(exit_path);
1629  add_map(link, &info->exits_from);
1630  add_map(info, &link->exits_to);
1631 
1632  if (do_regions_link) {
1633  mapstruct *link = ready_map_name(exit_path, 0);
1634 
1635  if (link && link != m) {
1636  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
1637  * want to reset it. */
1638  add_region_link(m, link);
1639  link->reset_time = 1;
1640  link->in_memory = MAP_IN_MEMORY;
1641  delete_map(link);
1642  }
1643  }
1644  } else {
1645  link = get_map_info(exit_path);
1646  info->tiles[x] = link;
1647  if (link->tiled_group) {
1648  if (info->tiled_group && link->tiled_group != info->tiled_group) {
1649  merge_tiled_maps(info, link);
1650  continue;
1651  }
1652  if (link->tiled_group == info->tiled_group) {
1653  continue;
1654  }
1655  if (!info->tiled_group) {
1656  add_map(info, &link->tiled_group->tiled_maps);
1657  continue;
1658  }
1659  }
1660 
1661  if (!info->tiled_group) {
1662  info->tiled_group = create_tiled_map();
1663  add_map(info, &info->tiled_group->tiled_maps);
1664  }
1665  link->tiled_group = info->tiled_group;
1666  add_map(link, &info->tiled_group->tiled_maps);
1667  }
1668  }
1669 
1670  info->width = MAP_WIDTH(m);
1671  info->height = MAP_HEIGHT(m);
1672 
1673  for (x = MAP_WIDTH(m)-1; x >= 0; x--)
1674  for (y = MAP_HEIGHT(m)-1; y >= 0; y--) {
1675  FOR_MAP_PREPARE(m, x, y, item) {
1676  if (item->type == EXIT || item->type == TELEPORTER || item->type == PLAYER_CHANGER) {
1677  char ep[500];
1678  const char *start;
1679 
1680  if (!item->slaying) {
1681  ep[0] = '\0';
1682  if (warn_no_path)
1683  printf(" exit without any path at %d, %d on %s\n", item->x, item->y, info->path);
1684  } else {
1685  memset(ep, 0, 500);
1686  if (strcmp(item->slaying, "/!"))
1687  strcpy(ep, EXIT_PATH(item));
1688  else {
1689  if (!item->msg) {
1690  printf(" random map without message in %s at %d, %d\n", info->path, item->x, item->y);
1691  } else {
1692  /* Some maps have a 'exit_on_final_map' flag, ignore it. */
1693  start = strstr(item->msg, "\nfinal_map ");
1694  if (!start && strncmp(item->msg, "final_map", strlen("final_map")) == 0)
1695  /* Message start is final_map, nice */
1696  start = item->msg;
1697  if (start) {
1698  char *end = strchr((char *)start+1, '\n');
1699 
1700  start += strlen("final_map")+2;
1701  strncpy(ep, start, end-start);
1702  }
1703  }
1704  }
1705 
1706  if (strlen(ep)) {
1707  path_combine_and_normalize(m->path, ep, exit_path, 500);
1708  create_pathname(exit_path, tmppath, MAX_BUF);
1709  if (stat(tmppath, &stats)) {
1710  printf(" map %s doesn't exist in map %s, at %d, %d.\n", ep, info->path, item->x, item->y);
1711  } else {
1712  link = get_map_info(exit_path);
1713  add_map(link, &info->exits_from);
1714  add_map(info, &link->exits_to);
1715 
1716  if (do_regions_link) {
1717  mapstruct *link = ready_map_name(exit_path, 0);
1718 
1719  if (link && link != m) {
1720  /* no need to link a map with itself. Also, if the exit points to the same map, we don't
1721  * want to reset it. */
1722  add_region_link(m, link);
1723  link->reset_time = 1;
1724  link->in_memory = MAP_IN_MEMORY;
1725  delete_map(link);
1726  }
1727  }
1728  }
1729  }
1730  }
1731  } else if (is_slaying(item))
1732  add_slaying(info, item);
1733 
1734  check_equipment(item, info);
1735 
1737 
1738  if (QUERY_FLAG(item, FLAG_MONSTER)) {
1739  /* need to get the "real" archetype, as the item's archetype can certainly be a temporary one. */
1740  archetype *arch = find_archetype(item->arch->name);
1741 
1742  add_monster(item, info);
1743  if (arch != NULL && (QUERY_FLAG(item, FLAG_UNAGGRESSIVE) || QUERY_FLAG(item, FLAG_FRIENDLY)) && (item->msg != arch->clone.msg) && (item->msg != NULL))
1744  add_npc_to_map(&info->npcs, item);
1745  } else if ((item->type == SIGN || item->type == BOOK) && (item->msg != item->arch->clone.msg) && (item->msg != NULL)) {
1746  add_npc_to_map(&info->readable, item);
1747  }
1748 
1749  if (item->invisible)
1750  continue;
1751 
1752  if (needpic) {
1753  int sx, sy, hx, hy;
1754 
1755  if (gdfaces[item->face->number] == NULL) {
1756  face_sets *fs = find_faceset(get_face_fallback(tileset, item->face->number));
1757 
1758  gdfaces[item->face->number] = gdImageCreateFromPngPtr(fs->faces[item->face->number].datalen, fs->faces[item->face->number].data);
1759  pics_allocated++;
1760  }
1761  if (item->head || item->more) {
1762  object_get_multi_size(item, &sx, &sy, &hx, &hy);
1763  } else {
1764  hx = 0;
1765  hy = 0;
1766  }
1767  if (gdfaces[item->face->number] != NULL && ((!item->head && !item->more) || (item->arch->clone.x+hx == 0 && item->arch->clone.y+hy == 0))) {
1768  gdImageCopy(pic, gdfaces[item->face->number], x*size_large, y*size_large, 0, 0, gdfaces[item->face->number]->sx, gdfaces[item->face->number]->sy);
1769  }
1770  }
1771  } FOR_MAP_FINISH();
1772  }
1773 
1774  if (needpic) {
1776  gdImageDestroy(pic);
1777  info->pic_was_done = 1;
1778  }
1779 
1780  m->reset_time = 1;
1781  m->in_memory = MAP_IN_MEMORY;
1782  delete_map(m);
1783 }
1784 
1788 static void write_world_map(void) {
1789 #define SIZE 50
1790  int x, y;
1791  FILE *out;
1792  int wx, wy;
1793  char file[500];
1794  char mapleft[10], maptop[10], mapright[10], mapbottom[10], mappath[5000];
1795  char name[100];
1796  gdImagePtr pic;
1797  gdImagePtr small;
1798  gdFontPtr font;
1799  int color;
1800 
1801  if (!world_map)
1802  return;
1803 
1804  printf("Generating world map in world.html...");
1805  fflush(stdout);
1806 
1807  pic = gdImageCreateTrueColor(SIZE*30, SIZE*30);
1808 
1809  strcpy(file, root);
1810  strcat(file, "/world.html");
1811 
1812  wx = 100;
1813  wy = 100;
1814 
1815  for (y = 0; y < 30; y++) {
1816  for (x = 0; x < 30; x++) {
1817  snprintf(name, sizeof(name), "world_%d_%d", wx, wy);
1818  snprintf(mapleft, sizeof(mapleft), "%d", SIZE*x);
1819  snprintf(maptop, sizeof(maptop), "%d", SIZE*y);
1820  snprintf(mapright, sizeof(mapright), "%d", SIZE*(x+1)-1);
1821  snprintf(mapbottom, sizeof(mapbottom), "%d", SIZE*(y+1)-1);
1822 
1823  snprintf(mappath, sizeof(mappath), "%s/world/%s.x1%s", root, name, output_extensions[output_format]);
1824 
1825  out = fopen(mappath, "rb");
1826  if (!out) {
1827  printf("\n warning: large pic not found for world_%d_%d", wx, wy);
1828  wx++;
1829  continue;
1830  }
1831  if (output_format == OF_PNG)
1832  small = gdImageCreateFromPng(out);
1833  else
1834  small = gdImageCreateFromJpeg(out);
1835  fclose(out);
1836  if (!small) {
1837  printf("\n warning: pic not found for world_%d_%d", wx, wy);
1838  wx++;
1839  continue;
1840  }
1841  gdImageCopyResized(pic, small, SIZE*x, SIZE*y, 0, 0, SIZE, SIZE, small->sx, small->sy);
1842  gdImageDestroy(small);
1843 
1844  wx++;
1845  }
1846  wy++;
1847  wx = 100;
1848  }
1849 
1850  snprintf(mappath, sizeof(mappath), "%s/world_raw%s", root, output_extensions[output_format]);
1851  out = fopen(mappath, "wb+");
1852  save_picture(out, pic);
1853  fclose(out);
1854 
1855  /* Write region names. */
1856  small = gdImageCreateTrueColor(SIZE*30, SIZE*30);
1857  font = gdFontGetGiant();
1858  color = gdImageColorAllocateAlpha(pic, 255, 0, 0, 20);
1859  for (size_t region = 0; region < region_allocated; region++) {
1860  if (!regions[region]->is_world || regions[region]->sum == 0)
1861  continue;
1862 
1863  x = regions[region]->sum_x*SIZE/regions[region]->sum+SIZE/2-strlen(regions[region]->reg->name)*font->w/2;
1864  y = regions[region]->sum_y*SIZE/regions[region]->sum+SIZE/2-font->h/2;
1865  gdImageString(small, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1866  gdImageString(pic, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1867 
1868  /* For exit/road map, size isn't the same. */
1869  x = regions[region]->sum_x*50/regions[region]->sum+50/2-strlen(regions[region]->reg->name)*font->w/2;
1870  y = regions[region]->sum_y*50/regions[region]->sum+50/2-font->h/2;
1871  gdImageString(infomap, font, x, y, (unsigned char *)regions[region]->reg->name, color);
1872  }
1873 
1874  snprintf(mappath, sizeof(mappath), "%s/world_regions%s", root, output_extensions[output_format]);
1875  out = fopen(mappath, "wb+");
1876  save_picture(out, small);
1877  fclose(out);
1878  gdImageDestroy(small);
1879 
1880  snprintf(mappath, sizeof(mappath), "%s/world%s", root, output_extensions[output_format]);
1881  out = fopen(mappath, "wb+");
1882  save_picture(out, pic);
1883  fclose(out);
1884  gdImageDestroy(pic);
1885 
1886  printf(" done.\n");
1887 #undef SIZE
1888 }
1889 
1891 static void fix_map_names(void) {
1892  for (size_t map = 0; map < maps_list.count; map++) {
1893  if (maps_list.maps[map]->name)
1894  continue;
1895  if (!maps_list.maps[map]->filename) {
1896  printf("map without path!\n");
1897  abort();
1898  }
1899  maps_list.maps[map]->name = strdup(maps_list.maps[map]->filename);
1900  }
1901 }
1902 
1909 static void fix_tiled_map(void) {
1910  size_t map, tile;
1911  char name[500];
1912  char *slash, *test;
1913  region *cfregion;
1914 
1915  for (map = 0; map < tiled_map_list.count; map++) {
1916  if (tiled_map_list.maps[map]->tiled_maps.count == 0) {
1917  printf("empty tiled map group!");
1918  abort();
1919  }
1920 
1921  snprintf(name, sizeof(name), "tiled_map_group_%zu", map);
1922  tiled_map_list.maps[map]->filename = strdup(name);
1923 
1924  cfregion = NULL;
1925  test = NULL;
1926 
1927  for (tile = 0; tile < tiled_map_list.maps[map]->tiled_maps.count; tile++) {
1929  /* map not processed, ignore it. */
1930  continue;
1931 
1932  if (!cfregion)
1934  else if (cfregion != tiled_map_list.maps[map]->tiled_maps.maps[tile]->cfregion) {
1935  printf("*** warning: tiled maps %s and %s not in same region (%s and %s).\n",
1938  cfregion = NULL;
1939  }
1940 
1942  /* map has a custom name, use it */
1943  if (!test)
1945  }
1946  }
1947 
1948  if (!test) {
1949  /* this can happen of course if only partial maps were processed, but well... */
1950  printf("*** warning: tiled map without any name. First map path %s\n", tiled_map_list.maps[map]->tiled_maps.maps[0]->path);
1951  test = name;
1952  }
1953 
1954  tiled_map_list.maps[map]->name = strdup(test);
1955  tiled_map_list.maps[map]->cfregion = cfregion;
1956 
1957  strncpy(name, tiled_map_list.maps[map]->tiled_maps.maps[0]->path, sizeof(name));
1958  slash = strrchr(name, '/');
1959  if (!slash)
1960  snprintf(name, sizeof(name), "/");
1961  else
1962  *(slash+1) = '\0';
1963  strncat(name, tiled_map_list.maps[map]->filename, sizeof(name) - strlen(name) - 1);
1964  tiled_map_list.maps[map]->path = strdup(name);
1965  }
1966 }
1967 
1978 static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from) {
1979  int map, max;
1980  struct_map_info *group;
1981 
1982  max = from->count-1;
1983  for (map = max; map >= 0; map--) {
1984  if (from->maps[map]->tiled_group) {
1985  group = from->maps[map]->tiled_group;
1986  if (map != max)
1987  from->maps[map] = from->maps[max];
1988  from->count--;
1989  max--;
1990  add_map(group, from);
1991  add_map(current->tiled_group ? current->tiled_group : current, is_from ? &group->exits_to : &group->exits_from);
1992  }
1993  }
1994 }
1995 
1997 static void fix_exits_to_tiled_maps(void) {
1998  int map, max;
1999  struct_map_info *group;
2000 
2001  for (map = 0; static_cast<size_t>(map) < maps_list.count; map++) {
2004  }
2005 
2006  for (size_t region = 0; region < region_count; region++) {
2008  for (map = max; map >= 0; map--) {
2011  if (map != max)
2014  max--;
2015  add_map(group, &regions[region]->maps_list);
2016  }
2017  }
2018  }
2019 }
2020 
2025 static void fix_tiled_map_monsters(void) {
2026  int map, max;
2027  struct_map_info *group;
2028 
2029  for (size_t race = 0; race < races.count; race++) {
2030  max = races.races[race]->origin.count-1;
2031  for (map = max; map >= 0; map--) {
2032  if (races.races[race]->origin.maps[map]->tiled_group) {
2033  group = races.races[race]->origin.maps[map]->tiled_group;
2034  if (map != max)
2035  races.races[race]->origin.maps[map] = races.races[race]->origin.maps[max];
2036  races.races[race]->origin.count--;
2037  max--;
2038  add_map(group, &races.races[race]->origin);
2039  }
2040  }
2041  }
2042 
2043  for (map = 0; static_cast<size_t>(map) < maps_list.count; map++) {
2044  if (maps_list.maps[map]->tiled_group) {
2045  for (size_t race = 0; race < maps_list.maps[map]->monsters.count; race++) {
2047  }
2048  }
2049  }
2050 }
2051 
2053  size_t test;
2054  char picpath[500];
2055  struct stat stats;
2056 
2057  for (size_t size = 0; size < num_sizes; size++) {
2058  generate_picture_path(map->path, size, picpath, sizeof(picpath));
2059  if (stat(picpath, &stats))
2060  return 1;
2061  }
2062 
2063  for (test = 0; test < map->tiled_maps.count; test++) {
2064  if (map->tiled_maps.maps[test]->pic_was_done)
2065  return 1;
2066  }
2067 
2068  return 0;
2069 }
2070 
2083  int xmin = 0, xmax = 0, ymin = 0, ymax = 0, count, last;
2084  size_t tiled;
2085  char picpath[500];
2086  gdImagePtr large, load;
2087  FILE *out;
2089 
2090  if (!generate_pics)
2091  return;
2092 
2093  printf(" Generating composite map for %s...", map->name);
2094  fflush(stdout);
2095 
2096  if (!tiled_map_need_pic(map)) {
2097  printf(" already uptodate.\n");
2098  return;
2099  }
2100 
2101  count = map->tiled_maps.count;
2102  if (count == 0) {
2103  printf("Tiled map without tiled maps?\n");
2104  abort();
2105  }
2106  map->tiled_maps.maps[0]->processed = 1;
2107  map->tiled_maps.maps[0]->tiled_x_from = 0;
2108  map->tiled_maps.maps[0]->tiled_y_from = 0;
2109 
2110  while (count > 0) {
2111  last = count;
2112 
2113  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2114  current = map->tiled_maps.maps[tiled];
2115  if (current->processed != 1)
2116  continue;
2117 
2118  count--;
2119 
2120  if ((current->tiles[0]) && (current->tiles[0]->processed == 0)) {
2121  current->tiles[0]->processed = 1;
2122  current->tiles[0]->tiled_x_from = current->tiled_x_from;
2123  current->tiles[0]->tiled_y_from = current->tiled_y_from-current->tiles[0]->height;
2124  }
2125  if ((current->tiles[1]) && (current->tiles[1]->processed == 0)) {
2126  current->tiles[1]->processed = 1;
2127  current->tiles[1]->tiled_x_from = current->tiled_x_from+current->width;
2128  current->tiles[1]->tiled_y_from = current->tiled_y_from;
2129  }
2130  if ((current->tiles[2]) && (current->tiles[2]->processed == 0)) {
2131  current->tiles[2]->processed = 1;
2132  current->tiles[2]->tiled_x_from = current->tiled_x_from;
2133  current->tiles[2]->tiled_y_from = current->tiled_y_from+current->height;
2134  }
2135  if ((current->tiles[3]) && (current->tiles[3]->processed == 0)) {
2136  current->tiles[3]->processed = 1;
2137  current->tiles[3]->tiled_x_from = current->tiled_x_from-current->tiles[3]->width;
2138  current->tiles[3]->tiled_y_from = current->tiled_y_from;
2139  }
2140  }
2141 
2142  if (last == count) {
2143  printf("do_tiled_map_picture: didn't process any map in %s (%d left)??\n", map->path, last);
2144  abort();
2145  }
2146  }
2147 
2148  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2149  if (map->tiled_maps.maps[tiled]->tiled_x_from < xmin)
2150  xmin = map->tiled_maps.maps[tiled]->tiled_x_from;
2151  if (map->tiled_maps.maps[tiled]->tiled_y_from < ymin)
2152  ymin = map->tiled_maps.maps[tiled]->tiled_y_from;
2153  if (map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width > xmax)
2154  xmax = map->tiled_maps.maps[tiled]->tiled_x_from+map->tiled_maps.maps[tiled]->width;
2155  if (map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height > ymax)
2156  ymax = map->tiled_maps.maps[tiled]->tiled_y_from+map->tiled_maps.maps[tiled]->height;
2157  }
2158 
2159  large = gdImageCreateTrueColor(size_large*(xmax-xmin), size_large*(ymax-ymin));
2160 
2161  for (tiled = 0; tiled < map->tiled_maps.count; tiled++) {
2162  generate_picture_path(map->tiled_maps.maps[tiled]->path, 0, picpath, sizeof(picpath));
2163 
2164  out = fopen(picpath, "rb");
2165  if (!out) {
2166  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);
2167  continue;
2168  }
2169  if (output_format == OF_PNG)
2170  load = gdImageCreateFromPng(out);
2171  else
2172  load = gdImageCreateFromJpeg(out);
2173  fclose(out);
2174  if (!load) {
2175  printf("\n do_tiled_map_picture: warning: pic not found for %s\n", map->tiled_maps.maps[tiled]->path);
2176  continue;
2177  }
2178  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);
2179  gdImageDestroy(load);
2180  }
2181 
2182  write_pictures_from_real_size(map->path, large, xmax-xmin, ymax-ymin);
2183 
2184  gdImageDestroy(large);
2185 
2186  printf(" done.\n");
2187 }
2188 
2191 
2193 
2196 // write_map_page(map);
2197 }
2198 
2200 static void write_tiled_maps(void) {
2201  printf("Writing tiled map information...\n");
2202 
2203  for (size_t map = 0; map < tiled_map_list.count; map++)
2205 
2206  printf(" done.\n");
2207 }
2208 
2209 static size_t system_quests_count = 0;
2210 static const quest_definition *system_quests[500];
2211 
2212 static void quest_callback(const quest_definition *quest, void *) {
2213  if (list_system_quests || !quest->quest_is_system) {
2215  }
2216 }
2217 
2218 static int sort_system_quest(const void *a, const void *b) {
2219  return strcmp((*((quest_definition **)a))->quest_code, (*((quest_definition **)b))->quest_code);
2220 }
2221 
2222 static int sort_system_quest_step(const void *a, const void *b) {
2223  return (*((quest_step_definition**)a))->step - (*((quest_step_definition**)b))->step;
2224 }
2225 
2226 static std::shared_ptr<inja::Environment> env;
2228 static std::set<std::string> rendered_templates;
2229 static std::map<struct_map_info *, std::string> reverse_maps;
2230 static std::map<region *, std::string> reverse_regions;
2237 static struct_map_info *find_map_by_key(const std::string &key) {
2238  auto found = std::find_if(reverse_maps.cbegin(), reverse_maps.cend(), [&key] (auto c) { return c.second == key; });
2239  if (found != reverse_maps.cend())
2240  return found->first;
2241  return nullptr;
2242 }
2243 
2249 static region *find_region_by_key(const std::string &key) {
2250  auto found = std::find_if(reverse_regions.cbegin(), reverse_regions.cend(), [&key] (auto c) { return c.second == key; });
2251  if (found != reverse_regions.cend())
2252  return found->first;
2253  return nullptr;
2254 }
2255 
2263  for (size_t m = 0; m < maps.count; m++) {
2264  auto map = reverse_maps.find(maps.maps[m]);
2265  if (map != reverse_maps.end()) {
2266  result.push_back(map->second);
2267  }
2268  }
2269  return result;
2270 }
2271 
2279  for (size_t n = 0; n < list.count; n++) {
2280  auto npc = list.npc[n];
2281  result.push_back({
2282  { "name", npc->name },
2283  { "x", npc->x },
2284  { "y", npc->y },
2285  { "message", npc->message },
2286  });
2287  }
2288  return result;
2289 }
2290 
2298  for (size_t n = 0; n < list.count; n++) {
2299  auto race = list.races[n];
2300  result.push_back({
2301  { "name", race->name },
2302  { "count", race->count },
2303  });
2304  }
2305  return result;
2306 }
2307 
2315  for (size_t m = 0; m < list.count; m++) {
2316  auto q = list.list[m];
2317  if (!q->map || !q->description)
2318  continue;
2319  ret.push_back({
2320  { "map", reverse_maps.find(q->map)->second },
2321  { "description", q->description },
2322  { "quest", q->quest->name },
2323  { "number", q->quest->number },
2324  });
2325  }
2326 
2327  return ret;
2328 }
2329 
2337  return {
2338  { "_key", key },
2339  { "name", map->name },
2340  { "path", map->path },
2341  { "region", map->cfregion ? reverse_regions[map->cfregion] : "reg_ffff" },
2342  { "level", map->level },
2343  { "reset_group", map->reset_group ? map->reset_group : "" },
2344  { "lore", map->lore && map->lore[0] ? map->lore : "" },
2345  { "exits_to", create_maps_array(map->exits_to) },
2346  { "exits_from", create_maps_array(map->exits_from) },
2347  { "npcs", create_npc_array(map->npcs) },
2348  { "readables", create_npc_array(map->readable) },
2349  { "monsters", create_race_array(map->monsters) },
2350  { "quests", create_map_in_quest_array(map->quests) },
2351  };
2352 }
2353 
2361  return {
2362  { "_key", key },
2363  { "number", quest->number },
2364  { "name", quest->name ? quest->name : "" },
2365  { "description", quest->description ? quest->description : "" },
2366  { "main_map", quest->mainmap ? reverse_maps.find(quest->mainmap)->second : "" },
2367  { "maps", create_map_in_quest_array(quest->maps) },
2368  };
2369 }
2370 
2376  char buf[50];
2377  for (size_t map = 0; map < list.count; map++) {
2378  auto cur = list.maps[map];
2379  if (cur->tiled_group)
2380  continue;
2381  snprintf(buf, sizeof(buf), "map_%04lu", map);
2382  reverse_maps.insert(std::make_pair(cur, buf));
2383  qsort(cur->exits_to.maps, cur->exits_to.count, sizeof(struct_map_info *), sort_map_info);
2384  qsort(cur->exits_from.maps, cur->exits_from.count, sizeof(struct_map_info *), sort_map_info);
2385  qsort(cur->monsters.races, cur->monsters.count, sizeof(struct_race *), sort_race);
2386  }
2387 }
2388 
2395  for (size_t map = 0; map < src.count; map++)
2396  add_map(src.maps[map], &dest);
2397 }
2398 
2404 static nlohmann::json create_region_array(const std::set<region *> &regions) {
2406  for (auto reg : regions) {
2407  auto r = reverse_regions.find(reg);
2408  if (r != reverse_regions.end()) {
2409  ret.push_back((*r).second);
2410  }
2411  }
2412  return ret;
2413 }
2414 
2421  char buf[10];
2422  struct_map_list all_maps;
2423  bool need_unknown_region = false;
2424 
2425  init_map_list(&all_maps);
2426  append_map_list(all_maps, maps_list);
2427  append_map_list(all_maps, tiled_map_list);
2428  qsort(all_maps.maps, all_maps.count, sizeof(struct_map_info *), sort_map_info);
2429 
2430  fill_reverse_maps(all_maps);
2431 
2432  for (size_t reg = 0; reg < region_count; reg++) {
2433  auto region = regions[reg];
2434  snprintf(buf, sizeof(buf), "reg_%04lu", reg);
2435  reverse_regions.insert(std::make_pair(region->reg, buf));
2436  }
2437 
2438  for (size_t reg = 0; reg < region_count; reg++) {
2439  auto region = regions[reg];
2440  qsort(region->maps_list.maps, region->maps_list.count, sizeof(struct_map_info *), sort_map_info);
2441 
2442  json["regions"].push_back({
2443  { "_key", reverse_regions[region->reg] },
2444  { "name", region->reg->name },
2445  { "longname", region->reg->longname },
2446  { "description", region->reg->msg ? region->reg->msg : "" },
2447  { "maps", create_maps_array(region->maps_list) },
2448  { "links", create_region_array(region_links[region->reg]) },
2449  });
2450  }
2451 
2452  for (auto map : reverse_maps) {
2453  auto cur = map.first;
2454  if (cur->tiled_group)
2455  continue;
2456  if (cur->cfregion == nullptr)
2457  need_unknown_region = true;
2458  json["maps"].push_back(create_map_object(cur, map.second));
2459  }
2460 
2461  if (need_unknown_region) {
2462  json["regions"].push_back({
2463  { "_key", "reg_ffff" },
2464  { "name", "unknown" },
2465  { "longname", "unknown" },
2466  { "description", "unknown" },
2467  { "maps", nlohmann::json::array() },
2468  { "links", nlohmann::json::array() },
2469  });
2470  }
2471 
2472  json["reset_groups"] = nlohmann::json::array();
2473  for (const auto &rg : reset_groups) {
2474  json["reset_groups"].push_back(rg);
2475  }
2476 
2477  json["items"] = nlohmann::json::array();
2478  for (size_t idx = 0; idx < equipment_count; idx++) {
2479  auto eq = special_equipment[idx];
2480  json["items"][idx] = {
2481  { "name", eq->name },
2482  { "power", eq->power },
2483  { "calc_power", eq->calc_power },
2484  { "diff", eq->diff },
2485  { "maps", create_maps_array(eq->origin) },
2486  };
2487  }
2488 
2489  json["monsters"] = nlohmann::json::array();
2490  for (size_t item = 0; item < races.count; item++) {
2491  auto race = races.races[item];
2492  qsort(race->origin.maps, race->origin.count, sizeof(struct_map_info *), sort_map_info);
2493  json["monsters"].push_back({
2494  { "name", race->name },
2495  { "count", race->count },
2496  { "maps", create_maps_array(race->origin) },
2497  });
2498  }
2499 
2500  json["system_quests"] = nlohmann::json::array();
2501  for (size_t q = 0; q < system_quests_count; q++) {
2502  auto quest = system_quests[q];
2503  nlohmann::json j({
2504  { "code", quest->quest_code },
2505  { "title", quest->quest_title },
2506  { "description", quest->quest_description ? quest->quest_description : "" },
2507  { "replayable", quest->quest_restart },
2508  { "steps", nlohmann::json::array() },
2509  { "maps", nlohmann::json::array() },
2510  });
2511 
2512  if (detail_quests) {
2513  quest_step_definition *steps[100];
2514  size_t steps_count = 0;
2515  quest_step_definition *step = quest->steps;
2516  while (step) {
2517  steps[steps_count++] = step;
2518  step = step->next;
2519  }
2520  qsort(steps, steps_count, sizeof(quest_step_definition *), sort_system_quest_step);
2521  for (size_t s = 0; s < steps_count; s++) {
2522  j["steps"].push_back({
2523  { "description", steps[s]->step_description ? steps[s]->step_description : "" },
2524  { "is_completion", steps[s]->is_completion_step ? true : false },
2525  });
2526  }
2527 
2528  auto qim = find_quest_info(quest->quest_code);
2529  if (qim) {
2530  for (size_t m = 0; m < qim->maps.count; m++) {
2531  auto map = reverse_maps.find(qim->maps.list[m]->map);
2532  assert(map != reverse_maps.end());
2533  j["maps"].push_back({
2534  { "description", qim->maps.list[m]->description },
2535  { "map", map->second },
2536  });
2537  }
2538  }
2539  }
2540  json["system_quests"].push_back(j);
2541  }
2542 
2543  json["slaying"] = nlohmann::json::array();
2544  for (size_t s = 0; s < slaying_count; s++) {
2545  auto info = slaying_info[s];
2546  json["slaying"].push_back({
2547  { "slaying", info->slaying },
2548  { "doors", create_maps_array(info->maps[S_DOOR]) },
2549  { "keys", create_maps_array(info->maps[S_KEY]) },
2550  { "containers", create_maps_array(info->maps[S_CONTAINER]) },
2551  { "detectors", create_maps_array(info->maps[S_DETECTOR]) },
2552  { "connections", create_maps_array(info->maps[S_CONNECT]) },
2553  });
2554  }
2555 
2556  json["quests"] = nlohmann::json::array();
2557  for (int quest = 0; quest < quests_count; quest++) {
2559  char buf[100];
2560  snprintf(buf, sizeof(buf), "quest_%d", quests[quest]->number);
2562  }
2563 }
2564 
2566 static std::vector<std::string> path_stack;
2567 
2568 void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string &param);
2569 
2575 static std::string path_from_current(const std::string &path) {
2576  auto p(path);
2577  char rel[1000];
2578  if (p[0] != '/')
2579  p = '/' + p;
2580  auto current(path_stack.back());
2581  if (current[0] != '/')
2582  current = '/' + current;
2583  relative_path(current.c_str(), p.c_str(), rel);
2584  return rel;
2585 }
2586 
2593  auto template_name = args.at(0)->get<std::string>();
2594  auto output_name(template_name);
2595  auto param = (args.size() > 1 ? args.at(1)->get<std::string>() : "");
2596 
2597  if (!param.empty()) {
2598  output_name = param + "_" + output_name;
2599  if (param.substr(0, 4) == "map_") {
2600  auto map = find_map_by_key(param);
2601  if (map != nullptr) {
2602  output_name = std::string(map->path + 1) + ".html";
2603  }
2604  }
2605  if (param.substr(0, 4) == "reg_") {
2606  auto reg = find_region_by_key(param);
2607  if (reg != nullptr) {
2608  output_name = std::string(reg->name) + ".html";
2609  }
2610  }
2611  }
2612 
2613  add_template_to_render(template_name, output_name, param);
2614  return path_from_current(output_name);
2615 }
2616 
2623  auto what = args.at(0)->get<std::string>();
2624  if (what.substr(0, 4) == "map_") {
2625  auto map = find_map_by_key(what);
2626  if (map == nullptr)
2627  return "";
2628  int size = 0;
2629  if (args.size() > 1) {
2630  size = args.at(1)->get<int>() - 1;
2631  }
2632  char picpath[1000];
2633  snprintf(picpath, sizeof(picpath), "%s.x%d%s", map->path, size + 1, output_extensions[output_format]);
2634  return path_from_current(picpath);
2635  }
2636  return "";
2637 }
2638 
2643 public:
2644  std::string template_name;
2645  std::string output_name;
2646  std::string param;
2647 };
2648 static std::vector<pageToRender> pages;
2656 void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string &param) {
2657  auto on(output_name);
2658  if (on[0] != '/')
2659  on = '/' + on;
2660  if (rendered_templates.find(on) != rendered_templates.end())
2661  return;
2662 
2663  rendered_templates.insert(on);
2664  pageToRender r;
2665  r.template_name = template_name;
2666  r.output_name = on;
2667  r.param = param;
2668  pages.push_back(r);
2669 }
2670 
2671 static std::vector<std::string> split(const std::string &field, const std::string &by) {
2672  std::vector<std::string> result;
2673  size_t start = 0, found;
2674  while ((found = field.find(by, start)) != std::string::npos) {
2675  result.push_back(field.substr(start, found - start));
2676  start = found + 1;
2677  }
2678  result.push_back(field.substr(start));
2679  return result;
2680 }
2681 
2682 static std::string templates_root("templates/");
2683 static std::vector<std::string> templates;
2688 static void init_renderer_env() {
2689  env = std::make_shared<inja::Environment>(templates_root, std::string(root) + "/");
2690  env->add_callback("link_to_page", generate_page_and_link);
2691  env->add_callback("substr", [] (inja::Arguments &args) {
2692  std::string str = args.at(0)->get<std::string>();
2693  size_t start = args.at(1)->get<size_t>();
2694  size_t len = args.size() > 2 ? args.at(2)->get<size_t>() : std::string::npos;
2695  return str.substr(start, len);
2696  });
2697  env->add_callback("picture", generate_picture_link);
2698  env->add_callback("pad", [] (inja::Arguments &args) {
2699  char buf[50];
2700  int val = args.at(0)->get<int>(), digits = args.at(1)->get<int>();
2701  snprintf(buf, sizeof(buf), "%0*d", digits, val);
2702  return std::string(buf);
2703  });
2704  env->add_callback("path_to_root", 0, [] (inja::Arguments &) {
2705  std::string r(root);
2706  char rel[1000];
2707  auto current(path_stack.back() + '/');
2708  if (current[0] != '/')
2709  current = '/' + current;
2710  relative_path(current.c_str(), r.c_str(), rel);
2711  return std::string(rel);
2712  });
2713  env->add_callback("get_by_field", 3, [] (inja::Arguments &args) {
2714  const auto &src = args.at(0);
2715  auto field = args.at(1)->get<std::string>();
2716  const auto &value = args.at(2);
2717  auto found = std::find_if(src->begin(), src->end(), [&field, &value] (auto item) {
2718  return item[field] == *value;
2719  });
2720  if (found == src->end()) {
2721  return nlohmann::json();
2722  }
2723  return *found;
2724  });
2725  env->add_callback("get_list_by_field", 3, [] (inja::Arguments &args) {
2727  const auto &src = args.at(0);
2728  auto field = args.at(1)->get<std::string>();
2729  const auto filter = args.at(2);
2730  if (filter->is_array()) {
2731  std::copy_if(src->begin(), src->end(), std::back_inserter(ret), [&] (auto &item) {
2732  auto val = item[field];
2733  return std::find_if(filter->begin(), filter->end(), [&] (auto li) { return val == li; }) != filter->end();
2734  });
2735  } else {
2736  std::copy_if(src->begin(), src->end(), std::back_inserter(ret), [&] (auto &item) {
2737  return filter->get<std::string>() == item[field];
2738  });
2739  }
2740  return ret;
2741  });
2742  env->add_callback("sort", [] (inja::Arguments &args) {
2743  const auto &src = args.at(0);
2744  std::vector<nlohmann::json> ret;
2745  for (auto i : *src) {
2746  ret.push_back(i);
2747  }
2748  auto fields = split(args.at(1)->get<std::string>(), ",");
2749  bool invert = args.size() > 2 ? args.at(2)->get<bool>() : false;
2750  bool ignore_case = args.size() > 3 ? args.at(3)->get<bool>() : true;
2751  std::sort(ret.begin(), ret.end(), [&] (auto left, auto right) {
2752  for (auto field : fields) {
2753  nlohmann::json l = left[field], r = right[field];
2754  if (ignore_case && l.is_string() && r.is_string()) {
2755  std::string ls(l.get<std::string>()), rs(r.get<std::string>());
2756  std::transform(ls.begin(), ls.end(), ls.begin(), [](unsigned char c){ return std::tolower(c); });
2757  std::transform(rs.begin(), rs.end(), rs.begin(), [](unsigned char c){ return std::tolower(c); });
2758  if (ls == rs) {
2759  continue;
2760  }
2761  return invert ? (rs < ls) : (ls < rs);
2762  }
2763  if (r == l) {
2764  continue;
2765  }
2766  return invert ? (r < l) : (l < r);
2767  }
2768  return false;
2769  });
2770  return ret;
2771  });
2772 
2773  env->set_trim_blocks(true);
2774  env->set_lstrip_blocks(true);
2775 }
2776 
2778 static const char *ignore_path[] = {
2779  "/Info",
2780  "/editor",
2781  "/python",
2782  "/styles",
2783  "/templates",
2784  "/test",
2785  "/unlinked",
2786  NULL };
2787 
2789 static const char *ignore_name[] = {
2790  ".",
2791  "..",
2792  ".svn",
2793  "README",
2794  NULL };
2795 
2802 static void find_maps(const char *from) {
2803  struct dirent *file;
2804  struct stat statbuf;
2805  int status, ignore;
2806  char path[1024], full[1024];
2807  DIR *dir;
2808 
2809  for (ignore = 0; ignore_path[ignore] != NULL; ignore++) {
2810  if (strcmp(from, ignore_path[ignore]) == 0)
2811  return;
2812  }
2813 
2814  snprintf(path, sizeof(path), "%s/%s%s", settings.datadir, settings.mapdir, from);
2815  dir = opendir(path);
2816 
2817  if (dir) {
2818  for (file = readdir(dir); file; file = readdir(dir)) {
2819 
2820  for (ignore = 0; ignore_name[ignore] != NULL; ignore++) {
2821  if (strcmp(file->d_name, ignore_name[ignore]) == 0)
2822  break;
2823  }
2824  if (ignore_name[ignore] != NULL)
2825  continue;
2826 
2827  snprintf(full, sizeof(full), "%s/%s", path, file->d_name);
2828 
2829  status = stat(full, &statbuf);
2830  if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
2831  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
2832  find_maps(full);
2833  continue;
2834  }
2836  found_maps_allocated += 50;
2837  found_maps = (char **)realloc(found_maps, found_maps_allocated*sizeof(char *));
2838  }
2839  snprintf(full, sizeof(full), "%s/%s", from, file->d_name);
2840  found_maps[found_maps_count++] = strdup(full);
2841  }
2842  closedir(dir);
2843  }
2844 }
2845 
2847 static void dump_unused_maps(void) {
2848  FILE *dump;
2849  char path[1024];
2850  int index, found = 0;
2851 
2852  snprintf(path, sizeof(path), "%s/%s", root, "maps.unused");
2853  dump = fopen(path, "w+");
2854  if (dump == NULL) {
2855  printf("Unable to open file maps.unused!\n");
2856  return;
2857  }
2858  for (index = 0; index < found_maps_count; index++) {
2859  if (found_maps[index] != NULL) {
2860  fprintf(dump, "%s\n", found_maps[index]);
2861  free(found_maps[index]);
2862  found++;
2863  }
2864  }
2865  fclose(dump);
2866  printf("%d unused maps.\n", found);
2867 }
2868 
2870 static void write_world_info(void) {
2871  FILE *file;
2872  char path[MAX_BUF];
2873  int x, y;
2874  gdImagePtr elevationmap;
2875 
2876  if (!world_exit_info)
2877  return;
2878 
2879  printf("Saving exit/blocking/road information...");
2880  snprintf(path, sizeof(path), "%s/%s%s", root, "world_info", output_extensions[output_format]);
2881  file = fopen(path, "wb+");
2883  fclose(file);
2884  printf("done.\n");
2885  gdImageDestroy(infomap);
2886  infomap = NULL;
2887 
2888  if (elevation_min == 0 || elevation_max == 0) {
2889  puts("Error: Could not save elevation world map due to not finding any minimum or maximum elevation.");
2890  return;
2891  }
2892 
2893  elevationmap = gdImageCreateTrueColor(30*50, 30*50);;
2894 
2895  for (x = 0; x < 30*50; x++) {
2896  for (y = 0; y < 30*50; y++) {
2897  gdImageSetPixel(elevationmap, x, y, get_elevation_color(elevation_info[x][y], elevationmap));
2898  }
2899  }
2900 
2901  printf("Saving elevation world map...");
2902  snprintf(path, sizeof(path), "%s/%s%s", root, "world_elevation", output_extensions[output_format]);
2903  file = fopen(path, "wb+");
2904  save_picture(file, elevationmap);
2905  fclose(file);
2906  printf("done.\n");
2907  gdImageDestroy(elevationmap);
2908  elevationmap = NULL;
2909 }
2910 
2921 static int sort_slaying(const void *left, const void *right) {
2924 
2925  return strcasecmp(l->slaying, r->slaying);
2926 }
2927 
2934 static void do_help(const char *program) {
2935  printf("Crossfire Mapper will generate pictures of maps, and create indexes for all maps and regions.\n\n");
2936  printf("Syntax: %s\n\n", program);
2937  printf("Optional arguments:\n");
2938  printf(" -nopics don't generate pictures.\n");
2939  printf(" -root=<path> destination path. Default 'html'.\n");
2940  printf(" -limit=<number> stop processing after this number of maps, -1 to do all maps (default).\n");
2941  printf(" -showmaps outputs the name of maps as they are processed.\n");
2942  printf(" -jpg[=quality] generate jpg pictures, instead of default png. Quality should be 0-95, -1 for automatic.\n");
2943  printf(" -forcepics force to regenerate pics, even if pics's date is after map's.\n");
2944  printf(" -addmap=<map> adds a map to process. Path is relative to map's directory root.\n");
2945  printf(" -rawmaps generates maps pics without items on random (shop, treasure) tiles.\n");
2946  printf(" -warnnopath inform when an exit has no path set.\n");
2947  printf(" -listunusedmaps finds all unused maps in the maps directory.\n");
2948  printf(" -noworldmap don't write the world map in world.png.\n");
2949  printf(" -noregionslink don't generate regions relation file.\n");
2950  printf(" -regionslink generate regions relation file.\n");
2951  printf(" -noexitmap don't generate map of exits.\n");
2952  printf(" -exitmap generate map of exits.\n");
2953  printf(" -tileset=<number> use specified tileset to generate the pictures. Default 0 (standard).\n");
2954  printf(" -details-quests list all quests steps. Default no.\n");
2955  printf(" -list-system-quests include 'system' quests in quest list. Default no.\n");
2956  printf(" -templates-dir=[dir] set the directory to get templates from. Default 'templates/'.\n");
2957  printf(" -add-template=[file] add a template to process. May be specified multiple times. If empty, 'index.html' is used.\n");
2958  printf(" -list-template-to-process display the name of the template about to be rendered. Useful for debugging.");
2959  printf("\n\n");
2960  exit(0);
2961 }
2962 
2971 static void do_parameters(int argc, char **argv) {
2972  int arg = 1;
2973  char path[500];
2974 
2975  root[0] = '\0';
2976 
2977  while (arg < argc) {
2978  if (strcmp(argv[arg], "-nopics") == 0)
2979  generate_pics = 0;
2980  else if (strncmp(argv[arg], "-root=", 6) == 0)
2981  strncpy(root, argv[arg]+6, 500);
2982  else if (strncmp(argv[arg], "-limit=", 7) == 0)
2983  map_limit = atoi(argv[arg]+7);
2984  else if (strcmp(argv[arg], "-showmaps") == 0)
2985  show_maps = 1;
2986  else if (strcmp(argv[arg], "-jpg") == 0) {
2988  if (argv[arg][4] == '=') {
2989  jpeg_quality = atoi(argv[arg]+5);
2990  if (jpeg_quality < 0)
2991  jpeg_quality = -1;
2992  }
2993  }
2994  else if (strcmp(argv[arg], "-forcepics") == 0)
2995  force_pics = 1;
2996  else if (strncmp(argv[arg], "-addmap=", 8) == 0) {
2997  if (*(argv[arg]+8) == '/')
2998  strncpy(path, argv[arg]+8, 500);
2999  else
3000  snprintf(path, 500, "/%s", argv[arg]+8);
3002  }
3003  else if (strcmp(argv[arg], "-rawmaps") == 0)
3004  rawmaps = 1;
3005  else if (strcmp(argv[arg], "-warnnopath") == 0)
3006  warn_no_path = 1;
3007  else if (strcmp(argv[arg], "-listunusedmaps") == 0)
3008  list_unused_maps = 1;
3009  else if (strcmp(argv[arg], "-noworldmap") == 0)
3010  world_map = 0;
3011  else if (strcmp(argv[arg], "-noregionslink") == 0)
3012  do_regions_link = false;
3013  else if (strcmp(argv[arg], "-regionslink") == 0)
3014  do_regions_link = true;
3015  else if (strcmp(argv[arg], "-noexitmap") == 0)
3016  world_exit_info = 0;
3017  else if (strcmp(argv[arg], "-exitmap") == 0)
3018  world_exit_info = 1;
3019  else if (strncmp(argv[arg], "-tileset=", 9) == 0) {
3020  tileset = atoi(argv[arg]+9);
3021  /* check of validity is done in main() as we need to actually have the sets loaded. */
3022  } else if (strcmp(argv[arg], "-detail-quests") == 0) {
3023  detail_quests = 1;
3024  } else if (strcmp(argv[arg], "-list-system-quests") == 0) {
3025  list_system_quests = 1;
3026  } else if (strncmp(argv[arg], "-templates-dir=", 15) == 0) {
3027  templates_root = argv[arg] + 15;
3028  } else if (strncmp(argv[arg], "-add-template=", 14) == 0) {
3029  templates.push_back(argv[arg] + 14);
3030  } else if (strcmp(argv[arg], "-list-template-to-process") == 0) {
3032  } else
3033  do_help(argv[0]);
3034  arg++;
3035  }
3036  if (!strlen(root))
3037  strcpy(root, "html");
3038  if (root[strlen(root)-1] == '/')
3039  root[strlen(root)-1] = '\0';
3040  if (map_limit < -1)
3041  map_limit = -1;
3042 
3043  if (templates_root.empty()) {
3044  templates_root = "templates/";
3045  } else if (templates_root[templates_root.length() - 1] != '/') {
3046  templates_root.append("/");
3047  }
3048 }
3049 
3053 static void create_destination(void) {
3054  char dummy[502];
3055 
3056  strcpy(dummy, root);
3057  strcat(dummy, "/a");
3058  make_path_to_file(dummy);
3059 }
3060 
3069 static const char *yesno(int value) {
3070  return (value ? "yes" : "no");
3071 }
3072 
3074 static inja::Template get_template(const std::string &filename) {
3075  auto find = templateCache.find(filename);
3076  if (find != templateCache.end()) {
3077  return find->second;
3078  }
3079  inja::Template parsed = env->parse_template(filename);
3080  templateCache[filename] = parsed;
3081  return parsed;
3082 }
3083 
3084 int main(int argc, char **argv) {
3085  size_t current_map = 0, i;
3086  char max[50];
3087  region *dummy;
3088 
3092  pics_allocated = 0;
3093 
3094  do_parameters(argc, argv);
3095 
3096  printf("Initializing Crossfire data...\n");
3097 
3099 
3100  init_globals();
3101  init_library();
3102  init_readable();
3103 
3104  init_gods();
3105 
3106  /* Add a dummy region so unlinked maps can be identified. */
3107  dummy = get_region_struct();
3108  dummy->fallback = 1;
3109  dummy->name = strdup_local("unlinked");
3110  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3111  dummy->longname = strdup_local("This dummy region contains all maps without a region set.");
3112  dummy->next = first_region;
3113  first_region = dummy;
3114 
3115  printf("\n\n done.\n\n");
3116 
3117  if (!is_valid_faceset(tileset)) {
3118  printf("Erreor: invalid tileset %d!\n", tileset);
3119  exit(1);
3120  }
3121 
3122  if (templates.empty()) {
3123  templates.push_back("index.html");
3124  }
3125 
3127  gdfaces = (gdImagePtr *)calloc(get_faces_count(), sizeof(gdImagePtr));
3128 
3129  if (map_limit != -1)
3130  snprintf(max, sizeof(max), "%d", map_limit);
3131  else
3132  strcpy(max, "(none)");
3133  printf("Crossfire map browser generator\n");
3134  printf("-------------------------------\n\n");
3135  printf("Parameters:\n");
3136  printf(" path to write files: %s\n", root);
3137  printf(" maximum number of maps to process: %s\n", max);
3138  printf(" will generate map picture: %s\n", yesno(generate_pics));
3139  printf(" will always generate map picture: %s\n", yesno(force_pics));
3140  printf(" picture output format: %s\n", output_extensions[output_format]);
3141  if (output_format == OF_JPG)
3142  printf(" JPEG quality: %d\n", jpeg_quality);
3143  printf(" show map being processed: %s\n", yesno(show_maps));
3144  printf(" generate raw maps: %s\n", yesno(rawmaps));
3145  printf(" warn of exit without path: %s\n", yesno(warn_no_path));
3146  printf(" list unused maps: %s\n", yesno(list_unused_maps));
3147  printf(" generate world map: %s\n", yesno(world_map));
3148  printf(" generate exit map: %s\n", yesno(world_exit_info));
3149  printf(" generate regions link file: %s\n", yesno(do_regions_link));
3150  printf(" tileset: %s\n", find_faceset(tileset)->fullname);
3151  printf(" detail quest steps: %s\n", yesno(detail_quests));
3152  printf(" list system quests: %s\n", yesno(list_system_quests));
3153  printf(" templates directory: %s\n", templates_root.c_str());
3154  printf(" templates to process: ");
3155  const char *sep = "";
3156  for (auto f : templates) {
3157  printf("%s%s", sep, f.c_str());
3158  sep = ", ";
3159  }
3160  printf("\n");
3161  printf(" display template to process: %s\n", yesno(display_rendered_template));
3162  printf("\n");
3163 
3164  if (list_unused_maps) {
3165  printf("listing all maps...");
3166  find_maps("");
3167  printf("done, %d maps found.\n", found_maps_count);
3168  qsort(found_maps, found_maps_count, sizeof(char *), sortbyname);
3169  }
3170 
3171  /* exit/blocking information. */
3172  infomap = gdImageCreateTrueColor(30*50, 30*50);
3173  color_unlinked_exit = gdImageColorResolve(infomap, 255, 0, 0);
3174  color_linked_exit = gdImageColorResolve(infomap, 255, 255, 255);
3175  color_road = gdImageColorResolve(infomap, 0, 255, 0);
3176  color_blocking = gdImageColorResolve(infomap, 0, 0, 255);
3177  color_slowing = gdImageColorResolve(infomap, 0, 0, 127);
3178  elevation_info = (int **)calloc(50*30, sizeof(int *));
3179  for (i = 0; i < 50*30; i++)
3180  elevation_info[i] = (int *)calloc(50*30, sizeof(int));
3181  elevation_min = 0;
3182  elevation_max = 0;
3183 
3184  printf("browsing maps...\n");
3185 
3187 
3188  while (current_map < maps_list.count) {
3190  if (current_map%100 == 0) {
3191  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);
3192  }
3193  if ((map_limit != -1) && (current_map == static_cast<size_t>(map_limit))) {
3194  printf(" --- map limit reached, stopping ---\n");
3195  break;
3196  }
3197  }
3198 
3199  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);
3200 
3201  if (list_unused_maps)
3202  dump_unused_maps();
3203 
3205  fix_map_names();
3206  fix_tiled_map();
3208  write_tiled_maps();
3209 
3210  write_world_map();
3211  write_world_info();
3212 
3214  qsort(regions, region_count, sizeof(struct_region_info *), sort_region);
3217  qsort(races.races, races.count, sizeof(struct_race *), sort_race);
3218  qsort(quests, quests_count, sizeof(struct_quest *), sort_struct_quest);
3219 
3222 
3224 
3226 
3227  for (auto file : templates) {
3228  if (!file.empty()) {
3230  }
3231  }
3232 
3233  const auto fullStart = time(nullptr);
3234  printf("rendering pages...");
3236  printf("\n");
3237  fflush(stdout);
3238 
3239  while (!pages.empty()) {
3240  auto p = pages.back();
3241  pages.pop_back();
3242  if (p.param.empty())
3243  all_data.erase("param");
3244  else
3245  all_data["param"] = p.param;
3246  const auto start = time(nullptr);
3248  printf(" rendering page %s (%s)... ", p.template_name.c_str(), p.param.c_str());
3249  fflush(stdout);
3250  }
3251  path_stack.push_back(p.output_name);
3252  inja::Template temp = get_template(p.template_name);
3253  env->write(temp, all_data, p.output_name);
3254  path_stack.pop_back();
3255  const auto elapsed = time(nullptr) - start;
3257  printf("took %ld seconds\n", elapsed);
3258  }
3259  }
3260 
3261  const auto elapsed = time(nullptr) - fullStart;
3262  printf(" done, took %ld seconds\n", elapsed);
3263 
3264  return 0;
3265 }
3266 
3268  int x, y;
3269 
3270  if (m == NULL)
3271  return;
3272 
3273  for (x = 0; x < MAP_WIDTH(m); x++)
3274  for (y = 0; y < MAP_HEIGHT(m); y++)
3275  FOR_MAP_PREPARE(m, x, y, tmp) {
3276  if (tmp->inv) {
3277  FOR_INV_PREPARE(tmp, invtmp) {
3278  if (QUERY_FLAG(invtmp, FLAG_AUTO_APPLY))
3279  apply_auto(invtmp);
3280  else if (invtmp->type == TREASURE && HAS_RANDOM_ITEMS(invtmp)) {
3281  while ((invtmp->stats.hp--) > 0)
3282  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3283  invtmp->randomitems = NULL;
3284  } else if (invtmp
3285  && invtmp->arch
3286  && invtmp->type != TREASURE
3287  && invtmp->type != SPELL
3288  && invtmp->type != CLASS
3289  && HAS_RANDOM_ITEMS(invtmp)) {
3290  create_treasure(invtmp->randomitems, invtmp, 0, m->difficulty, 0);
3291  /* Need to clear this so that we never try to create
3292  * treasure again for this object
3293  */
3294  invtmp->randomitems = NULL;
3295  }
3296  } FOR_INV_FINISH();
3297  /* This is really temporary - the code at the bottom will
3298  * also set randomitems to null. The problem is there are bunches
3299  * of maps/players already out there with items that have spells
3300  * which haven't had the randomitems set to null yet.
3301  * MSW 2004-05-13
3302  *
3303  * And if it's a spellbook, it's better to set randomitems to NULL too,
3304  * else you get two spells in the book ^_-
3305  * Ryo 2004-08-16
3306  */
3307  if (tmp->type == WAND
3308  || tmp->type == ROD
3309  || tmp->type == SCROLL
3310  || tmp->type == FIREWALL
3311  || tmp->type == POTION
3312  || tmp->type == ALTAR
3313  || tmp->type == SPELLBOOK)
3314  tmp->randomitems = NULL;
3315  }
3316 
3318  apply_auto(tmp);
3319  else if ((tmp->type == TREASURE || (tmp->type == CONTAINER)) && HAS_RANDOM_ITEMS(tmp)) {
3320  while ((tmp->stats.hp--) > 0)
3321  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
3322  tmp->randomitems = NULL;
3323  } else if (tmp->type == TIMED_GATE) {
3324  object *head = HEAD(tmp);
3325 
3326  if (QUERY_FLAG(head, FLAG_IS_LINKED)) {
3327  tmp->speed = 0;
3329  }
3330  /* This function can be called everytime a map is loaded, even when
3331  * swapping back in. As such, we don't want to create the treasure
3332  * over and ove again, so after we generate the treasure, blank out
3333  * randomitems so if it is swapped in again, it won't make anything.
3334  * This is a problem for the above objects, because they have counters
3335  * which say how many times to make the treasure.
3336  */
3337  } else if (tmp
3338  && tmp->arch
3339  && tmp->type != PLAYER
3340  && tmp->type != TREASURE
3341  && tmp->type != SPELL
3342  && tmp->type != PLAYER_CHANGER
3343  && tmp->type != CLASS
3344  && HAS_RANDOM_ITEMS(tmp)) {
3345  create_treasure(tmp->randomitems, tmp, 0, m->difficulty, 0);
3346  tmp->randomitems = NULL;
3347  }
3348  } FOR_MAP_FINISH();
3349 
3350  for (x = 0; x < MAP_WIDTH(m); x++)
3351  for (y = 0; y < MAP_HEIGHT(m); y++)
3352  FOR_MAP_PREPARE(m, x, y, tmp) {
3353  if (tmp->above
3354  && (tmp->type == TRIGGER_BUTTON || tmp->type == TRIGGER_PEDESTAL))
3355  check_trigger(tmp, tmp->above);
3356  } FOR_MAP_FINISH();
3357 }
3358 
3359 #ifndef DOXYGEN_SHOULD_SKIP_THIS
3360 
3365 void draw_ext_info(int, int, const object *, uint8_t, uint8_t, const char *txt) {
3366  fprintf(logfile, "%s\n", txt);
3367 }
3368 
3369 void draw_ext_info_format(int, int, const object *, uint8_t, uint8_t, const char *format, ...) {
3370  va_list ap;
3371 
3372  va_start(ap, format);
3373  vfprintf(logfile, format, ap);
3374  va_end(ap);
3375 }
3376 
3377 void ext_info_map(int, const mapstruct *, uint8_t, uint8_t, const char *str1) {
3378  fprintf(logfile, "ext_info_map: %s\n", str1);
3379 }
3380 
3381 void move_firewall(object *) {
3382 }
3383 
3384 void emergency_save(int) {
3385 }
3386 
3387 void clean_tmp_files(void) {
3388 }
3389 
3390 void esrv_send_item(object *, object *) {
3391 }
3392 
3393 void dragon_ability_gain(object *, int, int) {
3394 }
3395 
3397 }
3398 
3399 object *find_skill_by_number(object *, int) {
3400  return NULL;
3401 }
3402 
3403 void esrv_del_item(player *, object *) {
3404 }
3405 
3406 void esrv_update_item(int, object *, object *) {
3407 }
3408 
3410 }
3411 
3412 void rod_adjust(object *) {
3413 }
3414 
3415 /*
3416  * This a modified version of apply_auto: BOOK are not generated, so they don't pollute
3417  * the readable list.
3418  */
3419 int apply_auto(object *op) {
3420  object *tmp = NULL;
3421  int i;
3422 
3423  switch (op->type) {
3424  case SHOP_FLOOR:
3425  if (!HAS_RANDOM_ITEMS(op))
3426  return 0;
3427  do {
3428  i = 10; /* let's give it 10 tries */
3429  while ((tmp = generate_treasure(op->randomitems, op->stats.exp ? (int)op->stats.exp : MAX(op->map->difficulty, 5))) == NULL && --i)
3430  ;
3431  if (tmp == NULL)
3432  return 0;
3433  if (QUERY_FLAG(tmp, FLAG_CURSED) || QUERY_FLAG(tmp, FLAG_DAMNED) || tmp->type == BOOK) {
3435  tmp = NULL;
3436  }
3437  } while (!tmp);
3439  object_insert_in_map_at(tmp, op->map, NULL, 0, op->x, op->y);
3441  tmp = identify(tmp);
3442  break;
3443 
3444  case TREASURE:
3446  return 0;
3447 
3448  while ((op->stats.hp--) > 0)
3449  create_treasure(op->randomitems, op, 0, op->stats.exp ? (int)op->stats.exp : op->map == NULL ? 14 : op->map->difficulty, 0);
3450 
3451  /* If we generated an object and put it in this object inventory,
3452  * move it to the parent object as the current object is about
3453  * to disappear. An example of this item is the random_ *stuff
3454  * that is put inside other objects.
3455  */
3456  FOR_INV_PREPARE(op, tmp) {
3457  object_remove(tmp);
3458  if (op->env && tmp->type != BOOK)
3459  object_insert_in_ob(tmp, op->env);
3460  else
3462  }
3463  FOR_INV_FINISH();
3464  object_remove(op);
3466  break;
3467  }
3468  return tmp ? 1 : 0;
3469 }
3470 
3472 }
3473 
3475  return NULL;
3476 }
3477 
3479  return NULL;
3480 }
3481 
3483  return NULL;
3484 }
3485 
3487 }
3488 
3490 }
3491 
3492 void command_help(object *, const char *) {
3493 }
3494 
3495 void account_logout(const char *) {
3496 }
3497 
3498 #endif /* dummy DOXYGEN_SHOULD_SKIP_THIS */
get_race
static struct_race * get_race(const char *name)
Definition: mapper.cpp:619
struct_map_info::tiles
struct struct_map_info * tiles[4]
Definition: mapper.cpp:236
CLASS
@ CLASS
Definition: object.h:141
struct_region_info::sum_x
int sum_x
Definition: mapper.cpp:365
give.next
def next
Definition: give.py:44
move_firewall
void move_firewall(object *)
Definition: mapper.cpp:3381
init_globals
void init_globals(void)
Definition: init.cpp:397
write_tiled_map_page
static void write_tiled_map_page(struct_map_info *map)
Definition: mapper.cpp:2190
fix_tiled_map_monsters
static void fix_tiled_map_monsters(void)
Definition: mapper.cpp:2025
do_auto_apply
void do_auto_apply(mapstruct *m)
Definition: mapper.cpp:3267
add_map
static void add_map(struct_map_info *info, struct_map_list *list)
Definition: mapper.cpp:1214
HAS_RANDOM_ITEMS
#define HAS_RANDOM_ITEMS(op)
Definition: define.h:184
PLAYER
@ PLAYER
Definition: object.h:110
artifact
struct artifactstruct artifact
Settings::mapdir
const char * mapdir
Definition: global.h:251
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:534
settings
struct Settings settings
Definition: init.cpp:139
ignore_name
static const char * ignore_name[]
Definition: mapper.cpp:2789
struct_npc_info
struct struct_npc_info struct_npc_info
struct_equipment::diff
char * diff
Definition: mapper.cpp:250
banquet.l
l
Definition: banquet.py:164
get_quest_info
static struct_quest * get_quest_info(const char *name)
Definition: mapper.cpp:964
find_region_by_key
static region * find_region_by_key(const std::string &key)
Definition: mapper.cpp:2249
FOR_MAP_FINISH
#define FOR_MAP_FINISH()
Definition: define.h:730
found_maps_allocated
static int found_maps_allocated
Definition: mapper.cpp:376
process_map_lore
static void process_map_lore(struct_map_info *map)
Definition: mapper.cpp:1078
find_artifact
const artifact * find_artifact(const object *op, const char *name)
Definition: artifact.cpp:590
first_region
region * first_region
Definition: init.cpp:108
llevError
@ llevError
Definition: logger.h:11
get_region_struct
region * get_region_struct(void)
Definition: region.cpp:298
maps
static std::unordered_map< std::string, mapzone * > maps
Definition: citylife.cpp:92
compare_map_info
static int compare_map_info(const struct_map_info *left, const struct_map_info *right)
Definition: mapper.cpp:857
path_from_current
static std::string path_from_current(const std::string &path)
Definition: mapper.cpp:2575
MOVE_ALL
#define MOVE_ALL
Definition: define.h:398
WAND
@ WAND
Definition: object.h:223
quest_for_each
void quest_for_each(quest_op op, void *user)
Definition: assets.cpp:546
LOG
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.cpp:51
struct_region_info::is_world
int is_world
Definition: mapper.cpp:366
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:2622
struct_map_info::tiled_group
struct struct_map_info * tiled_group
Definition: mapper.cpp:233
struct_map_info::filename
char * filename
Definition: mapper.cpp:217
num_sizes
static const int num_sizes
Definition: mapper.cpp:321
add_slaying
static void add_slaying(struct_map_info *map, object *item)
Definition: mapper.cpp:1480
strdup_local
#define strdup_local
Definition: compat.h:29
diamondslots.x
x
Definition: diamondslots.py:15
ready_map_name
mapstruct * ready_map_name(const char *name, int flags)
Definition: map.cpp:1785
write_tiled_maps
static void write_tiled_maps(void)
Definition: mapper.cpp:2200
first_map_path
char first_map_path[MAX_BUF]
Definition: init.cpp:120
QUERY_FLAG
#define QUERY_FLAG(xyz, p)
Definition: define.h:226
struct_quest::maps
struct_map_in_quest_list maps
Definition: mapper.cpp:919
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:2360
create_map_info
static struct_map_info * create_map_info(void)
Definition: mapper.cpp:1235
struct_race::count
int count
Definition: mapper.cpp:264
TRIGGER_PEDESTAL
@ TRIGGER_PEDESTAL
Definition: object.h:137
nlohmann::json
basic_json<> json
default JSON class
Definition: json.hpp:3404
struct_map_in_quest::map
struct_map_info * map
Definition: mapper.cpp:910
esrv_del_item
void esrv_del_item(player *, object *)
Definition: mapper.cpp:3403
pageToRender::param
std::string param
Definition: mapper.cpp:2646
S_CONNECT
#define S_CONNECT
Definition: mapper.cpp:400
write_pictures_from_real_size
static void write_pictures_from_real_size(const char *path, gdImagePtr real, int width, int height)
Definition: mapper.cpp:1520
region_links
static std::map< region *, std::set< region * > > region_links
Definition: mapper.cpp:393
get_face_fallback
int get_face_fallback(int faceset, uint16_t imageno)
Definition: image.cpp:133
struct_npc_list
struct struct_npc_list struct_npc_list
Settings::datadir
const char * datadir
Definition: global.h:248
c
static event_registration c
Definition: citylife.cpp:425
filter
Definition: filter.py:1
disinfect.a
a
Definition: disinfect.py:13
output_format
static enum output_format_type output_format
Definition: mapper.cpp:350
stringbuffer_new
StringBuffer * stringbuffer_new(void)
Definition: stringbuffer.cpp:57
quests_count
static int quests_count
Definition: mapper.cpp:924
SHOP_FLOOR
@ SHOP_FLOOR
Definition: object.h:186
Ice.g
def g
Definition: Ice.py:63
pl
Definition: player.h:105
get_map_info
static struct_map_info * get_map_info(const char *path)
Definition: mapper.cpp:1307
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:1997
reverse_maps
static std::map< struct_map_info *, std::string > reverse_maps
Definition: mapper.cpp:2229
dump
static int dump(const std::set< std::string > &items, const char *name)
Definition: AssetsManager.cpp:46
guildoracle.list
list
Definition: guildoracle.py:87
struct_map_in_quest
Definition: mapper.cpp:907
slaying_allocated
static size_t slaying_allocated
Definition: mapper.cpp:411
give_artifact_abilities
void give_artifact_abilities(object *op, const object *artifact)
Definition: artifact.cpp:238
get_equipment
static struct_equipment * get_equipment(void)
Definition: mapper.cpp:445
is_special_equipment
static int is_special_equipment(object *item)
Definition: mapper.cpp:426
TIMED_GATE
@ TIMED_GATE
Definition: object.h:131
region_allocated
static size_t region_allocated
Definition: mapper.cpp:371
struct_map_list
Definition: mapper.cpp:207
generate_page_and_link
static nlohmann::json generate_page_and_link(inja::Arguments &args)
Definition: mapper.cpp:2592
struct_equipment::origin
struct_map_list origin
Definition: mapper.cpp:251
find_faceset
face_sets * find_faceset(int id)
Definition: assets.cpp:332
commongive.inv
inv
Definition: commongive.py:28
root
static char root[500]
Definition: mapper.cpp:312
create_map_in_quest_array
static nlohmann::json create_map_in_quest_array(struct_map_in_quest_list &list)
Definition: mapper.cpp:2313
yesno
static const char * yesno(int value)
Definition: mapper.cpp:3069
AMULET
@ AMULET
Definition: object.h:142
CHECK_INV
@ CHECK_INV
Definition: object.h:172
mapdef::in_memory
uint32_t in_memory
Definition: map.h:338
struct_map_info::name
char * name
Definition: mapper.cpp:216
fix_map_names
static void fix_map_names(void)
Definition: mapper.cpp:1891
struct_slaying_info::maps
struct_map_list maps[S_MAX]
Definition: mapper.cpp:406
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:240
TREASURE
@ TREASURE
Definition: object.h:113
color_unlinked_exit
static int color_unlinked_exit
Definition: mapper.cpp:380
struct_region_info::sum_y
int sum_y
Definition: mapper.cpp:365
pages
static std::vector< pageToRender > pages
Definition: mapper.cpp:2648
list_unused_maps
static int list_unused_maps
Definition: mapper.cpp:373
struct_map_info
Definition: mapper.cpp:214
draw_ext_info_format
void draw_ext_info_format(int, int, const object *, uint8_t, uint8_t, const char *format,...)
Definition: mapper.cpp:3369
esrv_send_item
void esrv_send_item(object *, object *)
Definition: mapper.cpp:3390
struct_map_info::min_monster
int min_monster
Definition: mapper.cpp:220
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:2404
struct_region_info
Definition: mapper.cpp:362
clean_tmp_files
void clean_tmp_files(void)
Definition: mapper.cpp:3387
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:214
struct_equipment::name
char * name
Definition: mapper.cpp:247
TRIGGER_BUTTON
@ TRIGGER_BUTTON
Definition: object.h:135
npc_dialog.filename
filename
Definition: npc_dialog.py:99
smoking_pipe.color
color
Definition: smoking_pipe.py:5
account_chars_struct
Definition: account_char.h:28
object_get_value
const char * object_get_value(const object *op, const char *const key)
Definition: object.cpp:4320
create_treasure
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
Definition: treasure.cpp:256
struct_map_info::max_monster
int max_monster
Definition: mapper.cpp:220
struct_slaying_info
Definition: mapper.cpp:404
buf
StringBuffer * buf
Definition: readable.cpp:1611
struct_equipment::calc_power
int calc_power
Definition: mapper.cpp:249
object_insert_in_ob
object * object_insert_in_ob(object *op, object *where)
Definition: object.cpp:2832
quest_step_definition
Definition: quest.h:29
MAX
#define MAX(x, y)
Definition: compat.h:24
apply_auto_fix
void apply_auto_fix(mapstruct *)
Definition: mapper.cpp:3471
account_char_save
void account_char_save(Account_Chars *)
Definition: mapper.cpp:3486
obj::nrof
uint32_t nrof
Definition: object.h:340
FLAG_NO_PICK
#define FLAG_NO_PICK
Definition: define.h:239
force_pics
static int force_pics
Definition: mapper.cpp:319
world_exit_info
static int world_exit_info
Definition: mapper.cpp:327
sort_struct_quest
static int sort_struct_quest(const void *left, const void *right)
Definition: mapper.cpp:1043
struct_quest
Definition: mapper.cpp:914
archt
Definition: object.h:472
struct_map_in_quest_list
Definition: mapper.cpp:200
struct_region_info::reg
region * reg
Definition: mapper.cpp:363
struct_map_in_quest::quest
struct struct_quest * quest
Definition: mapper.cpp:912
FLAG_IS_A_TEMPLATE
#define FLAG_IS_A_TEMPLATE
Definition: define.h:366
obj::slaying
sstring slaying
Definition: object.h:325
init_renderer_env
static void init_renderer_env()
Definition: mapper.cpp:2688
struct_quest::description
char * description
Definition: mapper.cpp:916
init_gods
void init_gods(void)
Definition: holy.cpp:61
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
stringbuffer_finish
char * stringbuffer_finish(StringBuffer *sb)
Definition: stringbuffer.cpp:76
S_CONTAINER
#define S_CONTAINER
Definition: mapper.cpp:398
struct_race
struct struct_race struct_race
object_free_drop_inventory
void object_free_drop_inventory(object *ob)
Definition: object.cpp:1541
item.q
q
Definition: item.py:32
opendir
DIR * opendir(const char *)
quest_step_definition::next
struct quest_step_definition * next
Definition: quest.h:33
struct_map_info::reset_group
sstring reset_group
Definition: mapper.cpp:224
templateCache
static inja::TemplateStorage templateCache
Definition: mapper.cpp:3073
disinfect.map
map
Definition: disinfect.py:4
regions
static struct struct_region_info ** regions
Definition: mapper.cpp:369
struct_npc_info::y
int y
Definition: mapper.cpp:182
struct_map_info::exits_from
struct_map_list exits_from
Definition: mapper.cpp:221
Settings::debug
LogLevel debug
Definition: global.h:243
detail_quests
static bool detail_quests
Definition: mapper.cpp:329
ensure_unique
static struct_equipment * ensure_unique(struct_equipment *item)
Definition: mapper.cpp:472
struct_npc_info::message
const char * message
Definition: mapper.cpp:181
special_equipment
static struct_equipment ** special_equipment
Definition: mapper.cpp:254
obj::name
sstring name
Definition: object.h:317
quest_step_definition::is_completion_step
int is_completion_step
Definition: quest.h:32
get_slaying_struct
static struct_slaying_info * get_slaying_struct(const char *slaying)
Definition: mapper.cpp:1437
generate_picture_path
static void generate_picture_path(const char *path, size_t pic_size, char *out, size_t len)
Definition: mapper.cpp:1516
make_face_from_files.args
args
Definition: make_face_from_files.py:31
OF_JPG
@ OF_JPG
Definition: mapper.cpp:340
struct_npc_list::count
size_t count
Definition: mapper.cpp:188
rotate-tower.result
bool result
Definition: rotate-tower.py:13
elevation_max
static int elevation_max
Definition: mapper.cpp:388
struct_map_info::pic_was_done
int pic_was_done
Definition: mapper.cpp:220
add_npc_to_map
static void add_npc_to_map(struct_npc_list *list, const object *npc)
Definition: mapper.cpp:1192
struct_map_info
struct struct_map_info struct_map_info
set_darkness_map
void set_darkness_map(mapstruct *)
Definition: mapper.cpp:3396
system_quests_count
static size_t system_quests_count
Definition: mapper.cpp:2209
POTION
@ POTION
Definition: object.h:114
struct_npc_info
Definition: mapper.cpp:179
define_quest
static void define_quest(const char *name, struct_map_info *mainmap, const char *description)
Definition: mapper.cpp:1059
path_combine_and_normalize
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Definition: path.cpp:172
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:934
do_tiled_map_picture
static void do_tiled_map_picture(struct_map_info *map)
Definition: mapper.cpp:2082
slaying_info
static struct_slaying_info ** slaying_info
Definition: mapper.cpp:409
add_string
sstring add_string(const char *str)
Definition: shstr.cpp:124
obj::name_pl
sstring name_pl
Definition: object.h:321
races
static struct_race_list races
Definition: mapper.cpp:268
object_get_multi_size
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
Definition: object.cpp:4718
main
int main(int argc, char **argv)
Definition: mapper.cpp:3084
HEAD
#define HEAD(op)
Definition: object.h:596
output_extensions
static const char * output_extensions[]
Definition: mapper.cpp:344
create_maps_array
static nlohmann::json create_maps_array(struct_map_list &maps)
Definition: mapper.cpp:2261
ROD
@ ROD
Definition: object.h:112
show_maps
static int show_maps
Definition: mapper.cpp:325
CONTAINER
@ CONTAINER
Definition: object.h:234
get_elevation_color
static int get_elevation_color(int elevation, gdImagePtr elevationmap)
Definition: mapper.cpp:733
reset_groups
static std::set< std::string > reset_groups
Definition: mapper.cpp:270
init_readable
void init_readable(void)
Definition: readable.cpp:904
make_face_from_files.str
str
Definition: make_face_from_files.py:24
S_MAX
#define S_MAX
Definition: mapper.cpp:401
quest_callback
static void quest_callback(const quest_definition *quest, void *)
Definition: mapper.cpp:2212
readdir
struct dirent * readdir(DIR *)
python_init.path
path
Definition: python_init.py:8
LOCKED_DOOR
@ LOCKED_DOOR
Definition: object.h:126
struct_race::name
char * name
Definition: mapper.cpp:263
dump
Definition: quest.cpp:859
is_slaying
static int is_slaying(object *item)
Definition: mapper.cpp:1424
struct_equipment::power
int power
Definition: mapper.cpp:248
create_race_array
static nlohmann::json create_race_array(struct_race_list &list)
Definition: mapper.cpp:2296
account_char_load
Account_Chars * account_char_load(const char *)
Definition: mapper.cpp:3482
dragon_ability_gain
void dragon_ability_gain(object *, int, int)
Definition: mapper.cpp:3393
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:127
inja::json
nlohmann::json json
Definition: inja.hpp:1565
object_update_speed
void object_update_speed(object *op)
Definition: object.cpp:1325
struct_race::origin
struct_map_list origin
Definition: mapper.cpp:265
color_slowing
static int color_slowing
Definition: mapper.cpp:384
Ice.b
b
Definition: Ice.py:48
regiondef::name
char * name
Definition: map.h:277
obj::x
int16_t x
Definition: object.h:333
system_quests
static const quest_definition * system_quests[500]
Definition: mapper.cpp:2210
struct_map_info::quests
struct_map_in_quest_list quests
Definition: mapper.cpp:223
write_world_map
static void write_world_map(void)
Definition: mapper.cpp:1788
FLAG_DAMNED
#define FLAG_DAMNED
Definition: define.h:317
struct_map_info::width
int width
Definition: mapper.cpp:234
add_map_to_quest
static void add_map_to_quest(struct_map_info *map, const char *name, const char *description)
Definition: mapper.cpp:993
create_npc_info
static struct_npc_info * create_npc_info(const object *npc)
Definition: mapper.cpp:1174
struct_quest
struct struct_quest struct_quest
face_info::data
uint8_t * data
Definition: image.h:11
color_road
static int color_road
Definition: mapper.cpp:382
tileset
static int tileset
Definition: mapper.cpp:328
esrv_update_item
void esrv_update_item(int, object *, object *)
Definition: mapper.cpp:3406
object_free
void object_free(object *ob, int flags)
Definition: object.cpp:1573
FOR_INV_FINISH
#define FOR_INV_FINISH()
Definition: define.h:677
is_blocking
static int is_blocking(object *item)
Definition: mapper.cpp:719
do_exit_map
static void do_exit_map(mapstruct *map)
Definition: mapper.cpp:748
create_destination
static void create_destination(void)
Definition: mapper.cpp:3053
struct_map_info::tiled_y_from
int tiled_y_from
Definition: mapper.cpp:235
struct_race_list::races
struct struct_race ** races
Definition: mapper.cpp:194
sstring
const typedef char * sstring
Definition: global.h:43
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:1508
say.max
dictionary max
Definition: say.py:148
jpeg_quality
static int jpeg_quality
Definition: mapper.cpp:353
sort_system_quest_step
static int sort_system_quest_step(const void *a, const void *b)
Definition: mapper.cpp:2222
sproto.h
append_map_list
static void append_map_list(struct_map_list &dest, struct_map_list &src)
Definition: mapper.cpp:2394
IS_SHIELD
#define IS_SHIELD(op)
Definition: define.h:170
logfile
FILE * logfile
Definition: init.cpp:114
mapdef
Definition: map.h:317
BOOK
@ BOOK
Definition: object.h:117
rawmaps
static int rawmaps
Definition: mapper.cpp:356
init_struct_map_in_quest_list
static void init_struct_map_in_quest_list(struct_map_in_quest_list *list)
Definition: mapper.cpp:928
struct_race_list
Definition: mapper.cpp:193
struct_race
Definition: mapper.cpp:262
emergency_save
void emergency_save(int)
Definition: mapper.cpp:3384
delete_map
void delete_map(mapstruct *m)
Definition: map.cpp:1722
struct_race_list::allocated
size_t allocated
Definition: mapper.cpp:196
struct_map_list::maps
struct struct_map_info ** maps
Definition: mapper.cpp:208
RING
@ RING
Definition: object.h:188
struct_race_list::count
size_t count
Definition: mapper.cpp:195
fill_json
static void fill_json(nlohmann::json &json)
Definition: mapper.cpp:2419
add_map_to_region
static void add_map_to_region(struct_map_info *map, region *reg)
Definition: mapper.cpp:1357
image.h
struct_map_info::level
int level
Definition: mapper.cpp:220
found_maps_count
static int found_maps_count
Definition: mapper.cpp:375
struct_equipment
struct struct_equipment struct_equipment
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.cpp:2079
FLAG_MONSTER
#define FLAG_MONSTER
Definition: define.h:245
list_system_quests
static bool list_system_quests
Definition: mapper.cpp:330
generate_pics
static int generate_pics
Definition: mapper.cpp:318
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:2336
struct_quest::mainmap
struct_map_info * mainmap
Definition: mapper.cpp:918
env
static std::shared_ptr< inja::Environment > env
Definition: mapper.cpp:2226
MAX_BUF
#define MAX_BUF
Definition: define.h:35
S_KEY
#define S_KEY
Definition: mapper.cpp:397
artifactstruct
Definition: artifact.h:14
sort_map_info
static int sort_map_info(const void *left, const void *right)
Definition: mapper.cpp:882
fill_reverse_maps
static void fill_reverse_maps(struct_map_list &list)
Definition: mapper.cpp:2375
is_valid_faceset
int is_valid_faceset(int fsn)
Definition: image.cpp:117
struct_map_info::tiled_x_from
int tiled_x_from
Definition: mapper.cpp:235
pageToRender
Definition: mapper.cpp:2642
IS_WEAPON
#define IS_WEAPON(op)
Definition: define.h:163
sort_slaying
static int sort_slaying(const void *left, const void *right)
Definition: mapper.cpp:2921
tiled_map_list
static struct_map_list tiled_map_list
Definition: mapper.cpp:243
add_race_to_list
static void add_race_to_list(struct_race *race, struct_race_list *list, int check)
Definition: mapper.cpp:293
StringBuffer
Definition: stringbuffer.cpp:25
equipment_count
static size_t equipment_count
Definition: mapper.cpp:256
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:584
sort_system_quest
static int sort_system_quest(const void *a, const void *b)
Definition: mapper.cpp:2218
FOR_MAP_PREPARE
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Definition: define.h:723
EXIT
@ EXIT
Definition: object.h:184
obj::y
int16_t y
Definition: object.h:333
sortbyname
static int sortbyname(const void *a, const void *b)
Definition: mapper.cpp:802
path_stack
static std::vector< std::string > path_stack
Definition: mapper.cpp:2566
create_npc_array
static nlohmann::json create_npc_array(struct_npc_list &list)
Definition: mapper.cpp:2277
merge_tiled_maps
static void merge_tiled_maps(struct_map_info *map, struct_map_info *tiled_map)
Definition: mapper.cpp:1273
cached_pics
static int cached_pics
Definition: mapper.cpp:335
struct_map_list::allocated
size_t allocated
Definition: mapper.cpp:210
list_map
static void list_map(const char *path)
Definition: mapper.cpp:1334
struct_map_info::exits_to
struct_map_list exits_to
Definition: mapper.cpp:222
struct_map_info::lore
char * lore
Definition: mapper.cpp:218
rendered_templates
static std::set< std::string > rendered_templates
Definition: mapper.cpp:2228
apply_auto
int apply_auto(object *op)
Definition: mapper.cpp:3419
check_trigger
int check_trigger(object *op, object *cause)
Definition: button.cpp:518
make_face_from_files.out
out
Definition: make_face_from_files.py:75
quest.h
obj::type
uint8_t type
Definition: object.h:346
dirent
#define dirent
Definition: xdir.h:12
S_DETECTOR
#define S_DETECTOR
Definition: mapper.cpp:399
struct_map_info::path
char * path
Definition: mapper.cpp:215
struct_map_in_quest_list::count
size_t count
Definition: mapper.cpp:202
init_map_list
static void init_map_list(struct_map_list *list)
Definition: mapper.cpp:418
add_region_link
static void add_region_link(mapstruct *source, mapstruct *dest)
Definition: mapper.cpp:1405
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:437
init_library
void init_library(void)
Definition: init.cpp:324
free_equipment
static void free_equipment(struct_equipment *equip)
Definition: mapper.cpp:458
esrv_update_spells
void esrv_update_spells(player *)
Definition: mapper.cpp:3409
created_pics
static int created_pics
Definition: mapper.cpp:334
bigchest.check
check
Definition: bigchest.py:10
size_large
#define size_large
Definition: mapper.cpp:322
add_map_to_slaying
static void add_map_to_slaying(struct_slaying_info *info, int item, struct_map_info *map)
Definition: mapper.cpp:1468
struct_region_info::sum
int sum
Definition: mapper.cpp:365
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:339
account_char_free
void account_char_free(Account_Chars *)
Definition: mapper.cpp:3489
struct_region_info::maps_list
struct_map_list maps_list
Definition: mapper.cpp:364
init_npc_list
static void init_npc_list(struct_npc_list *list)
Definition: mapper.cpp:1161
item
Definition: item.py:1
struct_map_info::processed
int processed
Definition: mapper.cpp:235
FIREWALL
@ FIREWALL
Definition: object.h:171
PLAYER_CHANGER
@ PLAYER_CHANGER
Definition: object.h:165
inja::Arguments
std::vector< const json * > Arguments
Definition: inja.hpp:1567
create_pathname
char * create_pathname(const char *name, char *buf, size_t size)
Definition: map.cpp:103
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:1391
create-tower.current_map
current_map
Definition: create-tower.py:7
display_rendered_template
static bool display_rendered_template
Definition: mapper.cpp:331
templates_root
static std::string templates_root("templates/")
FLAG_AUTO_APPLY
#define FLAG_AUTO_APPLY
Definition: define.h:250
quest_definition
Definition: quest.h:38
struct_map_info::monsters
struct_race_list monsters
Definition: mapper.cpp:228
find_archetype
archetype * find_archetype(const char *name)
Definition: assets.cpp:270
elevation_info
static int ** elevation_info
Definition: mapper.cpp:386
color_blocking
static int color_blocking
Definition: mapper.cpp:383
struct_map_in_quest::description
char * description
Definition: mapper.cpp:911
get_template
static inja::Template get_template(const std::string &filename)
Definition: mapper.cpp:3074
convert.dest
dest
Definition: convert.py:25
struct_map_info::tiled_maps
struct_map_list tiled_maps
Definition: mapper.cpp:226
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:3377
region_count
static size_t region_count
Definition: mapper.cpp:370
command_help
void command_help(object *, const char *)
Definition: mapper.cpp:3492
do_parameters
static void do_parameters(int argc, char **argv)
Definition: mapper.cpp:2971
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:324
all_data
static nlohmann::json all_data
Definition: mapper.cpp:2227
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:648
struct_map_in_quest_list::list
struct struct_map_in_quest ** list
Definition: mapper.cpp:201
MAP_HEIGHT
#define MAP_HEIGHT(m)
Definition: map.h:80
struct_quest::number
int number
Definition: mapper.cpp:917
pageToRender::template_name
std::string template_name
Definition: mapper.cpp:2644
struct_map_info::cfregion
region * cfregion
Definition: mapper.cpp:219
get_ob_diff
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Definition: object.cpp:4960
sort_race
static int sort_race(const void *a, const void *b)
Definition: mapper.cpp:670
obj::head
struct obj * head
Definition: object.h:302
do_regions_link
static bool do_regions_link
Definition: mapper.cpp:391
arch_to_object
object * arch_to_object(archetype *at)
Definition: arch.cpp:230
object_give_identified_properties
void object_give_identified_properties(object *op)
Definition: item.cpp:1344
init_race_list
static void init_race_list(struct_race_list *list)
Definition: mapper.cpp:277
create-tower.tile
tile
Definition: create-tower.py:8
process_map
static void process_map(struct_map_info *info)
Definition: mapper.cpp:1548
quests_allocated
static int quests_allocated
Definition: mapper.cpp:926
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:374
find_skill_by_number
object * find_skill_by_number(object *, int)
Definition: mapper.cpp:3399
sizes
static int sizes[]
Definition: mapper.cpp:320
account_logout
void account_logout(const char *)
Definition: mapper.cpp:3495
reverse_regions
static std::map< region *, std::string > reverse_regions
Definition: mapper.cpp:2230
get_region_by_map
region * get_region_by_map(mapstruct *m)
Definition: region.cpp:74
S_DOOR
#define S_DOOR
Definition: mapper.cpp:396
create_tiled_map
static struct_map_info * create_tiled_map(void)
Definition: mapper.cpp:1257
world_map
static int world_map
Definition: mapper.cpp:326
templates
static std::vector< std::string > templates
Definition: mapper.cpp:2683
ignore_path
static const char * ignore_path[]
Definition: mapper.cpp:2778
sort_equipment
static int sort_equipment(const void *a, const void *b)
Definition: mapper.cpp:601
struct_map_list::count
size_t count
Definition: mapper.cpp:209
slaying_count
static size_t slaying_count
Definition: mapper.cpp:410
player_get_delayed_buffer
SockList * player_get_delayed_buffer(player *)
Definition: mapper.cpp:3474
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:2656
struct_npc_list::allocated
size_t allocated
Definition: mapper.cpp:189
object_remove
void object_remove(object *op)
Definition: object.cpp:1814
regiondef::fallback
int8_t fallback
Definition: map.h:287
infomap
static gdImagePtr infomap
Definition: mapper.cpp:379
sort_struct_map_in_quest
static int sort_struct_map_in_quest(const void *left, const void *right)
Definition: mapper.cpp:1015
struct_map_info::height
int height
Definition: mapper.cpp:234
ALTAR
@ ALTAR
Definition: object.h:125
struct_npc_info::x
int x
Definition: mapper.cpp:182
relative_path
static void relative_path(const char *from, const char *to, char *result)
Definition: mapper.cpp:818
FLAG_UNPAID
#define FLAG_UNPAID
Definition: define.h:236
dump_unused_maps
static void dump_unused_maps(void)
Definition: mapper.cpp:2847
struct_npc_list::npc
struct_npc_info ** npc
Definition: mapper.cpp:187
rod_adjust
void rod_adjust(object *)
Definition: mapper.cpp:3412
struct_map_info::readable
struct_npc_list readable
Definition: mapper.cpp:231
sort_region
static int sort_region(const void *left, const void *right)
Definition: mapper.cpp:898
generate_treasure
object * generate_treasure(treasurelist *t, int difficulty)
Definition: treasure.cpp:288
make_path_to_file
void make_path_to_file(const char *filename)
Definition: porting.cpp:164
FREE_OBJ_FREE_INVENTORY
#define FREE_OBJ_FREE_INVENTORY
Definition: object.h:533
fix_exits_for_map
static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from)
Definition: mapper.cpp:1978
struct_npc_list
Definition: mapper.cpp:186
quest_step_definition::step_description
sstring step_description
Definition: quest.h:31
SCROLL
@ SCROLL
Definition: object.h:224
FLAG_IS_LINKED
#define FLAG_IS_LINKED
Definition: define.h:315
struct_npc_info::name
const char * name
Definition: mapper.cpp:180
draw_ext_info
void draw_ext_info(int, int, const object *, uint8_t, uint8_t, const char *txt)
Definition: mapper.cpp:3365
split
static std::vector< std::string > split(const std::string &field, const std::string &by)
Definition: mapper.cpp:2671
say.item
dictionary item
Definition: say.py:149
do_help
static void do_help(const char *program)
Definition: mapper.cpp:2934
struct_quest::name
char * name
Definition: mapper.cpp:915
nlohmann::basic_json::erase
IteratorType erase(IteratorType pos)
remove element given an iterator
Definition: json.hpp:21582
get_faces_count
size_t get_faces_count()
Definition: assets.cpp:297
calc_item_power
int calc_item_power(const object *op)
Definition: item.cpp:239
write_world_info
static void write_world_info(void)
Definition: mapper.cpp:2870
struct_map_in_quest_list::allocated
size_t allocated
Definition: mapper.cpp:203
tiled_map_need_pic
static int tiled_map_need_pic(struct_map_info *map)
Definition: mapper.cpp:2052
regiondef::msg
char * msg
Definition: map.h:285
face_sets
Definition: image.h:17
equipment_allocated
static size_t equipment_allocated
Definition: mapper.cpp:258
SPELL
@ SPELL
Definition: object.h:217
map_limit
static int map_limit
Definition: mapper.cpp:324
replace.current
current
Definition: replace.py:64
closedir
int closedir(DIR *)
quests
static struct_quest ** quests
Definition: mapper.cpp:922
guildbuy.temp
def temp
Definition: guildbuy.py:26
fix_tiled_map
static void fix_tiled_map(void)
Definition: mapper.cpp:1909
FLAG_CURSED
#define FLAG_CURSED
Definition: define.h:316
output_format_type
output_format_type
Definition: mapper.cpp:338
TELEPORTER
@ TELEPORTER
Definition: object.h:144
regiondef::longname
char * longname
Definition: map.h:283
gdfaces
static gdImagePtr * gdfaces
Definition: mapper.cpp:176
pics_allocated
static int pics_allocated
Definition: mapper.cpp:315
struct_equipment
Definition: mapper.cpp:246
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:206
FOR_INV_PREPARE
#define FOR_INV_PREPARE(op_, it_)
Definition: define.h:670
takeitem.status
status
Definition: takeitem.py:35
find_player_partial_name
player * find_player_partial_name(const char *)
Definition: mapper.cpp:3478
find_map_by_key
static struct_map_info * find_map_by_key(const std::string &key)
Definition: mapper.cpp:2237
warn_no_path
static int warn_no_path
Definition: mapper.cpp:359
find_quest_info
static struct_quest * find_quest_info(const char *name)
Definition: mapper.cpp:947
DETECTOR
@ DETECTOR
Definition: object.h:152
find_maps
static void find_maps(const char *from)
Definition: mapper.cpp:2802
struct_slaying_info::slaying
char * slaying
Definition: mapper.cpp:405
ring_occidental_mages.r
r
Definition: ring_occidental_mages.py:6
is_road
static int is_road(object *item)
Definition: mapper.cpp:683
obj::level
int16_t level
Definition: object.h:359
elevation_min
static int elevation_min
Definition: mapper.cpp:387
struct_map_info::npcs
struct_npc_list npcs
Definition: mapper.cpp:230
color_linked_exit
static int color_linked_exit
Definition: mapper.cpp:381
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:510
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:2645
identify
object * identify(object *op)
Definition: item.cpp:1409
regiondef
Definition: map.h:275