fixed bugs in map generation config dialog
This commit is contained in:
parent
8329ffc818
commit
7438c4ab0d
3 changed files with 30 additions and 216 deletions
|
@ -44,6 +44,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
log.cpp \
|
||||
map.cpp \
|
||||
mapgen.cpp \
|
||||
mapgen_dialog.cpp \
|
||||
mouse.cpp \
|
||||
multiplayer.cpp \
|
||||
multiplayer_client.cpp \
|
||||
|
@ -96,6 +97,7 @@ wesnoth_SOURCES = about.cpp \
|
|||
log.hpp \
|
||||
map.hpp \
|
||||
mapgen.hpp \
|
||||
mapgen_dialog.hpp \
|
||||
mouse.hpp \
|
||||
multiplayer.hpp \
|
||||
multiplayer_client.hpp \
|
||||
|
|
224
src/mapgen.cpp
224
src/mapgen.cpp
|
@ -9,17 +9,11 @@
|
|||
#include <ctime>
|
||||
#include <vector>
|
||||
|
||||
#include "events.hpp"
|
||||
#include "font.hpp"
|
||||
#include "language.hpp"
|
||||
#include "mapgen.hpp"
|
||||
#include "mapgen_dialog.hpp"
|
||||
#include "pathfind.hpp"
|
||||
#include "show_dialog.hpp"
|
||||
#include "util.hpp"
|
||||
|
||||
#include "widgets/button.hpp"
|
||||
#include "widgets/slider.hpp"
|
||||
|
||||
//function to generate a random map, from a string which describes
|
||||
//the generator to use and its arguments
|
||||
std::string random_generate_map(const std::string& parms)
|
||||
|
@ -292,11 +286,13 @@ double road_path_calculator::cost(const location& loc, double so_far) const
|
|||
return windiness*res;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//function to generate the map.
|
||||
std::string generate_map(size_t width, size_t height,
|
||||
size_t iterations, size_t hill_size,
|
||||
size_t max_lakes, size_t nvillages, size_t nplayers,
|
||||
const config& cfg)
|
||||
std::string default_generate_map(size_t width, size_t height,
|
||||
size_t iterations, size_t hill_size,
|
||||
size_t max_lakes, size_t nvillages, size_t nplayers,
|
||||
const config& cfg)
|
||||
{
|
||||
//find out what the 'flatland' on this map is. i.e. grassland.
|
||||
std::string flatland = cfg["default_flatland"];
|
||||
|
@ -363,6 +359,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
}
|
||||
}
|
||||
|
||||
std::cerr << "done generating rivers...\n";
|
||||
|
||||
//convert grassland terrain to other types of flat terrain.
|
||||
//we generate a 'temperature map' which uses the height generation algorithm to
|
||||
//generate the temperature levels all over the map. Then we can use a combination
|
||||
|
@ -371,10 +369,12 @@ std::string generate_map(size_t width, size_t height,
|
|||
atoi(cfg["temperature_iterations"].c_str()),
|
||||
atoi(cfg["temperature_size"].c_str()));
|
||||
|
||||
std::cerr << "generated temperature map...\n";
|
||||
|
||||
//iterate over every flatland tile, and determine what type of flatland it is,
|
||||
//based on our [flatland] tags.
|
||||
for(x = 0; x != width; ++x) {
|
||||
for(y = 0; y != width; ++y) {
|
||||
for(y = 0; y != height; ++y) {
|
||||
if(terrain[x][y] != grassland)
|
||||
continue;
|
||||
|
||||
|
@ -419,6 +419,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
}
|
||||
}
|
||||
|
||||
std::cerr << "placing roads...\n";
|
||||
|
||||
//place roads. We select two tiles at random locations on the borders of the map,
|
||||
//and try to build roads between them.
|
||||
const size_t nroads = atoi(cfg["roads"].c_str());
|
||||
|
@ -515,6 +517,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
}
|
||||
}
|
||||
|
||||
std::cerr << "placing villages...\n";
|
||||
|
||||
//place villages. We attempt to place nvillages, all at random locations.
|
||||
//After a location is chosen, we can through [village] tags to see
|
||||
//what kind of village we should place on that type of terrain. If no
|
||||
|
@ -522,8 +526,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
//will be placed.
|
||||
std::set<location> villages;
|
||||
for(size_t village = 0; village != nvillages; ++village) {
|
||||
const int x = rand()%height;
|
||||
const int y = rand()%width;
|
||||
const int x = rand()%width;
|
||||
const int y = rand()%height;
|
||||
const std::string str(1,terrain[x][y]);
|
||||
const config* const child = cfg.find_child("village","terrain",str);
|
||||
if(child != NULL) {
|
||||
|
@ -533,6 +537,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
}
|
||||
}
|
||||
|
||||
std::cerr << "placing castles...\n";
|
||||
|
||||
//try to find configuration for castles.
|
||||
const config* const castle_config = cfg.child("castle");
|
||||
if(castle_config == NULL) {
|
||||
|
@ -556,8 +562,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
|
||||
std::vector<location> castles;
|
||||
for(size_t player = 0; player != nplayers; ++player) {
|
||||
const int x = (rand()%(height/3)) + height/3;
|
||||
const int y = (rand()%(width/3)) + width/3;
|
||||
const int x = (rand()%(width/3)) + width/3;
|
||||
const int y = (rand()%(height/3)) + height/3;
|
||||
|
||||
castles.push_back(location(x,y));
|
||||
}
|
||||
|
@ -624,6 +630,8 @@ std::string generate_map(size_t width, size_t height,
|
|||
return output_map(terrain);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
typedef std::map<std::string,map_generator*> generator_map;
|
||||
generator_map generators;
|
||||
|
||||
|
@ -654,190 +662,6 @@ map_generator* get_map_generator(const std::string& name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
default_map_generator::default_map_generator(const config& game_config)
|
||||
: width_(40), height_(40), iterations_(1000), hill_size_(10), max_lakes_(20),
|
||||
nvillages_(300), nplayers_(2), cfg_(NULL)
|
||||
{
|
||||
const config* const cfg = game_config.find_child("map_generator","name",name());
|
||||
if(cfg != NULL) {
|
||||
cfg_ = cfg;
|
||||
|
||||
const int width = ::atoi((*cfg)["map_width"].c_str());
|
||||
if(width > 0)
|
||||
width_ = width;
|
||||
|
||||
const int height = ::atoi((*cfg)["map_height"].c_str());
|
||||
if(height > 0)
|
||||
height_ = height;
|
||||
|
||||
const int iterations = ::atoi((*cfg)["iterations"].c_str());
|
||||
if(iterations > 0)
|
||||
iterations_ = iterations;
|
||||
|
||||
const int hill_size = ::atoi((*cfg)["hill_size"].c_str());
|
||||
if(hill_size > 0)
|
||||
hill_size_ = hill_size;
|
||||
|
||||
const int max_lakes = ::atoi((*cfg)["max_lakes"].c_str());
|
||||
if(max_lakes > 0)
|
||||
max_lakes_ = max_lakes;
|
||||
|
||||
const int nvillages = ::atoi((*cfg)["villages"].c_str());
|
||||
if(nvillages > 0)
|
||||
nvillages_ = nvillages;
|
||||
|
||||
const int nplayers = ::atoi((*cfg)["players"].c_str());
|
||||
if(nplayers > 0)
|
||||
nplayers_ = nplayers;
|
||||
}
|
||||
}
|
||||
|
||||
bool default_map_generator::allow_user_config() const { return true; }
|
||||
|
||||
void default_map_generator::user_config(display& disp)
|
||||
{
|
||||
const events::resize_lock prevent_resizing;
|
||||
const events::event_context dialog_events_context;
|
||||
|
||||
const int width = 600;
|
||||
const int height = 400;
|
||||
const int xpos = disp.x()/2 - width/2;
|
||||
const int ypos = disp.y()/2 - height/2;
|
||||
|
||||
SDL_Rect dialog_rect = {xpos-10,ypos-10,width+20,height+20};
|
||||
surface_restorer restorer(&disp.video(),dialog_rect);
|
||||
|
||||
gui::draw_dialog_frame(xpos,ypos,width,height,disp);
|
||||
|
||||
SDL_Rect title_rect = font::draw_text(NULL,disp.screen_area(),24,font::NORMAL_COLOUR,
|
||||
string_table["map_generator"],0,0);
|
||||
|
||||
gui::button close_button(disp,string_table["close_window"]);
|
||||
|
||||
close_button.set_x(xpos + width/2 - close_button.width()/2);
|
||||
close_button.set_y(ypos + height - close_button.height()-14);
|
||||
|
||||
const std::string& players_label = string_table["num_players"] + ":";
|
||||
const std::string& width_label = string_table["map_width"] + ":";
|
||||
const std::string& height_label = string_table["map_height"] + ":";
|
||||
|
||||
SDL_Rect players_rect = font::draw_text(NULL,disp.screen_area(),14,font::NORMAL_COLOUR,players_label,0,0);
|
||||
SDL_Rect width_rect = font::draw_text(NULL,disp.screen_area(),14,font::NORMAL_COLOUR,width_label,0,0);
|
||||
SDL_Rect height_rect = font::draw_text(NULL,disp.screen_area(),14,font::NORMAL_COLOUR,height_label,0,0);
|
||||
|
||||
const int horz_margin = 5;
|
||||
const int text_right = xpos + horz_margin + maximum<int>(maximum<int>(players_rect.w,width_rect.w),height_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;
|
||||
|
||||
const int vertical_margin = 20;
|
||||
players_rect.y = ypos + title_rect.h + 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;
|
||||
|
||||
const int max_players = 9;
|
||||
|
||||
const int right_space = 100;
|
||||
|
||||
const int slider_left = text_right + 10;
|
||||
const int slider_right = xpos + width - horz_margin - right_space;
|
||||
SDL_Rect slider_rect = { slider_left,players_rect.y,slider_right-slider_left,players_rect.h};
|
||||
gui::slider players_slider(disp,slider_rect,gui::slider::normalize(nplayers_,2,max_players));
|
||||
|
||||
const int min_width = 20;
|
||||
const int max_width = 80;
|
||||
const int min_height = 20;
|
||||
const int max_height = 80;
|
||||
|
||||
slider_rect.y = width_rect.y;
|
||||
gui::slider width_slider(disp,slider_rect,gui::slider::normalize(width_,min_height,max_height));
|
||||
|
||||
slider_rect.y = height_rect.y;
|
||||
gui::slider height_slider(disp,slider_rect,gui::slider::normalize(height_,min_width,max_width));
|
||||
|
||||
|
||||
for(bool draw = true;; draw = false) {
|
||||
int mousex, mousey;
|
||||
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
|
||||
|
||||
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
|
||||
|
||||
if(close_button.process(mousex,mousey,left_button)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const double new_players = players_slider.process(mousex,mousey,left_button);
|
||||
if(new_players >= 0.0) {
|
||||
nplayers_ = gui::slider::denormalize(new_players,2,max_players);
|
||||
std::cerr << "set players to " << nplayers_ << "," << new_players << "\n";
|
||||
draw = true;
|
||||
}
|
||||
|
||||
const double new_width = width_slider.process(mousex,mousey,left_button);
|
||||
if(new_width >= 0.0) {
|
||||
width_ = gui::slider::denormalize(new_width,min_width,max_width);
|
||||
draw = true;
|
||||
}
|
||||
|
||||
const double new_height = height_slider.process(mousex,mousey,left_button);
|
||||
if(new_height >= 0.0) {
|
||||
height_ = gui::slider::denormalize(new_height,min_height,max_height);
|
||||
draw = true;
|
||||
}
|
||||
|
||||
if(draw) {
|
||||
|
||||
gui::draw_dialog_frame(xpos,ypos,width,height,disp);
|
||||
|
||||
title_rect = font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
|
||||
string_table["map_generator"],xpos+(width-title_rect.w)/2,ypos+10);
|
||||
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,players_label,players_rect.x,players_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,width_label,width_rect.x,width_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,height_label,height_rect.x,height_rect.y);
|
||||
|
||||
std::stringstream players_str;
|
||||
players_str << nplayers_;
|
||||
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,players_str.str(),
|
||||
slider_right+horz_margin,players_rect.y);
|
||||
|
||||
std::stringstream width_str;
|
||||
width_str << width_;
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,width_str.str(),
|
||||
slider_right+horz_margin,width_rect.y);
|
||||
|
||||
std::stringstream height_str;
|
||||
height_str << height_;
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,height_str.str(),
|
||||
slider_right+horz_margin,height_rect.y);
|
||||
|
||||
players_slider.draw();
|
||||
width_slider.draw();
|
||||
height_slider.draw();
|
||||
close_button.draw();
|
||||
|
||||
update_rect(xpos,ypos,width,height);
|
||||
}
|
||||
|
||||
disp.update_display();
|
||||
SDL_Delay(10);
|
||||
events::pump();
|
||||
}
|
||||
}
|
||||
|
||||
std::string default_map_generator::name() const { return "default"; }
|
||||
|
||||
std::string default_map_generator::create_map(const std::vector<std::string>& args) const
|
||||
{
|
||||
if(cfg_ != NULL)
|
||||
return generate_map(width_,height_,iterations_,hill_size_,max_lakes_,nvillages_,nplayers_,*cfg_);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
#ifdef TEST_MAPGEN
|
||||
|
||||
int main(int argc, char** argv)
|
||||
|
|
|
@ -38,21 +38,9 @@ public:
|
|||
|
||||
map_generator* get_map_generator(const std::string& name);
|
||||
|
||||
class default_map_generator : public map_generator
|
||||
{
|
||||
public:
|
||||
default_map_generator(const config& game_config);
|
||||
|
||||
bool allow_user_config() const;
|
||||
void user_config(display& disp);
|
||||
|
||||
std::string name() const;
|
||||
|
||||
std::string create_map(const std::vector<std::string>& args) const;
|
||||
|
||||
private:
|
||||
size_t width_, height_, iterations_, hill_size_, max_lakes_, nvillages_, nplayers_;
|
||||
const config* cfg_;
|
||||
};
|
||||
std::string default_generate_map(size_t width, size_t height,
|
||||
size_t iterations, size_t hill_size,
|
||||
size_t max_lakes, size_t nvillages, size_t nplayers,
|
||||
const config& cfg);
|
||||
|
||||
#endif
|
Loading…
Add table
Reference in a new issue