* Fixing crash on the multi-hex tile code, ...

...when there is a map only containing blank lines

* Optimizing the multi-hex calculations, making them ways faster.
This commit is contained in:
Philippe Plantier 2004-05-15 15:29:44 +00:00
parent 9c0ecd5a45
commit 5a35533ce6
4 changed files with 76 additions and 7 deletions

View File

@ -42,6 +42,8 @@ const std::vector<image::locator> *terrain_builder::get_terrain_at(const gamemap
void terrain_builder::rebuild_terrain(const gamemap::location &loc)
{
tile_map_.clear();
terrain_by_type_.clear();
// For now, rebuild the whole map on each rebuilt_terrain. This is highly slow and
// inefficient, but this is simple
build_terrains();
@ -170,8 +172,12 @@ void terrain_builder::parse_mapstring(const std::string &mapstring, struct build
std::vector<std::string>::const_iterator line = lines.begin();
//Strips trailing empty lines
while(std::find_if(line->begin(),line->end(),config::notspace) == line->end())
while(line != lines.end() && std::find_if(line->begin(),line->end(),config::notspace) == line->end()) {
line++;
}
//Break if there only are blank lines
if(line == lines.end())
return;
//If the strings starts with a space, the first line is an odd line, else it is an even one
if((*line)[0] == ' ')
@ -304,6 +310,9 @@ void terrain_builder::parse_config(const config &cfg)
bool terrain_builder::rule_matches(const terrain_builder::building_rule &rule, const gamemap::location &loc)
{
if(!loc.valid())
return false;
if(rule.location_constraints.valid() && rule.location_constraints != loc)
return false;
@ -398,14 +407,49 @@ void terrain_builder::build_terrains()
log_scope("terrain_builder::build_terrains");
//builds the terrain_by_type_ cache
for(int x = -1; x <= map_.x(); ++x) {
for(int y = -1; y <= map_.y(); ++y) {
const gamemap::location loc(x,y);
const gamemap::TERRAIN t = map_.get_terrain(loc);
terrain_by_type_[t].push_back(loc);
}
}
for(building_ruleset::const_iterator rule = building_rules_.begin();
rule != building_rules_.end(); ++rule) {
for(int x = -1; x <= map_.x(); ++x) {
for(int y = -1; y <= map_.y(); ++y) {
const gamemap::location loc(x,y);
if(rule_matches(*rule, loc))
apply_rule(*rule, loc);
//find a constraint that contains an unique terrain type on the current
//rule
building_rule::constraint_set::const_iterator constraint;
for(constraint = rule->constraints.begin();
constraint != rule->constraints.end(); ++constraint) {
if(constraint->second.terrain_types.size() == 1 && (constraint->second.terrain_types[0] != '*')) {
break;
}
}
if(constraint != rule->constraints.end()) {
gamemap::TERRAIN c = constraint->second.terrain_types[0];
gamemap::location loc = constraint->second.loc;
const std::vector<gamemap::location>& locations = terrain_by_type_[c];
for(std::vector<gamemap::location>::const_iterator itor = locations.begin();
itor != locations.end(); ++itor) {
if(rule_matches(*rule, *itor - loc)) {
apply_rule(*rule, *itor - loc);
}
}
} else {
for(int x = -1; x <= map_.x(); ++x) {
for(int y = -1; y <= map_.y(); ++y) {
const gamemap::location loc(x,y);
if(rule_matches(*rule, loc))
apply_rule(*rule, loc);
}
}
}
}

View File

@ -104,6 +104,9 @@ private:
const gamemap& map_;
tilemap tile_map_;
typedef std::map<unsigned char, std::vector<gamemap::location> > terrain_by_type_map;
terrain_by_type_map terrain_by_type_;
typedef std::vector<building_rule> building_ruleset;
building_ruleset building_rules_;

View File

@ -147,6 +147,15 @@ bool gamemap::location::operator<(const gamemap::location& a) const
return x < a.x || x == a.x && y < a.y;
}
gamemap::location gamemap::location::operator-() const
{
location ret;
ret.x = -x;
ret.y = -y;
return ret;
}
gamemap::location gamemap::location::operator+(const gamemap::location& a) const
{
gamemap::location ret = *this;
@ -154,7 +163,7 @@ gamemap::location gamemap::location::operator+(const gamemap::location& a) const
return ret;
}
gamemap::location &gamemap::location::operator+=(const gamemap::location &a)
gamemap::location& gamemap::location::operator+=(const gamemap::location &a)
{
bool parity = (x & 1) != 0;
@ -169,6 +178,16 @@ gamemap::location &gamemap::location::operator+=(const gamemap::location &a)
return *this;
}
gamemap::location gamemap::location::operator-(const gamemap::location &a) const
{
return operator+(-a);
}
gamemap::location& gamemap::location::operator-=(const gamemap::location &a)
{
return operator+=(-a);
}
gamemap::location gamemap::location::get_direction(
gamemap::location::DIRECTION dir) const
{

View File

@ -69,8 +69,11 @@ public:
bool operator==(const location& a) const;
bool operator!=(const location& a) const;
// Adds an absolute location to a "delta" location
location operator-() const;
location operator+(const location &a) const;
location &operator+=(const location &a);
location operator-(const location &a) const;
location &operator-=(const location &a);
location get_direction(DIRECTION d) const;