Applied patch from Silene (patch #3320) to speed up village location

This commit is contained in:
Isaac Clerencia Perez 2004-08-28 23:23:05 +00:00
parent ea48dbb192
commit 002ae3fde6
3 changed files with 44 additions and 20 deletions

View File

@ -1108,30 +1108,22 @@ bool event_handler::handle_event_command(const queued_event& event_info, const s
const size_t radius = minimum<size_t>(MaxLoop,lexical_cast_default<size_t>(cfg["radius"]));
std::set<gamemap::location> res;
for(std::vector<gamemap::location>::const_iterator i = locs.begin(); i != locs.end(); ++i) {
get_tiles_radius(*i,radius,res);
}
get_tiles_radius(*game_map, locs, radius, res);
size_t added = 0;
for(std::set<gamemap::location>::const_iterator j = res.begin(); j != res.end() && added != MaxLoop; ++j) {
if(game_map->on_board(*j)) {
if(terrain.empty() == false) {
const gamemap::TERRAIN c = game_map->get_terrain(*j);
if(std::find(terrain.begin(),terrain.end(),c) == terrain.end()) {
continue;
}
}
if(unit_filter != NULL) {
const unit_map::const_iterator u = units->find(*j);
if(u == units->end() || game_events::unit_matches_filter(u,*unit_filter) == false) {
continue;
}
}
j->write(state_of_game->variables.add_child(variable));
++added;
if (terrain.empty() == false) {
const gamemap::TERRAIN c = game_map->get_terrain(*j);
if(std::find(terrain.begin(), terrain.end(), c) == terrain.end())
continue;
}
if (unit_filter != NULL) {
const unit_map::const_iterator u = units->find(*j);
if (u == units->end() || !game_events::unit_matches_filter(u, *unit_filter))
continue;
}
j->write(state_of_game->variables.add_child(variable));
++added;
}
}

View File

@ -119,6 +119,34 @@ void get_tiles_radius(const gamemap::location& a, size_t radius, std::set<gamema
get_tiles_radius_internal(a,radius,res,visited);
}
void get_tiles_radius(const gamemap& map, const std::vector<gamemap::location>& locs, size_t radius,
std::set<gamemap::location>& res)
{
typedef std::set<gamemap::location> location_set;
location_set not_visited(locs.begin(), locs.end()), must_visit, visited;
++radius;
for(;;) {
location_set::const_iterator it = not_visited.begin(), it_end = not_visited.end();
visited.insert(it, it_end);
for(; it != it_end; ++it) {
gamemap::location adj[6];
get_adjacent_tiles(*it, adj);
for(size_t i = 0; i != 6; ++i) {
gamemap::location const &loc = adj[i];
if (!map.on_board(loc)) continue;
if (visited.find(loc) != visited.end()) continue;
must_visit.insert(loc);
}
}
if (--radius == 0 || must_visit.empty()) break;
not_visited.swap(must_visit);
must_visit.clear();
}
res.insert(visited.begin(), visited.end());
}
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b)
{
//two tiles are adjacent if y is different by 1, and x by 0, or if

View File

@ -39,6 +39,10 @@ typedef util::array<gamemap::location,6> adjacent_tiles_array;
//function which, given a location, will find all tiles within 'radius' of that tile
void get_tiles_radius(const gamemap::location& a, size_t radius, std::set<gamemap::location>& res);
//function which, given a set of locations, will find all tiles within 'radius' of those tiles
void get_tiles_radius(const gamemap& map, const std::vector<gamemap::location>& locs, size_t radius,
std::set<gamemap::location>& res);
//function which tells if two locations are adjacent.
bool tiles_adjacent(const gamemap::location& a, const gamemap::location& b);