Skip to content

Commit

Permalink
Usability improvement, mouse interaction.
Browse files Browse the repository at this point in the history
When the game is cluttered with units from any side, the probability
of 'landing' the mouse cursor on top of a unit after activating the
'show [best possible] enemy moves' facility (via mouse) increases
drastically. In that scenario, the slightest mouse move rewinded back
enemy units movements highlight.

After this rev, if the cursor lands on a unit, an object field gets
toggled and it prevents normal single unit movements highlight until
mouse stops hovering units. Then it gets switched back to normal
interaction.

Final form of changes largely credited to review from @CelticMinstrel,
@jyrkive and @Vultraz. Abstraction `mouse_handler::hex_hosts_unit`
devised by @CelticMinstrel. Abstraction `mouse_handler::hovered_hex`
devised by @jyrkive.

src/menu_events.cpp: Disable unit movements highlighting when mouse
landing on unit after activating 'show [best possible] enemy moves'
via mouse.

src/mouse_events.cpp: On mouse_handler construction, normal units
highlighting is allowed. If the mouse is hovering a unit, do not show
unit paths if the toggle for preventing it is active. If the mouse is
not on a unit, disable the toggle.

src/mouse_events.hpp: Add object field that will be responsible to
control prevention of unit paths highlighting when that gets judged
as improper. Add new public function for querying if a given hex is
occupied by a unit. Add new public function for returning the hex the
mouse is hovering, if any.
  • Loading branch information
galegosimpatico authored and GregoryLundberg committed Nov 30, 2017
1 parent 756dcfa commit 5c099e0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/menu_events.cpp
Expand Up @@ -454,6 +454,20 @@ void menu_handler::show_enemy_moves(bool ignore_units, int side_num)
gui_->highlight_another_reach(path);
}
}

// 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) {
// At this point, a single pixel move would remove the enemy
// [best possible] movements hex tiles highlights, so some
// prevention on normal unit mouseover movement highlight
// has to be toggled temporarily.
mh.disable_units_highlight();
}
}

void menu_handler::toggle_shroud_updates(int side_num)
Expand Down
39 changes: 39 additions & 0 deletions src/mouse_events.cpp
Expand Up @@ -81,6 +81,7 @@ mouse_handler::mouse_handler(game_display* gui, play_controller& pc)
, over_route_(false)
, reachmap_invalid_(false)
, show_partial_move_(false)
, preventing_units_highlight_(false)
{
singleton_ = this;
}
Expand Down Expand Up @@ -296,6 +297,14 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m
} // end planned unit map scope

if((!selected_hex_.valid()) && un && current_paths_.destinations.empty() && !gui().fogged(un->get_location())) {
/*
* Only process unit if toggler not preventing normal unit
* processing. This can happen e.g. if, after activating 'show
* [best possible] enemy movements' through the UI menu, the
* mouse cursor lands on a hex with unit in it.
*/
if(!preventing_units_highlight_) {

if(un->side() == side_num_) {
// unit is on our team, show path if the unit has one
const map_location go_to = un->get_goto();
Expand Down Expand Up @@ -324,6 +333,13 @@ void mouse_handler::mouse_motion(int x, int y, const bool browse, bool update, m
unselected_paths_ = true;

gui().highlight_reach(current_paths_);

} // !preventing_units_highlight_
}

if(!un && preventing_units_highlight_) {
// Cursor on empty hex, turn unit highlighting back on.
enable_units_highlight();
}
}

Expand Down Expand Up @@ -352,6 +368,19 @@ unit_map::const_iterator mouse_handler::find_unit(const map_location& hex) const
return pc_.gamestate().board_.find_visible_unit(hex, viewing_team());
}

const map_location mouse_handler::hovered_hex() const
{
int x = -1;
int y = -1;
SDL_GetMouseState(&x, &y);
return gui_->hex_clicked_on(x, y);
}

bool mouse_handler::hex_hosts_unit(const map_location& hex) const
{
return find_unit(hex).valid();
}

map_location mouse_handler::current_unit_attacks_from(const map_location& loc) const
{
if(loc == selected_hex_) {
Expand Down Expand Up @@ -1213,4 +1242,14 @@ team& mouse_handler::current_team()

mouse_handler* mouse_handler::singleton_ = nullptr;

void mouse_handler::disable_units_highlight()
{
preventing_units_highlight_ = true;
}

void mouse_handler::enable_units_highlight()
{
preventing_units_highlight_ = false;
}

} // end namespace events
27 changes: 27 additions & 0 deletions src/mouse_events.hpp
Expand Up @@ -87,6 +87,31 @@ class mouse_handler : public mouse_handler_base {

void select_or_action(bool browse);

/**
* Uses SDL and @ref game_display::hex_clicked_on
* to fetch the hex the mouse is hovering, if applicable.
*/
const map_location hovered_hex() const;

/** Unit exists on the hex, no matter if friend or foe. */
bool hex_hosts_unit(const map_location& hex) const;

/**
* Use this to disable hovering an unit from highlighting its movement
* range.
*
* @see enable_units_highlight()
*/
void disable_units_highlight();

/**
* When unit highlighting is disabled, call this when the mouse no
* longer hovers any unit to enable highlighting again.
*
* @see disable_units_highlight()
*/
void enable_units_highlight();

protected:
/**
* Due to the way this class is constructed we can assume that the
Expand Down Expand Up @@ -146,6 +171,8 @@ class mouse_handler : public mouse_handler_base {
bool show_partial_move_;

static mouse_handler * singleton_;

bool preventing_units_highlight_;
};

}

0 comments on commit 5c099e0

Please sign in to comment.