Lifted the reach map data structure from game_display to display.

The reach map is useful in the editor as well.
For now the map is used to show the highlighted reach in the minimap if
a unit is selected.
This commit is contained in:
fendrin 2013-12-05 21:19:00 +01:00
parent 5afac25dd8
commit c31a065340
4 changed files with 56 additions and 49 deletions

View file

@ -187,6 +187,9 @@ display::display(unit_map* units, CVideo& video, const gamemap* map, const std::
activeTeam_(0),
drawing_buffer_(),
map_screenshot_(false),
reach_map_(),
reach_map_old_(),
reach_map_changed_(true),
fps_handle_(0),
invalidated_hexes_(0),
drawn_hexes_(0),
@ -1563,6 +1566,7 @@ void display::select_hex(map_location hex)
invalidate(selectedHex_);
selectedHex_ = hex;
invalidate(selectedHex_);
recalculate_minimap();
}
void display::highlight_hex(map_location hex)
@ -1802,7 +1806,7 @@ void display::draw_minimap()
}
if(minimap_ == NULL || minimap_->w > area.w || minimap_->h > area.h) {
minimap_ = image::getMinimap(area.w, area.h, get_map(), viewpoint_);
minimap_ = image::getMinimap(area.w, area.h, get_map(), viewpoint_, selectedHex_.valid() ? &reach_map_ : NULL);
if(minimap_ == NULL) {
return;
}
@ -3061,5 +3065,46 @@ void display::read(const config& cfg)
color_adjust_.b = cfg["color_adjust_blue_"].to_int(0);
}
void display::process_reachmap_changes()
{
if (!reach_map_changed_) return;
if (reach_map_.empty() != reach_map_old_.empty()) {
// Invalidate everything except the non-darkened tiles
reach_map &full = reach_map_.empty() ? reach_map_old_ : reach_map_;
rect_of_hexes hexes = get_visible_hexes();
rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
for (;i != end; ++i) {
reach_map::iterator reach = full.find(*i);
if (reach == full.end()) {
// Location needs to be darkened or brightened
invalidate(*i);
} else if (reach->second != 1) {
// Number needs to be displayed or cleared
invalidate(*i);
}
}
} else if (!reach_map_.empty()) {
// Invalidate only changes
reach_map::iterator reach, reach_old;
for (reach = reach_map_.begin(); reach != reach_map_.end(); ++reach) {
reach_old = reach_map_old_.find(reach->first);
if (reach_old == reach_map_old_.end()) {
invalidate(reach->first);
} else {
if (reach_old->second != reach->second) {
invalidate(reach->first);
}
reach_map_old_.erase(reach_old);
}
}
for (reach_old = reach_map_old_.begin(); reach_old != reach_map_old_.end(); ++reach_old) {
invalidate(reach_old->first);
}
}
reach_map_old_ = reach_map_;
reach_map_changed_ = false;
}
display *display::singleton_ = NULL;

View file

@ -1000,6 +1000,15 @@ public: //operations for the arrow framework
/** Called by arrow objects when they change. You should not need to call this directly. */
void update_arrow(arrow & a);
protected:
// Tiles lit for showing where unit(s) can reach
typedef std::map<map_location,unsigned int> reach_map;
reach_map reach_map_;
reach_map reach_map_old_;
bool reach_map_changed_;
void process_reachmap_changes();
private:
typedef std::multimap<map_location, overlay> overlay_map;

View file

@ -77,9 +77,6 @@ game_display::game_display(unit_map& units, CVideo& video, const gamemap& map,
in_game_(false),
observers_(),
chat_messages_(),
reach_map_(),
reach_map_old_(),
reach_map_changed_(true),
game_mode_(RUNNING)
{
@ -578,46 +575,7 @@ void game_display::unhighlight_reach()
reach_map_changed_ = true;
}
void game_display::process_reachmap_changes()
{
if (!reach_map_changed_) return;
if (reach_map_.empty() != reach_map_old_.empty()) {
// Invalidate everything except the non-darkened tiles
reach_map &full = reach_map_.empty() ? reach_map_old_ : reach_map_;
rect_of_hexes hexes = get_visible_hexes();
rect_of_hexes::iterator i = hexes.begin(), end = hexes.end();
for (;i != end; ++i) {
reach_map::iterator reach = full.find(*i);
if (reach == full.end()) {
// Location needs to be darkened or brightened
invalidate(*i);
} else if (reach->second != 1) {
// Number needs to be displayed or cleared
invalidate(*i);
}
}
} else if (!reach_map_.empty()) {
// Invalidate only changes
reach_map::iterator reach, reach_old;
for (reach = reach_map_.begin(); reach != reach_map_.end(); ++reach) {
reach_old = reach_map_old_.find(reach->first);
if (reach_old == reach_map_old_.end()) {
invalidate(reach->first);
} else {
if (reach_old->second != reach->second) {
invalidate(reach->first);
}
reach_map_old_.erase(reach_old);
}
}
for (reach_old = reach_map_old_.begin(); reach_old != reach_map_old_.end(); ++reach_old) {
invalidate(reach_old->first);
}
}
reach_map_old_ = reach_map_;
reach_map_changed_ = false;
}
void game_display::invalidate_route()
{

View file

@ -346,12 +346,7 @@ private:
std::vector<chat_message> chat_messages_;
// Tiles lit for showing where unit(s) can reach
typedef std::map<map_location,unsigned int> reach_map;
reach_map reach_map_;
reach_map reach_map_old_;
bool reach_map_changed_;
void process_reachmap_changes();
tgame_mode game_mode_;