From 845978dc9cb2e449f6c65856d43a405f63f98932 Mon Sep 17 00:00:00 2001 From: blaf Date: Mon, 18 Feb 2019 18:45:25 +0100 Subject: [PATCH] Fix #3912: Abilities display in sidebar should use the mouseover hex (#3929) Show ability of a selected unit as active/inactive with respect to mouseover hex. For example, selecting an Elvish Ranger that stands on a forest and highlighting a water hex should show the "ambush" ability in gray. --- changelog.md | 1 + data/core/about.cfg | 3 ++ src/reports.cpp | 17 +++++++---- src/units/abilities.cpp | 62 +++++++++++++++++++++++++++++------------ src/units/unit.hpp | 23 +++++++++++---- 5 files changed, 77 insertions(+), 29 deletions(-) diff --git a/changelog.md b/changelog.md index cb50afd10871..1b7f8eae7152 100644 --- a/changelog.md +++ b/changelog.md @@ -103,6 +103,7 @@ * Re-added the Font Scaling preference. * Enabled wesnothd and campaignd to accept IPv6 connections too * Added support for directly supplying IPv6 address of the server to multiplayer client and addon client. It must be done like this: ```[ipv6_address]``` or ```[ipv6_address]:port``` + * Show ability of a selected unit as active/inactive with respect to mouseover hex. (issue #3912) ## Version 1.14.5+dev ### AI diff --git a/data/core/about.cfg b/data/core/about.cfg index 265adb232805..ad2d9cd0262d 100644 --- a/data/core/about.cfg +++ b/data/core/about.cfg @@ -1129,6 +1129,9 @@ name = "Chusslove Illich (caslav.ilic)" comment = "wmlxgetext improvements" [/entry] + [entry] + name = "David SlabĂ˝ (blaf)" + [/entry] [entry] name = "Daniel Bruegmann" [/entry] diff --git a/src/reports.cpp b/src/reports.cpp index 6a3a8b340488..4cfec466db19 100644 --- a/src/reports.cpp +++ b/src/reports.cpp @@ -395,14 +395,13 @@ REPORT_GENERATOR(selected_unit_alignment, rc) return unit_alignment(rc, u, hex_to_show_alignment_at); } - -static config unit_abilities(const unit* u) +static config unit_abilities(const unit* u, const map_location& loc) { if (!u) return config(); config res; boost::dynamic_bitset<> active; - const std::vector> &abilities = u->ability_tooltips(&active); + const std::vector> &abilities = u->ability_tooltips(active, loc); const std::size_t abilities_size = abilities.size(); for ( std::size_t i = 0; i != abilities_size; ++i ) { @@ -433,12 +432,20 @@ static config unit_abilities(const unit* u) REPORT_GENERATOR(unit_abilities, rc) { const unit *u = get_visible_unit(rc); - return unit_abilities(u); + const map_location& mouseover_hex = rc.screen().mouseover_hex(); + + return unit_abilities(u, mouseover_hex); } REPORT_GENERATOR(selected_unit_abilities, rc) { const unit *u = get_selected_unit(rc); - return unit_abilities(u); + + const map_location& mouseover_hex = rc.screen().mouseover_hex(); + const unit *visible_unit = get_visible_unit(rc); + if(visible_unit && u && visible_unit->id() != u->id() && mouseover_hex.valid()) + return unit_abilities(u, mouseover_hex); + else + return unit_abilities(u, u->get_location()); } diff --git a/src/units/abilities.cpp b/src/units/abilities.cpp index 8571680bf501..ad65896d1f47 100644 --- a/src/units/abilities.cpp +++ b/src/units/abilities.cpp @@ -265,39 +265,36 @@ namespace { gender == unit_race::MALE ? male_key : female_key, default_key); } -} - -std::vector> unit::ability_tooltips(boost::dynamic_bitset<>* active_list) const -{ - std::vector> res; - if ( active_list ) - active_list->clear(); - for (const config::any_child &ab : this->abilities_.all_children_range()) + /** + * Adds a quadruple consisting of (in order) id, base name, + * male or female name as appropriate for the unit, and description. + * + * @returns Whether name was resolved and quadruple added. + */ + bool add_ability_tooltip(const config::any_child &ab, unit_race::GENDER gender, std::vector>& res, bool active) { - if ( !active_list || ability_active(ab.key, ab.cfg, loc_) ) - { - const t_string& name = - gender_value(ab.cfg, gender_, "name", "female_name", "name").t_str(); + const t_string& name = + gender_value(ab.cfg, gender, "name", "female_name", "name").t_str(); + if (active) { if (!name.empty()) { res.emplace_back( ab.cfg["id"], ab.cfg["name"].t_str(), name, ab.cfg["description"].t_str() ); - if ( active_list ) - active_list->push_back(true); + return true; } } else { // See if an inactive name was specified. const config::attribute_value& inactive_value = - gender_value(ab.cfg, gender_, "name_inactive", - "female_name_inactive", "name_inactive"); + gender_value(ab.cfg, gender, "name_inactive", + "female_name_inactive", "name_inactive"); const t_string& name = !inactive_value.blank() ? inactive_value.t_str() : - gender_value(ab.cfg, gender_, "name", "female_name", "name").t_str(); + gender_value(ab.cfg, gender, "name", "female_name", "name").t_str(); if (!name.empty()) { res.emplace_back( @@ -305,9 +302,38 @@ std::vector> unit::ability default_value(ab.cfg, "name_inactive", "name").t_str(), name, default_value(ab.cfg, "description_inactive", "description").t_str() ); - active_list->push_back(false); + return true; } } + + return false; + } +} + +std::vector> unit::ability_tooltips() const +{ + std::vector> res; + + for (const config::any_child &ab : this->abilities_.all_children_range()) + { + add_ability_tooltip(ab, gender_, res, true); + } + + return res; +} + +std::vector> unit::ability_tooltips(boost::dynamic_bitset<>& active_list, const map_location& loc) const +{ + std::vector> res; + active_list.clear(); + + for (const config::any_child &ab : this->abilities_.all_children_range()) + { + bool active = ability_active(ab.key, ab.cfg, loc); + if (add_ability_tooltip(ab, gender_, res, active)) + { + active_list.push_back(active); + } } return res; } diff --git a/src/units/unit.hpp b/src/units/unit.hpp index a83ad7acf456..9a721872e46f 100644 --- a/src/units/unit.hpp +++ b/src/units/unit.hpp @@ -1573,18 +1573,29 @@ class unit return get_abilities(tag_name, loc_, weapon, opp_weapon); } + /** + * Gets the names and descriptions of this unit's abilities. Location-independent variant + * with all abilities shown as active. + * + * @returns A list of quadruples consisting of (in order) id, base name, + * male or female name as appropriate for the unit, and description. + */ + std::vector> + ability_tooltips() const; + /** * Gets the names and descriptions of this unit's abilities. * - * @param active_list If nullptr, then all abilities are forced active. If not, this vector - * will be the same length as the returned one and will indicate whether or - * not the corresponding ability is active. + * @param active_list This vector will be the same length as the returned one and will + * indicate whether or not the corresponding ability is active. + * + * @param loc The location on which to resolve the ability. * - * @returns A list of triples consisting of (in order) id, base name, male or female - * name as appropriate for the unit, and description. + * @returns A list of quadruples consisting of (in order) id, base name, + * male or female name as appropriate for the unit, and description. */ std::vector> - ability_tooltips(boost::dynamic_bitset<>* active_list = nullptr) const; + ability_tooltips(boost::dynamic_bitset<>& active_list, const map_location& loc) const; /** Get a list of all abilities by ID. */ std::vector get_ability_list() const;