added in 'landform' setting to map generator
This commit is contained in:
parent
00e44b11ea
commit
4baca7de7f
6 changed files with 117 additions and 33 deletions
|
@ -67,16 +67,42 @@ typedef std::vector<std::vector<char> > terrain_map;
|
|||
//we generate 'iterations' hills in total.
|
||||
//the range of heights is normalized to 0-1000
|
||||
//'island_size' controls whether or not the map should tend toward an island shape, and if
|
||||
//so, how large the island should be. Hills will not have centers that are more than 'island_size'
|
||||
//away from the center of the map. 'island_size' as 0 will allow hills anywhere.
|
||||
//so, how large the island should be. Hills with centers that are more than 'island_size'
|
||||
//away from the center of the map will be inverted (i.e. be valleys).
|
||||
//'island_size' as 0 indicates no island
|
||||
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_size, size_t island_off_center)
|
||||
{
|
||||
height_map res(width,std::vector<int>(height,0));
|
||||
|
||||
const size_t center_x = width/2;
|
||||
const size_t center_y = height/2;
|
||||
size_t center_x = width/2;
|
||||
size_t center_y = height/2;
|
||||
|
||||
std::cerr << "off-centering...\n";
|
||||
|
||||
if(island_off_center != 0) {
|
||||
switch(rand()%4) {
|
||||
case 0:
|
||||
center_x += island_off_center;
|
||||
break;
|
||||
case 1:
|
||||
center_y += island_off_center;
|
||||
break;
|
||||
case 2:
|
||||
if(center_x < island_off_center)
|
||||
center_x = 0;
|
||||
else
|
||||
center_x -= island_off_center;
|
||||
break;
|
||||
case 3:
|
||||
if(center_y < island_off_center)
|
||||
center_y = 0;
|
||||
else
|
||||
center_y -= island_off_center;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i != iterations; ++i) {
|
||||
|
||||
|
@ -89,25 +115,22 @@ height_map generate_height_map(size_t width, size_t height,
|
|||
//a rectangle that contains all the positive values for this formula --
|
||||
//the rectangle is given by min_x,max_x,min_y,max_y
|
||||
|
||||
int x1 = 0, y1 = 0, tries = 0;
|
||||
bool valid_values = false;
|
||||
//is this a negative hill? (i.e. a valley)
|
||||
bool is_valley = false;
|
||||
|
||||
while(!valid_values && tries < 20) {
|
||||
|
||||
x1 = island_size > 0 ? center_x - island_size + (rand()%(island_size*2)) :
|
||||
int x1 = island_size > 0 ? center_x - island_size + (rand()%(island_size*2)) :
|
||||
int(rand()%width);
|
||||
y1 = island_size > 0 ? center_y - island_size + (rand()%(island_size*2)) :
|
||||
std::cerr << "y\n";
|
||||
int y1 = island_size > 0 ? center_y - island_size + (rand()%(island_size*2)) :
|
||||
int(rand()%height);
|
||||
if(island_size == 0) {
|
||||
valid_values = true;
|
||||
} else {
|
||||
const size_t diffx = abs(x1 - center_x);
|
||||
const size_t diffy = abs(y1 - center_y);
|
||||
const size_t dist = size_t(sqrt(double(diffx*diffx + diffy*diffy)));
|
||||
valid_values = dist < island_size;
|
||||
}
|
||||
std::cerr << "z\n";
|
||||
|
||||
++tries;
|
||||
//we have to check whether this is actually a valley
|
||||
if(island_size != 0) {
|
||||
const size_t diffx = abs(x1 - center_x);
|
||||
const size_t diffy = abs(y1 - center_y);
|
||||
const size_t dist = size_t(sqrt(double(diffx*diffx + diffy*diffy)));
|
||||
is_valley = dist > island_size;
|
||||
}
|
||||
|
||||
const int radius = rand()%hill_size + 1;
|
||||
|
@ -117,13 +140,23 @@ height_map generate_height_map(size_t width, size_t height,
|
|||
const int min_y = y1 - radius > 0 ? y1 - radius : 0;
|
||||
const int max_y = y1 + radius < res.front().size() ? y1 + radius : res.front().size();
|
||||
|
||||
for(int x2 = min_x; size_t(x2) != max_x; ++x2) {
|
||||
for(int y2 = min_y; size_t(y2) != max_y; ++y2) {
|
||||
for(int x2 = min_x; x2 < max_x; ++x2) {
|
||||
for(int y2 = min_y; y2 < max_y; ++y2) {
|
||||
const int xdiff = (x2-x1);
|
||||
const int ydiff = (y2-y1);
|
||||
|
||||
const int height = radius - int(sqrt(double(xdiff*xdiff + ydiff*ydiff)));
|
||||
|
||||
if(height > 0) {
|
||||
res[x2][y2] += height;
|
||||
if(is_valley) {
|
||||
if(height > res[x2][y2]) {
|
||||
res[x2][y2] = 0;
|
||||
} else {
|
||||
res[x2][y2] -= height;
|
||||
}
|
||||
} else {
|
||||
res[x2][y2] += height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +510,7 @@ void place_castles(std::vector<gamemap::location>& castles, const std::set<gamem
|
|||
}
|
||||
|
||||
//function to generate the map.
|
||||
std::string default_generate_map(size_t width, size_t height, size_t island_size,
|
||||
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 nplayers,
|
||||
const config& cfg)
|
||||
|
@ -503,8 +536,10 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
|
|||
width *= 3;
|
||||
height *= 3;
|
||||
|
||||
std::cerr << "generating height map...\n";
|
||||
//generate the height of everything.
|
||||
const height_map heights = generate_height_map(width,height,iterations,hill_size,20);
|
||||
const height_map heights = generate_height_map(width,height,iterations,hill_size,island_size,island_off_center);
|
||||
std::cerr << "done generating height map...\n";
|
||||
|
||||
//the configuration file should contain a number of [height] tags:
|
||||
//[height]
|
||||
|
@ -560,7 +595,7 @@ std::string default_generate_map(size_t width, size_t height, size_t island_size
|
|||
//of height and terrain to divide flatland up into more interesting types than the default
|
||||
const height_map temperature_map = generate_height_map(width,height,
|
||||
atoi(cfg["temperature_iterations"].c_str()),
|
||||
atoi(cfg["temperature_size"].c_str()),0);
|
||||
atoi(cfg["temperature_size"].c_str()),0,0);
|
||||
|
||||
std::cerr << "generated temperature map...\n";
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
|
||||
map_generator* create_map_generator(const std::string& name, const config* cfg);
|
||||
|
||||
std::string default_generate_map(size_t width, size_t height, size_t island_size,
|
||||
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 nplayers,
|
||||
const config& cfg);
|
||||
|
|
|
@ -10,6 +10,11 @@
|
|||
#include "widgets/button.hpp"
|
||||
#include "widgets/slider.hpp"
|
||||
|
||||
namespace {
|
||||
const size_t max_island = 10;
|
||||
const size_t max_coastal = 5;
|
||||
}
|
||||
|
||||
default_map_generator::default_map_generator(const config* cfg)
|
||||
: width_(40), height_(40), island_size_(0), iterations_(1000), hill_size_(10), max_lakes_(20),
|
||||
nvillages_(25), nplayers_(2), cfg_(cfg)
|
||||
|
@ -168,7 +173,7 @@ void default_map_generator::user_config(display& disp)
|
|||
villages_slider.set_value(nvillages_);
|
||||
|
||||
const int min_landform = 0;
|
||||
const int max_landform = 10;
|
||||
const int max_landform = int(max_island);
|
||||
slider_rect.y = landform_rect.y;
|
||||
gui::slider landform_slider(disp,slider_rect);
|
||||
landform_slider.set_min(min_landform);
|
||||
|
@ -218,6 +223,7 @@ void default_map_generator::user_config(display& disp)
|
|||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,iterations_label,iterations_rect.x,iterations_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,hillsize_label,hillsize_rect.x,hillsize_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,villages_label,villages_rect.x,villages_rect.y);
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,landform_label,landform_rect.x,landform_rect.y);
|
||||
|
||||
std::stringstream players_str;
|
||||
players_str << nplayers_;
|
||||
|
@ -240,7 +246,7 @@ void default_map_generator::user_config(display& disp)
|
|||
slider_right+horz_margin,villages_rect.y);
|
||||
|
||||
std::stringstream landform_str;
|
||||
landform_str << string_table[island_size_ == 0 ? "inland" : (island_size_ < 5 ? "coastal" : "island")];
|
||||
landform_str << string_table[island_size_ == 0 ? "inland" : (island_size_ < max_coastal ? "coastal" : "island")];
|
||||
font::draw_text(&disp,disp.screen_area(),14,font::NORMAL_COLOUR,landform_str.str(),
|
||||
slider_right+horz_margin,landform_rect.y);
|
||||
|
||||
|
@ -258,11 +264,31 @@ std::string default_map_generator::name() const { return "default"; }
|
|||
|
||||
std::string default_map_generator::create_map(const std::vector<std::string>& args)
|
||||
{
|
||||
//many less iterations for an island, to make the island shaped
|
||||
const size_t iterations = island_size_ > 0 ? iterations_/10 : iterations_;
|
||||
const size_t island_size = island_size_ == 0 ? 0 : 120 - island_size_*10;
|
||||
size_t iterations = iterations_;
|
||||
size_t island_size = 0;
|
||||
size_t island_off_center = 0;
|
||||
size_t max_lakes = max_lakes_;
|
||||
|
||||
if(island_size_ >= max_coastal) {
|
||||
|
||||
//islands look good with much fewer iterations than normal, and fewer lakes
|
||||
iterations /= 10;
|
||||
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) {
|
||||
std::cerr << "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 = minimum<size_t>(width_,height_);
|
||||
std::cerr << "calculated coastal params...\n";
|
||||
}
|
||||
|
||||
if(cfg_ != NULL)
|
||||
return default_generate_map(width_,height_,island_size,iterations,hill_size_,max_lakes_,(nvillages_*width_*height_)/1000,nplayers_,*cfg_);
|
||||
return default_generate_map(width_,height_,island_size,island_off_center,iterations,hill_size_,max_lakes,(nvillages_*width_*height_)/1000,nplayers_,*cfg_);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -420,6 +420,24 @@ void send_data_all_except(const config& cfg, connection connection_num, size_t m
|
|||
}
|
||||
}
|
||||
|
||||
std::string ip_address(connection connection_num)
|
||||
{
|
||||
std::stringstream str;
|
||||
const IPaddress* const ip = SDLNet_TCP_GetPeerAddress(connection_num);
|
||||
if(ip != NULL) {
|
||||
const unsigned char* buf = reinterpret_cast<const unsigned char*>(&ip->host);
|
||||
for(int i = 0; i != sizeof(ip->host); ++i) {
|
||||
str << int(buf[i]);
|
||||
if(i+1 != sizeof(ip->host)) {
|
||||
str << '.';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
std::pair<int,int> current_transfer_stats()
|
||||
{
|
||||
if(current_connection == received_data.end())
|
||||
|
|
|
@ -92,6 +92,9 @@ void process_send_queue(connection connection_num=0, size_t max_size=0);
|
|||
//function to send data to all peers except 'connection_num'
|
||||
void send_data_all_except(const config& cfg, connection connection_num, size_t max_size=0);
|
||||
|
||||
//function to get the remote ip address of a socket
|
||||
std::string ip_address(connection connection_num);
|
||||
|
||||
//function to see the number of bytes being processed on the current socket
|
||||
std::pair<int,int> current_transfer_stats();
|
||||
|
||||
|
|
|
@ -130,6 +130,8 @@ void server::run()
|
|||
//send other players in the lobby the update that the player has joined
|
||||
lobby_players_.send_data(sync_initial_response(),sock);
|
||||
|
||||
std::cout << "'" << username << "' (" << network::ip_address(sock) << ") has logged on\n";
|
||||
|
||||
} else if(lobby_players_.is_member(sock)) {
|
||||
const config* const create_game = data.child("create_game");
|
||||
if(create_game != NULL) {
|
||||
|
|
Loading…
Add table
Reference in a new issue