39 #define ERR_NG LOG_STREAM(err, log_mapgen)
40 #define LOG_NG LOG_STREAM(info, log_mapgen)
41 #define DBG_NG LOG_STREAM(debug, log_mapgen)
57 , windiness_(std::max<int>(1,
cfg[
"road_windiness"].to_int()))
71 mutable std::map<t_translation::terrain_code, double> cache_;
74 double road_path_calculator::cost(
const map_location&
loc,
const double )
const
89 double windiness = 1.0;
93 unsigned int a = (
loc.
x + 92872973) ^ 918273;
94 unsigned int b = (
loc.
y + 1672517) ^ 128123;
95 unsigned int c = a*
b + a +
b + seed_;
96 unsigned int random =
c*
c;
100 int noise = random % (windiness_ * 137) / 137;
105 const std::map<t_translation::terrain_code, double>::const_iterator itor = cache_.find(
c);
106 if(itor != cache_.end()) {
107 return itor->second*windiness;
110 static std::string terrain;
112 double res = getNoPathValue();
113 if(
auto child = cfg_.find_child(
"road_cost",
"terrain", terrain)) {
114 res = child[
"cost"].to_double();
117 cache_.emplace(
c, res);
118 return windiness*res;
125 bool operator()(
int x,
int y)
const;
132 : map_(map), terrain_(terrain_list)
136 bool is_valid_terrain::operator()(
int x,
int y)
const
138 if(x < 0 || x >= map_.w || y < 0 || y >= map_.h) {
156 class terrain_height_mapper
159 explicit terrain_height_mapper(
const config&
cfg);
161 bool convert_terrain(
const int height)
const;
169 terrain_height_mapper::terrain_height_mapper(
const config&
cfg) :
170 terrain_height(
cfg[
"height"].to_int()),
173 const std::string& terrain =
cfg[
"terrain"];
174 if(!terrain.empty()) {
179 bool terrain_height_mapper::convert_terrain(
const int height)
const
181 return height >= terrain_height;
190 class terrain_converter
193 explicit terrain_converter(
const config&
cfg);
199 int min_temp, max_temp, min_height, max_height;
204 terrain_converter::terrain_converter(
const config&
cfg)
205 : min_temp(
cfg[
"min_temperature"].to_int(-100000))
206 , max_temp(
cfg[
"max_temperature"].to_int(100000))
207 , min_height(
cfg[
"min_height"].to_int(-100000))
208 , max_height(
cfg[
"max_height"].to_int(100000))
212 const std::string& to_str =
cfg[
"to"];
213 if(!to_str.empty()) {
219 const int height,
const int temperature)
const
259 std::size_t center_x = width/2;
260 std::size_t center_y = height/2;
262 LOG_NG <<
"off-centering...";
264 if(island_off_center != 0) {
267 center_x += island_off_center;
270 center_y += island_off_center;
273 if(center_x < island_off_center) {
276 center_x -= island_off_center;
280 if(center_y < island_off_center) {
283 center_y -= island_off_center;
288 return generate_height_map(width, height, iterations, hill_size, island_size, center_x, center_y);
293 height_map res(width, std::vector<int>(height,0));
295 DBG_NG << iterations <<
" iterations";
296 for(std::size_t
i = 0;
i != iterations; ++
i) {
309 bool is_valley =
false;
311 int x1 = island_size > 0 ? center_x - island_size + (
rng_()%(island_size*2)) :
static_cast<int>(
rng_()%width);
312 int y1 = island_size > 0 ? center_y - island_size + (
rng_()%(island_size*2)) :
static_cast<int>(
rng_()%height);
315 if(island_size != 0) {
316 const std::size_t diffx = std::abs(x1 -
static_cast<int>(center_x));
317 const std::size_t diffy = std::abs(y1 -
static_cast<int>(center_y));
318 const std::size_t dist = std::size_t(std::sqrt(
static_cast<double>(diffx*diffx + diffy*diffy)));
319 is_valley = dist > island_size;
322 const int radius =
rng_()%hill_size + 1;
323 DBG_NG <<
"placing hill at " << x1 <<
"," << y1 <<
" radius=" << radius <<
" is_valley=" << is_valley;
325 const int min_x = x1 - radius > 0 ? x1 - radius : 0;
326 const int max_x = x1 + radius < static_cast<long>(res.size()) ? x1 + radius : res.size();
327 const int min_y = y1 - radius > 0 ? y1 - radius : 0;
328 const int max_y = y1 + radius < static_cast<long>(res.front().size()) ? y1 + radius : res.front().size();
330 for(
int x2 = min_x; x2 < max_x; ++x2) {
331 for(
int y2 = min_y; y2 < max_y; ++y2) {
332 const int xdiff = (x2-x1);
333 const int ydiff = (y2-y1);
335 const int hill_height = radius -
static_cast<int>(std::sqrt(
static_cast<double>(xdiff*xdiff + ydiff*ydiff)));
337 if(hill_height > 0) {
339 if(hill_height > res[x2][y2]) {
342 res[x2][y2] -= hill_height;
345 res[x2][y2] += hill_height;
353 int highest = 0, lowest = 100000, x;
354 for(x = 0; std::size_t(x) != res.size(); ++x) {
355 for(
int y = 0; std::size_t(y) != res[x].size(); ++y) {
356 if(res[x][y] > highest) {
360 if(res[x][y] < lowest) {
366 LOG_NG <<
"generate_height_map"
367 <<
" lowest=" << lowest
368 <<
" highest =" << highest;
371 for(x = 0; std::size_t(x) != res.size(); ++x) {
372 for(
int y = 0; std::size_t(y) != res[x].size(); ++y) {
376 res[x][y] /= highest;
395 if(x < 0 || y < 0 || x >= terrain.
w || y >= terrain.
h || lake_fall_off < 0) {
399 unsigned int ulake_fall_off = lake_fall_off;
403 if((
rng_()%100) < ulake_fall_off) {
407 if((
rng_()%100) < ulake_fall_off) {
411 if((
rng_()%100) < ulake_fall_off) {
415 if((
rng_()%100) < ulake_fall_off) {
441 terrain_map& terrain,
int x,
int y, std::vector<map_location>& river,
442 std::set<map_location>& seen_locations,
int river_uphill)
444 const bool on_map = x >= 0 && y >= 0 &&
445 x < static_cast<long>(heights.size()) &&
446 y < static_cast<long>(heights.back().size());
448 if(on_map && !river.empty() && heights[x][y] >
449 heights[river.back().x][river.back().y] + river_uphill) {
458 LOG_NG <<
"generating river...";
461 for(
auto i : river) {
465 LOG_NG <<
"done generating river";
475 seen_locations.insert(current_loc);
476 river.push_back(current_loc);
478 if(seen_locations.count(
loc) == 0) {
494 std::vector<map_location> river;
495 std::set<map_location> seen_locations;
510 const int side =
rng_()%4;
512 const int x =
rng_()%width;
513 const int y = side == 0 ? 0 : height-1;
516 const int y =
rng_()%height;
517 const int x = side == 2 ? 0 : width-1;
536 for(std::size_t y = begin_y; y != end_y; ++y) {
537 for(std::size_t x = begin_x; x != end_x; ++x) {
538 map[x - begin_x][y - begin_y] = terrain[x][y];
550 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, std::size_t min_distance,
const std::vector<map_location>& other_castles,
int highest_ranking)
554 std::size_t avg_distance = 0, lowest_distance = 1000;
556 for(std::vector<map_location>::const_iterator
c = other_castles.begin();
c != other_castles.end(); ++
c) {
562 if(distance < lowest_distance) {
563 lowest_distance = distance;
566 if(distance < min_distance) {
570 avg_distance += distance;
573 if(!other_castles.empty()) {
574 avg_distance /= other_castles.size();
577 for(
int i = x-1;
i <= x+1; ++
i) {
578 for(
int j = y-1; j <= y+1; ++j) {
579 if(!valid_terrain(
i,j)) {
585 const int x_from_border = std::min<int>(x - min_x,max_x - x);
586 const int y_from_border = std::min<int>(y - min_y,max_y - y);
588 const int border_ranking = min_distance - std::min<int>(x_from_border,y_from_border) + min_distance - x_from_border - y_from_border;
590 int current_ranking = border_ranking*2 + avg_distance*10 + lowest_distance*10;
591 static const int num_nearby_locations = 11*11;
593 const int max_possible_ranking = current_ranking + num_nearby_locations;
595 if(max_possible_ranking < highest_ranking) {
596 return current_ranking;
599 int surrounding_ranking = 0;
601 for(
int xpos = x-5; xpos <= x+5; ++xpos) {
602 for(
int ypos = y-5; ypos <= y+5; ++ypos) {
603 if(valid_terrain(xpos,ypos)) {
604 ++surrounding_ranking;
609 return surrounding_ranking + current_ranking;
615 const std::size_t x,
const std::size_t y,
const std::size_t radius,
const config&
cfg,
619 std::set<map_location> locs;
624 if(
i.x < 0 ||
i.y < 0 ||
i.x >= map.
w ||
635 if(l != adj_liked_cache.end()) {
636 adjacent_liked = &(l->second);
639 adjacent_liked = &(adj_liked_cache[
t]);
642 int rating = child[
"rating"].to_int();
644 if(adj.x < 0 || adj.y < 0 || adj.x >= map.
w || adj.y >= map.
h) {
649 rating += std::count(adjacent_liked->begin(),adjacent_liked->end(),t2);
652 if(rating > best_rating) {
654 best_rating = rating;
665 unsigned width,
unsigned height,
666 std::size_t label_count, std::map<map_location,std::string>* labels,
const std::string& full_name) {
672 if(
static_cast<unsigned>(adj.x) >= width / 3 ||
static_cast<unsigned>(adj.y) >= height / 3) {
678 tile_names.emplace(adj, name);
680 if(label_count % 6 == 0) {
681 labels->emplace(adj, full_name);
684 flood_name(adj, name, tile_names, tile_types, terrain, width, height, label_count++, labels, full_name);
693 LOG_NG <<
"default_generate_map parameters"
694 <<
" width=" <<
data.width
695 <<
" height=" <<
data.height
696 <<
" nplayers=" <<
data.nplayers
697 <<
" nvillages=" <<
data.nvillages
698 <<
" iterations=" <<
data.iterations
699 <<
" hill_size=" <<
data.hill_size
700 <<
" castle_size=" <<
data.castle_size
701 <<
" island_size=" <<
data.island_size
702 <<
" island_off_center=" <<
data.island_off_center
703 <<
" max_lakes=" <<
data.max_lakes
704 <<
" link_castles=" <<
data.link_castles
705 <<
" show_labels=" <<
data.show_labels;
730 std::map<map_location,std::string>* misc_labels = naming.
empty() ? nullptr : labels;
732 std::shared_ptr<name_generator>
733 base_name_generator, river_name_generator, lake_name_generator,
734 road_name_generator, bridge_name_generator, mountain_name_generator,
735 forest_name_generator, swamp_name_generator;
737 if(misc_labels !=
nullptr) {
738 name_generator_factory base_generator_factory{ naming, {
"male",
"base",
"bridge",
"road",
"river",
"forest",
"lake",
"mountain",
"swamp"} };
743 base_name_generator = base_generator_factory.get_name_generator( (naming.
has_attribute(
"base_names") || naming.
has_attribute(
"base_name_generator")) ?
"base" :
"male" );
744 river_name_generator = base_generator_factory.get_name_generator(
"river");
745 lake_name_generator = base_generator_factory.get_name_generator(
"lake");
746 road_name_generator = base_generator_factory.get_name_generator(
"road");
747 bridge_name_generator = base_generator_factory.get_name_generator(
"bridge");
748 mountain_name_generator = base_generator_factory.get_name_generator(
"mountain");
749 forest_name_generator = base_generator_factory.get_name_generator(
"forest");
750 swamp_name_generator = base_generator_factory.get_name_generator(
"swamp");
756 LOG_NG <<
"Done generating height map. " << timer <<
" ticks elapsed";
759 std::string flatland =
cfg[
"default_flatland"];
760 if(flatland.empty()) {
766 std::vector<terrain_height_mapper> height_conversion;
768 height_conversion.emplace_back(
h);
772 for(std::size_t x = 0; x != heights.size(); ++x) {
773 for(std::size_t y = 0; y != heights[x].size(); ++y) {
774 for(
auto i : height_conversion) {
775 if(
i.convert_terrain(heights[x][y])) {
776 terrain[x][y] =
i.convert_to();
785 LOG_NG <<
"Placed landforms. " << timer <<
" ticks elapsed";
799 std::set<map_location> lake_locs;
801 std::map<map_location, std::string> river_names, lake_names, road_names, bridge_names, mountain_names, forest_names, swamp_names;
803 const std::size_t nlakes =
data.max_lakes > 0 ? (
rng_()%
data.max_lakes) : 0;
804 for(std::size_t lake = 0; lake != nlakes; ++lake) {
805 for(
int tries = 0; tries != 100; ++tries) {
809 if(heights[x][y] <=
cfg[
"min_lake_height"].to_int()) {
813 std::vector<map_location> river =
generate_river(heights, terrain, x, y,
cfg[
"river_frequency"].to_int());
815 if(!river.empty() && misc_labels !=
nullptr) {
816 const std::string
base_name = base_name_generator->generate();
817 const std::string& name = river_name_generator->generate({{
"base",
base_name}});
818 LOG_NG <<
"Named river '" << name <<
"'";
820 std::size_t name_frequency = 20;
821 for(std::vector<map_location>::const_iterator r = river.begin(); r != river.end(); ++r) {
824 if(((r - river.begin())%name_frequency) == name_frequency/2) {
825 misc_labels->emplace(
loc, name);
832 LOG_NG <<
"Generating lake...";
834 std::set<map_location> locs;
835 if(
generate_lake(terrain, x, y,
cfg[
"lake_size"].to_int(), locs) && misc_labels !=
nullptr) {
836 bool touches_other_lake =
false;
838 std::string
base_name = base_name_generator->generate();
839 const std::string& name = lake_name_generator->generate({{
"base",
base_name}});
844 if(lake_locs.count(
i) != 0) {
845 touches_other_lake =
true;
849 const std::map<map_location,std::string>::const_iterator other_name = lake_names.find(
loc);
850 if(other_name != lake_names.end()) {
858 if(!touches_other_lake) {
860 misc_labels->erase(
loc);
861 misc_labels->emplace(
loc, name);
874 LOG_NG <<
"Generated rivers. " << timer <<
" ticks elapsed";
876 const std::size_t default_dimensions = 40*40*9;
887 cfg[
"temperature_iterations"].to_size_t() *
data.width *
data.height / default_dimensions,
888 cfg[
"temperature_size"].to_size_t(), 0, 0);
890 LOG_NG <<
"Generated temperature map. " << timer <<
" ticks elapsed";
892 std::vector<terrain_converter> converters;
894 converters.emplace_back(cv);
898 for(
int x = 0; x !=
data.width; ++x) {
899 for(
int y = 0; y !=
data.height; ++y) {
900 for(
auto i : converters) {
901 if(
i.convert_terrain(terrain[x][y],heights[x][y],temperature_map[x][y])) {
902 terrain[x][y] =
i.convert_to();
909 LOG_NG <<
"Converted terrain. " << timer <<
" ticks elapsed";
910 LOG_NG <<
"Placing castles...";
921 std::vector<map_location> castles;
922 std::set<map_location> failed_locs;
933 for(
int player = 0; player !=
data.nplayers; ++player) {
934 LOG_NG <<
"placing castle for " << player;
936 const int min_x =
data.width/3 + 3;
937 const int min_y =
data.height/3 + 3;
938 const int max_x = (
data.width/3)*2 - 4;
939 const int max_y = (
data.height/3)*2 - 4;
940 int min_distance = castle_config[
"min_distance"].to_int();
943 int best_ranking = 0;
944 for(
int x = min_x; x != max_x; ++x) {
945 for(
int y = min_y; y != max_y; ++y) {
947 if(failed_locs.count(
loc)) {
951 const int ranking =
rank_castle_location(x, y, terrain_tester, min_x, max_x, min_y, max_y, min_distance, castles, best_ranking);
953 failed_locs.insert(
loc);
956 if(ranking > best_ranking) {
957 best_ranking = ranking;
963 if(best_ranking == 0) {
964 ERR_NG <<
"No castle location found, for " <<
data.nplayers <<
" players aborting. ";
965 const std::string error =
_(
"No valid castle location found. Too many or too few mountain hexes? (please check the ‘max hill size’ parameter)");
970 castles.push_back(best_loc);
973 failed_locs.insert(best_loc);
976 LOG_NG <<
"Placed castles. " << timer <<
" ticks elapsed";
978 LOG_NG <<
"Placing roads...";
983 int nroads =
cfg[
"roads"].to_int();
984 if(
data.link_castles) {
985 nroads += castles.size()*castles.size();
988 std::set<map_location> bridges;
990 road_path_calculator calc(terrain,
cfg,
rng_());
991 for(
int road = 0; road != nroads; ++road) {
1007 if(
data.link_castles && road <
static_cast<int>(castles.size() * castles.size())) {
1008 const std::size_t src_castle = road/castles.size();
1009 const std::size_t dst_castle = road%castles.size();
1010 if(src_castle >= dst_castle) {
1014 src = castles[src_castle];
1015 dst = castles[dst_castle];
1021 if(calc.cost(
src, 0.0) >= 1000.0 || calc.cost(
dst, 0.0) >= 1000.0) {
1028 const std::string& road_base_name = misc_labels !=
nullptr
1029 ? base_name_generator->generate()
1031 const std::string& road_name = misc_labels !=
nullptr
1032 ? road_name_generator->generate({{
"base", road_base_name}})
1034 const int name_frequency = 20;
1037 bool on_bridge =
false;
1041 for(std::vector<map_location>::const_iterator step = rt.
steps.begin();
1042 step != rt.
steps.end(); ++step) {
1044 const int x = step->x;
1045 const int y = step->y;
1047 if(x < 0 || y < 0 || x >=
static_cast<long>(
data.width) || y >=
static_cast<long>(
data.height)) {
1053 if(!child || child->empty()){
1064 const std::string& convert_to_bridge = child[
"convert_to_bridge"];
1065 if(!convert_to_bridge.empty()) {
1066 if(step == rt.
steps.begin() || step+1 == rt.
steps.end()) {
1077 if((last == adj[0] && next == adj[3]) || (last == adj[3] && next == adj[0])) {
1082 else if((last == adj[1] && next == adj[4]) || (last == adj[4] && next == adj[1])) {
1087 else if((last == adj[2] && next == adj[5]) || (last == adj[5] && next == adj[2])) {
1091 if(misc_labels !=
nullptr && !on_bridge) {
1093 std::string bridge_base_name = base_name_generator->generate();
1094 const std::string& name = bridge_name_generator->generate({{
"base", bridge_base_name}});
1096 misc_labels->emplace(
loc, name);
1097 bridge_names.emplace(
loc, bridge_base_name);
1098 bridges.insert(
loc);
1101 if(direction != -1) {
1102 const std::vector<std::string> items =
utils::split(convert_to_bridge);
1103 if(std::size_t(direction) < items.size() && !items[direction].empty()) {
1114 const std::string& convert_to = child[
"convert_to"];
1115 if(!convert_to.empty()) {
1117 if(misc_labels !=
nullptr && terrain[x][y] != letter && name_count++ == name_frequency && !on_bridge) {
1122 terrain[x][y] = letter;
1123 if(misc_labels !=
nullptr) {
1125 if(!road_base_name.empty())
1126 road_names.emplace(
loc, road_base_name);
1133 for(std::vector<map_location>::const_iterator
c = castles.begin();
c != castles.end(); ++
c) {
1140 const int player =
c - castles.begin() + 1;
1142 starting_positions.insert(t_translation::starting_positions::value_type(std::to_string(player), coord));
1145 const int castle_array[13][2] {
1146 {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1},
1147 {-2, 1}, {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, {1, -2}
1150 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1155 if(labels !=
nullptr) {
1157 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1163 LOG_NG <<
"Placed roads. " << timer <<
" ticks elapsed";
1169 if(misc_labels !=
nullptr) {
1170 std::set<std::string> used_names;
1171 for(
int x =
data.width / 3; x < (
data.width / 3)*2; x++) {
1172 for(
int y =
data.height / 3; y < (
data.height / 3) * 2;y++) {
1180 if((
rng_() % 15) == 0) {
1181 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1182 base_name = base_name_generator->generate();
1183 name = mountain_name_generator->generate({{
"base",
base_name}});
1185 misc_labels->emplace(
loc, name);
1190 const std::map<map_location, std::string>::const_iterator forest_name = forest_names.find(
loc);
1191 if(forest_name == forest_names.end()) {
1192 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1193 base_name = base_name_generator->generate();
1194 name = forest_name_generator->generate({{
"base",
base_name}});
1202 const std::map<map_location, std::string>::const_iterator swamp_name = swamp_names.find(
loc);
1203 if(swamp_name == swamp_names.end()) {
1204 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1205 base_name = base_name_generator->generate();
1206 name = swamp_name_generator->generate({{
"base",
base_name}});
1214 used_names.insert(name);
1220 LOG_NG <<
"Named landforms. " << timer <<
" ticks elapsed";
1221 LOG_NG <<
"Placing villages...";
1228 std::set<map_location> villages;
1230 if(
data.nvillages > 0) {
1233 const std::size_t tiles_per_village = ((
data.width*
data.height)/9)/
data.nvillages;
1234 std::size_t village_x = 1, village_y = 1;
1239 while(village_x*village_y < tiles_per_village) {
1240 if(village_x < village_y) {
1247 std::set<std::string> used_names;
1257 std::map<map_location,std::string>* village_labels = village_naming.
empty() ? nullptr : labels;
1259 for(
int vx = 0; vx <
data.width; vx += village_x) {
1260 LOG_NG <<
"village at " << vx;
1262 for(
int vy =
rng_()%village_y; vy <
data.height; vy += village_y) {
1263 const std::size_t add =
rng_()%3;
1264 const std::size_t x = (vx + add) - 1;
1265 const std::size_t y = (vy + add) - 1;
1269 if(res.
x <
static_cast<long>(
data.width ) / 3 ||
1270 res.
x >=
static_cast<long>(
data.width * 2) / 3 ||
1271 res.
y <
static_cast<long>(
data.height ) / 3 ||
1272 res.
y >=
static_cast<long>(
data.height * 2) / 3) {
1279 if(convert_to.empty()) {
1285 villages.insert(res);
1287 if(village_labels ==
nullptr) {
1292 {
"base",
"male",
"village",
"lake",
"river",
"bridge",
"grassland",
"forest",
"hill",
"mountain",
"mountain_anon",
"road",
"swamp"} };
1297 base_name_generator = village_name_generator_factory.get_name_generator(
1303 std::string name_type =
"village";
1310 std::size_t field_count = 0, forest_count = 0, mountain_count = 0, hill_count = 0;
1312 std::map<std::string,std::string> symbols;
1315 for(
n = 0;
n != 6; ++
n) {
1316 const std::map<map_location,std::string>::const_iterator road_name = road_names.find(adj[
n]);
1317 if(road_name != road_names.end()) {
1318 symbols[
"road"] = road_name->second;
1323 const std::map<map_location,std::string>::const_iterator river_name = river_names.find(adj[
n]);
1324 if(river_name != river_names.end()) {
1325 symbols[
"river"] = river_name->second;
1326 name_type =
"river";
1328 const std::map<map_location,std::string>::const_iterator bridge_name = bridge_names.find(adj[
n]);
1329 if(bridge_name != bridge_names.end()) {
1331 symbols[
"bridge"] = bridge_name->second;
1332 name_type =
"river_bridge";
1338 const std::map<map_location,std::string>::const_iterator forest_name = forest_names.find(adj[
n]);
1339 if(forest_name != forest_names.end()) {
1340 symbols[
"forest"] = forest_name->second;
1341 name_type =
"forest";
1345 const std::map<map_location,std::string>::const_iterator lake_name = lake_names.find(adj[
n]);
1346 if(lake_name != lake_names.end()) {
1347 symbols[
"lake"] = lake_name->second;
1352 const std::map<map_location,std::string>::const_iterator mountain_name = mountain_names.find(adj[
n]);
1353 if(mountain_name != mountain_names.end()) {
1354 symbols[
"mountain"] = mountain_name->second;
1355 name_type =
"mountain";
1359 const std::map<map_location,std::string>::const_iterator swamp_name = swamp_names.find(adj[
n]);
1360 if(swamp_name != swamp_names.end()) {
1361 symbols[
"swamp"] = swamp_name->second;
1362 name_type =
"swamp";
1368 if(std::count(field.begin(),field.end(),terr) > 0) {
1370 }
else if(std::count(forest.begin(),forest.end(),terr) > 0) {
1372 }
else if(std::count(hill.begin(),hill.end(),terr) > 0) {
1374 }
else if(std::count(mountain.begin(),mountain.end(),terr) > 0) {
1380 if(field_count == 6) {
1381 name_type =
"grassland";
1382 }
else if(forest_count >= 2) {
1383 name_type =
"forest";
1384 }
else if(mountain_count >= 1) {
1385 name_type =
"mountain_anon";
1386 }
else if(hill_count >= 2) {
1393 symbols[
"base"] = base_name_generator->generate();
1394 std::shared_ptr<name_generator> village_name_generator = village_name_generator_factory.get_name_generator(name_type);
1396 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1397 name = village_name_generator->generate(symbols);
1400 used_names.insert(name);
1401 village_labels->emplace(
loc, name);
1406 LOG_NG <<
"Placed villages. " << timer <<
" ticks elapsed";
A config object defines a single node in a WML file, with access to child nodes.
const attribute_value & get_old_attribute(config_key_type key, const std::string &old_key, const std::string &in_tag, const std::string &message="") const
Function to handle backward compatibility Get the value of key and if missing try old_key and log a d...
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
config & find_mandatory_child(config_key_type key, const std::string &name, const std::string &value)
optional_config_impl< config > find_child(config_key_type key, const std::string &name, const std::string &value)
Returns the first child of tag key with a name attribute containing value.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
bool has_attribute(config_key_type key) const
child_itors child_range(config_key_type key)
void append_attributes(const config &cfg)
Adds attributes from cfg.
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
map_location random_point_at_side(std::size_t width, std::size_t height)
Returns a random tile at one of the borders of a map that is of the given dimensions.
std::string default_generate_map(generator_data data, std::map< map_location, std::string > *labels, const config &cfg)
Generate the map.
std::vector< map_location > generate_river(const height_map &heights, terrain_map &terrain, int x, int y, int river_uphill)
bool generate_lake(t_translation::ter_map &terrain, int x, int y, int lake_fall_off, std::set< map_location > &locs_touched)
Generate a lake.
const game_config_view & game_config_
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)
River generation.
height_map generate_height_map(std::size_t width, std::size_t height, std::size_t iterations, std::size_t hill_size, std::size_t island_size, std::size_t island_off_center)
Generate a height-map.
std::vector< std::vector< int > > height_map
default_map_generator_job()
const config & mandatory_child(config_key_type key) const
static const int default_border
The default border style for a map.
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, std::size_t min_distance, const std::vector< map_location > &other_castles, int highest_ranking)
std::map< t_translation::terrain_code, t_translation::ter_list > tcode_list_cache
static lg::log_domain log_mapgen("mapgen")
t_translation::ter_map terrain_map
static map_location place_village(const t_translation::ter_map &map, const std::size_t x, const std::size_t y, const std::size_t radius, const config &cfg, tcode_list_cache &adj_liked_cache)
static void flood_name(const map_location &start, const std::string &name, std::map< map_location, std::string > &tile_names, const t_translation::ter_match &tile_types, const terrain_map &terrain, unsigned width, unsigned height, std::size_t label_count, std::map< map_location, std::string > *labels, const std::string &full_name)
static std::string output_map(const terrain_map &terrain, t_translation::starting_positions &starting_positions)
Function which, given the map will output it in a valid format.
std::vector< std::vector< int > > height_map
static std::string _(const char *str)
std::size_t distance_between(const map_location &a, const map_location &b)
Function which gives the number of hexes between two tiles (i.e.
void get_adjacent_tiles(const map_location &a, utils::span< map_location, 6 > res)
Function which, given a location, will place all adjacent locations in res.
Standard logging facilities (interface).
#define log_scope(description)
constexpr bool is_even(T num)
static bool is_valid_terrain(const t_translation::terrain_code &c)
EXIT_STATUS start(bool clear_id, const std::string &filename, bool take_screenshot, const std::string &screenshot_filename)
Main interface for launching the editor from the title screen.
std::string base_name(const std::string &file, const bool remove_extension)
Returns the base filename of a file, with directory name stripped.
Game configuration data as global variables.
std::vector< game_tip > shuffle(const std::vector< game_tip > &tips)
Shuffles the tips.
plain_route a_star_search(const map_location &src, const map_location &dst, double stop_at, const cost_calculator &calc, const std::size_t width, const std::size_t height, const teleport_map *teleports, bool border)
terrain_code read_terrain_code(std::string_view str, const ter_layer filler)
Reads a single terrain from a string.
const ter_match ALL_FORESTS
std::string write_game_map(const ter_map &map, const starting_positions &starting_positions, coordinate border_offset)
Write a gamemap in to a vector string.
const terrain_code SHALLOW_WATER
const ter_match ALL_SWAMPS("!,*^V*,*^B*,!,S*")
const terrain_code HUMAN_CASTLE
bool terrain_matches(const terrain_code &src, const terrain_code &dest)
Tests whether a specific terrain matches an expression, for matching rules see above.
std::vector< terrain_code > ter_list
const terrain_code GRASS_LAND
const terrain_code DEEP_WATER
boost::bimaps::bimap< boost::bimaps::set_of< std::string >, boost::bimaps::multiset_of< coordinate > > starting_positions
const terrain_code FOREST
ter_list read_list(std::string_view str, const ter_layer filler)
Reads a list of terrains from a string, when reading the.
const ter_match ALL_MOUNTAINS("!,*^V*,!,M*")
const terrain_code MOUNTAIN
std::string write_terrain_code(const terrain_code &tcode)
Writes a single terrain code to a string.
const terrain_code HUMAN_KEEP
const terrain_code NONE_TERRAIN
bool contains(const Container &container, const Value &value)
Returns true iff value is found in container.
std::vector< std::string > split(const config_attribute_value &val)
std::string::const_iterator iterator
This module contains various pathfinding functions and utilities.
void get_tiles_radius(const map_location ¢er, std::size_t radius, std::set< map_location > &result)
Function that will add to result all locations within radius tiles of center (including center itself...
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
Encapsulates the map of the game.
static double getNoPathValue()
virtual double cost(const map_location &loc, const double so_far) const =0
Structure which holds a single route between one location and another.
std::vector< map_location > steps
This structure can be used for matching terrain strings.
A terrain string which is converted to a terrain is a string with 1 or 2 layers the layers are separa...
Reports time elapsed at the end of an object scope.
static map_location::direction n
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
#define VALIDATE(cond, message)
The macro to use for the validation of WML.