38 #define ERR_NG LOG_STREAM(err, log_mapgen)
39 #define LOG_NG LOG_STREAM(info, log_mapgen)
40 #define DBG_NG LOG_STREAM(debug, log_mapgen)
56 , windiness_(std::max<int>(1, cfg[
"road_windiness"].to_int()))
70 mutable std::map<t_translation::terrain_code, double> cache_;
73 double road_path_calculator::cost(
const map_location& loc,
const double )
const
76 if(loc.
x < 0 || loc.
y < 0 || loc.
x >= map_.w || loc.
y >= map_.h) {
88 double windiness = 1.0;
92 unsigned int a = (loc.
x + 92872973) ^ 918273;
93 unsigned int b = (loc.
y + 1672517) ^ 128123;
94 unsigned int c = a*
b + a +
b + seed_;
95 unsigned int random =
c*
c;
99 int noise = random % (windiness_ * 137) / 137;
104 const std::map<t_translation::terrain_code, double>::const_iterator itor = cache_.find(
c);
105 if(itor != cache_.end()) {
106 return itor->second*windiness;
109 static std::string terrain;
111 double res = getNoPathValue();
112 if(
auto child = cfg_.find_child(
"road_cost",
"terrain", terrain)) {
113 res = child[
"cost"].to_double();
116 cache_.emplace(
c, res);
117 return windiness*res;
124 bool operator()(
int x,
int y)
const;
131 : map_(map), terrain_(terrain_list)
135 bool is_valid_terrain::operator()(
int x,
int y)
const
137 if(x < 0 || x >= map_.w || y < 0 || y >= map_.h) {
142 return std::find(terrain_.begin(),terrain_.end(),map_[x][y]) != terrain_.end();
155 class terrain_height_mapper
158 explicit terrain_height_mapper(
const config& cfg);
160 bool convert_terrain(
const int height)
const;
168 terrain_height_mapper::terrain_height_mapper(
const config& cfg) :
169 terrain_height(cfg[
"height"].to_int()),
172 const std::string& terrain = cfg[
"terrain"];
173 if(!terrain.empty()) {
178 bool terrain_height_mapper::convert_terrain(
const int height)
const
180 return height >= terrain_height;
189 class terrain_converter
192 explicit terrain_converter(
const config& cfg);
198 int min_temp, max_temp, min_height, max_height;
203 terrain_converter::terrain_converter(
const config& cfg)
204 : min_temp(cfg[
"min_temperature"].to_int(-100000))
205 , max_temp(cfg[
"max_temperature"].to_int(100000))
206 , min_height(cfg[
"min_height"].to_int(-100000))
207 , max_height(cfg[
"max_height"].to_int(100000))
211 const std::string& to_str = cfg[
"to"];
212 if(!to_str.empty()) {
218 const int height,
const int temperature)
const
220 return std::find(from.begin(),from.end(),terrain) != from.end() && height >= min_height && height <= max_height && temperature >= min_temp && temperature <= max_temp && to !=
t_translation::NONE_TERRAIN;
258 size_t center_x = width/2;
259 size_t center_y = height/2;
261 LOG_NG <<
"off-centering...";
263 if(island_off_center != 0) {
266 center_x += island_off_center;
269 center_y += island_off_center;
272 if(center_x < island_off_center) {
275 center_x -= island_off_center;
279 if(center_y < island_off_center) {
282 center_y -= island_off_center;
287 return generate_height_map(width, height, iterations, hill_size, island_size, center_x, center_y);
292 height_map res(width, std::vector<int>(height,0));
294 DBG_NG << iterations <<
" iterations";
295 for(std::size_t
i = 0;
i != iterations; ++
i) {
308 bool is_valley =
false;
310 int x1 = island_size > 0 ? center_x - island_size + (
rng_()%(island_size*2)) :
static_cast<int>(
rng_()%width);
311 int y1 = island_size > 0 ? center_y - island_size + (
rng_()%(island_size*2)) :
static_cast<int>(
rng_()%height);
314 if(island_size != 0) {
315 const std::size_t diffx = std::abs(x1 -
static_cast<int>(center_x));
316 const std::size_t diffy = std::abs(y1 -
static_cast<int>(center_y));
317 const std::size_t dist = std::size_t(std::sqrt(
static_cast<double>(diffx*diffx + diffy*diffy)));
318 is_valley = dist > island_size;
321 const int radius =
rng_()%hill_size + 1;
322 DBG_NG <<
"placing hill at " << x1 <<
"," << y1 <<
" radius=" << radius <<
" is_valley=" << is_valley;
324 const int min_x = x1 - radius > 0 ? x1 - radius : 0;
325 const int max_x = x1 + radius < static_cast<long>(res.size()) ? x1 + radius : res.size();
326 const int min_y = y1 - radius > 0 ? y1 - radius : 0;
327 const int max_y = y1 + radius < static_cast<long>(res.front().size()) ? y1 + radius : res.front().size();
329 for(
int x2 = min_x; x2 < max_x; ++x2) {
330 for(
int y2 = min_y; y2 < max_y; ++y2) {
331 const int xdiff = (x2-x1);
332 const int ydiff = (y2-y1);
334 const int hill_height = radius -
static_cast<int>(std::sqrt(
static_cast<double>(xdiff*xdiff + ydiff*ydiff)));
336 if(hill_height > 0) {
338 if(hill_height > res[x2][y2]) {
341 res[x2][y2] -= hill_height;
344 res[x2][y2] += hill_height;
352 int highest = 0, lowest = 100000, x;
353 for(x = 0; std::size_t(x) != res.size(); ++x) {
354 for(
int y = 0; std::size_t(y) != res[x].size(); ++y) {
355 if(res[x][y] > highest) {
359 if(res[x][y] < lowest) {
365 LOG_NG <<
"generate_height_map"
366 <<
" lowest=" << lowest
367 <<
" highest =" << highest;
370 for(x = 0; std::size_t(x) != res.size(); ++x) {
371 for(
int y = 0; std::size_t(y) != res[x].size(); ++y) {
375 res[x][y] /= highest;
394 if(x < 0 || y < 0 || x >= terrain.
w || y >= terrain.
h || lake_fall_off < 0) {
398 unsigned int ulake_fall_off = lake_fall_off;
402 if((
rng_()%100) < ulake_fall_off) {
406 if((
rng_()%100) < ulake_fall_off) {
410 if((
rng_()%100) < ulake_fall_off) {
414 if((
rng_()%100) < ulake_fall_off) {
440 terrain_map& terrain,
int x,
int y, std::vector<map_location>& river,
441 std::set<map_location>& seen_locations,
int river_uphill)
443 const bool on_map = x >= 0 && y >= 0 &&
444 x < static_cast<long>(heights.size()) &&
445 y < static_cast<long>(heights.back().size());
447 if(on_map && !river.empty() && heights[x][y] >
448 heights[river.back().x][river.back().y] + river_uphill) {
457 LOG_NG <<
"generating river...";
460 for(
auto i : river) {
464 LOG_NG <<
"done generating river";
474 seen_locations.insert(current_loc);
475 river.push_back(current_loc);
477 if(seen_locations.count(loc) == 0) {
493 std::vector<map_location> river;
494 std::set<map_location> seen_locations;
509 const int side =
rng_()%4;
511 const int x =
rng_()%width;
512 const int y = side == 0 ? 0 : height-1;
515 const int y =
rng_()%height;
516 const int x = side == 2 ? 0 : width-1;
535 for(std::size_t y = begin_y; y != end_y; ++y) {
536 for(std::size_t x = begin_x; x != end_x; ++x) {
537 map[x - begin_x][y - begin_y] = terrain[x][y];
549 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)
553 std::size_t avg_distance = 0, lowest_distance = 1000;
555 for(std::vector<map_location>::const_iterator
c = other_castles.begin();
c != other_castles.end(); ++
c) {
561 if(distance < lowest_distance) {
562 lowest_distance = distance;
565 if(distance < min_distance) {
569 avg_distance += distance;
572 if(!other_castles.empty()) {
573 avg_distance /= other_castles.size();
576 for(
int i = x-1;
i <= x+1; ++
i) {
577 for(
int j = y-1; j <= y+1; ++j) {
578 if(!valid_terrain(
i,j)) {
584 const int x_from_border = std::min<int>(x - min_x,max_x - x);
585 const int y_from_border = std::min<int>(y - min_y,max_y - y);
587 const int border_ranking = min_distance - std::min<int>(x_from_border,y_from_border) + min_distance - x_from_border - y_from_border;
589 int current_ranking = border_ranking*2 + avg_distance*10 + lowest_distance*10;
590 static const int num_nearby_locations = 11*11;
592 const int max_possible_ranking = current_ranking + num_nearby_locations;
594 if(max_possible_ranking < highest_ranking) {
595 return current_ranking;
598 int surrounding_ranking = 0;
600 for(
int xpos = x-5; xpos <= x+5; ++xpos) {
601 for(
int ypos = y-5; ypos <= y+5; ++ypos) {
602 if(valid_terrain(xpos,ypos)) {
603 ++surrounding_ranking;
608 return surrounding_ranking + current_ranking;
614 const std::size_t x,
const std::size_t y,
const std::size_t radius,
const config& cfg,
618 std::set<map_location> locs;
623 if(
i.x < 0 ||
i.y < 0 ||
i.x >= map.
w ||
631 if(
auto child = cfg.
find_child(
"village",
"terrain", str)) {
634 if(l != adj_liked_cache.end()) {
635 adjacent_liked = &(l->second);
638 adjacent_liked = &(adj_liked_cache[
t]);
641 int rating = child[
"rating"].to_int();
643 if(adj.x < 0 || adj.y < 0 || adj.x >= map.
w || adj.y >= map.
h) {
648 rating += std::count(adjacent_liked->begin(),adjacent_liked->end(),t2);
651 if(rating > best_rating) {
653 best_rating = rating;
664 unsigned width,
unsigned height,
665 std::size_t label_count, std::map<map_location,std::string>* labels,
const std::string& full_name) {
671 if(
static_cast<unsigned>(adj.x) >= width / 3 ||
static_cast<unsigned>(adj.y) >= height / 3) {
677 tile_names.emplace(adj, name);
679 if(label_count % 6 == 0) {
680 labels->emplace(adj, full_name);
683 flood_name(adj, name, tile_names, tile_types, terrain, width, height, label_count++, labels, full_name);
692 LOG_NG <<
"default_generate_map parameters"
693 <<
" width=" <<
data.width
694 <<
" height=" <<
data.height
695 <<
" nplayers=" <<
data.nplayers
696 <<
" nvillages=" <<
data.nvillages
697 <<
" iterations=" <<
data.iterations
698 <<
" hill_size=" <<
data.hill_size
699 <<
" castle_size=" <<
data.castle_size
700 <<
" island_size=" <<
data.island_size
701 <<
" island_off_center=" <<
data.island_off_center
702 <<
" max_lakes=" <<
data.max_lakes
703 <<
" link_castles=" <<
data.link_castles
704 <<
" show_labels=" <<
data.show_labels;
729 std::map<map_location,std::string>* misc_labels = naming.
empty() ? nullptr : labels;
731 std::shared_ptr<name_generator>
732 base_name_generator, river_name_generator, lake_name_generator,
733 road_name_generator, bridge_name_generator, mountain_name_generator,
734 forest_name_generator, swamp_name_generator;
736 if(misc_labels !=
nullptr) {
737 name_generator_factory base_generator_factory{ naming, {
"male",
"base",
"bridge",
"road",
"river",
"forest",
"lake",
"mountain",
"swamp"} };
742 base_name_generator = base_generator_factory.get_name_generator( (naming.
has_attribute(
"base_names") || naming.
has_attribute(
"base_name_generator")) ?
"base" :
"male" );
743 river_name_generator = base_generator_factory.get_name_generator(
"river");
744 lake_name_generator = base_generator_factory.get_name_generator(
"lake");
745 road_name_generator = base_generator_factory.get_name_generator(
"road");
746 bridge_name_generator = base_generator_factory.get_name_generator(
"bridge");
747 mountain_name_generator = base_generator_factory.get_name_generator(
"mountain");
748 forest_name_generator = base_generator_factory.get_name_generator(
"forest");
749 swamp_name_generator = base_generator_factory.get_name_generator(
"swamp");
755 LOG_NG <<
"Done generating height map. " << timer <<
" ticks elapsed";
758 std::string flatland = cfg[
"default_flatland"];
759 if(flatland.empty()) {
765 std::vector<terrain_height_mapper> height_conversion;
767 height_conversion.emplace_back(
h);
771 for(std::size_t x = 0; x != heights.size(); ++x) {
772 for(std::size_t y = 0; y != heights[x].size(); ++y) {
773 for(
auto i : height_conversion) {
774 if(
i.convert_terrain(heights[x][y])) {
775 terrain[x][y] =
i.convert_to();
784 LOG_NG <<
"Placed landforms. " << timer <<
" ticks elapsed";
798 std::set<map_location> lake_locs;
800 std::map<map_location, std::string> river_names, lake_names, road_names, bridge_names, mountain_names, forest_names, swamp_names;
802 const std::size_t nlakes =
data.max_lakes > 0 ? (
rng_()%
data.max_lakes) : 0;
803 for(std::size_t lake = 0; lake != nlakes; ++lake) {
804 for(
int tries = 0; tries != 100; ++tries) {
808 if(heights[x][y] <= cfg[
"min_lake_height"].to_int()) {
812 std::vector<map_location> river =
generate_river(heights, terrain, x, y, cfg[
"river_frequency"].to_int());
814 if(!river.empty() && misc_labels !=
nullptr) {
815 const std::string
base_name = base_name_generator->generate();
816 const std::string& name = river_name_generator->generate({{
"base",
base_name}});
817 LOG_NG <<
"Named river '" << name <<
"'";
819 std::size_t name_frequency = 20;
820 for(std::vector<map_location>::const_iterator r = river.begin(); r != river.end(); ++r) {
823 if(((r - river.begin())%name_frequency) == name_frequency/2) {
824 misc_labels->emplace(loc, name);
831 LOG_NG <<
"Generating lake...";
833 std::set<map_location> locs;
834 if(
generate_lake(terrain, x, y, cfg[
"lake_size"].to_int(), locs) && misc_labels !=
nullptr) {
835 bool touches_other_lake =
false;
837 std::string
base_name = base_name_generator->generate();
838 const std::string& name = lake_name_generator->generate({{
"base",
base_name}});
843 if(lake_locs.count(
i) != 0) {
844 touches_other_lake =
true;
848 const std::map<map_location,std::string>::const_iterator other_name = lake_names.find(loc);
849 if(other_name != lake_names.end()) {
857 if(!touches_other_lake) {
859 misc_labels->erase(loc);
860 misc_labels->emplace(loc, name);
873 LOG_NG <<
"Generated rivers. " << timer <<
" ticks elapsed";
875 const std::size_t default_dimensions = 40*40*9;
886 cfg[
"temperature_iterations"].to_size_t() *
data.width *
data.height / default_dimensions,
887 cfg[
"temperature_size"].to_size_t(), 0, 0);
889 LOG_NG <<
"Generated temperature map. " << timer <<
" ticks elapsed";
891 std::vector<terrain_converter> converters;
893 converters.emplace_back(cv);
897 for(
int x = 0; x !=
data.width; ++x) {
898 for(
int y = 0; y !=
data.height; ++y) {
899 for(
auto i : converters) {
900 if(
i.convert_terrain(terrain[x][y],heights[x][y],temperature_map[x][y])) {
901 terrain[x][y] =
i.convert_to();
908 LOG_NG <<
"Converted terrain. " << timer <<
" ticks elapsed";
909 LOG_NG <<
"Placing castles...";
920 std::vector<map_location> castles;
921 std::set<map_location> failed_locs;
932 for(
int player = 0; player !=
data.nplayers; ++player) {
933 LOG_NG <<
"placing castle for " << player;
935 const int min_x =
data.width/3 + 3;
936 const int min_y =
data.height/3 + 3;
937 const int max_x = (
data.width/3)*2 - 4;
938 const int max_y = (
data.height/3)*2 - 4;
939 int min_distance = castle_config[
"min_distance"].to_int();
942 int best_ranking = 0;
943 for(
int x = min_x; x != max_x; ++x) {
944 for(
int y = min_y; y != max_y; ++y) {
946 if(failed_locs.count(loc)) {
950 const int ranking =
rank_castle_location(x, y, terrain_tester, min_x, max_x, min_y, max_y, min_distance, castles, best_ranking);
952 failed_locs.insert(loc);
955 if(ranking > best_ranking) {
956 best_ranking = ranking;
962 if(best_ranking == 0) {
963 ERR_NG <<
"No castle location found, for " <<
data.nplayers <<
" players aborting. ";
964 const std::string error =
_(
"No valid castle location found. Too many or too few mountain hexes? (please check the ‘max hill size’ parameter)");
968 assert(std::find(castles.begin(), castles.end(), best_loc) == castles.end());
969 castles.push_back(best_loc);
972 failed_locs.insert(best_loc);
975 LOG_NG <<
"Placed castles. " << timer <<
" ticks elapsed";
977 LOG_NG <<
"Placing roads...";
982 int nroads = cfg[
"roads"].to_int();
983 if(
data.link_castles) {
984 nroads += castles.size()*castles.size();
987 std::set<map_location> bridges;
989 road_path_calculator calc(terrain, cfg,
rng_());
990 for(
int road = 0; road != nroads; ++road) {
1006 if(
data.link_castles && road <
static_cast<int>(castles.size() * castles.size())) {
1007 const std::size_t src_castle = road/castles.size();
1008 const std::size_t dst_castle = road%castles.size();
1009 if(src_castle >= dst_castle) {
1013 src = castles[src_castle];
1014 dst = castles[dst_castle];
1020 if(calc.cost(
src, 0.0) >= 1000.0 || calc.cost(
dst, 0.0) >= 1000.0) {
1027 const std::string& road_base_name = misc_labels !=
nullptr
1028 ? base_name_generator->generate()
1030 const std::string& road_name = misc_labels !=
nullptr
1031 ? road_name_generator->generate({{
"base", road_base_name}})
1033 const int name_frequency = 20;
1036 bool on_bridge =
false;
1040 for(std::vector<map_location>::const_iterator step = rt.
steps.begin();
1041 step != rt.
steps.end(); ++step) {
1043 const int x = step->x;
1044 const int y = step->y;
1046 if(x < 0 || y < 0 || x >=
static_cast<long>(
data.width) || y >=
static_cast<long>(
data.height)) {
1052 if(!child || child->empty()){
1063 const std::string& convert_to_bridge = child[
"convert_to_bridge"];
1064 if(!convert_to_bridge.empty()) {
1065 if(step == rt.
steps.begin() || step+1 == rt.
steps.end()) {
1076 if((last == adj[0] && next == adj[3]) || (last == adj[3] && next == adj[0])) {
1081 else if((last == adj[1] && next == adj[4]) || (last == adj[4] && next == adj[1])) {
1086 else if((last == adj[2] && next == adj[5]) || (last == adj[5] && next == adj[2])) {
1090 if(misc_labels !=
nullptr && !on_bridge) {
1092 std::string bridge_base_name = base_name_generator->generate();
1093 const std::string& name = bridge_name_generator->generate({{
"base", bridge_base_name}});
1095 misc_labels->emplace(loc, name);
1096 bridge_names.emplace(loc, bridge_base_name);
1097 bridges.insert(loc);
1100 if(direction != -1) {
1101 const std::vector<std::string> items =
utils::split(convert_to_bridge);
1102 if(std::size_t(direction) < items.size() && !items[direction].empty()) {
1113 const std::string& convert_to = child[
"convert_to"];
1114 if(!convert_to.empty()) {
1116 if(misc_labels !=
nullptr && terrain[x][y] != letter && name_count++ == name_frequency && !on_bridge) {
1121 terrain[x][y] = letter;
1122 if(misc_labels !=
nullptr) {
1124 if(!road_base_name.empty())
1125 road_names.emplace(loc, road_base_name);
1132 for(std::vector<map_location>::const_iterator
c = castles.begin();
c != castles.end(); ++
c) {
1139 const int player =
c - castles.begin() + 1;
1141 starting_positions.insert(t_translation::starting_positions::value_type(std::to_string(player), coord));
1144 const int castle_array[13][2] {
1145 {-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {0, 1}, {-1, 1},
1146 {-2, 1}, {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, {1, -2}
1149 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1154 if(labels !=
nullptr) {
1156 for(
int i = 0;
i <
data.castle_size - 1;
i++) {
1162 LOG_NG <<
"Placed roads. " << timer <<
" ticks elapsed";
1168 if(misc_labels !=
nullptr) {
1169 std::set<std::string> used_names;
1170 for(
int x =
data.width / 3; x < (
data.width / 3)*2; x++) {
1171 for(
int y =
data.height / 3; y < (
data.height / 3) * 2;y++) {
1179 if((
rng_() % 15) == 0) {
1180 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1181 base_name = base_name_generator->generate();
1182 name = mountain_name_generator->generate({{
"base",
base_name}});
1184 misc_labels->emplace(loc, name);
1189 const std::map<map_location, std::string>::const_iterator forest_name = forest_names.find(loc);
1190 if(forest_name == forest_names.end()) {
1191 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1192 base_name = base_name_generator->generate();
1193 name = forest_name_generator->generate({{
"base",
base_name}});
1201 const std::map<map_location, std::string>::const_iterator swamp_name = swamp_names.find(loc);
1202 if(swamp_name == swamp_names.end()) {
1203 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1204 base_name = base_name_generator->generate();
1205 name = swamp_name_generator->generate({{
"base",
base_name}});
1213 used_names.insert(name);
1219 LOG_NG <<
"Named landforms. " << timer <<
" ticks elapsed";
1220 LOG_NG <<
"Placing villages...";
1227 std::set<map_location> villages;
1229 if(
data.nvillages > 0) {
1232 const std::size_t tiles_per_village = ((
data.width*
data.height)/9)/
data.nvillages;
1233 std::size_t village_x = 1, village_y = 1;
1238 while(village_x*village_y < tiles_per_village) {
1239 if(village_x < village_y) {
1246 std::set<std::string> used_names;
1256 std::map<map_location,std::string>* village_labels = village_naming.
empty() ? nullptr : labels;
1258 for(
int vx = 0; vx <
data.width; vx += village_x) {
1259 LOG_NG <<
"village at " << vx;
1261 for(
int vy =
rng_()%village_y; vy <
data.height; vy += village_y) {
1262 const std::size_t add =
rng_()%3;
1263 const std::size_t x = (vx + add) - 1;
1264 const std::size_t y = (vy + add) - 1;
1268 if(res.
x <
static_cast<long>(
data.width ) / 3 ||
1269 res.
x >=
static_cast<long>(
data.width * 2) / 3 ||
1270 res.
y <
static_cast<long>(
data.height ) / 3 ||
1271 res.
y >=
static_cast<long>(
data.height * 2) / 3) {
1277 const std::string& convert_to = cfg.
find_mandatory_child(
"village",
"terrain", str)[
"convert_to"].str();
1278 if(convert_to.empty()) {
1284 villages.insert(res);
1286 if(village_labels ==
nullptr) {
1291 {
"base",
"male",
"village",
"lake",
"river",
"bridge",
"grassland",
"forest",
"hill",
"mountain",
"mountain_anon",
"road",
"swamp"} };
1296 base_name_generator = village_name_generator_factory.get_name_generator(
1302 std::string name_type =
"village";
1309 std::size_t field_count = 0, forest_count = 0, mountain_count = 0, hill_count = 0;
1311 std::map<std::string,std::string> symbols;
1314 for(
n = 0;
n != 6; ++
n) {
1315 const std::map<map_location,std::string>::const_iterator road_name = road_names.find(adj[
n]);
1316 if(road_name != road_names.end()) {
1317 symbols[
"road"] = road_name->second;
1322 const std::map<map_location,std::string>::const_iterator river_name = river_names.find(adj[
n]);
1323 if(river_name != river_names.end()) {
1324 symbols[
"river"] = river_name->second;
1325 name_type =
"river";
1327 const std::map<map_location,std::string>::const_iterator bridge_name = bridge_names.find(adj[
n]);
1328 if(bridge_name != bridge_names.end()) {
1330 symbols[
"bridge"] = bridge_name->second;
1331 name_type =
"river_bridge";
1337 const std::map<map_location,std::string>::const_iterator forest_name = forest_names.find(adj[
n]);
1338 if(forest_name != forest_names.end()) {
1339 symbols[
"forest"] = forest_name->second;
1340 name_type =
"forest";
1344 const std::map<map_location,std::string>::const_iterator lake_name = lake_names.find(adj[
n]);
1345 if(lake_name != lake_names.end()) {
1346 symbols[
"lake"] = lake_name->second;
1351 const std::map<map_location,std::string>::const_iterator mountain_name = mountain_names.find(adj[
n]);
1352 if(mountain_name != mountain_names.end()) {
1353 symbols[
"mountain"] = mountain_name->second;
1354 name_type =
"mountain";
1358 const std::map<map_location,std::string>::const_iterator swamp_name = swamp_names.find(adj[
n]);
1359 if(swamp_name != swamp_names.end()) {
1360 symbols[
"swamp"] = swamp_name->second;
1361 name_type =
"swamp";
1367 if(std::count(field.begin(),field.end(),terr) > 0) {
1369 }
else if(std::count(forest.begin(),forest.end(),terr) > 0) {
1371 }
else if(std::count(hill.begin(),hill.end(),terr) > 0) {
1373 }
else if(std::count(mountain.begin(),mountain.end(),terr) > 0) {
1379 if(field_count == 6) {
1380 name_type =
"grassland";
1381 }
else if(forest_count >= 2) {
1382 name_type =
"forest";
1383 }
else if(mountain_count >= 1) {
1384 name_type =
"mountain_anon";
1385 }
else if(hill_count >= 2) {
1392 symbols[
"base"] = base_name_generator->generate();
1393 std::shared_ptr<name_generator> village_name_generator = village_name_generator_factory.get_name_generator(name_type);
1395 for(std::size_t ntry = 0; ntry != 30 && (ntry == 0 || used_names.count(name) > 0); ++ntry) {
1396 name = village_name_generator->generate(symbols);
1399 used_names.insert(name);
1400 village_labels->emplace(loc, name);
1405 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.
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.
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.
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)
void get_adjacent_tiles(const map_location &a, map_location *res)
Function which, given a location, will place all adjacent locations in res.
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.
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
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.