Neaten display::set_paths() and display::set_reach_map().

Bug #5145 was caused by a missing set_paths(NULL), because the display
object used to keep the paths pointer it was passed.

This is unnecessary, because the gui only needs to keep which tiles to
highlight: it does not need to keep the paths themselves.  Also, both
interfaces are very similar and should be combined.  While we're
there, rename them: we don't use it for the actual "route"
highlighting (ie. the footsteps), just for showing where a unit/units
can reach.
This commit is contained in:
Rusty Russell 2006-01-26 02:35:07 +00:00
parent 17b0702c09
commit a5b935bc09
9 changed files with 73 additions and 81 deletions

View file

@ -2122,7 +2122,7 @@ void apply_shroud_changes(undo_list& undos, display* disp, const gamestatus& sta
disp->invalidate_game_status();
clear_shroud(*disp,status,map,gamedata,units,teams,team);
disp->recalculate_minimap();
disp->set_paths(NULL);
disp->unhighlight_reach();
disp->set_route(NULL);
} else {
recalculate_fog(map,status,gamedata,units,teams,team);

View file

@ -500,7 +500,7 @@ gamemap::location ai_interface::move_unit_partial(location from, location to, st
game_events::fire("sighted",to);
}
info_.disp.set_paths(NULL);
info_.disp.unhighlight_reach();
sync_network();
return to;

View file

@ -81,7 +81,7 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
screen_(video), xpos_(0), ypos_(0),
zoom_(DefaultZoom), map_(map), units_(units),
minimap_(NULL), redrawMinimap_(false),
pathsList_(NULL), status_(status),
status_(status),
teams_(t), lastDraw_(0), drawSkips_(0),
invalidateAll_(true), invalidateUnit_(true),
invalidateGameStatus_(true), panelsDrawn_(false),
@ -90,7 +90,7 @@ display::display(unit_map& units, CVideo& video, const gamemap& map,
turbo_(false), grid_(false), sidebarScaling_(1.0),
theme_(theme_cfg,screen_area()), builder_(cfg, level, map),
first_turn_(true), in_game_(false), map_labels_(*this,map),
tod_hex_mask1(NULL), tod_hex_mask2(NULL), enemy_reach_(NULL),
tod_hex_mask1(NULL), tod_hex_mask2(NULL),
diagnostic_label_(0), fps_handle_(0)
{
if(non_interactive()) {
@ -1536,6 +1536,8 @@ void display::draw_terrain_on_tile(int x, int y, image::TYPE image_type, ADJACEN
void display::draw_tile(int x, int y, surface unit_image, fixed_t alpha, Uint32 blend_to)
{
reach_map::iterator reach = reach_map_.end();
if(screen_.update_locked()) {
return;
}
@ -1574,16 +1576,10 @@ void display::draw_tile(int x, int y, surface unit_image, fixed_t alpha, Uint32
mask = tod_at.image_mask;
}
//find if this tile should be darkened or bightened (on a path)
if(pathsList_ != NULL) {
if (pathsList_->routes.find(gamemap::location(x,y)) == pathsList_->routes.end()) {
image_type = image::DARKENED;
} else {
image_type = image::UNMASKED;
}
}
if(enemy_reach_ != NULL) {
if (enemy_reach_->find(loc) == enemy_reach_->end()) {
//find if this tile should be darkened or bightened (reach of a unit)
if (!reach_map_.empty()) {
reach = reach_map_.find(gamemap::location(x,y));
if (reach == reach_map_.end()) {
image_type = image::DARKENED;
} else {
image_type = image::UNMASKED;
@ -1655,8 +1651,8 @@ void display::draw_tile(int x, int y, surface unit_image, fixed_t alpha, Uint32
if(!shrouded(x,y)) {
draw_terrain_on_tile(x,y,image_type,ADJACENT_FOGSHROUD);
if (enemy_reach_ != NULL)
draw_enemies_reach(loc,xpos,ypos);
if (reach != reach_map_.end())
draw_enemies_reach(reach->second,xpos,ypos);
}
//draw the time-of-day mask on top of the hex
@ -1696,22 +1692,14 @@ void display::draw_tile(int x, int y, surface unit_image, fixed_t alpha, Uint32
update_rect(xpos,ypos,zoom_,zoom_);
}
void display::draw_enemies_reach(const gamemap::location& loc, int xloc, int yloc)
void display::draw_enemies_reach(unsigned int num, int xloc, int yloc)
{
const reach_map::const_iterator reach_it = enemy_reach_->find(loc);
// not reachable, leave greyed out.
if (reach_it == enemy_reach_->end())
// only one can reach, don't number it
if (num == 1)
return;
// only one can reach, leave highlighted.
if (reach_it->second == 1)
return;
// multiple can reach: print number
std::stringstream text;
text << reach_it->second;
const std::string &str = text.str();
// multiple can reach: print number (ie. Show Enemy Moves)
std::string str = lexical_cast<std::string>(num);
const SDL_Rect& rect = map_area();
const SDL_Rect& text_area = font::text_area(str,font::SIZE_LARGE);
@ -2031,17 +2019,26 @@ surface display::get_minimap(int w, int h)
return minimap_;
}
void display::set_paths(const paths* paths_list)
void display::highlight_reach(const paths &paths_list)
{
pathsList_ = paths_list;
enemy_reach_ = NULL;
invalidate_all();
unhighlight_reach();
highlight_another_reach(paths_list);
}
void display::set_reach_map(const reach_map *reach_map)
void display::highlight_another_reach(const paths &paths_list)
{
pathsList_ = NULL;
enemy_reach_ = reach_map;
paths::routes_map::const_iterator r;
// Fold endpoints of routes into reachability map.
for (r = paths_list.routes.begin(); r != paths_list.routes.end(); ++r) {
reach_map_[r->first]++;
invalidate(r->first);
}
}
void display::unhighlight_reach()
{
reach_map_ = reach_map();
invalidate_all();
}

View file

@ -169,15 +169,15 @@ public:
bool unit_image_on(int x, int y);
//sets the paths that are currently displayed as available for the unit
//to move along. All other paths will be greyed out. If NULL, no paths
//will be displayed as selected.
//paths_list must remain valid until it is set again
void set_paths(const paths* paths_list);
//to move along. All other paths will be greyed out.
void highlight_reach(const paths &paths_list);
//variation of set_paths which shows how many units can reach each tile.
//Setting the reach_map clears the paths_list, and vice-versa.
typedef std::map<gamemap::location,unsigned int> reach_map;
void set_reach_map(const reach_map *reach_map);
//add more paths to highlight. Print numbers where they overlap.
//Used only by Show Enemy Moves.
void highlight_another_reach(const paths &paths_list);
//reset highlighting of paths.
void unhighlight_reach();
//sets the route along which footsteps are drawn to show movement of a
//unit. If NULL, no route is displayed.
@ -220,7 +220,7 @@ private:
// void draw_tile_adjacent(int x, int y, image::TYPE image_type, ADJACENT_TERRAIN_TYPE type);
void draw_enemies_reach(const gamemap::location& loc, int xloc, int yloc);
void draw_enemies_reach(unsigned int num, int xloc, int yloc);
public:
//function to draw a footstep for the given location, on screen at
@ -425,7 +425,6 @@ private:
surface minimap_;
bool redrawMinimap_;
const paths* pathsList_;
paths::route route_;
const gamestatus& status_;
@ -507,11 +506,13 @@ private:
//then we will use these two masks on top of all hexes when we blit
surface tod_hex_mask1, tod_hex_mask2;
//tiles lit for showing where unit(s) can reach
typedef std::map<gamemap::location,unsigned int> reach_map;
reach_map reach_map_;
typedef std::map<gamemap::location,int> halo_map;
halo_map haloes_;
const reach_map *enemy_reach_;
//for debug mode
static std::map<gamemap::location,fixed_t> debugHighlights_;

View file

@ -101,7 +101,7 @@ void mouse_handler::mouse_motion(int x, int y)
if(enemy_paths_) {
enemy_paths_ = false;
current_paths_ = paths();
(*gui_).set_paths(NULL);
gui_->unhighlight_reach();
}
const gamemap::location& dest = attack_from.valid() ? attack_from : new_hex;
@ -150,7 +150,7 @@ void mouse_handler::mouse_motion(int x, int y)
const bool teleport = un->second.type().teleports();
current_paths_ = paths(map_,status_,gameinfo_,units_,new_hex,teams_,
ignore_zocs,teleport,NULL,path_turns_);
(*gui_).set_paths(&current_paths_);
gui_->highlight_reach(current_paths_);
enemy_paths_ = true;
}
}
@ -253,7 +253,7 @@ void mouse_handler::mouse_press(const SDL_MouseButtonEvent& event, const int pla
if(!current_paths_.routes.empty()) {
selected_hex_ = gamemap::location();
gui_->select_hex(gamemap::location());
gui_->set_paths(NULL);
gui_->unhighlight_reach();
current_paths_ = paths();
current_route_.steps.clear();
gui_->set_route(NULL);
@ -357,7 +357,7 @@ void mouse_handler::left_click(const SDL_MouseButtonEvent& event)
paths orig_paths = current_paths_;
{
gui_->set_paths(NULL);
gui_->unhighlight_reach();
current_paths_ = paths();
selected_hex_ = hex;
@ -377,7 +377,7 @@ void mouse_handler::left_click(const SDL_MouseButtonEvent& event)
show_attack_options(it);
gui_->set_paths(&current_paths_);
gui_->highlight_reach(current_paths_);
unit u = it->second;
const gamemap::location go_to = u.get_goto();

View file

@ -501,7 +501,7 @@ redo_turn:
recorder.end_turn();
ai_obj->sync_network();
gui.set_paths(NULL);
gui.unhighlight_reach();
gui.recalculate_minimap();
clear_shroud(gui,status,map,gameinfo,units,teams,player_number-1);
gui.invalidate_unit();

View file

@ -135,7 +135,6 @@ void play_turn(const game_data& gameinfo, game_state& state_of_game,
turn_data.turn_slice();
} catch(end_level_exception& e) {
turn_data.send_data();
gui.set_paths(NULL);
throw e;
}
@ -186,7 +185,7 @@ void play_turn(const game_data& gameinfo, game_state& state_of_game,
//send one more time to make sure network is up-to-date.
turn_data.send_data();
gui.set_paths(NULL);
gui.unhighlight_reach();
}
turn_info::turn_info(const game_data& gameinfo, game_state& state_of_game,
@ -309,7 +308,7 @@ void turn_info::handle_event(const SDL_Event& event)
current_paths_ = paths(map_,status_,gameinfo_,units_,u->first,
teams_,ignore_zocs,teleport,NULL,
path_turns_);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
}
}
}
@ -403,9 +402,9 @@ void turn_info::mouse_motion(int x, int y)
}
if(enemy_paths_) {
enemy_paths_ = false;
gui_.unhighlight_reach();
current_paths_ = paths();
gui_.set_paths(NULL);
enemy_paths_ = false;
}
const gamemap::location& dest = attack_from.valid() ? attack_from : new_hex;
@ -453,7 +452,7 @@ void turn_info::mouse_motion(int x, int y)
const bool teleport = un->second.type().teleports();
current_paths_ = paths(map_,status_,gameinfo_,units_,new_hex,teams_,
ignore_zocs,teleport,&current_team,path_turns_);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
enemy_paths_ = true;
}
}
@ -551,7 +550,7 @@ void turn_info::mouse_press(const SDL_MouseButtonEvent& event)
if(!current_paths_.routes.empty()) {
selected_hex_ = gamemap::location();
gui_.select_hex(gamemap::location());
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
current_route_.steps.clear();
gui_.set_route(NULL);
@ -755,7 +754,7 @@ bool turn_info::attack_enemy(unit_map::iterator attacker, unit_map::iterator def
redo_stack_.clear();
current_paths_ = paths();
gui_.set_paths(NULL);
gui_.unhighlight_reach();
game_events::fire("attack",attacker_loc,defender_loc);
@ -821,7 +820,7 @@ bool turn_info::move_unit_along_current_route(bool check_shroud)
gui_.select_hex(gamemap::location());
gui_.set_route(NULL);
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
if(moves == 0)
@ -848,7 +847,7 @@ bool turn_info::move_unit_along_current_route(bool check_shroud)
current_paths_.routes[dst] = paths::route();
selected_hex_ = dst;
gui_.select_hex(dst);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
}
}
@ -913,7 +912,7 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event)
selected_hex_ = src;
gui_.select_hex(src);
current_paths_ = orig_paths;
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
return;
}
}
@ -945,7 +944,7 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event)
clear_undo_stack();
}
} else {
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
selected_hex_ = hex;
@ -965,7 +964,7 @@ void turn_info::left_click(const SDL_MouseButtonEvent& event)
show_attack_options(it);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
unit u = it->second;
const gamemap::location go_to = u.get_goto();
@ -1285,7 +1284,7 @@ void turn_info::cycle_units()
const bool ignore_zocs = it->second.type().is_skirmisher();
const bool teleport = it->second.type().teleports();
current_paths_ = paths(map_,status_,gameinfo_,units_,it->first,teams_,ignore_zocs,teleport,NULL,path_turns_);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
gui_.scroll_to_tile(it->first.x,it->first.y,display::WARP);
}
@ -1331,7 +1330,7 @@ void turn_info::cycle_back_units()
const bool ignore_zocs = it->second.type().is_skirmisher();
const bool teleport = it->second.type().teleports();
current_paths_ = paths(map_,status_,gameinfo_,units_,it->first,teams_,ignore_zocs,teleport,NULL,path_turns_);
gui_.set_paths(&current_paths_);
gui_.highlight_reach(current_paths_);
gui_.scroll_to_tile(it->first.x,it->first.y,display::WARP);
}
@ -1429,7 +1428,7 @@ void turn_info::unit_hold_position()
gui_.draw_tile(selected_hex_.x,selected_hex_.y);
gui_.set_route(NULL);
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
gui_.draw();
@ -1454,7 +1453,7 @@ void turn_info::end_unit_turn()
gui_.draw_tile(selected_hex_.x,selected_hex_.y);
gui_.set_route(NULL);
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
gui_.draw();
@ -1532,7 +1531,7 @@ void turn_info::undo()
redo_stack_.push_back(action);
undo_stack_.pop_back();
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
selected_hex_ = gamemap::location();
current_route_.steps.clear();
@ -1557,7 +1556,7 @@ void turn_info::redo()
const command_disabler disable_commands;
//clear routes, selected hex, etc
gui_.set_paths(NULL);
gui_.unhighlight_reach();
current_paths_ = paths();
selected_hex_ = gamemap::location();
current_route_.steps.clear();
@ -2719,7 +2718,7 @@ bool turn_info::enemies_visible() const
// Highlights squares that an enemy could move to on their turn, showing how many can reach each square.
void turn_info::show_enemy_moves(bool ignore_units)
{
reach_map_ = display::reach_map();
gui_.unhighlight_reach();
// Compute enemy movement positions
for(unit_map::iterator u = units_.begin(); u != units_.end(); ++u) {
@ -2737,13 +2736,9 @@ void turn_info::show_enemy_moves(bool ignore_units)
const paths& path = paths(map_,status_,gameinfo_,ignore_units?units:units_,
u->first,teams_,is_skirmisher,teleports,&current_team());
for (paths::routes_map::const_iterator route = path.routes.begin(); route != path.routes.end(); ++route) {
reach_map_[route->first]++;
}
gui_.highlight_another_reach(path);
}
}
gui_.set_reach_map(&reach_map_);
}
void turn_info::toggle_shroud_updates() {

View file

@ -218,7 +218,6 @@ private:
gamemap::location next_unit_;
paths current_paths_, all_paths_;
paths::route current_route_;
display::reach_map reach_map_;
bool enemy_paths_;
gamemap::location last_hex_;
gamemap::location::DIRECTION last_nearest_, last_second_nearest_;

View file

@ -850,7 +850,7 @@ bool do_replay(display& disp, const gamemap& map, const game_data& gameinfo,
}
fix_shroud = !replayer.is_skipping();
disp.set_paths(NULL);
disp.unhighlight_reach();
}
else if((child = cfg->child("attack")) != NULL) {