Default Map Generator: refactored generator setting parameters into a struct

This commit is contained in:
Charles Dang 2016-09-03 04:33:30 +11:00
parent f66884cf01
commit 0d07c1a815
4 changed files with 151 additions and 174 deletions

View file

@ -36,62 +36,27 @@ namespace {
const size_t max_coastal = 5;
}
default_map_generator::default_map_generator(const config &cfg) :
default_width_(40),
default_height_(40),
width_(40),
height_(40),
island_size_(0),
iterations_(1000),
hill_size_(10),
max_lakes_(20),
nvillages_(25),
castle_size_(9),
nplayers_(2),
link_castles_(true),
show_labels_(true),
cfg_(cfg ? cfg : config())
generator_data::generator_data(const config &cfg)
: width(std::max(0, cfg["map_width"].to_int(40)))
, height(std::max(0, cfg["map_height"].to_int(40)))
, default_width(width)
, default_height(height)
, nplayers(std::max(0, cfg["players"].to_int(2)))
, nvillages(std::max(0, cfg["villages"].to_int(25)))
, iterations(std::max(0, cfg["iterations"].to_int(1000)))
, hill_size(std::max(0, cfg["hill_size"].to_int(10)))
, castle_size(std::max(0, cfg["castle_size"].to_int(9)))
, island_size(std::max(0, cfg["island_size"].to_int(0)))
, max_lakes(std::max(0, cfg["max_lakes"].to_int(20)))
, link_castles(true)
, show_labels(true)
{
if (!cfg) return;
}
int width = cfg["map_width"];
if (width > 0)
width_ = width;
int height = cfg["map_height"];
if (height > 0)
height_ = height;
default_width_ = width_;
default_height_ = height_;
int iterations = cfg["iterations"];
if (iterations > 0)
iterations_ = iterations;
int hill_size = cfg["hill_size"];
if (hill_size > 0)
hill_size_ = hill_size;
int max_lakes = cfg["max_lakes"];
if (max_lakes > 0)
max_lakes_ = max_lakes;
int nvillages = cfg["villages"];
if (nvillages > 0)
nvillages_ = nvillages;
int castle_size = cfg["castle_size"];
if (castle_size > 0)
castle_size_ = castle_size;
int nplayers = cfg["players"];
if (nplayers > 0)
nplayers_ = nplayers;
int island_size = cfg["island_size"];
if (island_size > 0)
island_size_ = island_size;
default_map_generator::default_map_generator(const config& cfg)
: cfg_(cfg)
, data_(cfg)
{
}
bool default_map_generator::allow_user_config() const { return true; }
@ -129,7 +94,7 @@ void default_map_generator::user_config(CVideo& v)
SDL_Rect players_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,0,0);
SDL_Rect width_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,0,0);
SDL_Rect height_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,0,0);
SDL_Rect iterations_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,0,0);
SDL_Rect iteration_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,0,0);
SDL_Rect hillsize_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,0,0);
SDL_Rect villages_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,0,0);
SDL_Rect castlesize_rect = font::draw_text(nullptr,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,0,0);
@ -138,12 +103,12 @@ void default_map_generator::user_config(CVideo& v)
const int horz_margin = 15;
const int text_right = xpos + horz_margin +
std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>(std::max<int>(
players_rect.w,width_rect.w),height_rect.w),iterations_rect.w),hillsize_rect.w),villages_rect.w),castlesize_rect.w);
players_rect.w,width_rect.w),height_rect.w),iteration_rect.w),hillsize_rect.w),villages_rect.w),castlesize_rect.w);
players_rect.x = text_right - players_rect.w;
width_rect.x = text_right - width_rect.w;
height_rect.x = text_right - height_rect.w;
iterations_rect.x = text_right - iterations_rect.w;
iteration_rect.x = text_right - iteration_rect.w;
hillsize_rect.x = text_right - hillsize_rect.w;
villages_rect.x = text_right - villages_rect.w;
castlesize_rect.x = text_right - castlesize_rect.w;
@ -153,10 +118,10 @@ void default_map_generator::user_config(CVideo& v)
players_rect.y = ypos + vertical_margin*2;
width_rect.y = players_rect.y + players_rect.h + vertical_margin;
height_rect.y = width_rect.y + width_rect.h + vertical_margin;
iterations_rect.y = height_rect.y + height_rect.h + vertical_margin;
hillsize_rect.y = iterations_rect.y + iterations_rect.h + vertical_margin;
iteration_rect.y = height_rect.y + height_rect.h + vertical_margin;
hillsize_rect.y = iteration_rect.y + iteration_rect.h + vertical_margin;
villages_rect.y = hillsize_rect.y + hillsize_rect.h + vertical_margin;
castlesize_rect.y = villages_rect.y + iterations_rect.h + vertical_margin;
castlesize_rect.y = villages_rect.y + iteration_rect.h + vertical_margin;
landform_rect.y = castlesize_rect.y + villages_rect.h + vertical_margin;
const int right_space = 150;
@ -172,7 +137,7 @@ void default_map_generator::user_config(CVideo& v)
players_slider.set_location(slider_rect);
players_slider.set_min(2);
players_slider.set_max(gamemap::MAX_PLAYERS);
players_slider.set_value(nplayers_);
players_slider.set_value(data_.nplayers);
const int min_width = 20;
const int max_width = 100;
@ -184,24 +149,24 @@ void default_map_generator::user_config(CVideo& v)
width_slider.set_location(slider_rect);
width_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
width_slider.set_max(max_width);
width_slider.set_value(width_);
width_slider.set_value(data_.width);
slider_rect.y = height_rect.y;
gui::slider height_slider(screen);
height_slider.set_location(slider_rect);
height_slider.set_min(min_width+(players_slider.value()-2)*extra_size_per_player);
height_slider.set_max(max_height);
height_slider.set_value(height_);
height_slider.set_value(data_.height);
const int min_iterations = 10;
const int max_iterations = 3000;
slider_rect.y = iterations_rect.y;
slider_rect.y = iteration_rect.y;
gui::slider iterations_slider(screen);
iterations_slider.set_location(slider_rect);
iterations_slider.set_min(min_iterations);
iterations_slider.set_max(max_iterations);
iterations_slider.set_value(iterations_);
iterations_slider.set_value(data_.iterations);
const int min_hillsize = 1;
const int max_hillsize = 50;
@ -211,7 +176,7 @@ void default_map_generator::user_config(CVideo& v)
hillsize_slider.set_location(slider_rect);
hillsize_slider.set_min(min_hillsize);
hillsize_slider.set_max(max_hillsize);
hillsize_slider.set_value(hill_size_);
hillsize_slider.set_value(data_.hill_size);
const int min_villages = 0;
const int max_villages = 50;
@ -221,7 +186,7 @@ void default_map_generator::user_config(CVideo& v)
villages_slider.set_location(slider_rect);
villages_slider.set_min(min_villages);
villages_slider.set_max(max_villages);
villages_slider.set_value(nvillages_);
villages_slider.set_value(data_.nvillages);
const int min_castlesize = 2;
const int max_castlesize = 14;
@ -231,7 +196,7 @@ void default_map_generator::user_config(CVideo& v)
castlesize_slider.set_location(slider_rect);
castlesize_slider.set_min(min_castlesize);
castlesize_slider.set_max(max_castlesize);
castlesize_slider.set_value(castle_size_);
castlesize_slider.set_value(data_.castle_size);
const int min_landform = 0;
@ -241,31 +206,31 @@ void default_map_generator::user_config(CVideo& v)
landform_slider.set_location(slider_rect);
landform_slider.set_min(min_landform);
landform_slider.set_max(max_landform);
landform_slider.set_value(island_size_);
landform_slider.set_value(data_.island_size);
SDL_Rect link_rect = slider_rect;
link_rect.y = link_rect.y + link_rect.h + vertical_margin;
gui::button link_castles(screen,_("Roads between castles"),gui::button::TYPE_CHECK);
link_castles.set_check(link_castles_);
link_castles.set_check(data_.link_castles);
link_castles.set_location(link_rect);
SDL_Rect labels_rect = link_rect;
labels_rect.y = labels_rect.y + labels_rect.h + vertical_margin;
gui::button show_labels(screen,_("Show labels"),gui::button::TYPE_CHECK);
show_labels.set_check(show_labels_);
show_labels.set_check(data_.show_labels);
show_labels.set_location(labels_rect);
while(true) {
nplayers_ = players_slider.value();
width_ = width_slider.value();
height_ = height_slider.value();
iterations_ = iterations_slider.value();
hill_size_ = hillsize_slider.value();
nvillages_ = villages_slider.value();
castle_size_ = castlesize_slider.value();
island_size_ = landform_slider.value();
data_.nplayers = players_slider.value();
data_.width = width_slider.value();
data_.height = height_slider.value();
data_.iterations = iterations_slider.value();
data_.hill_size = hillsize_slider.value();
data_.nvillages = villages_slider.value();
data_.castle_size = castlesize_slider.value();
data_.island_size = landform_slider.value();
dialog_restorer.restore();
close_button.set_dirty(true);
@ -293,35 +258,35 @@ void default_map_generator::user_config(CVideo& v)
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,players_label,players_rect.x,players_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,width_label,width_rect.x,width_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,height_label,height_rect.x,height_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,iterations_rect.x,iterations_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,iterations_label,iteration_rect.x,iteration_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,hillsize_label,hillsize_rect.x,hillsize_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_label,villages_rect.x,villages_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,castlesize_label,castlesize_rect.x,castlesize_rect.y);
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_label,landform_rect.x,landform_rect.y);
font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
font::NORMAL_COLOR, std::to_string(nplayers_),
font::NORMAL_COLOR, std::to_string(data_.nplayers),
slider_right + horz_margin, players_rect.y);
font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
font::NORMAL_COLOR, std::to_string(width_),
font::NORMAL_COLOR, std::to_string(data_.width),
slider_right + horz_margin, width_rect.y);
font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
font::NORMAL_COLOR, std::to_string(height_),
font::NORMAL_COLOR, std::to_string(data_.height),
slider_right+horz_margin,height_rect.y);
std::stringstream villages_str;
villages_str << nvillages_ << _("/1000 tiles");
villages_str << data_.nvillages << _("/1000 tiles");
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,villages_str.str(),
slider_right+horz_margin,villages_rect.y);
font::draw_text(&screen, screen_area(), font::SIZE_NORMAL,
font::NORMAL_COLOR, std::to_string(castle_size_),
font::NORMAL_COLOR, std::to_string(data_.castle_size),
slider_right + horz_margin, castlesize_rect.y);
std::stringstream landform_str;
landform_str << translation::gettext(island_size_ == 0 ? N_("Inland") : (island_size_ < max_coastal ? N_("Coastal") : N_("Island")));
landform_str << translation::gettext(data_.island_size == 0 ? N_("Inland") : (data_.island_size < max_coastal ? N_("Coastal") : N_("Island")));
font::draw_text(&screen,screen_area(),font::SIZE_NORMAL,font::NORMAL_COLOR,landform_str.str(),
slider_right+horz_margin,landform_rect.y);
@ -332,8 +297,8 @@ void default_map_generator::user_config(CVideo& v)
events::pump();
}
link_castles_ = link_castles.checked();
show_labels_ = show_labels.checked();
data_.link_castles = link_castles.checked();
data_.show_labels = show_labels.checked();
}
std::string default_map_generator::name() const { return "default"; }
@ -362,36 +327,37 @@ std::string default_map_generator::generate_map(std::map<map_location,std::strin
}
// Suppress labels?
if ( !show_labels_ )
if ( !data_.show_labels )
labels = nullptr;
// the random generator thinks odd widths are nasty, so make them even
if (is_odd(width_))
++width_;
if (is_odd(data_.width))
++data_.width;
size_t iterations = (iterations_*width_*height_)/(default_width_*default_height_);
size_t island_size = 0;
data_.island_size = 0;
data_.iterations = (data_.iterations*data_.width*data_.height)/(data_.default_width*data_.default_height);
size_t island_off_center = 0;
size_t max_lakes = max_lakes_;
if(island_size_ >= max_coastal) {
if(static_cast<unsigned>(data_.island_size) >= max_coastal) {
//islands look good with much fewer iterations than normal, and fewer lake
iterations /= 10;
max_lakes /= 9;
data_.iterations /= 10;
data_.max_lakes /= 9;
//the radius of the island should be up to half the width of the map
const size_t island_radius = 50 + ((max_island - island_size_)*50)/(max_island - max_coastal);
island_size = (island_radius*(width_/2))/100;
} else if(island_size_ > 0) {
const size_t island_radius = 50 + ((max_island - data_.island_size)*50)/(max_island - max_coastal);
data_.island_size = (island_radius*(data_.width/2))/100;
} else if(data_.island_size > 0) {
DBG_NG << "coastal...\n";
//the radius of the island should be up to twice the width of the map
const size_t island_radius = 40 + ((max_coastal - island_size_)*40)/max_coastal;
island_size = (island_radius*width_*2)/100;
island_off_center = std::min<size_t>(width_,height_);
const size_t island_radius = 40 + ((max_coastal - data_.island_size)*40)/max_coastal;
data_.island_size = (island_radius*data_.width*2)/100;
island_off_center = std::min<size_t>(data_.width,data_.height);
DBG_NG << "calculated coastal params...\n";
}
data_.nvillages = (data_.nvillages * data_.width * data_.height) / 1000;
// A map generator can fail so try a few times to get a map before aborting.
std::string map;
// Keep a copy of labels as it can be written to by the map generator func
@ -407,9 +373,7 @@ std::string default_map_generator::generate_map(std::map<map_location,std::strin
labels_copy = *labels;
}
try{
map = job.default_generate_map(width_, height_, island_size, island_off_center,
iterations, hill_size_, max_lakes, (nvillages_ * width_ * height_) / 1000,
castle_size_, nplayers_, link_castles_, labels_ptr, cfg_);
map = job.default_generate_map(data_, island_off_center, labels_ptr, cfg_);
error_message = "";
}
catch (mapgen_exception& exc){
@ -451,8 +415,8 @@ config default_map_generator::create_scenario(boost::optional<uint32_t> randomse
labels.begin(); i != labels.end(); ++i) {
if(i->first.x >= 0 && i->first.y >= 0 &&
i->first.x < static_cast<long>(width_) &&
i->first.y < static_cast<long>(height_)) {
i->first.x < static_cast<long>(data_.width) &&
i->first.y < static_cast<long>(data_.height)) {
config& label = res.add_child("label");
label["text"] = i->second;

View file

@ -18,6 +18,24 @@
#include "config.hpp"
#include "generators/map_generator.hpp"
struct generator_data {
generator_data(const config& cfg);
int width;
int height;
int default_width;
int default_height;
int nplayers;
int nvillages;
int iterations;
int hill_size;
int castle_size;
int island_size;
int max_lakes;
bool link_castles;
bool show_labels;
};
class default_map_generator : public map_generator
{
public:
@ -34,12 +52,11 @@ public:
config create_scenario(boost::optional<uint32_t> randomseed);
private:
std::string generate_map(std::map<map_location,std::string>* labels, boost::optional<uint32_t> randomseed);
size_t default_width_, default_height_, width_, height_, island_size_, iterations_, hill_size_, max_lakes_, nvillages_, castle_size_, nplayers_;
bool link_castles_, show_labels_;
config cfg_;
generator_data data_;
};
#endif

View file

@ -705,14 +705,12 @@ static void flood_name(const map_location& start, const std::string& name, std::
}
}
std::string default_map_generator_job::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)
std::string default_map_generator_job::default_generate_map(generator_data data, size_t island_off_center, std::map<map_location,std::string>* labels, const config& cfg)
{
log_scope("map generation");
// Odd widths are nasty
VALIDATE(is_even(width), _("Random maps with an odd width aren't supported."));
VALIDATE(is_even(data.width), _("Random maps with an odd data.width aren't supported."));
// Try to find configuration for castles
const config& castle_config = cfg.child("castle");
@ -727,8 +725,8 @@ std::string default_map_generator_job::default_generate_map(
// Only the middle part of the map will be used, but the rest is so that the map we
// end up using can have a context (e.g. rivers flowing from out of the map into the map,
// same for roads, etc.)
width *= 3;
height *= 3;
data.width *= 3;
data.height *= 3;
config naming = game_config_.child("naming");
@ -761,7 +759,7 @@ std::string default_map_generator_job::default_generate_map(
}
// Generate the height of everything.
const height_map heights = generate_height_map(width, height, iterations, hill_size, island_size, island_off_center);
const height_map heights = generate_height_map(data.width, data.height, data.iterations, data.hill_size, data.island_size, island_off_center);
LOG_NG << "Done generating height map. " << (SDL_GetTicks() - ticks) << " ticks elapsed" << "\n";
ticks = SDL_GetTicks();
@ -779,7 +777,7 @@ std::string default_map_generator_job::default_generate_map(
height_conversion.push_back(terrain_height_mapper(h));
}
terrain_map terrain(width, t_translation::t_list(height, grassland));
terrain_map terrain(data.width, t_translation::t_list(data.height, grassland));
size_t x, y;
for(x = 0; x != heights.size(); ++x) {
for(y = 0; y != heights[x].size(); ++y) {
@ -813,11 +811,11 @@ std::string default_map_generator_job::default_generate_map(
std::map<map_location, std::string> river_names, lake_names, road_names, bridge_names, mountain_names, forest_names, swamp_names;
const size_t nlakes = max_lakes > 0 ? (rng_()%max_lakes) : 0;
const size_t nlakes = data.max_lakes > 0 ? (rng_()%data.max_lakes) : 0;
for(size_t lake = 0; lake != nlakes; ++lake) {
for(int tries = 0; tries != 100; ++tries) {
const int x = rng_()%width;
const int y = rng_()%height;
const int x = rng_()%data.width;
const int y = rng_()%data.height;
if(heights[x][y] <= cfg["min_lake_height"].to_int()) {
continue;
@ -832,7 +830,7 @@ std::string default_map_generator_job::default_generate_map(
size_t name_frequency = 20;
for(std::vector<map_location>::const_iterator r = river.begin(); r != river.end(); ++r) {
const map_location loc(r->x-width/3,r->y-height/3);
const map_location loc(r->x-data.width/3,r->y-data.height/3);
if(((r - river.begin())%name_frequency) == name_frequency/2) {
misc_labels->insert(std::pair<map_location,std::string>(loc,name));
@ -858,7 +856,7 @@ std::string default_map_generator_job::default_generate_map(
touches_other_lake = true;
// Reassign the name of this lake to be the same as the other lake
const map_location loc(i.x-width/3,i.y-height/3);
const map_location loc(i.x-data.width/3,i.y-data.height/3);
const std::map<map_location,std::string>::const_iterator other_name = lake_names.find(loc);
if(other_name != lake_names.end()) {
base_name = other_name->second;
@ -869,13 +867,13 @@ std::string default_map_generator_job::default_generate_map(
}
if(!touches_other_lake) {
const map_location loc(x-width/3,y-height/3);
const map_location loc(x-data.width/3,y-data.height/3);
misc_labels->erase(loc);
misc_labels->insert(std::pair<map_location,std::string>(loc,name));
}
for(auto i : locs) {
const map_location loc(i.x-width/3,i.y-height/3);
const map_location loc(i.x-data.width/3,i.y-data.height/3);
lake_names.insert(std::pair<map_location, std::string>(loc, base_name));
}
}
@ -897,8 +895,8 @@ std::string default_map_generator_job::default_generate_map(
* can use a combination of height and terrain to divide terrain up into
* more interesting types than the default.
*/
const height_map temperature_map = generate_height_map(width,height,
cfg["temperature_iterations"].to_int() * width * height / default_dimensions,
const height_map temperature_map = generate_height_map(data.width,data.height,
cfg["temperature_iterations"].to_int() * data.width * data.height / default_dimensions,
cfg["temperature_size"], 0, 0);
LOG_NG << "Generated temperature map. " << (SDL_GetTicks() - ticks) << " ticks elapsed" << "\n";
@ -913,8 +911,8 @@ std::string default_map_generator_job::default_generate_map(
ticks = SDL_GetTicks();
// Iterate over every flatland tile, and determine what type of flatland it is, based on our [convert] tags.
for(x = 0; x != width; ++x) {
for(y = 0; y != height; ++y) {
for(x = 0; x != static_cast<unsigned>(data.width); ++x) {
for(y = 0; y != static_cast<unsigned>(data.height); ++y) {
for(auto i : converters) {
if(i.convert_terrain(terrain[x][y],heights[x][y],temperature_map[x][y])) {
terrain[x][y] = i.convert_to();
@ -947,13 +945,13 @@ std::string default_map_generator_job::default_generate_map(
std::vector<map_location> castles;
std::set<map_location> failed_locs;
for(size_t player = 0; player != nplayers; ++player) {
for(int player = 0; player != data.nplayers; ++player) {
LOG_NG << "placing castle for " << player << "\n";
log_scope("placing castle");
const int min_x = width/3 + 3;
const int min_y = height/3 + 3;
const int max_x = (width/3)*2 - 4;
const int max_y = (height/3)*2 - 4;
const int min_x = data.width/3 + 3;
const int min_y = data.height/3 + 3;
const int max_x = (data.width/3)*2 - 4;
const int max_y = (data.height/3)*2 - 4;
int min_distance = castle_config["min_distance"];
map_location best_loc;
@ -997,7 +995,7 @@ std::string default_map_generator_job::default_generate_map(
// We select two tiles at random locations on the borders of the map
// and try to build roads between them.
int nroads = cfg["roads"];
if(roads_between_castles) {
if(data.link_castles) {
nroads += castles.size()*castles.size();
}
@ -1012,15 +1010,15 @@ std::string default_map_generator_job::default_generate_map(
* going to use, since roads on other parts of the map won't have any
* influence, and doing it like this will be quicker.
*/
map_location src = random_point_at_side(width/3 + 2,height/3 + 2);
map_location dst = random_point_at_side(width/3 + 2,height/3 + 2);
map_location src = random_point_at_side(data.width/3 + 2,data.height/3 + 2);
map_location dst = random_point_at_side(data.width/3 + 2,data.height/3 + 2);
src.x += width/3 - 1;
src.y += height/3 - 1;
dst.x += width/3 - 1;
dst.y += height/3 - 1;
src.x += data.width/3 - 1;
src.y += data.height/3 - 1;
dst.x += data.width/3 - 1;
dst.y += data.height/3 - 1;
if(roads_between_castles && road < int(castles.size() * castles.size())) {
if(data.link_castles && road < int(castles.size() * castles.size())) {
const size_t src_castle = road/castles.size();
const size_t dst_castle = road%castles.size();
if(src_castle >= dst_castle) {
@ -1039,7 +1037,7 @@ std::string default_map_generator_job::default_generate_map(
}
// Search a path out for the road
pathfind::plain_route rt = pathfind::a_star_search(src, dst, 10000.0, calc, width, height);
pathfind::plain_route rt = pathfind::a_star_search(src, dst, 10000.0, calc, data.width, data.height);
const std::string& road_base_name = misc_labels != nullptr
? base_name_generator->generate()
@ -1060,7 +1058,7 @@ std::string default_map_generator_job::default_generate_map(
const int x = step->x;
const int y = step->y;
if(x < 0 || y < 0 || x >= static_cast<long>(width) || y >= static_cast<long>(height)) {
if(x < 0 || y < 0 || x >= static_cast<long>(data.width) || y >= static_cast<long>(data.height)) {
continue;
}
@ -1110,7 +1108,7 @@ std::string default_map_generator_job::default_generate_map(
on_bridge = true;
std::string bridge_base_name = base_name_generator->generate();
const std::string& name = bridge_name_generator->generate({{"base", bridge_base_name}});
const map_location loc(x - width / 3, y-height/3);
const map_location loc(x - data.width / 3, y-data.height/3);
misc_labels->insert(std::pair<map_location,std::string>(loc,name));
bridge_names.insert(std::pair<map_location,std::string>(loc, bridge_base_name)); //add to use for village naming
bridges.insert(loc);
@ -1133,13 +1131,13 @@ std::string default_map_generator_job::default_generate_map(
if(!convert_to.empty()) {
const t_translation::t_terrain letter = t_translation::read_terrain_code(convert_to);
if(misc_labels != nullptr && terrain[x][y] != letter && name_count++ == name_frequency && !on_bridge) {
misc_labels->insert(std::pair<map_location,std::string>(map_location(x-width/3,y-height/3),road_name));
misc_labels->insert(std::pair<map_location,std::string>(map_location(x-data.width/3,y-data.height/3),road_name));
name_count = 0;
}
terrain[x][y] = letter;
if(misc_labels != nullptr) {
const map_location loc(x - width / 3, y - height / 3); //add to use for village naming
const map_location loc(x - data.width / 3, y - data.height / 3); //add to use for village naming
if(road_base_name != "")
road_names.insert(std::pair<map_location,std::string>(loc, road_base_name));
}
@ -1165,15 +1163,15 @@ std::string default_map_generator_job::default_generate_map(
{-2, 1}, {-2, 0}, {-2, -1}, {-1, -2}, {0, -2}, {1, -2}
};
for(size_t i = 0; i < castle_size - 1; i++) {
for(int i = 0; i < data.castle_size - 1; i++) {
terrain[x+castles[i][0]][y+castles[i][1]] = t_translation::HUMAN_CASTLE;
}
// Remove all labels under the castle tiles
if(labels != nullptr) {
labels->erase(map_location(x-width/3,y-height/3));
for(size_t i = 0; i < castle_size - 1; i++) {
labels->erase(map_location(x+castles[i][0]-width/3, y+castles[i][1]-height/3));
labels->erase(map_location(x-data.width/3,y-data.height/3));
for(int i = 0; i < data.castle_size - 1; i++) {
labels->erase(map_location(x+castles[i][0]-data.width/3, y+castles[i][1]-data.height/3));
}
}
}
@ -1186,10 +1184,10 @@ std::string default_map_generator_job::default_generate_map(
* roads could split a forest)
*/
if(misc_labels != nullptr) {
for(x = width / 3; x < (width / 3)*2; x++) {
for(y = height / 3; y < (height / 3) * 2;y++) {
for(x = static_cast<unsigned>(data.width) / 3; x < (static_cast<unsigned>(data.width) / 3)*2; x++) {
for(y = static_cast<unsigned>(data.height) / 3; y < (static_cast<unsigned>(data.height) / 3) * 2;y++) {
//check the terrain of the tile
const map_location loc(x - width / 3, y - height / 3);
const map_location loc(x - data.width / 3, y - data.height / 3);
const t_translation::t_terrain terr = terrain[x][y];
std::string name, base_name;
std::set<std::string> used_names;
@ -1214,7 +1212,7 @@ std::string default_map_generator_job::default_generate_map(
}
forest_names.insert(std::pair<map_location, std::string>(loc, base_name));
// name all connected forest tiles accordingly
flood_name(loc, base_name, forest_names, t_translation::ALL_FORESTS, terrain, width, height, 0, misc_labels, name);
flood_name(loc, base_name, forest_names, t_translation::ALL_FORESTS, terrain, data.width, data.height, 0, misc_labels, name);
}
} else if(t_translation::terrain_matches(terr, t_translation::ALL_SWAMPS)) {
// If the swamp tile is not named yet, name it
@ -1226,7 +1224,7 @@ std::string default_map_generator_job::default_generate_map(
}
swamp_names.insert(std::pair<map_location, std::string>(loc, base_name));
// name all connected swamp tiles accordingly
flood_name(loc, base_name, swamp_names, t_translation::ALL_SWAMPS, terrain, width, height, 0, misc_labels, name);
flood_name(loc, base_name, swamp_names, t_translation::ALL_SWAMPS, terrain, data.width, data.height, 0, misc_labels, name);
}
}
}
@ -1243,10 +1241,10 @@ std::string default_map_generator_job::default_generate_map(
*/
std::set<map_location> villages;
if(nvillages > 0) {
if(data.nvillages > 0) {
// First we work out the size of the x and y distance between villages
const size_t tiles_per_village = ((width*height)/9)/nvillages;
const size_t tiles_per_village = ((data.width*data.height)/9)/data.nvillages;
size_t village_x = 1, village_y = 1;
// Alternate between incrementing the x and y value.
@ -1272,20 +1270,20 @@ std::string default_map_generator_job::default_generate_map(
// If the [village_naming] child is empty, we cannot provide good names.
std::map<map_location,std::string>* village_labels = village_naming.empty() ? nullptr : labels;
for(size_t vx = 0; vx < width; vx += village_x) {
for(int vx = 0; vx < data.width; vx += village_x) {
LOG_NG << "village at " << vx << "\n";
for(size_t vy = rng_()%village_y; vy < height; vy += village_y) {
for(int vy = rng_()%village_y; vy < data.height; vy += village_y) {
const size_t add = rng_()%3;
const size_t x = (vx + add) - 1;
const size_t y = (vy + add) - 1;
const map_location res = place_village(terrain, x, y, 2, cfg, adj_liked_cache);
if(res.x < static_cast<long>(width ) / 3 ||
res.x >= static_cast<long>(width * 2) / 3 ||
res.y < static_cast<long>(height ) / 3 ||
res.y >= static_cast<long>(height * 2) / 3) {
if(res.x < static_cast<long>(data.width ) / 3 ||
res.x >= static_cast<long>(data.width * 2) / 3 ||
res.y < static_cast<long>(data.height ) / 3 ||
res.y >= static_cast<long>(data.height * 2) / 3) {
continue;
}
@ -1313,7 +1311,7 @@ std::string default_map_generator_job::default_generate_map(
base_name_generator = village_name_generator_factory.get_name_generator(
(village_naming.has_attribute("base_names") || village_naming.has_attribute("base_name_generator")) ? "base" : "male" );
const map_location loc(res.x-width/3,res.y-height/3);
const map_location loc(res.x-data.width/3,res.y-data.height/3);
map_location adj[6];
get_adjacent_tiles(loc,adj);
@ -1381,7 +1379,7 @@ std::string default_map_generator_job::default_generate_map(
break;
}
const t_translation::t_terrain terr = terrain[adj[n].x+width/3][adj[n].y+height/3];
const t_translation::t_terrain terr = terrain[adj[n].x+data.width/3][adj[n].y+data.height/3];
if(std::count(field.begin(),field.end(),terr) > 0) {
++field_count;

View file

@ -19,10 +19,11 @@
class config;
#include "util.hpp"
#include "default_map_generator.hpp"
#include "map/location.hpp"
#include "terrain/translation.hpp"
#include "serialization/string_utils.hpp"
#include "terrain/translation.hpp"
#include "util.hpp"
#include "utils/name_generator.hpp"
#include <boost/random.hpp>
@ -37,11 +38,8 @@ public:
default_map_generator_job(uint32_t seed);
/** Generate the map. */
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);
std::string default_generate_map(generator_data data, size_t island_off_center, std::map<map_location,std::string>* labels, const config& cfg);
private:
typedef std::vector<std::vector<int> > height_map;
typedef t_translation::t_map terrain_map;