Hi all,

        I submitted this patch just after the freeze, and so am re-sending it
now.  It puts numbers on hexes when showing enemy moves, which I find
this extremely useful for making sure only one enemy can reach me, or
indicating what hexes would allow me to be completely mobbed.

The patch itself uses exactly the same logic as set_paths/pathsList_,
but a map of unsigned ints is used indicating how many can reach each
point.  It's quite simple.

Thanks for the great game!
Rusty.
Index: src/playturn.cpp
===================================================================
--- src/playturn.cpp    (revision 8764)
+++ src/playturn.cpp    (working copy)
@@ -2676,10 +2676,10 @@
        return false;
 }
 
-// Highlights squares that an enemy could move to on their turn
+// 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)
 {
-       all_paths_ = paths();
+       reach_map_ = display::reach_map();
 
        // Compute enemy movement positions
        for(unit_map::iterator u = units_.begin(); u != units_.end(); ++u) {
@@ -2693,14 +2693,12 @@
                                                                          
u->first,teams_,is_skirmisher,teleports);
 
                        for (paths::routes_map::const_iterator route = 
path.routes.begin(); route != path.routes.end(); ++route) {
-                               // map<...>::operator[](const key_type& key) 
inserts key into
-                               // the map with a default instance of value_type
-                               all_paths_.routes[route->first];
+                               reach_map_[route->first]++;
                        }
                }
        }
 
-       gui_.set_paths(&all_paths_);
+       gui_.set_reach_map(&reach_map_);
 }
 
 void turn_info::toggle_shroud_updates() {
Index: src/display.cpp
===================================================================
--- src/display.cpp     (revision 8764)
+++ src/display.cpp     (working copy)
@@ -78,7 +78,7 @@
        screen_(video), xpos_(0), ypos_(0),
        zoom_(DefaultZoom), map_(map), units_(units),
        minimap_(NULL), redrawMinimap_(false),
-       pathsList_(NULL), status_(status),
+       pathsList_(NULL), enemy_reach_(NULL), status_(status),
        teams_(t), lastDraw_(0), drawSkips_(0),
        invalidateAll_(true), invalidateUnit_(true),
        invalidateGameStatus_(true), panelsDrawn_(false),
@@ -1406,6 +1406,9 @@
                                                 pathsList_->routes.end()) {
                image_type = image::GREYED;
        }
+       if(enemy_reach_ != NULL && enemy_reach_->find(loc) == 
enemy_reach_->end()) {
+               image_type = image::GREYED;
+       }
 
        unit_map::iterator un = find_visible_unit(units_, loc, map_,
                
status_.get_time_of_day().lawful_bonus,teams_,teams_[currentTeam_]);
@@ -1455,6 +1458,8 @@
                SDL_BlitSurface(surface,NULL,dst,&dstrect);
        }
 
+       if (enemy_reach_ != NULL)
+               draw_enemies_reach(loc,xpos,ypos);
        draw_footstep(loc,xpos,ypos);
        draw_unit_on_tile(x,y,unit_image,alpha,blend_to);
 
@@ -1511,6 +1516,40 @@
        update_rect(xpos,ypos,zoom_,zoom_);
 }
 
+void display::draw_enemies_reach(const gamemap::location& loc, 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())
+               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();
+       const SDL_Rect& rect = map_area();
+
+       const SDL_Rect& text_area = font::text_area(str,font::SIZE_LARGE);
+       const int x = xloc + zoom_/2 - text_area.w/2;
+       const int y = yloc + zoom_/2 - text_area.h/2;
+
+       //draw the text with a black outline
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x-1,y-1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x-1,y);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x-1,y+1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x,y-1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x+1,y-1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x+1,y);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x+1,y+1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::DARK_COLOUR,str,x,y+1);
+       
font::draw_text(&screen_,rect,font::SIZE_LARGE,font::YELLOW_COLOUR,str,x,y);
+}
+
 void display::draw_footstep(const gamemap::location& loc, int xloc, int yloc)
 {
        std::vector<gamemap::location>::const_iterator i =
@@ -1809,9 +1848,17 @@
 void display::set_paths(const paths* paths_list)
 {
        pathsList_ = paths_list;
+       enemy_reach_ = NULL;
        invalidate_all();
 }
 
+void display::set_reach_map(const reach_map *reach_map)
+{
+       pathsList_ = NULL;
+       enemy_reach_ = reach_map;
+       invalidate_all();
+}
+
 void display::invalidate_route()
 {
        for(std::vector<gamemap::location>::const_iterator i = 
route_.steps.begin();
Index: src/playturn.hpp
===================================================================
--- src/playturn.hpp    (revision 8764)
+++ src/playturn.hpp    (working copy)
@@ -227,6 +227,7 @@
        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_;
Index: src/display.hpp
===================================================================
--- src/display.hpp     (revision 8764)
+++ src/display.hpp     (working copy)
@@ -161,6 +161,11 @@
        //paths_list must remain valid until it is set again
        void set_paths(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);
+  
        //sets the route along which footsteps are drawn to show movement of a
        //unit. If NULL, no route is displayed.
        //route does not have to remain valid after being set
@@ -200,6 +205,7 @@
 
        // 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);
 
 public:
        //function to draw a footstep for the given location, on screen at
@@ -493,6 +499,8 @@
        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_;
 

-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman


Reply via email to