UI: Highlight enemy units in "Show Enemy Moves" mode (#3961)

Fixes #1989
This commit is contained in:
jostephd 2019-03-05 17:09:13 +00:00 committed by josteph
parent ebcfcaf8c5
commit b7293272f9
5 changed files with 37 additions and 11 deletions

View file

@ -556,17 +556,25 @@ void game_display::highlight_reach(const pathfind::paths &paths_list)
highlight_another_reach(paths_list);
}
void game_display::highlight_another_reach(const pathfind::paths &paths_list)
void game_display::highlight_another_reach(const pathfind::paths &paths_list,
const map_location& goal)
{
// Fold endpoints of routes into reachability map.
for (const pathfind::paths::step &dest : paths_list.destinations) {
reach_map_[dest.curr]++;
}
reach_map_changed_ = true;
if(goal != map_location::null_location() && paths_list.destinations.contains(goal)) {
const auto& path_to_goal = paths_list.destinations.get_path(paths_list.destinations.find(goal));
const map_location enemy_unit_location = path_to_goal[0];
units_that_can_reach_goal_.insert(enemy_unit_location);
}
}
bool game_display::unhighlight_reach()
{
units_that_can_reach_goal_.clear();
if(!reach_map_.empty()) {
reach_map_.clear();
reach_map_changed_ = true;

View file

@ -95,9 +95,15 @@ public:
/**
* Add more paths to highlight. Print numbers where they overlap.
* Used only by Show Enemy Moves.
* Used by Show Enemy Moves. If @a goal is not @c null_location, highlight
* enemy units that can reach @a goal.
*/
void highlight_another_reach(const pathfind::paths &paths_list);
void highlight_another_reach(const pathfind::paths &paths_list,
const map_location& goal = map_location::null_location());
/**
* Return the locations of units that can reach @a goal (@see highlight_another_reach()).
*/
const std::set<map_location>& units_that_can_reach_goal() const { return units_that_can_reach_goal_; }
/** Reset highlighting of paths. */
bool unhighlight_reach();
@ -142,6 +148,8 @@ protected:
virtual void draw_hex(const map_location& loc) override;
std::set<map_location> units_that_can_reach_goal_;
public:
/** Set the attack direction indicator. */
void set_attack_indicator(const map_location& src, const map_location& dst);

View file

@ -439,6 +439,9 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
{
wb::future_map future; // use unit positions as if all planned actions were executed
mouse_handler& mh = pc_.get_mouse_handler_base();
const map_location& hex_under_mouse = mh.hovered_hex();
gui_->unhighlight_reach();
// Compute enemy movement positions
@ -451,14 +454,12 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
const pathfind::paths& path
= pathfind::paths(u, false, true, teams()[gui_->viewing_team()], 0, false, ignore_units);
gui_->highlight_another_reach(path);
gui_->highlight_another_reach(path, hex_under_mouse);
}
}
// Find possible unit (no matter whether friend or foe) under the
// mouse cursor.
mouse_handler& mh = pc_.get_mouse_handler_base();
const map_location& hex_under_mouse = mh.hovered_hex();
const bool selected_hex_has_unit = mh.hex_hosts_unit(hex_under_mouse);
if(selected_hex_has_unit) {

View file

@ -17,6 +17,7 @@
#include "display.hpp"
#include "display_context.hpp"
#include "formatter.hpp"
#include "game_display.hpp"
#include "preferences/game.hpp"
#include "halo.hpp"
#include "map/map.hpp"
@ -49,7 +50,11 @@ unit_drawer::unit_drawer(display & thedisp) :
zoom_factor(disp.get_zoom_factor()),
hex_size(disp.hex_size()),
hex_size_by_2(disp.hex_size()/2)
{}
{
if(const game_display* game_display = dynamic_cast<class game_display*>(&disp)) {
units_that_can_reach_goal = game_display->units_that_can_reach_goal();
}
}
void unit_drawer::redraw_unit (const unit & u) const
{
@ -79,6 +84,9 @@ void unit_drawer::redraw_unit (const unit & u) const
std::string ellipse=u.image_ellipse();
const bool is_highlighted_enemy = units_that_can_reach_goal.count(loc) > 0;
const bool is_selected_hex = (loc == sel_hex || is_highlighted_enemy);
if ( hidden || is_blindfolded || !u.is_visible_to_team(viewing_team_ref, dc, show_everything) )
{
ac.clear_haloes();
@ -109,7 +117,7 @@ void unit_drawer::redraw_unit (const unit & u) const
params.highlight_ratio > 0.6) {
params.highlight_ratio = 0.6;
}
if (loc == sel_hex && params.highlight_ratio == 1.0) {
if (is_selected_hex && params.highlight_ratio == 1.0) {
params.highlight_ratio = 1.5;
}
@ -184,7 +192,7 @@ void unit_drawer::redraw_unit (const unit & u) const
surface ellipse_back(nullptr);
int ellipse_floating = 0;
// Always show the ellipse for selected units
if(draw_bars && (preferences::show_side_colors() || sel_hex == loc)) {
if(draw_bars && (preferences::show_side_colors() || is_selected_hex)) {
if(adjusted_params.submerge > 0.0) {
// The division by 2 seems to have no real meaning,
// It just works fine with the current center of ellipse
@ -200,7 +208,7 @@ void unit_drawer::redraw_unit (const unit & u) const
// check if the unit has a ZoC or can recruit
const std::string nozoc = !emit_zoc ? "nozoc-" : "";
const std::string leader = can_recruit ? "leader-" : "";
const std::string selected = sel_hex == loc ? "selected-" : "";
const std::string selected = is_selected_hex? "selected-" : "";
const std::string tc = team::get_side_color_id(side);
const std::string ellipse_top = formatter() << ellipse << "-" << leader << nozoc << selected << "top.png~RC(ellipse_red>" << tc << ")";
@ -296,7 +304,7 @@ void unit_drawer::redraw_unit (const unit & u) const
const int bar_shift = static_cast<int>(-5*zoom_factor);
const int hp_bar_height = static_cast<int>(max_hitpoints * u.hp_bar_scaling());
const fixed_t bar_alpha = (loc == mouse_hex || loc == sel_hex) ? ftofxp(1.0): ftofxp(0.8);
const fixed_t bar_alpha = (loc == mouse_hex || is_selected_hex) ? ftofxp(1.0): ftofxp(0.8);
draw_bar(*energy_file, xsrc+xoff+bar_shift, ysrc+yoff+adjusted_params.y,
loc, hp_bar_height, unit_energy,hp_color, bar_alpha);

View file

@ -60,6 +60,7 @@ private:
map_location sel_hex;
map_location mouse_hex;
double zoom_factor;
std::set<map_location> units_that_can_reach_goal;
int hex_size;
int hex_size_by_2;