attempt to fix bug with energy bars not displaying properly on OSX

added improvements to castle placement algorithm for random maps
This commit is contained in:
uid68803 2004-02-05 14:38:57 +00:00
parent 208d7b04cf
commit 2b4079fccb
4 changed files with 152 additions and 5 deletions

View file

@ -1187,7 +1187,7 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image_override,
return;
}
energy_image.assign(image::get_image(*energy_file));
energy_image.assign(image::get_image(*energy_file,image::SCALED,image::NO_ADJUST_COLOUR));
if(energy_image.get() == NULL) {
std::cerr << "failed to get energy image: '" << *energy_file << "'\n";
return;

View file

@ -173,7 +173,7 @@ void set_zoom(double amount)
}
}
SDL_Surface* get_image(const std::string& filename,TYPE type)
SDL_Surface* get_image(const std::string& filename, TYPE type, COLOUR_ADJUSTMENT adjust_colour)
{
SDL_Surface* result = NULL;
if(type == GREYED) {
@ -254,7 +254,9 @@ SDL_Surface* get_image(const std::string& filename,TYPE type)
if(result == NULL)
return NULL;
adjust_surface_colour(result,red_adjust,green_adjust,blue_adjust);
if(adjust_colour == ADJUST_COLOUR) {
adjust_surface_colour(result,red_adjust,green_adjust,blue_adjust);
}
scaledImages_.insert(std::pair<std::string,SDL_Surface*>(filename,result));
}

View file

@ -51,10 +51,12 @@ namespace image {
enum TYPE { UNSCALED, SCALED, FOGGED, GREYED, BRIGHTENED };
enum COLOUR_ADJUSTMENT { ADJUST_COLOUR, NO_ADJUST_COLOUR };
//function to get the surface corresponding to an image.
//note that this surface must be freed by the user by calling
//SDL_FreeSurface
SDL_Surface* get_image(const std::string& filename,TYPE type=SCALED);
SDL_Surface* get_image(const std::string& filename,TYPE type=SCALED, COLOUR_ADJUSTMENT adj=ADJUST_COLOUR);
//function to get a scaled image, but scale it to specific dimensions.
//if you later try to get the same image using get_image() the image will

View file

@ -286,6 +286,147 @@ double road_path_calculator::cost(const location& loc, double so_far) const
return windiness*res;
}
//a function that takes the locations of castles, villages, and the map border,
//and repositions castles to be better located.
//This function runs the castles through an attraction/repulsion system, where
// - castles repel each other (strongly)
// - villages attract castles (mildly)
// - map borders repel castles (moderately)
// the aim is to have castles nicely spread out
void place_castles(std::vector<gamemap::location>& castles, const std::set<gamemap::location>& village_locs,
int min_x, int min_y, int max_x, int max_y)
{
std::vector<double> xvelocity, yvelocity;
std::vector<gamemap::location>::iterator ci;
for(ci = castles.begin(); ci != castles.end(); ++ci) {
ci->x *= 1000;
ci->y *= 1000;
xvelocity.push_back(0.0);
yvelocity.push_back(0.0);
std::cerr << "castle at " << ci->x << "," << ci->y << "\n";
}
std::set<gamemap::location> villages = village_locs;
std::set<gamemap::location>::iterator v;
for(v = villages.begin(); v != villages.end(); ++v) {
v->x *= 1000;
v->y *= 1000;
}
const double force_multiplier = 0.1;
const int niterations = 20;
for(int i = 0; i != niterations; ++i) {
//go through each castle, repelling
for(ci = castles.begin(); ci != castles.end(); ++ci) {
const size_t index = ci - castles.begin();
for(std::vector<gamemap::location>::iterator i = castles.begin(); i != castles.end(); ++i) {
if(i == ci)
continue;
if(*i == *ci)
i->x += 1;
const double xdist = double(abs(i->x - ci->x));
const double ydist = double(abs(i->y - ci->y));
const double dist = sqrt(xdist*xdist + ydist*ydist);
const double force_size = 50000;
if(dist < force_size) {
const double power = force_multiplier * (force_size - dist);
const double xpower = power * xdist/(xdist+ydist) * (ci->x < i->x ? -1.0 : 1.0);
const double ypower = power * ydist/(xdist+ydist) * (ci->y < i->y ? -1.0 : 1.0);
xvelocity[index] += xpower;
yvelocity[index] += ypower;
std::cerr << "xpower = " << xpower << ", ypower = " << ypower << "\n";
}
}
//go through each village, attracting
for(v = villages.begin(); v != villages.end(); ++v) {
if(v->x < min_x*1000 || v->x > max_x*1000 || v->y < min_y*1000 || v->y > max_y*1000) {
continue;
}
const double xdist = double(abs(v->x - ci->x));
const double ydist = double(abs(v->y - ci->y));
const double dist = sqrt(xdist*xdist + ydist*ydist);
if(*ci == *v)
ci->x += 1;
const double force_size = 20000;
if(dist < force_size) {
const double power = force_multiplier * (force_size - dist);
const double xpower = power * xdist/(xdist+ydist) * (ci->x < v->x ? 1.0 : -1.0);
const double ypower = power * ydist/(xdist+ydist) * (ci->y < v->y ? 1.0 : -1.0);
xvelocity[index] += xpower;
yvelocity[index] += ypower;
}
}
//repel from the borders
const int border_force = 30000;
if(ci->x < min_x*1000 + border_force) {
const double power = force_multiplier * (border_force - (ci->x - min_x*1000));
xvelocity[index] += power;
}
if(ci->x > max_x*1000 - border_force) {
const double power = force_multiplier * (border_force - (max_x*1000 - ci->x));
xvelocity[index] -= power;
}
if(ci->y < min_y*1000 + border_force) {
const double power = force_multiplier * (border_force - (ci->y - min_y*1000));
yvelocity[index] += power;
}
if(ci->y > max_y*1000 - border_force) {
const double power = force_multiplier * (border_force - (max_y*1000 - ci->y));
yvelocity[index] -= power;
}
const double friction = 0.8;
xvelocity[index] *= friction;
yvelocity[index] *= friction;
ci->x += int(xvelocity[index]);
ci->y += int(yvelocity[index]);
if(ci->x > max_x*1000) {
xvelocity[index] *= -1.0;
ci->x = max_x*1000;
}
if(ci->x < min_x*1000) {
xvelocity[index] *= -1.0;
ci->x = min_x*1000;
}
if(ci->y > max_y*1000) {
yvelocity[index] *= -1.0;
ci->y = max_y*1000;
}
if(ci->y < min_y*1000) {
yvelocity[index] *= -1.0;
ci->y = min_y*1000;
}
std::cerr << "castle at " << ci->x << "," << ci->y << " (" << xvelocity[index] << "," << yvelocity[index] << "\n";
}
}
for(ci = castles.begin(); ci != castles.end(); ++ci) {
ci->x /= 1000;
ci->y /= 1000;
ci->x = minimum<int>(maximum<int>(ci->x,min_x),max_x);
ci->y = minimum<int>(maximum<int>(ci->y,min_y),max_y);
}
}
}
//function to generate the map.
@ -557,7 +698,7 @@ std::string default_generate_map(size_t width, size_t height,
//in 'valid_terrain'.
int ntries = 0;
bool placing_bad = true;
const size_t max_tries = 50000;
const size_t max_tries = 1; //50000;
while(placing_bad && ntries++ < max_tries) {
std::vector<location> castles;
@ -568,6 +709,8 @@ std::string default_generate_map(size_t width, size_t height,
castles.push_back(location(x,y));
}
place_castles(castles,villages,width/3,height/3,(width/3)*2 - 1,(height/3)*2 - 1);
//make sure all castles are placed on valid terrain. Check the castle tile
//itself, and all surrounding tiles
placing_bad = false;