186 #include <sys/stat.h> 187 #include <sys/types.h> 339 for (test = 0; test < list->
count; test++) {
340 if (list->
races[test] == race)
362 static int sizes[] = {32, 16, 8, 4, 2};
364 #define size_large sizes[0] 365 #define size_small sizes[1] 439 #define S_CONTAINER 2 575 if (artifact == NULL) {
610 if (add->
diff == NULL || strcmp(add->
diff,
"") == 0) {
652 for (test = 0; test < races.
count; test++) {
653 if (strcmp(races.
races[test]->
name, name) == 0) {
655 return races.
races[test];
660 item->
name = strdup(name);
680 if (monster->
head && monster != monster->
head)
715 const char *roads[] = {
721 const char *partial[] = {
725 for (test = 0; partial[test] != NULL; test++) {
726 if (strstr(item->
arch->
name, partial[test]) != NULL)
733 for (test = 0; roads[test] != NULL; test++) {
734 if (strcmp(item->
arch->
name, roads[test]) == 0)
764 return gdImageColorResolve(elevationmap, 200*elevation/elevation_max, 0, 0);
766 return gdImageColorResolve(elevationmap, 0, 0, 200*elevation/elevation_min);
781 if (sscanf(map->
path,
"/world/world_%d_%d", &x, &y) != 2)
787 for (tx = 0; tx <
MAP_WIDTH(map); tx++) {
794 int elevation = item->elevation;
795 if (elevation != 0) {
796 elevation_min =
MIN(elevation_min, elevation);
797 elevation_max =
MAX(elevation_max, elevation);
798 elevation_info[x*50+tx][y*50+ty] = elevation;
803 gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_unlinked_exit);
805 gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_linked_exit);
807 gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_road);
809 gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_blocking);
813 gdImageSetPixel(infomap, x*50+tx, y*50+ty, color_slowing);
840 fslash = strchr(from+1,
'/');
842 strcpy(result, to+1);
846 rslash = strchr(to+1,
'/');
847 while (fslash && rslash && (fslash-from == rslash-to) && strncmp(from, to, fslash-from+1) == 0) {
850 fslash = strchr(fslash+1,
'/');
851 rslash = strchr(rslash+1,
'/');
855 strcat(result,
"../");
856 fslash = strchr(fslash+1,
'/');
858 if (strlen(result) && result[strlen(result)-1] ==
'/' && *to ==
'/')
859 result[strlen(result)-1] =
'\0';
971 if (strcmp(quests[test]->name, name) == 0)
991 if (quests_count == quests_allocated) {
992 quests_allocated += 10;
996 add->
name = strdup(name);
1084 printf(
"warning, multiple quest definition for %s, found in %s and %s.\n", quest->
name, quest->
mainmap ? quest->
mainmap->
path :
"(unknown map)", mainmap->
path);
1100 char *start, *end, *next;
1102 char description[500];
1104 start = strstr(map->
lore,
"@def");
1106 description[0] =
'\0';
1108 end = strstr(start,
"\n");
1110 strncpy(name, start+5, end-start-5);
1111 name[end-start-5] =
'\0';
1113 end = strstr(next,
"@end");
1115 strncpy(description, next, end-next);
1116 description[end-next] =
'\0';
1118 memmove(start, end+4, strlen(map->
lore)-(end-start+3));
1122 strcpy(description, next);
1127 strcpy(name, start);
1133 start = end ? strstr(end,
"@def") : NULL;
1136 start = strstr(map->
lore,
"@quest");
1138 description[0] =
'\0';
1140 end = strstr(start,
"\n");
1142 strncpy(name, start+7, end-start-7);
1143 name[end-start-7] =
'\0';
1145 end = strstr(next,
"@end");
1147 strncpy(description, next, end-next);
1148 description[end-next] =
'\0';
1150 memmove(start, end+4, strlen(map->
lore)-(end-start+3));
1154 strcpy(description, next);
1159 strcpy(name, start);
1165 start = end ? strstr(end,
"@quest") : NULL;
1187 info->
name = strdup(npc->
name ? npc->
name :
"(null name)");
1221 for (map = 0; map < list->
count; map++)
1222 if (list->
maps[map] == info)
1264 add_map(add, &tiled_map_list);
1289 for (g = 0; g < tiled_map_list.
count; g++) {
1290 if (tiled_map_list.
maps[g] == group) {
1291 if (g < tiled_map_list.
count-1)
1292 tiled_map_list.
maps[g] = tiled_map_list.
maps[tiled_map_list.
count-1];
1293 tiled_map_list.
count--;
1298 printf(
"tiled_map not in tiled_map_list!");
1315 for (
size_t map = 0; map < maps_list.
count; map++) {
1316 if (strcmp(maps_list.
maps[map]->
path, path) == 0)
1317 return maps_list.
maps[map];
1321 add->
path = strdup(path);
1322 tmp = strrchr((
char *)path,
'/');
1339 for (
auto map = found_maps.begin(); map != found_maps.end(); ++map) {
1340 if (strcmp(path, *map) == 0) {
1342 found_maps.erase(map);
1346 printf(
"Map processed but not found in directory reading? %s\n", path);
1364 if (regions[test]->reg == reg)
1367 if (test == region_count) {
1368 if (test == region_allocated) {
1374 regions[test]->
reg = reg;
1376 add_map(map, ®ions[test]->maps_list);
1377 if (sscanf(map->
path,
"/world/world_%d_%d", &x, &y) == 2) {
1378 regions[test]->
sum_x += (x-100);
1379 regions[test]->
sum_y += (y-100);
1380 regions[test]->
sum++;
1394 if (output_format ==
OF_PNG)
1395 gdImagePng(pic, file);
1397 gdImageJpeg(pic, file, jpeg_quality);
1415 region_links[s].insert(d);
1441 if (!strcmp(slaying_info[l]->slaying, slaying))
1442 return slaying_info[l];
1444 if (slaying_count == slaying_allocated) {
1445 slaying_allocated += 10;
1450 add->
slaying = strdup(slaying);
1451 for (
size_t l = 0; l <
S_MAX; l++)
1519 snprintf(out, len,
"%s%s.x%zu%s",
root, path, pic_size + 1, output_extensions[output_format]);
1527 FILE *out = fopen(picpath,
"wb+");
1531 for (
size_t i = 1; i <
num_sizes; i++) {
1533 gdImagePtr small = gdImageCreateTrueColor(width*
sizes[i], height*
sizes[i]);
1534 gdImageCopyResampled(small, real, 0, 0, 0, 0, width*
sizes[i], height*
sizes[i], width*
size_large, height*size_large);
1535 out = fopen(picpath,
"wb+");
1538 gdImageDestroy(small);
1553 gdImagePtr pic =
nullptr;
1555 struct stat statspic;
1556 char exit_path[500];
1562 if (list_unused_maps)
1566 printf(
" processing map %s\n", info->
path);
1570 printf(
"couldn't load map %s\n", info->
path);
1589 isworld = (sscanf(info->
path,
"/world/world_%d_%d", &x, &y) == 2);
1607 stat(tmppath, &stats);
1608 if (stat(picpath[0], &statspic) || (statspic.st_mtime < stats.st_mtime))
1621 for (x = 0; x < 4; x++)
1625 if (stat(tmppath, &stats)) {
1626 printf(
" map %s doesn't exist in map %s, for tile %d.\n", exit_path, info->
path, x);
1634 if (do_regions_link) {
1637 if (link && link != m) {
1682 if (!item->slaying) {
1685 printf(
" exit without any path at %d, %d on %s\n", item->x, item->y, info->
path);
1688 if (strcmp(item->slaying,
"/!"))
1692 printf(
" random map without message in %s at %d, %d\n", info->
path, item->x, item->y);
1695 start = strstr(item->msg,
"\nfinal_map ");
1696 if (!start && strncmp(item->msg,
"final_map", strlen(
"final_map")) == 0)
1700 char *end = strchr((
char *)start+1,
'\n');
1702 start += strlen(
"final_map")+2;
1703 strncpy(ep, start, end-start);
1711 if (stat(tmppath, &stats)) {
1712 printf(
" map %s doesn't exist in map %s, at %d, %d.\n", ep, info->
path, item->x, item->y);
1718 if (do_regions_link) {
1721 if (link && link != m) {
1747 }
else if ((item->type ==
SIGN || item->type ==
BOOK) && (item->msg != item->arch->clone.msg) && (item->msg != NULL)) {
1751 if (item->invisible)
1757 if (
gdfaces.size() <= item->face->number)
1758 gdfaces.resize(item->face->number + 1,
nullptr);
1760 if (
gdfaces[item->face->number] == NULL) {
1766 if (item->head || item->more) {
1772 if (
gdfaces[item->face->number] != NULL && ((!item->head && !item->more) || (item->arch->clone.x+hx == 0 && item->arch->clone.y+hy == 0))) {
1781 gdImageDestroy(pic);
1799 char mapleft[10], maptop[10], mapright[10], mapbottom[10], mappath[5000];
1809 printf(
"Generating world map in world.html...");
1812 pic = gdImageCreateTrueColor(
SIZE*30,
SIZE*30);
1815 strcat(file,
"/world.html");
1820 for (y = 0; y < 30; y++) {
1821 for (x = 0; x < 30; x++) {
1822 snprintf(name,
sizeof(name),
"world_%d_%d", wx, wy);
1823 snprintf(mapleft,
sizeof(mapleft),
"%d",
SIZE*x);
1824 snprintf(maptop,
sizeof(maptop),
"%d",
SIZE*y);
1825 snprintf(mapright,
sizeof(mapright),
"%d",
SIZE*(x+1)-1);
1826 snprintf(mapbottom,
sizeof(mapbottom),
"%d",
SIZE*(y+1)-1);
1828 snprintf(mappath,
sizeof(mappath),
"%s/world/%s.x1%s",
root, name, output_extensions[output_format]);
1830 out = fopen(mappath,
"rb");
1832 printf(
"\n warning: large pic not found for world_%d_%d", wx, wy);
1836 if (output_format ==
OF_PNG)
1837 small = gdImageCreateFromPng(out);
1839 small = gdImageCreateFromJpeg(out);
1842 printf(
"\n warning: pic not found for world_%d_%d", wx, wy);
1846 gdImageCopyResized(pic, small,
SIZE*x,
SIZE*y, 0, 0,
SIZE,
SIZE, small->sx, small->sy);
1847 gdImageDestroy(small);
1855 snprintf(mappath,
sizeof(mappath),
"%s/world_raw%s",
root, output_extensions[output_format]);
1856 out = fopen(mappath,
"wb+");
1861 small = gdImageCreateTrueColor(
SIZE*30,
SIZE*30);
1862 font = gdFontGetGiant();
1863 color = gdImageColorAllocateAlpha(pic, 255, 0, 0, 20);
1865 if (!regions[
region]->is_world || regions[
region]->sum == 0)
1870 gdImageString(small, font, x, y, (
unsigned char *)regions[
region]->reg->name, color);
1871 gdImageString(pic, font, x, y, (
unsigned char *)regions[
region]->reg->name, color);
1876 gdImageString(infomap, font, x, y, (
unsigned char *)regions[
region]->reg->name, color);
1879 snprintf(mappath,
sizeof(mappath),
"%s/world_regions%s",
root, output_extensions[output_format]);
1880 out = fopen(mappath,
"wb+");
1883 gdImageDestroy(small);
1885 snprintf(mappath,
sizeof(mappath),
"%s/world%s",
root, output_extensions[output_format]);
1886 out = fopen(mappath,
"wb+");
1889 gdImageDestroy(pic);
1897 for (
size_t map = 0; map < maps_list.
count; map++) {
1901 printf(
"map without path!\n");
1920 for (map = 0; map < tiled_map_list.
count; map++) {
1922 printf(
"empty tiled map group!");
1926 snprintf(name,
sizeof(name),
"tiled_map_group_%zu", map);
1940 printf(
"*** warning: tiled maps %s and %s not in same region (%s and %s).\n",
1955 printf(
"*** warning: tiled map without any name. First map path %s\n", tiled_map_list.
maps[map]->
tiled_maps.
maps[0]->
path);
1959 tiled_map_list.
maps[map]->
name = strdup(test);
1963 slash = strrchr(name,
'/');
1965 snprintf(name,
sizeof(name),
"/");
1968 strncat(name, tiled_map_list.
maps[map]->
filename,
sizeof(name) - strlen(name) - 1);
1969 tiled_map_list.
maps[map]->
path = strdup(name);
1987 max = from->
count-1;
1988 for (map = max; map >= 0; map--) {
2006 for (map = 0;
static_cast<size_t>(map) < maps_list.
count; map++) {
2013 for (map = max; map >= 0; map--) {
2034 for (
size_t race = 0; race < races.
count; race++) {
2036 for (map = max; map >= 0; map--) {
2048 for (map = 0;
static_cast<size_t>(map) < maps_list.
count; map++) {
2062 for (
size_t size = 0; size <
num_sizes; size++) {
2064 if (stat(picpath, &stats))
2088 int xmin = 0, xmax = 0, ymin = 0, ymax = 0, count, last;
2091 gdImagePtr large, load;
2098 printf(
" Generating composite map for %s...", map->
name);
2102 printf(
" already uptodate.\n");
2108 printf(
"Tiled map without tiled maps?\n");
2147 if (last == count) {
2148 printf(
"do_tiled_map_picture: didn't process any map in %s (%d left)??\n", map->
path, last);
2169 out = fopen(picpath,
"rb");
2171 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);
2174 if (output_format ==
OF_PNG)
2175 load = gdImageCreateFromPng(out);
2177 load = gdImageCreateFromJpeg(out);
2180 printf(
"\n do_tiled_map_picture: warning: pic not found for %s\n", map->
tiled_maps.
maps[tiled]->
path);
2184 gdImageDestroy(load);
2189 gdImageDestroy(large);
2206 printf(
"Writing tiled map information...\n");
2208 for (
size_t map = 0; map < tiled_map_list.
count; map++)
2218 system_quests.push_back(const_cast<quest_definition *>(quest));
2222 static std::shared_ptr<inja::Environment>
env;
2234 auto found = std::find_if(reverse_maps.cbegin(), reverse_maps.cend(), [&key] (
auto c) {
return c.second == key; });
2235 if (found != reverse_maps.cend())
2236 return found->first;
2246 auto found = std::find_if(reverse_regions.cbegin(), reverse_regions.cend(), [&key] (
auto c) {
return c.second == key; });
2247 if (found != reverse_regions.cend())
2248 return found->first;
2258 nlohmann::json result = nlohmann::json::array();
2259 for (
size_t m = 0; m < maps.
count; m++) {
2260 auto map = reverse_maps.find(maps.
maps[m]);
2261 if (map != reverse_maps.end()) {
2262 result.push_back(map->second);
2274 nlohmann::json result;
2275 for (
size_t n = 0; n < list.size(); n++) {
2278 {
"name", npc->name },
2281 {
"message", npc->message },
2293 nlohmann::json result;
2294 for (
size_t n = 0; n < list.
count; n++) {
2295 auto race = list.
races[n];
2297 {
"name", race->name },
2298 {
"count", race->count },
2310 nlohmann::json ret = nlohmann::json::array();
2311 for (
size_t m = 0; m < list.
count; m++) {
2312 auto q = list.
list[
m];
2313 if (!q->map || !q->description)
2316 {
"map", reverse_maps.find(q->map)->second },
2317 {
"description", q->description },
2318 {
"quest", q->quest->name },
2319 {
"number", q->quest->number },
2328 return path && path[0] ==
'/' ? path + 1 : path;
2340 {
"name", map->
name },
2343 {
"level", map->
level },
2345 {
"lore", map->
lore && map->
lore[0] ? map->
lore :
"" },
2364 {
"number", quest->
number },
2365 {
"name", quest->
name ? quest->
name :
"" },
2367 {
"main_map", quest->
mainmap ? reverse_maps.find(quest->
mainmap)->second :
"" },
2378 for (
size_t map = 0; map < list.
count; map++) {
2379 auto cur = list.
maps[map];
2380 if (cur->tiled_group)
2382 snprintf(buf,
sizeof(buf),
"map_%04lu", map);
2383 reverse_maps.insert(std::make_pair(cur, buf));
2396 for (
size_t map = 0; map < src.
count; map++)
2406 nlohmann::json ret = nlohmann::json::array();
2407 for (
auto reg : regions) {
2408 auto r = reverse_regions.find(reg);
2409 if (r != reverse_regions.end()) {
2410 ret.push_back((*r).second);
2418 auto find = templateCache.find(filename);
2419 if (find != templateCache.end()) {
2420 return find->second;
2422 inja::Template parsed = env->parse_template(filename);
2423 templateCache[filename] = parsed;
2432 nlohmann::json
maps;
2435 bool need_unknown_region =
false;
2436 nlohmann::json search;
2446 auto region = regions[reg];
2447 snprintf(buf,
sizeof(buf),
"reg_%04lu", reg);
2448 reverse_regions.insert(std::make_pair(
region->reg, buf));
2452 auto region = regions[reg];
2454 nlohmann::json r = {
2455 {
"_key", reverse_regions[
region->reg] },
2463 json[
"regions"].push_back(r);
2464 auto link = env->render(
get_template(
"search-links/region"), r);
2465 search[
"reg_" + std::to_string(reg)] = {
2473 size_t map_index = 0;
2474 for (
auto map : reverse_maps) {
2475 auto cur = map.first;
2476 if (cur->tiled_group)
2478 if (cur->cfregion ==
nullptr)
2479 need_unknown_region =
true;
2481 m[
"_index"] = map_index;
2482 json[
"maps"].push_back(m);
2483 auto link = env->render(
get_template(
"search-links/map"), m);
2484 search[
"map_" + std::to_string(map_index++)] = {
2486 {
"name", cur->name },
2487 {
"text", std::string(cur->lore ? cur->lore :
"") },
2492 if (need_unknown_region) {
2493 json[
"regions"].push_back({
2494 {
"_key",
"reg_ffff" },
2495 {
"name",
"unknown" },
2496 {
"longname",
"unknown" },
2497 {
"description",
"unknown" },
2498 {
"maps", nlohmann::json::array() },
2499 {
"links", nlohmann::json::array() },
2503 json[
"reset_groups"] = nlohmann::json::array();
2505 json[
"reset_groups"].push_back(rg);
2508 json[
"items"] = nlohmann::json::array();
2511 nlohmann::json item = {
2513 {
"name", eq->name },
2514 {
"power", eq->power },
2515 {
"calc_power", eq->calc_power },
2516 {
"diff", eq->diff },
2519 json[
"items"][idx] = item;
2520 auto link = env->render(
get_template(
"search-links/item"), item);
2521 search[
"item_" + std::to_string(idx)] = {
2523 {
"name", eq->name },
2528 json[
"monsters"] = nlohmann::json::array();
2529 for (
size_t item = 0; item < races.
count; item++) {
2530 auto race = races.
races[item];
2532 nlohmann::json m = {
2534 {
"name", race->
name },
2535 {
"count", race->count },
2538 json[
"monsters"].push_back(m);
2539 auto link = env->render(
get_template(
"search-links/monster"), m);
2540 search[
"monster_" + std::to_string(item)] = {
2542 {
"name", race->name },
2547 json[
"system_quests"] = nlohmann::json::array();
2548 for (
size_t q = 0; q < system_quests.size(); q++) {
2549 auto quest = system_quests[q];
2552 {
"code", quest->quest_code },
2553 {
"title", quest->quest_title },
2554 {
"description", quest->quest_description ? quest->quest_description :
"" },
2555 {
"replayable", quest->quest_restart },
2556 {
"steps", nlohmann::json::array() },
2557 {
"maps", nlohmann::json::array() },
2560 if (detail_quests) {
2561 std::sort(quest->steps.begin(), quest->steps.end(), [] (
auto left,
auto right) {
return left->step < right->step; });
2562 for (
size_t s = 0; s < quest->steps.size(); s++) {
2563 j[
"steps"].push_back({
2564 {
"description", quest->steps[s]->step_description ? quest->steps[s]->step_description :
"" },
2565 {
"is_completion", quest->steps[s]->is_completion_step ? true :
false },
2571 for (
size_t m = 0; m < qim->maps.count; m++) {
2572 auto map = reverse_maps.find(qim->maps.list[m]->map);
2573 assert(map != reverse_maps.end());
2574 j[
"maps"].push_back({
2575 {
"description", qim->maps.list[
m]->description },
2576 {
"map", map->second },
2581 json[
"system_quests"].push_back(j);
2582 search[
"quest_" + std::to_string(q)] = {
2584 {
"name", quest->quest_title ? quest->quest_title :
"" },
2585 {
"text", quest->quest_description ? quest->quest_description :
"" },
2586 {
"url",
"system_quests.html#q" + std::to_string(q) },
2590 json[
"slaying"] = nlohmann::json::array();
2592 auto info = slaying_info[s];
2593 json[
"slaying"].push_back({
2594 {
"slaying", info->slaying },
2603 json[
"quests"] = nlohmann::json::array();
2607 snprintf(buf,
sizeof(buf),
"quest_%d", quests[quest]->number);
2612 if (build_search_file) {
2613 std::string out(
root);
2614 out +=
"/search_data.js";
2615 std::ofstream sf(out, std::ios_base::trunc);
2616 sf <<
"var search_data = " << search <<
";" << std::endl;
2617 sf <<
"var search_type = { ";
2620 sf << sep << i <<
": \"" <<
SearchName[i] <<
"\"";
2623 sf <<
" };" << std::endl;
2630 void add_template_to_render(
const std::string &template_name,
const std::string &output_name,
const std::string ¶m);
2642 auto current(path_stack.back());
2643 if (current[0] !=
'/')
2644 current =
'/' + current;
2655 auto template_name = args.at(0)->get<std::string>();
2656 auto output_name(template_name);
2657 auto param = (args.size() > 1 ? args.at(1)->get<std::string>() :
"");
2659 if (!param.empty()) {
2660 output_name = param +
"_" + output_name;
2661 if (param.substr(0, 4) ==
"map_") {
2663 if (map !=
nullptr) {
2664 output_name = std::string(map->path + 1) +
".html";
2667 if (param.substr(0, 4) ==
"reg_") {
2669 if (reg !=
nullptr) {
2670 output_name = std::string(reg->name) +
".html";
2675 if (template_name !=
"search_data.js" && template_name !=
"search_index.js")
2686 auto what = args.at(0)->get<std::string>();
2687 if (what.substr(0, 4) ==
"map_") {
2692 if (args.size() > 1) {
2693 size = args.at(1)->get<
int>() - 1;
2696 snprintf(picpath,
sizeof(picpath),
"%s.x%d%s", map->path, size + 1, output_extensions[output_format]);
2720 auto on(output_name);
2723 if (rendered_templates.find(on) != rendered_templates.end())
2726 rendered_templates.insert(on);
2734 static std::vector<std::string>
split(
const std::string &field,
const std::string &by) {
2735 std::vector<std::string> result;
2736 size_t start = 0, found;
2737 while ((found = field.find(by, start)) != std::string::npos) {
2738 result.push_back(field.substr(start, found - start));
2741 result.push_back(field.substr(start));
2754 env->add_callback(
"substr", [] (inja::Arguments &args) {
2755 std::string str = args.at(0)->get<std::string>();
2756 size_t start = args.at(1)->get<
size_t>();
2757 size_t len = args.size() > 2 ? args.at(2)->get<
size_t>() : std::string::npos;
2758 return str.substr(start, len);
2761 env->add_callback(
"pad", [] (inja::Arguments &args) {
2763 int val = args.at(0)->get<
int>(), digits = args.at(1)->get<
int>();
2764 snprintf(buf,
sizeof(buf),
"%0*d", digits, val);
2765 return std::string(buf);
2767 env->add_callback(
"path_to_root", 0, [] (inja::Arguments &) {
2769 auto current(path_stack.back());
2770 if (current[0] ==
'/')
2771 current = current.substr(1);
2773 while ((start = current.find(
'/', start)) != std::string::npos) {
2779 env->add_callback(
"get_by_field", 3, [] (inja::Arguments &args) {
2780 const auto &src = args.at(0);
2781 auto field = args.at(1)->get<std::string>();
2782 const auto &value = args.at(2);
2783 auto found = std::find_if(src->begin(), src->end(), [&field, &value] (
auto item) {
2784 return item[field] == *value;
2786 if (found == src->end()) {
2787 return nlohmann::json();
2791 env->add_callback(
"get_list_by_field", 3, [] (inja::Arguments &args) {
2792 nlohmann::json ret = nlohmann::json::array();
2793 const auto &src = args.at(0);
2794 auto field = args.at(1)->get<std::string>();
2795 const auto filter = args.at(2);
2796 if (filter->is_array()) {
2797 std::copy_if(src->begin(), src->end(), std::back_inserter(ret), [&] (
auto &item) {
2798 auto val = item[field];
2799 return std::find_if(filter->begin(), filter->end(), [&] (
auto li) {
return val == li; }) != filter->end();
2802 std::copy_if(src->begin(), src->end(), std::back_inserter(ret), [&] (
auto &item) {
2803 return filter->get<std::string>() == item[field];
2808 env->add_callback(
"sort", [] (inja::Arguments &args) {
2809 const auto &src = args.at(0);
2810 std::vector<nlohmann::json> ret;
2811 for (
auto i : *src) {
2814 auto fields =
split(args.at(1)->get<std::string>(),
",");
2815 bool invert = args.size() > 2 ? args.at(2)->get<
bool>() :
false;
2816 bool ignore_case = args.size() > 3 ? args.at(3)->get<
bool>() :
true;
2817 std::sort(ret.begin(), ret.end(), [&] (
auto left,
auto right) {
2818 for (
auto field : fields) {
2819 nlohmann::json l = left[field], r = right[field];
2820 if (ignore_case && l.is_string() && r.is_string()) {
2821 std::string ls(l.get<std::string>()), rs(r.get<std::string>());
2822 std::transform(ls.begin(), ls.end(), ls.begin(), [](
unsigned char c){
return std::tolower(
c); });
2823 std::transform(rs.begin(), rs.end(), rs.begin(), [](
unsigned char c){
return std::tolower(
c); });
2827 return invert ? (rs < ls) : (ls < rs);
2832 return invert ? (r < l) : (l < r);
2839 env->set_trim_blocks(
true);
2840 env->set_lstrip_blocks(
true);
2871 struct stat statbuf;
2876 for (ignore = 0; ignore_path[ignore] != NULL; ignore++) {
2877 if (strcmp(from, ignore_path[ignore]) == 0)
2887 for (ignore = 0; ignore_name[ignore] != NULL; ignore++) {
2888 if (strcmp(file->d_name, ignore_name[ignore]) == 0)
2891 if (ignore_name[ignore] != NULL)
2894 snprintf(full,
sizeof(full),
"%s/%s", path, file->d_name);
2896 status = stat(full, &statbuf);
2897 snprintf(full,
sizeof(full),
"%s/%s", from, file->d_name);
2898 if ((status != -1) && (S_ISDIR(statbuf.st_mode))) {
2902 found_maps.push_back(strdup(full));
2913 snprintf(path,
sizeof(path),
"%s/%s",
root,
"maps.unused");
2914 dump = fopen(path,
"w+");
2916 printf(
"Unable to open file maps.unused!\n");
2919 for (
auto map = found_maps.cbegin(); map != found_maps.cend(); ++map) {
2920 fprintf(dump,
"%s\n", *map);
2923 printf(
"%ld unused maps.\n", found_maps.size());
2929 char path[strlen(
root) + 150 + strlen(output_extensions[output_format])];
2931 gdImagePtr elevationmap;
2933 if (!world_exit_info)
2937 printf(
"Saving exit/blocking/road information...");
2938 snprintf(path,
sizeof(path),
"%s/%s%s",
root,
"world_info", output_extensions[output_format]);
2939 file = fopen(path,
"wb+");
2943 gdImageDestroy(infomap);
2946 if (elevation_min == 0 || elevation_max == 0) {
2947 puts(
"Error: Could not save elevation world map due to not finding any minimum or maximum elevation.");
2951 elevationmap = gdImageCreateTrueColor(30*50, 30*50);;
2953 for (x = 0; x < 30*50; x++) {
2954 for (y = 0; y < 30*50; y++) {
2955 gdImageSetPixel(elevationmap, x, y,
get_elevation_color(elevation_info[x][y], elevationmap));
2959 printf(
"Saving elevation world map...");
2960 snprintf(path,
sizeof(path),
"%s/%s%s",
root,
"world_elevation", output_extensions[output_format]);
2961 file = fopen(path,
"wb+");
2965 gdImageDestroy(elevationmap);
2966 elevationmap = NULL;
2993 printf(
"Crossfire Mapper will generate pictures of maps, and create indexes for all maps and regions.\n\n");
2994 printf(
"Syntax: %s\n\n", program);
2995 printf(
"Optional arguments:\n");
2996 printf(
" -nopics don't generate pictures.\n");
2997 printf(
" -root=<path> destination path. Default 'html'.\n");
2998 printf(
" -limit=<number> stop processing after this number of maps, -1 to do all maps (default).\n");
2999 printf(
" -showmaps outputs the name of maps as they are processed.\n");
3000 printf(
" -jpg[=quality] generate jpg pictures, instead of default png. Quality should be 0-95, -1 for automatic.\n");
3001 printf(
" -forcepics force to regenerate pics, even if pics's date is after map's.\n");
3002 printf(
" -addmap=<map> adds a map to process. Path is relative to map's directory root.\n");
3003 printf(
" -rawmaps generates maps pics without items on random (shop, treasure) tiles.\n");
3004 printf(
" -warnnopath inform when an exit has no path set.\n");
3005 printf(
" -listunusedmaps finds all unused maps in the maps directory.\n");
3006 printf(
" -noworldmap don't write the world map in world.png.\n");
3007 printf(
" -noregionslink don't generate regions relation file.\n");
3008 printf(
" -regionslink generate regions relation file.\n");
3009 printf(
" -noexitmap don't generate map of exits.\n");
3010 printf(
" -exitmap generate map of exits.\n");
3011 printf(
" -tileset=<number> use specified tileset to generate the pictures. Default 0 (standard).\n");
3012 printf(
" -details-quests list all quests steps. Default no.\n");
3013 printf(
" -list-system-quests include 'system' quests in quest list. Default no.\n");
3014 printf(
" -templates-dir=[dir] set the directory to get templates from. Default 'templates/'.\n");
3015 printf(
" -add-template=[file] add a template to process. May be specified multiple times. If empty, 'index.html' is used.\n");
3016 printf(
" -list-template-to-process display the name of the template about to be rendered. Useful for debugging.");
3035 while (arg < argc) {
3036 if (strcmp(argv[arg],
"-nopics") == 0)
3038 else if (strncmp(argv[arg],
"-root=", 6) == 0)
3039 strncpy(
root, argv[arg]+6, 500);
3040 else if (strncmp(argv[arg],
"-limit=", 7) == 0)
3041 map_limit = atoi(argv[arg]+7);
3042 else if (strcmp(argv[arg],
"-showmaps") == 0)
3044 else if (strcmp(argv[arg],
"-jpg") == 0) {
3046 if (argv[arg][4] ==
'=') {
3047 jpeg_quality = atoi(argv[arg]+5);
3048 if (jpeg_quality < 0)
3052 else if (strcmp(argv[arg],
"-forcepics") == 0)
3054 else if (strncmp(argv[arg],
"-addmap=", 8) == 0) {
3055 if (*(argv[arg]+8) ==
'/')
3056 strncpy(path, argv[arg]+8, 500);
3058 snprintf(path, 500,
"/%s", argv[arg]+8);
3061 else if (strcmp(argv[arg],
"-rawmaps") == 0)
3063 else if (strcmp(argv[arg],
"-warnnopath") == 0)
3065 else if (strcmp(argv[arg],
"-listunusedmaps") == 0)
3066 list_unused_maps = 1;
3067 else if (strcmp(argv[arg],
"-noworldmap") == 0)
3069 else if (strcmp(argv[arg],
"-noregionslink") == 0)
3070 do_regions_link =
false;
3071 else if (strcmp(argv[arg],
"-regionslink") == 0)
3072 do_regions_link =
true;
3073 else if (strcmp(argv[arg],
"-noexitmap") == 0)
3074 world_exit_info = 0;
3075 else if (strcmp(argv[arg],
"-exitmap") == 0)
3076 world_exit_info = 1;
3077 else if (strncmp(argv[arg],
"-tileset=", 9) == 0) {
3078 tileset = atoi(argv[arg]+9);
3080 }
else if (strcmp(argv[arg],
"-detail-quests") == 0) {
3082 }
else if (strcmp(argv[arg],
"-list-system-quests") == 0) {
3083 list_system_quests = 1;
3084 }
else if (strncmp(argv[arg],
"-templates-dir=", 15) == 0) {
3085 templates_root = argv[arg] + 15;
3086 }
else if (strncmp(argv[arg],
"-add-template=", 14) == 0) {
3087 templates.push_back(argv[arg] + 14);
3088 }
else if (strcmp(argv[arg],
"-list-template-to-process") == 0) {
3089 display_rendered_template = 1;
3090 }
else if (strncmp(argv[arg],
"-build-search-data", 18) == 0) {
3091 build_search_file =
true;
3097 strcpy(
root,
"html");
3103 if (templates_root.empty()) {
3104 templates_root =
"templates/";
3105 }
else if (templates_root[templates_root.length() - 1] !=
'/') {
3106 templates_root.append(
"/");
3116 strcpy(dummy,
root);
3117 strcat(dummy,
"/a");
3130 return (value ?
"yes" :
"no");
3134 size_t current_map = 0, i;
3145 printf(
"Initializing Crossfire data...\n");
3163 printf(
"\n\n done.\n\n");
3166 printf(
"Erreor: invalid tileset %d!\n", tileset);
3170 if (templates.empty()) {
3171 templates.push_back(
"index.html");
3177 if (map_limit != -1)
3178 snprintf(max,
sizeof(max),
"%d", map_limit);
3180 strcpy(max,
"(none)");
3181 printf(
"Crossfire map browser generator\n");
3182 printf(
"-------------------------------\n\n");
3183 printf(
"Parameters:\n");
3184 printf(
" path to write files: %s\n",
root);
3185 printf(
" maximum number of maps to process: %s\n", max);
3188 printf(
" picture output format: %s\n", output_extensions[output_format]);
3189 if (output_format ==
OF_JPG)
3190 printf(
" JPEG quality: %d\n", jpeg_quality);
3191 printf(
" show map being processed: %s\n",
yesno(show_maps));
3192 printf(
" generate raw maps: %s\n",
yesno(rawmaps));
3193 printf(
" warn of exit without path: %s\n",
yesno(warn_no_path));
3194 printf(
" list unused maps: %s\n",
yesno(list_unused_maps));
3195 printf(
" generate world map: %s\n",
yesno(world_map));
3196 printf(
" generate exit map: %s\n",
yesno(world_exit_info));
3197 printf(
" generate regions link file: %s\n",
yesno(do_regions_link));
3198 printf(
" tileset: %s\n",
find_faceset(tileset)->fullname);
3199 printf(
" detail quest steps: %s\n",
yesno(detail_quests));
3200 printf(
" list system quests: %s\n",
yesno(list_system_quests));
3201 printf(
" templates directory: %s\n", templates_root.c_str());
3202 printf(
" templates to process: ");
3203 const char *sep =
"";
3204 for (
auto f : templates) {
3205 printf(
"%s%s", sep, f.c_str());
3209 printf(
" display template to process: %s\n",
yesno(display_rendered_template));
3212 if (list_unused_maps) {
3213 printf(
"listing all maps...");
3215 printf(
"done, %ld maps found.\n", found_maps.size());
3219 infomap = gdImageCreateTrueColor(30*50, 30*50);
3220 color_unlinked_exit = gdImageColorResolve(infomap, 255, 0, 0);
3221 color_linked_exit = gdImageColorResolve(infomap, 255, 255, 255);
3222 color_road = gdImageColorResolve(infomap, 0, 255, 0);
3223 color_blocking = gdImageColorResolve(infomap, 0, 0, 255);
3224 color_slowing = gdImageColorResolve(infomap, 0, 0, 127);
3225 elevation_info = (
int **)calloc(50*30,
sizeof(
int *));
3226 for (i = 0; i < 50*30; i++)
3227 elevation_info[i] = (
int *)calloc(50*30,
sizeof(
int));
3231 printf(
"browsing maps...\n");
3235 while (current_map < maps_list.
count) {
3237 if (current_map%100 == 0) {
3238 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);
3240 if ((map_limit != -1) && (current_map == static_cast<size_t>(map_limit))) {
3241 printf(
" --- map limit reached, stopping ---\n");
3246 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);
3248 if (list_unused_maps)
3268 std::sort(system_quests.begin(), system_quests.end(), [] (
const auto &left,
const auto &right) {
return strcmp(left->quest_code, right->quest_code) < 0; });
3274 for (
auto file : templates) {
3275 if (!file.empty()) {
3280 const auto fullStart = time(
nullptr);
3281 printf(
"rendering pages...");
3282 if (display_rendered_template)
3286 while (!pages.empty()) {
3287 auto p = pages.back();
3289 if (p.param.empty())
3290 all_data.erase(
"param");
3292 all_data[
"param"] = p.param;
3293 const auto start = time(
nullptr);
3294 if (display_rendered_template) {
3295 printf(
" rendering page %s (%s)... ", p.template_name.c_str(), p.param.c_str());
3298 path_stack.push_back(p.output_name);
3300 env->write(temp, all_data, p.output_name);
3301 path_stack.pop_back();
3302 const auto elapsed = time(
nullptr) - start;
3303 if (display_rendered_template) {
3304 printf(
"took %ld seconds\n", elapsed);
3308 const auto elapsed = time(
nullptr) - fullStart;
3309 printf(
" done, took %ld seconds\n", elapsed);
3328 while ((invtmp->stats.hp--) > 0)
3330 invtmp->randomitems = NULL;
3334 && invtmp->type !=
SPELL 3335 && invtmp->type !=
CLASS 3341 invtmp->randomitems = NULL;
3354 if (tmp->type ==
WAND 3359 || tmp->type ==
ALTAR 3361 tmp->randomitems = NULL;
3367 while ((tmp->stats.hp--) > 0)
3369 tmp->randomitems = NULL;
3371 object *head =
HEAD(tmp);
3388 && tmp->type !=
SPELL 3390 && tmp->type !=
CLASS 3393 tmp->randomitems = NULL;
3406 #ifndef DOXYGEN_SHOULD_SKIP_THIS 3412 void draw_ext_info(
int,
int,
const object *, uint8_t, uint8_t,
const char *txt) {
3413 fprintf(
logfile,
"%s\n", txt);
3416 void draw_ext_info_format(
int,
int,
const object *, uint8_t, uint8_t,
const char *format, ...) {
3419 va_start(ap, format);
3420 vfprintf(
logfile, format, ap);
3425 fprintf(
logfile,
"ext_info_map: %s\n", str1);
struct_map_in_quest_list quests
void clean_tmp_files(void)
Save unique maps and clean up temporary map files unless recycling temporary maps.
static int list_unused_maps
If set, program will list maps found in directory but not linked from the first maps.
static event_registration c
static nlohmann::json all_data
All JSON data available to templates.
static struct_map_info * create_tiled_map(void)
Create a new tiled map and link it to the tiled map list.
char * slaying
Slaying value.
char first_map_path[MAX_BUF]
The start-level.
static int warn_no_path
Whether to warn of exits without a path.
static int dump(const std::set< std::string > &items, const char *name)
static size_t slaying_count
Count of items in slaying_info.
#define FLAG_DAMNED
The object is very cursed.
static nlohmann::json create_quest_object(struct_quest *quest, const std::string &key)
Return a JSON quest object.
#define FLAG_UNPAID
Object hasn't been paid for yet.
char * stringbuffer_finish(StringBuffer *sb)
Deallocate the string buffer instance and return the string.
#define FLAG_IS_LINKED
The object is linked with other objects.
struct_map_info * map
Linked map.
static std::string SearchName[int(SearchType::Count)]
Search names for types, for the JS search engine.
static std::map< region *, std::set< region * > > region_links
int8_t item_power
Power rating of the object.
static struct_quest * get_quest_info(const char *name)
Gets the information for a quest, create the field if needed.
int calc_item_power(const object *op)
This takes an object 'op' and figures out what its item_power rating should be.
struct archetype * arch
Pointer to archetype.
face_info * faces
images in this faceset
static int world_map
If set, will generate a world map.
static void process_map_lore(struct_map_info *map)
Extracts from the map's lore quest information if found.
Definition of an in-game quest.
static void write_tiled_map_page(struct_map_info *map)
Writes the page for a tiled map group.
FILE * logfile
Used by server/daemon.c.
static const char * remove_trailing_slash(const char *path)
region * get_region_by_map(mapstruct *m)
Gets a region from a map.
void esrv_send_item(object *pl, object *op)
Sends item's info to player.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
void init_readable(void)
Initialize linked lists utilized by message functions in tailor_readable_ob()
struct struct_map_in_quest ** list
static nlohmann::json generate_picture_link(inja::Arguments &args)
Return the link to the picture of the specified item.
static size_t region_allocated
Allocated size of regions.
struct_race_list monsters
int apply_auto(object *op)
Map was just loaded, handle op's initialization.
static void fix_exits_for_map(struct_map_info *current, struct_map_list *from, int is_from)
Changes for the list all maps to the tiled map they are part of, if applicable.
static int sort_struct_quest(const void *left, const void *right)
Sorts 2 struct_quest, on the map's name or path.
static enum output_format_type output_format
Selected output format.
struct_map_list maps[S_MAX]
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...) PRINTF_ARGS(6
static void generate_picture_path(const char *path, size_t pic_size, char *out, size_t len)
static std::vector< std::string > split(const std::string &field, const std::string &by)
std::string output_name
Output file name.
struct_map_list tiled_maps
static void init_renderer_env()
Initialize env and set various callbacks and options.
static int elevation_max
Lowest elevation found.
#define FLAG_FRIENDLY
Will help players.
#define FLAG_IS_FLOOR
Can't see what's underneath this object.
archetype * find_archetype(const char *name)
static std::string path_from_current(const std::string &path)
Compute the relative path from the specified file to the current file.
char * name
Quest's name.
void object_remove(object *op)
This function removes the object op from the linked list of objects which it is currently tied to...
void init_library(void)
It is vital that init_library() is called by any functions using this library.
size_t allocated
Allocated space.
static struct_equipment * ensure_unique(struct_equipment *item)
Searches the item list for an identical item, except maps.
#define HUGE_BUF
Used for messages - some can be quite long.
void esrv_update_item(int flags, object *pl, object *op)
Updates object *op for player *pl.
static struct_map_info * get_map_info(const char *path)
Gets or creates if required the info structure for a map.
sstring slaying
Which race to do double damage to.
sstring add_string(const char *str)
Share a string.
#define MAP_HEIGHT(m)
Map height.
static int get_elevation_color(int elevation, gdImagePtr elevationmap)
Gets the color for an elevation.
static std::set< std::string > reset_groups
All defined reset groups.
struct_map_info * mainmap
Map defining the quest.
std::vector< region * > all_regions
struct_map_in_quest_list maps
Maps part of this quest.
DIR * opendir(const char *)
Object for applying character class modifications to someone.
void make_path_to_file(const char *filename)
Checks if any directories in the given path doesn't exist, and creates if necessary.
void quest_for_each(quest_op op, void *user)
Iterate over all quests.
int get_face_fallback(int faceset, uint16_t imageno)
This returns the set we will actually use when sending a face.
static nlohmann::json create_npc_array(npc_list &list)
Return an array of NPC information.
int16_t y
Position in the map for this object.
static int elevation_min
Maximal elevation found.
#define FREE_OBJ_NO_DESTROY_CALLBACK
Do not run the destroy callback.
static const char * output_extensions[]
Extensions depending on output format.
face_sets * find_faceset(int id)
char * description
Description, from the main map's lore.
int count
Number found on map.
int number
Unique quest identifier.
uint32_t reset_time
Server time when map gets reset, seconds since epoch.
MoveType move_block
What movement types this blocks.
StringBuffer * stringbuffer_new(void)
Create a new string buffer.
LogLevel debug
Default debugging level.
static const char * yesno(int value)
Helper to write yes/no.
static void fix_map_names(void)
Ensures all maps have a name (if there was a limit to map processing, some maps will have a NULL name...
const char * name
NPC's name.
static int color_slowing
Slows movement.
Global type definitions and header inclusions.
void init_globals(void)
Initialises all global variables.
const char * message
NPC's message.
static void add_map_to_quest(struct_map_info *map, const char *name, const char *description)
Links a map to a quest.
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Sends message to player(s).
char * longname
Official title of the region, this might be defined to be the same as name.
struct struct_quest * quest
Point back to the quest.
peterm: detector is an object which notices the presense of another object and is triggered like butt...
static int color_road
Road or equivalent.
static void fill_json(nlohmann::json &json)
Add all global variables to the data available to templates.
static struct_map_info * create_map_info(void)
Returns an initialised struct_map_info.
One special item (weapon, shield, ...).
static nlohmann::json create_map_object(struct_map_info *map, const std::string &key)
Return a JSON map object.
static std::shared_ptr< inja::Environment > env
Rendering environment.
static void append_map_list(struct_map_list &dest, struct_map_list &src)
Append the contents of src to dest.
static const int num_sizes
static int world_exit_info
If set, will generate a world map of exits.
#define MOVE_ALL
Mask of all movement types.
void esrv_del_item(player *pl, object *ob)
Tells the client to delete an item.
static bool detail_quests
Whether to show all quests details or not.
static std::map< struct_map_info *, std::string > reverse_maps
Link between a map and its unique identifier.
#define MAP_IN_MEMORY
Map is fully loaded.
int16_t level
Level of creature or object.
static size_t slaying_allocated
Allocated size of slaying_info.
static void check_equipment(object *item, struct_map_info *map)
Checks if item and its inventory are worthy to be listed.
void object_free(object *ob, int flags)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
#define FREE_OBJ_FREE_INVENTORY
Free inventory objects; if not set, drop inventory.
sstring reset_group
For reset purpose, all maps in the same group reset at the same time.
SearchType
Search values, for the JS search engine.
static struct struct_region_info ** regions
Found regions.
Link between a quest and a map.
int8_t fallback
Whether, in the event of a region not existing, this should be the one we fall back on as the default...
void create_treasure(treasurelist *t, object *op, int flag, int difficulty, int tries)
This calls the appropriate treasure creation function.
object * identify(object *op)
Identifies an item.
The archetype structure is a set of rules on how to generate and manipulate objects which point to ar...
void object_get_multi_size(const object *ob, int *sx, int *sy, int *hx, int *hy)
Computes the size of a multitile object.
Image-related structures.
static void free_equipment(struct_equipment *equip)
Frees a struct_equipment.
static std::vector< gdImagePtr > gdfaces
static std::vector< pageToRender > pages
List of pages to render.
sstring name
More definite name, like "generate_kobold".
static int show_maps
If set, will generate much information on map loaded.
static std::vector< quest_definition * > system_quests
region * get_region_struct(void)
Allocates and zeros a region struct, this isn't free()'d anywhere, so might be a memory leak...
static void merge_tiled_maps(struct_map_info *map, struct_map_info *tiled_map)
Merge two tiled maps groups.
void account_logout(const char *account_name)
Remove 'account_name' from the list of logged in accounts.
static void define_quest(const char *name, struct_map_info *mainmap, const char *description)
Sets the main map for a quest.
object * arch_to_object(archetype *at)
Creates and returns a new object which is a copy of the given archetype.
static int is_blocking(object *item)
Checks if item blocks movement or not.
char path[HUGE_BUF]
Filename of the map.
static nlohmann::json create_race_array(struct_race_list &list)
Return an array of monster information.
object * env
Pointer to the object which is the environment.
uint8_t * data
Image data.
One page to render, with its parameters.
static nlohmann::json create_map_in_quest_array(struct_map_in_quest_list &list)
Return an array of map-in-quest items.
#define FLAG_UNAGGRESSIVE
Monster doesn't attack players.
#define QUERY_FLAG(xyz, p)
const artifact * find_artifact(const object *op, const char *name)
Searches and returns a specific artifact compatible with an object, NULL if not found.
static void check_slaying_inventory(struct_map_info *map, object *item)
Recursively checks if the object should be considered for slaying information.
static struct_map_list maps_list
Maps to process or found.
static nlohmann::json create_maps_array(struct_map_list &maps)
Return an array of map identifiers.
bool quest_is_system
If set then the quest isn't counted or listed.
void give_artifact_abilities(object *op, const object *artifact)
Fixes the given object, giving it the abilities and titles it should have due to the second artifact-...
struct struct_map_info * tiled_group
void account_char_save(Account_Chars *chars)
Saves the character information for the given account.
void object_give_identified_properties(object *op)
Ensure op has all its "identified" properties set.
static int created_pics
Picture statistics.
Information about a NPC with a custom message.
int strcasecmp(const char *s1, const char *s2)
void object_free_drop_inventory(object *ob)
Frees everything allocated by an object, removes it from the list of used objects, and puts it on the list of free objects.
#define FLAG_IDENTIFIED
Item is identifiable (e.g.
static int color_blocking
Block all movement.
#define FOR_INV_FINISH()
Finishes FOR_INV_PREPARE().
static int rawmaps
Whether to generate raw pics or instancied ones.
sstring msg
If this is a book/sign/magic mouth/etc.
int is_world
If set, this region has at least one map part of the world, thus region name should be written...
char * name
Monster's name.
char * name
Shortend name of the region as maps refer to it.
object * head
Points to the main object of a large body.
SockList * player_get_delayed_buffer(player *pl)
Get a delayed socket buffer, that will be sent after the player's tick is complete.
struct struct_map_info * tiles[4]
static void create_destination(void)
Ensures destination directory exists.
static void add_map_to_region(struct_map_info *map, region *reg)
Links a map to a region.
static void do_tiled_map_picture(struct_map_info *map)
Generates the large and small pictures for a tiled map.
static struct_slaying_info ** slaying_info
Found slaying fields.
std::vector< struct_npc_info * > npc_list
List of NPCs with a custom message.
int main(int argc, char **argv)
int power
Item power as declared by the item itself.
static int jpeg_quality
Quality for jpg pictures.
static int force_pics
To force picture regeneration even if map didn't change.
char * name
Item's name.
size_t count
Number of races.
#define FLAG_IS_A_TEMPLATE
Object has no ingame life until instantiated.
static bool do_regions_link
static int is_slaying(object *item)
Is the slaying field relevant for this item?
static void process_map(struct_map_info *info)
Processes a map.
char * tile_path[4]
Path to adjoining maps.
static int sort_slaying(const void *left, const void *right)
Helper function to sort an array of struct_slaying_info.
static void add_race_to_list(struct_race *race, struct_race_list *list, int check)
Appends a race to a race list.
char * maplore
Map lore information.
static std::vector< std::string > path_stack
Path, relative to output root, of pages being generated.
#define S_DOOR
Connection/slaying information.
static void write_world_map(void)
Generates a big world map.
static int generate_pics
Whether to generate the picture or not.
struct Settings settings
Global settings.
static inja::TemplateStorage templateCache
static const char * ignore_path[]
Directories to ignore for map search.
static void init_struct_map_in_quest_list(struct_map_in_quest_list *list)
static gdImagePtr infomap
World map with exits / roads / blocking / ...
char * path_combine_and_normalize(const char *src, const char *dst, char *path, size_t size)
Combines the 2 paths.
static int sort_struct_map_in_quest(const void *left, const void *right)
Sorts 2 struct_map_in_quest, on the map's name or path.
static int quests_allocated
Allocated items in quests.
static std::vector< struct_equipment * > special_equipment
Special equipment list.
std::string template_name
Template name to use.
#define HEAD(op)
Returns the head part of an object.
void emergency_save(int flag)
Save all players.
living stats
Str, Con, Dex, etc.
#define MAX_BUF
Used for all kinds of things.
void add_template_to_render(const std::string &template_name, const std::string &output_name, const std::string ¶m)
Push the specified template, with optional param, on the list of files to process.
static struct_slaying_info * get_slaying_struct(const char *slaying)
Returns a struct_slaying_info for specified slaying.
static struct_map_list tiled_map_list
Pseudo-maps grouping other maps.
static struct_race_list races
Monsters found in maps.
void delete_map(mapstruct *m)
Frees the map, including the mapstruct.
static void add_region_link(mapstruct *source, mapstruct *dest)
Creates a link between two maps if they are on different regions.
static void write_world_info(void)
Writes the exit information world map.
char * filename
Filename of the map.
Structure handling character information for an account.
struct mapstruct * map
Pointer to the map in which this object is present.
static std::string templates_root("templates/")
Directory to get templates from, with a leading /.
char * description
Description associated with the map for the quest.
void command_help(object *op, const char *params)
Player is asking for some help.
static int map_limit
Maximum number of maps to browse, -1 for all.
uint32_t in_memory
Combination of IN_MEMORY_xxx flags.
static int sort_map_info(const void *left, const void *right)
Sorts the struct_map_info according to the map name or the path if equal.
struct_map_list maps_list
Maps in the region.
void move_firewall(object *op)
Move for FIREWALL.
static void add_to_struct_map_in_quest_list(struct_map_in_quest_list *list, struct_map_in_quest *item)
#define FOR_MAP_FINISH()
Finishes FOR_MAP_PREPARE().
MoveType move_slow
Movement types this slows down.
char * diff
Result of get_ob_diff() with the item's clone.
#define FLAG_CURSED
The object is cursed.
const char * datadir
Read only data files.
static void add_monster(object *monster, struct_map_info *map)
Adds a monster to the monster list.
int is_valid_faceset(int fsn)
Checks specified faceset is valid.
struct treasurelist * randomitems
Items to be generated.
static struct_npc_info * create_npc_info(const object *npc)
Create the struct_npc_info from the specified NPC.
static void add_map_to_slaying(struct_slaying_info *info, int item, struct_map_info *map)
Adds the specified map to the slaying information if not already present.
static struct_map_info * find_map_by_key(const std::string &key)
Get the map with the specified key, nullptr if not found.
static void quest_callback(const quest_definition *quest, void *)
static int cached_pics
Non recreated pics.
sstring name_pl
The plural name of the object.
#define FLAG_AUTO_APPLY
Will be applied when created.
static int tileset
Tileset to use to generate pics.
static void find_maps(const char *from)
Recursively find all all maps in a directory.
static int is_road(object *item)
Checks if object is considered a road or not.
Account_Chars * account_char_load(const char *account_name)
For a given account name, load the character information and return it.
static inja::Template get_template(const std::string &filename)
static std::set< std::string > rendered_templates
List of generated files, to not generate multiple times.
static event_registration m
static int color_linked_exit
Exit leading to another map.
char * create_pathname(const char *name, char *buf, size_t size)
Get the full path to a map file.
static bool sort_equipment(const struct_equipment *l, const struct_equipment *r)
Sort 2 struct_equipment.
object * generate_treasure(treasurelist *t, int difficulty)
Generate a treasure from a list generating a single item.
static nlohmann::json create_region_array(const std::set< region *> ®ions)
Return an array of region identifiers.
uint16_t datalen
Length of data.
struct struct_race ** races
Races on the list.
sstring name
The name of the object, obviously...
static struct_race * get_race(const char *name)
Returns the race for specified name.
sstring title
Of foo, etc.
#define MAP_WIDTH(m)
Map width.
static void fix_tiled_map_monsters(void)
Makes all monsters point to tiled maps instead of map when appliable, and merge map monster to tiled ...
uint32_t nrof
Number of objects.
static struct_quest * find_quest_info(const char *name)
Gets the information for a quest if it exists.
const char * mapdir
Where the map files are.
static void do_exit_map(mapstruct *map)
Proceses exit / road / blocking information for specified map into the global infomap map...
static void init_race_list(struct_race_list *list)
Blanks a struct_race_list.
Utility structure to group map-quest link structure.
char * msg
The description of the region.
#define CLEAR_FLAG(xyz, p)
uint8_t type
PLAYER, BULLET, etc.
void account_char_free(Account_Chars *chars)
This frees all data associated with the character information.
struct dirent * readdir(DIR *)
static std::map< region *, std::string > reverse_regions
Link between a region and its unique identifier.
void get_ob_diff(StringBuffer *sb, const object *op, const object *op2)
Returns a pointer to a static string which contains all variables which are different in the two give...
void object_update_speed(object *op)
Updates the speed of an object.
void init_gods(void)
This takes a look at all of the archetypes to find the objects which correspond to the GODS (type GOD...
static std::vector< std::string > templates
List of template files to start processing from.
void apply_auto_fix(mapstruct *m)
Go through the entire map (only the first time when an original map is loaded) and performs special a...
int calc_power
Item power calculated via calc_item_power().
static void do_help(const char *program)
Prints usage information, and exit.
static void relative_path(const char *from, const char *to, char *result)
Computes the shortest path from one file to another.
static void dump_unused_maps(void)
Writes the list of unused maps, maps found in the directories but not linked from the other maps...
std::string param
Optional template parameter.
static int tiled_map_need_pic(struct_map_info *map)
static int sort_region(const void *left, const void *right)
Sorts an array of struct_region_info by region name.
static size_t region_count
Count of regions.
static bool build_search_file
If set, will build the 'search_data.js' file.
static const char * ignore_name[]
File names to ignore for map search.
static void do_parameters(int argc, char **argv)
Handles command-line parameters.
static bool list_system_quests
Whether to show 'system' quests or not.
static region * find_region_by_key(const std::string &key)
Get the region with the specified key, nullptr if not found.
#define FLAG_MONSTER
Will attack players.
static void fill_reverse_maps(struct_map_list &list)
Fill the reverse_maps array with the provided list.
output_format_type
Map output formats.
void dragon_ability_gain(object *who, int atnr, int level)
When a dragon-player gains a new stage of evolution, he gets some treasure.
static void init_map_list(struct_map_list *list)
Initialises a list structure.
char * name
Map's name as defined in the map file.
static void write_pictures_from_real_size(const char *path, gdImagePtr real, int width, int height)
#define FOR_MAP_PREPARE(map_, mx_, my_, it_)
Constructs a loop iterating over all objects of a map tile.
struct struct_map_info ** maps
static void add_slaying(struct_map_info *map, object *item)
Adds the item's information to the map.
static void list_map(const char *path)
Marks specified path as processed.
static int quests_count
Count of quests.
struct_map_list origin
Maps to find said monster.
One monster race in the maps.
A buffer that will be expanded as content is added to it.
void rod_adjust(object *rod)
Adjusts rod attributes.
uint16_t difficulty
What level the player should be to play here.
static void write_tiled_maps(void)
Outputs all tiled map pages.
void set_darkness_map(mapstruct *m)
Set the darkness level for a map, based on the time of the day.
void esrv_update_spells(player *pl)
This looks for any spells the player may have that have changed their stats.
static void fix_tiled_map(void)
Ensures all tiled maps have a name, a region, a filename and a path.
int sum
Sum of locations, to compute name position.
object * find_skill_by_number(object *who, int skillno)
This returns the first skill pointer of the given subtype (the one that accumulates exp...
Contains the base information we use to make up a packet we want to send.
object * object_insert_in_ob(object *op, object *where)
This function inserts the object op in the linked list inside the object environment.
object * object_insert_in_map_at(object *op, mapstruct *m, object *originator, int flag, int x, int y)
Same as object_insert_in_map() except it handle separate coordinates and do a clean job preparing mul...
static int pics_allocated
Number of created pictures for GD.
struct_map_list origin
Map(s) this item is found in.
static struct_equipment * get_equipment(void)
Gets an empty struct_equipment.
static nlohmann::json generate_page_and_link(inja::Arguments &args)
Create a link to a page, generating it if needed.
#define FLAG_NO_PICK
Object can't be picked up.
mapstruct * ready_map_name(const char *name, int flags)
Makes sure the given map is loaded and swapped in.
static bool display_rendered_template
Whether to display the template to be rendered or not.
static std::vector< char * > found_maps
Maps found in directories.
static std::unordered_map< std::string, mapzone * > maps
All defined maps, with the path as key.
void void ext_info_map(int color, const mapstruct *map, uint8_t type, uint8_t subtype, const char *str1)
Writes to everyone on the specified map.
#define tolower(C)
Simple macro to convert a letter to lowercase.
static struct_quest ** quests
All quests in the game.
struct_map_list exits_from
static void add_map(struct_map_info *info, struct_map_list *list)
Adds a map to specified array, if it isn't already.
This is one artifact, ie one special item.
Information about one face set.
player * find_player_partial_name(const char *plname)
Find a player by a partial name.
static int color_unlinked_exit
Color for exits without a path set.
sstring artifact
If set, the item is the artifact with this name and the matching type.
static void fix_exits_to_tiled_maps(void)
Changes all exits to maps in a tiled map to point directly to the tiled map.
object clone
An object from which to do object_copy()
static void add_one_item(object *item, struct_map_info *map)
Adds an item to the list of special items.
static int is_special_equipment(object *item)
#define HAS_RANDOM_ITEMS(op)
This return TRUE if object has still randomitems which could be expanded.
static void save_picture(FILE *file, gdImagePtr pic)
Saves a map to a file, based on jpg/png settings.
#define FOR_INV_PREPARE(op_, it_)
Constructs a loop iterating over the inventory of an object.
static int sort_race(const void *a, const void *b)
Sort 2 struct_race.
char * name
Name of map as given by its creator.
static int ** elevation_info
All elevation spots in the "world_" maps.
object * item
Special values of the artifact.
void do_auto_apply(mapstruct *m)
char * path
Full path of the map from the start directory.
static char root[500]
Path to store generated files.
static void add_npc_to_map(npc_list *list, const object *npc)
Add the specified NPC to the list.
int y
Coordinates in the map.
static int compare_map_info(const struct_map_info *left, const struct_map_info *right)
Compares struct_map_info according to the map name or the path if equal.