39 #define ERR_NG LOG_STREAM(err, log_mapgen)
40 #define LOG_NG LOG_STREAM(info, log_mapgen)
73 size_t iterations,
size_t hill_size,
74 size_t island_size,
size_t island_off_center)
78 size_t center_x = width/2;
79 size_t center_y = height/2;
81 LOG_NG <<
"off-centering...\n";
83 if(island_off_center != 0) {
86 center_x += island_off_center;
89 center_y += island_off_center;
92 if(center_x < island_off_center)
95 center_x -= island_off_center;
98 if(center_y < island_off_center)
101 center_y -= island_off_center;
106 for(
size_t i = 0;
i != iterations; ++
i) {
119 bool is_valley =
false;
121 int x1 = island_size > 0 ? center_x - island_size + (
rng_()%(island_size*2)) :
123 int y1 = island_size > 0 ? center_y - island_size + (
rng_()%(island_size*2)) :
127 if(island_size != 0) {
128 const size_t diffx = abs(x1 -
int(center_x));
129 const size_t diffy = abs(y1 -
int(center_y));
130 const size_t dist = size_t(std::sqrt(
double(diffx*diffx + diffy*diffy)));
131 is_valley = dist > island_size;
134 const int radius =
rng_()%hill_size + 1;
136 const int min_x = x1 - radius > 0 ? x1 - radius : 0;
137 const int max_x = x1 + radius < static_cast<long>(res.size()) ? x1 + radius : res.size();
138 const int min_y = y1 - radius > 0 ? y1 - radius : 0;
139 const int max_y = y1 + radius < static_cast<long>(res.front().size()) ? y1 + radius : res.front().size();
141 for(
int x2 = min_x; x2 < max_x; ++x2) {
142 for(
int y2 = min_y; y2 < max_y; ++y2) {
143 const int xdiff = (x2-x1);
144 const int ydiff = (y2-y1);
146 const int height = radius -
int(std::sqrt(
double(xdiff*xdiff + ydiff*ydiff)));
150 if(height > res[x2][y2]) {
164 int heighest = 0, lowest = 100000,
x;
165 for(
x = 0; size_t(
x) != res.size(); ++
x) {
166 for(
int y = 0; size_t(
y) != res[
x].size(); ++
y) {
167 if(res[
x][
y] > heighest)
168 heighest = res[
x][
y];
170 if(res[
x][
y] < lowest)
177 for(
x = 0; size_t(
x) != res.size(); ++
x) {
178 for(
int y = 0; size_t(
y) != res[
x].size(); ++
y) {
182 res[
x][
y] /= heighest;
200 if(x < 0 || y < 0 ||
size_t(x) >= terrain.size() || size_t(y) >= terrain.front().size() || lake_fall_off < 0) {
204 unsigned int ulake_fall_off = lake_fall_off;
208 if((
rng_()%100) < ulake_fall_off) {
212 if((
rng_()%100) < ulake_fall_off) {
216 if((
rng_()%100) < ulake_fall_off) {
220 if((
rng_()%100) < ulake_fall_off) {
247 struct for_randomshuffle
249 for_randomshuffle(boost::random::mt19937& rng) : rng_(rng) {}
250 boost::random::mt19937& rng_;
256 std::set<location>& seen_locations,
int river_uphill)
258 const bool on_map = x >= 0 && y >= 0 &&
260 y < static_cast<long>(heights.back().size());
262 if(on_map && !river.empty() && heights[
x][
y] >
263 heights[river.back().x][river.back().y] + river_uphill) {
272 LOG_NG <<
"generating river...\n";
275 for(std::vector<location>::const_iterator
i = river.begin();
276 i != river.end(); ++
i) {
280 LOG_NG <<
"done generating river\n";
288 int items[6] = {0,1,2,3,4,5};
289 for_randomshuffle shufflehelper(
rng_);
290 std::random_shuffle(items, items + 4, shufflehelper);
293 seen_locations.insert(current_loc);
294 river.push_back(current_loc);
295 for(
int a = 0;
a != 6; ++
a) {
297 if(seen_locations.count(loc) == 0) {
313 std::vector<location> river;
314 std::set<location> seen_locations;
329 const int side =
rng_()%4;
332 const int y = side == 0 ? 0 : height-1;
336 const int x = side == 2 ? 0 : width-1;
355 map.resize(end_x - begin_x);
356 for(
size_t y = begin_y;
y != end_y; ++
y) {
357 for(
size_t x = begin_x;
x != end_x; ++
x) {
358 if((
y - begin_y) == 0){
359 map[
x - begin_x].resize(end_y - begin_y);
361 map[
x - begin_x][
y - begin_y] = terrain[
x][
y];
367 for (
auto it = starting_positions.left.begin(); it != starting_positions.left.end(); ++it) {
386 windiness_(
std::max<
int>(1, cfg[
"road_windiness"].to_int())),
392 virtual double cost(
const location& loc,
const double so_far)
const;
400 mutable std::map<t_translation::t_terrain, double>
cache_;
403 double road_path_calculator::cost(
const location& loc,
407 if (loc.
x < 0 || loc.
y < 0 || loc.
x >= static_cast<long>(
map_.size()) ||
408 loc.
y >= static_cast<long>(
map_.front().size())) {
420 double windiness = 1.0;
422 if (windiness_ > 1) {
424 unsigned int a = (loc.
x + 92872973) ^ 918273;
425 unsigned int b = (loc.
y + 1672517) ^ 128123;
426 unsigned int c = a*b + a + b + seed_;
427 unsigned int random = c*
c;
431 int noise = random % (windiness_ * 137) / 137;
436 const std::map<t_translation::t_terrain, double>::const_iterator
itor =
cache_.find(c);
437 if(itor !=
cache_.end()) {
438 return itor->second*windiness;
443 double res = getNoPathValue();
444 if (
const config &child = cfg_.
find_child(
"road_cost",
"terrain", terrain)) {
445 res = child[
"cost"].to_double();
448 cache_.insert(std::pair<t_translation::t_terrain, double>(c,res));
449 return windiness*
res;
456 bool operator()(
int x,
int y)
const;
464 :
map_(map), terrain_(terrain_list)
467 bool is_valid_terrain::operator()(
int x,
int y)
const
475 return std::find(terrain_.begin(),terrain_.end(),
map_[
x][
y]) != terrain_.end();
481 size_t min_distance,
const std::vector<map_location>& other_castles,
int highest_ranking)
485 size_t avg_distance = 0, lowest_distance = 1000;
487 for(std::vector<map_location>::const_iterator c = other_castles.begin(); c != other_castles.end(); ++
c) {
493 if(distance < lowest_distance) {
494 lowest_distance = distance;
497 if(distance < min_distance) {
502 avg_distance += distance;
505 if(other_castles.empty() ==
false) {
506 avg_distance /= other_castles.size();
509 for(
int i = x-1;
i <= x+1; ++
i) {
510 for(
int j = y-1; j <= y+1; ++j) {
511 if(!valid_terrain(
i,j)) {
517 const int x_from_border = std::min<int>(x - min_x,max_x -
x);
518 const int y_from_border = std::min<int>(y - min_y,max_y -
y);
520 const int border_ranking = min_distance - std::min<int>(x_from_border,y_from_border) +
521 min_distance - x_from_border - y_from_border;
523 int current_ranking = border_ranking*2 + avg_distance*10 + lowest_distance*10;
524 static const int num_nearby_locations = 11*11;
526 const int max_possible_ranking = current_ranking + num_nearby_locations;
528 if(max_possible_ranking < highest_ranking) {
529 return current_ranking;
532 int surrounding_ranking = 0;
534 for(
int xpos = x-5; xpos <= x+5; ++xpos) {
535 for(
int ypos = y-5; ypos <= y+5; ++ypos) {
536 if(valid_terrain(xpos,ypos)) {
537 ++surrounding_ranking;
542 return surrounding_ranking + current_ranking;
548 const size_t x,
const size_t y,
const size_t radius,
const config& cfg,
549 tcode_list_cache &adj_liked_cache)
552 std::set<map_location> locs;
556 for(std::set<map_location>::const_iterator
i = locs.begin();
557 i != locs.end(); ++
i) {
559 if(
i->x < 0 ||
i->y < 0 ||
i->x >= static_cast<long>(map.size()) ||
560 i->y >= static_cast<long>(map[
i->x].size())) {
570 if (l != adj_liked_cache.end()) {
571 adjacent_liked = &(l->second);
574 adjacent_liked = &(adj_liked_cache[
t]);
577 int rating = child[
"rating"];
580 for(
size_t n = 0;
n != 6; ++
n) {
581 if(adj[
n].x < 0 || adj[
n].y < 0 ||
582 adj[
n].x >= static_cast<long>(map.size()) ||
583 adj[
n].y >= static_cast<long>(map[adj[
n].x].
size())) {
589 rating +=
std::count(adjacent_liked->begin(),adjacent_liked->end(),t2);
592 if(rating > best_rating) {
594 best_rating = rating;
606 if(!options.empty() && name_generator !=
nullptr) {
607 const size_t choice =
rng_()%options.size();
608 LOG_NG <<
"calling name generator...\n";
610 LOG_NG <<
"name generator returned '" << name <<
"'\n";
611 if(base_name !=
nullptr) {
615 LOG_NG <<
"assigned base name..\n";
617 if(additional_symbols ==
nullptr) {
618 additional_symbols = &
table;
621 LOG_NG <<
"got additional symbols\n";
623 (*additional_symbols)[
"name"] =
name;
624 LOG_NG <<
"interpolation variables into '" << options[choice] <<
"'\n";
635 size_t label_count, std::map<map_location,std::string>* labels,
const std::string& full_name) {
640 for (n = 0; n < 6; n++) {
643 if (
unsigned(adj[n].x) >= width / 3 ||
unsigned(adj[n].y) >= height / 3) {
648 const location loc(adj[n].x, adj[n].y);
650 tile_names.insert(std::pair<location, std::string>(loc, name));
652 if (label_count % 6 == 0) {
653 labels->insert(std::pair<map_location, std::string>(loc, full_name));
656 flood_name(adj[n], name, tile_names, tile_types, terrain, width, height, label_count++, labels, full_name);
671 class terrain_height_mapper
674 explicit terrain_height_mapper(
const config& cfg);
676 bool convert_terrain(
const int height)
const;
684 terrain_height_mapper::terrain_height_mapper(
const config& cfg) :
685 terrain_height(cfg[
"height"]),
694 bool terrain_height_mapper::convert_terrain(
const int height)
const
696 return height >= terrain_height;
704 class terrain_converter
707 explicit terrain_converter(
const config& cfg);
713 int min_temp, max_temp, min_height, max_height;
718 terrain_converter::terrain_converter(
const config& cfg)
719 : min_temp(cfg[
"min_temperature"].to_int(-100000))
720 , max_temp(cfg[
"max_temperature"].to_int(100000))
721 , min_height(cfg[
"min_height"].to_int(-100000))
722 , max_height(cfg[
"max_height"].to_int(100000))
733 const int height,
const int temperature)
const
735 return std::find(from.begin(),from.end(),
terrain) != from.end() && height >= min_height && height <= max_height &&
747 size_t iterations,
size_t hill_size,
748 size_t max_lakes,
size_t nvillages,
size_t castle_size,
size_t nplayers,
bool roads_between_castles,
749 std::map<map_location,std::string>* labels,
const config& cfg)
754 VALIDATE(
is_even(width),
_(
"Random maps with an odd width aren't supported."));
756 int ticks = SDL_GetTicks();
775 LOG_NG <<
"generating height map...\n";
778 LOG_NG <<
"done generating height map...\n";
779 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
783 std::map<map_location,std::string>* misc_labels = naming.
empty() ?
nullptr : labels;
788 if(!name_generator->is_valid()) {
789 name_generator.reset();
793 "[naming]male_names is deprecated, use names instead");
794 if(!markov_list.
blank()) {
798 std::vector<terrain_height_mapper> height_conversion;
801 height_conversion.push_back(terrain_height_mapper(
h));
806 for(x = 0; x != heights.size(); ++
x) {
807 for(y = 0; y != heights[
x].size(); ++
y) {
808 for(std::vector<terrain_height_mapper>::const_iterator
i = height_conversion.begin();
809 i != height_conversion.end(); ++
i) {
810 if(
i->convert_terrain(heights[x][y])) {
811 terrain[
x][
y] =
i->convert_to();
820 LOG_NG <<
"placed land forms\n";
821 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
836 std::set<location> lake_locs;
838 std::map<location, std::string> river_names, lake_names, road_names, bridge_names, mountain_names, forest_names, swamp_names;
840 const size_t nlakes = max_lakes > 0 ? (
rng_()%max_lakes) : 0;
841 for(
size_t lake = 0; lake != nlakes; ++lake) {
842 for(
int tries = 0; tries != 100; ++tries) {
845 if (heights[x][y] > cfg[
"min_lake_height"].to_int()) {
847 terrain, x, y, cfg[
"river_frequency"]);
849 if(river.empty() ==
false && misc_labels !=
nullptr) {
851 LOG_NG <<
"generating name for river...\n";
853 LOG_NG <<
"named river '" << name <<
"'\n";
854 size_t name_frequency = 20;
855 for(std::vector<location>::const_iterator
r = river.begin();
r != river.end(); ++
r) {
859 if(((
r - river.begin())%name_frequency) == name_frequency/2) {
860 misc_labels->insert(std::pair<map_location,std::string>(loc,name));
863 river_names.insert(std::pair<location,std::string>(loc,base_name));
866 LOG_NG <<
"put down river name...\n";
869 LOG_NG <<
"generating lake...\n";
870 std::set<location> locs;
871 bool res =
generate_lake(terrain, x, y, cfg[
"lake_size"], locs);
872 if(res && misc_labels !=
nullptr) {
873 bool touches_other_lake =
false;
878 std::set<location>::const_iterator
i;
882 for(i = locs.begin(); i != locs.end(); ++
i) {
883 if(lake_locs.count(*i) != 0) {
884 touches_other_lake =
true;
887 const location loc(i->x-width/3,i->y-height/3);
888 const std::map<location,std::string>::const_iterator other_name = lake_names.find(loc);
889 if(other_name != lake_names.end()) {
890 base_name = other_name->second;
894 lake_locs.insert(*i);
897 if(!touches_other_lake) {
899 misc_labels->erase(loc);
900 misc_labels->insert(std::pair<map_location,std::string>(loc,name));
903 for(i = locs.begin(); i != locs.end(); ++
i) {
904 const location loc(i->x-width/3,i->y-height/3);
905 lake_names.insert(std::pair<location, std::string>(loc, base_name));
914 LOG_NG <<
"done generating rivers...\n";
915 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
917 const size_t default_dimensions = 40*40*9;
928 cfg[
"temperature_iterations"].to_int() * width * height / default_dimensions,
929 cfg[
"temperature_size"], 0, 0);
931 LOG_NG <<
"generated temperature map...\n";
932 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
934 std::vector<terrain_converter> converters;
936 converters.push_back(terrain_converter(cv));
939 LOG_NG <<
"created terrain converters\n";
940 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
945 for(x = 0; x !=
width; ++
x) {
947 for(std::vector<terrain_converter>::const_iterator
i = converters.begin();
i != converters.end(); ++
i) {
948 if(
i->convert_terrain(terrain[x][y],heights[x][y],temperature_map[x][y])) {
949 terrain[
x][
y] =
i->convert_to();
956 LOG_NG <<
"placing villages...\n";
957 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
964 std::set<location> villages;
966 LOG_NG <<
"placing castles...\n";
970 if (!castle_config) {
971 LOG_NG <<
"Could not find castle configuration\n";
993 std::vector<location> castles;
994 std::set<location> failed_locs;
996 for(
size_t player = 0; player != nplayers; ++player) {
997 LOG_NG <<
"placing castle for " << player <<
"\n";
999 const int min_x = width/3 + 3;
1000 const int min_y = height/3 + 3;
1001 const int max_x = (width/3)*2 - 4;
1002 const int max_y = (height/3)*2 - 4;
1003 int min_distance = castle_config[
"min_distance"];
1006 int best_ranking = 0;
1007 for(
int x = min_x; x != max_x; ++
x) {
1008 for(
int y = min_y; y != max_y; ++
y) {
1010 if(failed_locs.count(loc)) {
1014 const int ranking =
rank_castle_location(x,y,terrain_tester,min_x,max_x,min_y,max_y,min_distance,castles,best_ranking);
1016 failed_locs.insert(loc);
1019 if(ranking > best_ranking) {
1020 best_ranking = ranking;
1025 if(best_ranking == 0) {
1026 ERR_NG <<
"No castle location found, aborting." << std::endl;
1027 std::string error =
_(
"No valid castle location found. Too many or too few mountain hexes? (please check the 'max hill size' parameter)");
1030 assert(
std::find(castles.begin(), castles.end(), best_loc) == castles.end());
1031 castles.push_back(best_loc);
1033 failed_locs.insert(best_loc);
1036 LOG_NG <<
"placing roads...\n";
1037 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
1042 int nroads = cfg[
"roads"];
1043 if(roads_between_castles) {
1044 nroads += castles.size()*castles.size();
1047 std::set<location> bridges;
1049 road_path_calculator calc(terrain, cfg,
rng_());
1050 for (
int road = 0; road != nroads; ++road) {
1061 src.
x += width/3 - 1;
1062 src.
y += height/3 - 1;
1063 dst.
x += width/3 - 1;
1064 dst.
y += height/3 - 1;
1066 if (roads_between_castles && road <
int(castles.size() * castles.size())) {
1067 const size_t src_castle = road/castles.size();
1068 const size_t dst_castle = road%castles.size();
1069 if(src_castle >= dst_castle) {
1073 src = castles[src_castle];
1074 dst = castles[dst_castle];
1078 else if(src.
x == dst.
x || src.
y == dst.
y) {
1082 if (calc.cost(src, 0.0) >= 1000.0 || calc.cost(dst, 0.0) >= 1000.0) {
1091 const int name_frequency = 20;
1094 bool on_bridge =
false;
1098 for(std::vector<location>::const_iterator step = rt.
steps.begin();
1099 step != rt.
steps.end(); ++step) {
1101 const int x = step->x;
1102 const int y = step->y;
1105 y >=
static_cast<long>(
height)) {
1124 const std::string &convert_to_bridge = child[
"convert_to_bridge"];
1125 if(convert_to_bridge.empty() ==
false) {
1126 if(step == rt.
steps.begin() || step+1 == rt.
steps.end())
1138 if((last == adj[0] && next == adj[3]) || (last == adj[3] && next == adj[0])) {
1143 else if((last == adj[1] && next == adj[4]) || (last == adj[4] && next == adj[1])) {
1148 else if((last == adj[2] && next == adj[5]) || (last == adj[5] && next == adj[2])) {
1152 if(misc_labels !=
nullptr && on_bridge ==
false) {
1156 const location loc(x - width / 3, y-height/3);
1157 misc_labels->insert(std::pair<map_location,std::string>(loc,name));
1158 bridge_names.insert(std::pair<location,std::string>(loc, bridge_base_name));
1159 bridges.insert(loc);
1162 if(direction != -1) {
1164 if(
size_t(direction) < items.size() && items[direction].empty() ==
false) {
1175 const std::string &convert_to = child[
"convert_to"];
1176 if(convert_to.empty() ==
false) {
1179 if(misc_labels !=
nullptr && terrain[x][y] != letter && name_count++ == name_frequency && on_bridge ==
false) {
1180 misc_labels->insert(std::pair<map_location,std::string>(
map_location(x-width/3,y-height/3),name));
1184 terrain[
x][
y] = letter;
1185 const location loc(x - width / 3, y - height / 3);
1186 road_names.insert(std::pair<location,std::string>(loc, road_base_name));
1191 LOG_NG <<
"looked at " << calc.calls <<
" locations\n";
1196 for(std::vector<location>::const_iterator c = castles.begin(); c != castles.end(); ++
c) {
1197 if(c->valid() ==
false) {
1203 const int player = c - castles.begin() + 1;
1205 starting_positions.insert(t_translation::tstarting_positions::value_type(std::to_string(player), coord));
1208 const int castles[13][2] = {
1209 {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1},
1210 {-2, 1}, {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, {1, -2}
1213 for (
size_t i = 0;
i < castle_size - 1;
i++) {
1218 if(labels !=
nullptr) {
1219 labels->erase(
location(x-width/3,y-height/3));
1220 for (
size_t i = 0;
i < castle_size - 1;
i++) {
1221 labels->erase(
location(x+castles[
i][0]-width/3,
1222 y+castles[
i][1]-height/3));
1229 LOG_NG <<
"placed castles\n";
1230 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
1236 if ( misc_labels !=
nullptr ) {
1237 for (x = width / 3; x < (width / 3)*2; x++) {
1238 for (y = height / 3; y < (height / 3) * 2;y++) {
1240 const location loc(x - width / 3, y - height / 3);
1243 std::set<std::string> used_names;
1246 if ((
rng_()%15) == 0) {
1247 for(
size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1248 name =
generate_name(name_generator,
"mountain_name", &base_name);
1250 misc_labels->insert(std::pair<map_location, std::string>(loc, name));
1251 mountain_names.insert(std::pair<location, std::string>(loc, base_name));
1256 const std::map<location, std::string>::const_iterator forest_name = forest_names.find(loc);
1257 if(forest_name == forest_names.end()) {
1258 for(
size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1259 name =
generate_name(name_generator,
"forest_name", &base_name);
1261 forest_names.insert(std::pair<location, std::string>(loc, base_name));
1268 const std::map<location, std::string>::const_iterator swamp_name = swamp_names.find(loc);
1269 if(swamp_name == swamp_names.end()) {
1270 for(
size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1271 name =
generate_name(name_generator,
"swamp_name", &base_name);
1273 swamp_names.insert(std::pair<location, std::string>(loc, base_name));
1286 std::map<map_location,std::string>* village_labels = naming_cfg.
empty() ?
nullptr : labels;
1292 if(!village_names_generator->is_valid()) {
1293 village_names_generator.reset();
1297 "[village_naming]male_names is deprecated, use names instead");
1298 if(!markov_list.
blank()) {
1303 const size_t tiles_per_village = ((width*
height)/9)/nvillages;
1304 size_t village_x = 1, village_y = 1;
1309 while(village_x*village_y < tiles_per_village) {
1310 if(village_x < village_y) {
1317 std::set<std::string> used_names;
1318 tcode_list_cache adj_liked_cache;
1320 for(
size_t vx = 0; vx <
width; vx += village_x) {
1321 LOG_NG <<
"village at " << vx <<
"\n";
1322 for(
size_t vy =
rng_()%village_y; vy <
height; vy += village_y) {
1324 const size_t add_x =
rng_()%3;
1325 const size_t add_y =
rng_()%3;
1326 const size_t x = (vx + add_x) - 1;
1327 const size_t y = (vy + add_y) - 1;
1331 if(res.
x >= static_cast<long>(width) / 3 &&
1332 res.
x < static_cast<long>(width * 2) / 3 &&
1333 res.
y >= static_cast<long>(height) / 3 &&
1334 res.
y < static_cast<long>(height * 2) / 3) {
1340 const std::string &convert_to = child[
"convert_to"];
1341 if(convert_to !=
"") {
1342 terrain[res.
x][res.
y] =
1345 villages.insert(res);
1347 if ( village_labels !=
nullptr ) {
1360 size_t field_count = 0, forest_count = 0, mountain_count = 0, hill_count = 0;
1365 for(n = 0; n != 6; ++
n) {
1366 const std::map<location,std::string>::const_iterator road_name = road_names.find(adj[n]);
1367 if(road_name != road_names.end()) {
1368 symbols[
"road"] = road_name->second;
1369 name_type =
"village_name_road";
1373 const std::map<location,std::string>::const_iterator river_name = river_names.find(adj[n]);
1374 if(river_name != river_names.end()) {
1375 symbols[
"river"] = river_name->second;
1376 name_type =
"village_name_river";
1378 const std::map<location,std::string>::const_iterator bridge_name = bridge_names.find(adj[n]);
1379 if(bridge_name != bridge_names.end()) {
1381 symbols[
"bridge"] = bridge_name->second;
1382 name_type =
"village_name_river_bridge";
1388 const std::map<location,std::string>::const_iterator forest_name = forest_names.find(adj[n]);
1389 if(forest_name != forest_names.end()) {
1390 symbols[
"forest"] = forest_name->second;
1391 name_type =
"village_name_forest";
1395 const std::map<location,std::string>::const_iterator lake_name = lake_names.find(adj[n]);
1396 if(lake_name != lake_names.end()) {
1397 symbols[
"lake"] = lake_name->second;
1398 name_type =
"village_name_lake";
1402 const std::map<location,std::string>::const_iterator mountain_name = mountain_names.find(adj[n]);
1403 if(mountain_name != mountain_names.end()) {
1404 symbols[
"mountain"] = mountain_name->second;
1405 name_type =
"village_name_mountain";
1409 const std::map<location,std::string>::const_iterator swamp_name = swamp_names.find(adj[n]);
1410 if(swamp_name != swamp_names.end()) {
1411 symbols[
"swamp"] = swamp_name->second;
1412 name_type =
"village_name_swamp";
1417 terrain[adj[
n].
x+width/3][adj[
n].
y+height/3];
1419 if(
std::count(field.begin(),field.end(),terr) > 0) {
1421 }
else if(
std::count(forest.begin(),forest.end(),terr) > 0) {
1423 }
else if(
std::count(hill.begin(),hill.end(),terr) > 0) {
1425 }
else if(
std::count(mountain.begin(),mountain.end(),terr) > 0) {
1431 if(field_count == 6) {
1432 name_type =
"village_name_grassland";
1433 }
else if(forest_count >= 2) {
1434 name_type =
"village_name_forest";
1435 }
else if(mountain_count >= 1) {
1436 name_type =
"village_name_mountain_anonymous";
1437 }
else if(hill_count >= 2) {
1438 name_type =
"village_name_hill";
1443 for(
size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1444 name =
generate_name(village_names_generator,name_type,
nullptr,&symbols);
1447 used_names.insert(name);
1448 village_labels->insert(std::pair<map_location,std::string>(loc,name));
1457 LOG_NG <<
"placed villages\n";
1458 LOG_NG << (SDL_GetTicks() - ticks) <<
"\n"; ticks = SDL_GetTicks();
1460 return output_map(terrain, starting_positions);
const attribute_value & get_old_attribute(const std::string &key, const std::string &old_key, const std::string &msg="") const
Function to handle backward compatibility Get the value of key and if missing try old_key and log msg...
child_itors child_range(const std::string &key)
Contains an x and y coordinate used for starting positions in maps.
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator *calc, const size_t width, const size_t height, const teleport_map *teleports, bool border)
std::string default_generate_map(size_t width, size_t height, size_t island_size, size_t island_off_center, size_t iterations, size_t hill_size, size_t max_lakes, size_t nvillages, size_t castle_size, size_t nplayers, bool roads_between_castles, std::map< map_location, std::string > *labels, const config &cfg)
Generate the map.
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate >> tstarting_positions
static map_location place_village(const t_translation::t_map &map, const size_t x, const size_t y, const size_t radius, const config &cfg, tcode_list_cache &adj_liked_cache)
t_list read_list(const std::string &str, const t_layer filler)
Reads a list of terrains from a string, when reading the.
std::vector< map_location > generate_river(const height_map &heights, terrain_map &terrain, int x, int y, int river_uphill)
std::string write_game_map(const t_map &map, const tstarting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
static int rank_castle_location(int x, int y, const is_valid_terrain &valid_terrain, int min_x, int max_x, int min_y, int max_y, size_t min_distance, const std::vector< map_location > &other_castles, int highest_ranking)
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
static void flood_name(const map_location &start, const std::string &name, std::map< map_location, std::string > &tile_names, const t_translation::t_match &tile_types, const terrain_map &terrain, unsigned width, unsigned height, size_t label_count, std::map< map_location, std::string > *labels, const std::string &full_name)
const t_terrain NONE_TERRAIN
static l_noret error(LoadState *S, const char *why)
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
t_translation::t_map terrain_map
static const int default_border
The default border style for a map.
const t_terrain DEEP_WATER
boost::random::mt19937 rng_
GLint GLint GLint GLint GLint GLint y
const std::vector< std::string > items
const config & child_or_empty(const std::string &key) const
Returns the first child with the given key, or an empty config if there is none.
t_terrain read_terrain_code(const std::string &str, const t_layer filler)
Reads a single terrain from a string.
Variant for storing WML attributes.
bool generate_river_internal(const height_map &heights, terrain_map &terrain, int x, int y, std::vector< map_location > &river, std::set< map_location > &seen_locations, int river_uphill)
static double getNoPathValue()
bool blank() const
Tests for an attribute that was never set.
const t_terrain HUMAN_KEEP
GLdouble GLdouble GLdouble b
std::vector< std::vector< t_terrain > > t_map
static UNUSEDNOWARN std::string _(const char *str)
const t_terrain GRASS_LAND
const t_match ALL_FORESTS
map_location random_point_at_side(size_t width, size_t height)
Returns a random tile at one of the borders of a map that is of the given dimensions.
std::vector< map_location > steps
std::map< std::string, t_string > string_map
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
Structure which holds a single route between one location and another.
const std::string name_type
type of possible name identificator
This structure can be used for matching terrain strings.
size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
static std::string output_map(const terrain_map &terrain, t_translation::tstarting_positions &starting_positions)
Function which, given the map will output it in a valid format.
std::string base_name(const std::string &file)
Returns the base filename of a file, with directory name stripped.
GLboolean GLboolean GLboolean GLboolean a
static void field(LexState *ls, struct ConsControl *cc)
static const ::config * terrain
The terrain used to create the cache.
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
Templates and utility-routines for strings and numbers.
GLuint GLuint GLsizei count
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
const t_terrain HUMAN_CASTLE
Encapsulates the map of the game.
default_map_generator_job()
static lg::log_domain log_mapgen("mapgen")
std::map< std::string, tfilter >::iterator itor
const t_match ALL_MOUNTAINS("!,*^V*,!,M*")
#define log_scope(description)
GLfloat GLfloat GLfloat GLfloat h
bool terrain_matches(const t_terrain &src, const t_terrain &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
GLint GLint GLint GLint GLint x
void get_tiles_radius(const map_location ¢er, size_t radius, std::set< map_location > &result)
Function that will add to result all locations within radius tiles of center (including center itself...
GLdouble GLdouble GLdouble r
t_translation::t_map terrain_map
std::string write_terrain_code(const t_terrain &tcode)
Writes a single terrain code to a string.
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
GLuint const GLchar * name
std::vector< std::vector< int > > height_map
bool has_attribute(const std::string &key) const
virtual double cost(const map_location &loc, const double so_far) const =0
bool find(E event, F functor)
Tests whether an event handler is available.
bool generate_lake(t_translation::t_map &terrain, int x, int y, int lake_fall_off, std::set< map_location > &locs_touched)
Generate a lake.
symbol_table string_table
static bool is_valid_terrain(const t_translation::t_terrain &c)
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
config & find_child(const std::string &key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
Standard logging facilities (interface).
height_map generate_height_map(size_t width, size_t height, size_t iterations, size_t hill_size, size_t island_size, size_t island_off_center)
Generate a height-map.
const t_match ALL_SWAMPS("!,*^V*,*^B*,!,S*")
GLint GLint GLint GLint GLint GLint GLsizei width
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
const t_terrain SHALLOW_WATER
A config object defines a single node in a WML file, with access to child nodes.
This module contains various pathfinding functions and utilities.
GLenum GLsizei GLenum GLenum const GLvoid * table
GLsizei const GLcharARB ** string
std::map< t_translation::t_terrain, t_translation::t_list > tcode_list_cache
std::vector< std::vector< int > > height_map
std::vector< t_terrain > t_list
std::string generate_name(boost::shared_ptr< name_generator > &name_generator, const std::string &id, std::string *base_name=nullptr, utils::string_map *additional_symbols=nullptr)