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.
This commit is contained in:
blaf 2019-02-18 18:45:25 +01:00 committed by Jyrki Vesterinen
parent 2975d616dc
commit 845978dc9c
5 changed files with 79 additions and 31 deletions

View file

@ -103,6 +103,7 @@
* Re-added the Font Scaling preference. * Re-added the Font Scaling preference.
* Enabled wesnothd and campaignd to accept IPv6 connections too * 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``` * 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 ## Version 1.14.5+dev
### AI ### AI

View file

@ -1129,6 +1129,9 @@
name = "Chusslove Illich (caslav.ilic)" name = "Chusslove Illich (caslav.ilic)"
comment = "wmlxgetext improvements" comment = "wmlxgetext improvements"
[/entry] [/entry]
[entry]
name = "David Slabý (blaf)"
[/entry]
[entry] [entry]
name = "Daniel Bruegmann" name = "Daniel Bruegmann"
[/entry] [/entry]

View file

@ -395,14 +395,13 @@ REPORT_GENERATOR(selected_unit_alignment, rc)
return unit_alignment(rc, u, hex_to_show_alignment_at); return unit_alignment(rc, u, hex_to_show_alignment_at);
} }
static config unit_abilities(const unit* u, const map_location& loc)
static config unit_abilities(const unit* u)
{ {
if (!u) return config(); if (!u) return config();
config res; config res;
boost::dynamic_bitset<> active; boost::dynamic_bitset<> active;
const std::vector<std::tuple<std::string, t_string,t_string,t_string>> &abilities = u->ability_tooltips(&active); const std::vector<std::tuple<std::string, t_string,t_string,t_string>> &abilities = u->ability_tooltips(active, loc);
const std::size_t abilities_size = abilities.size(); const std::size_t abilities_size = abilities.size();
for ( std::size_t i = 0; i != abilities_size; ++i ) 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) REPORT_GENERATOR(unit_abilities, rc)
{ {
const unit *u = get_visible_unit(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) REPORT_GENERATOR(selected_unit_abilities, rc)
{ {
const unit *u = get_selected_unit(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());
} }

View file

@ -265,39 +265,36 @@ namespace {
gender == unit_race::MALE ? male_key : female_key, gender == unit_race::MALE ? male_key : female_key,
default_key); default_key);
} }
}
std::vector<std::tuple<std::string, t_string, t_string, t_string>> unit::ability_tooltips(boost::dynamic_bitset<>* active_list) const /**
{ * Adds a quadruple consisting of (in order) id, base name,
std::vector<std::tuple<std::string, t_string,t_string,t_string>> res; * male or female name as appropriate for the unit, and description.
if ( active_list ) *
active_list->clear(); * @returns Whether name was resolved and quadruple added.
*/
for (const config::any_child &ab : this->abilities_.all_children_range()) bool add_ability_tooltip(const config::any_child &ab, unit_race::GENDER gender, std::vector<std::tuple<std::string, t_string,t_string,t_string>>& 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()) { if (!name.empty()) {
res.emplace_back( res.emplace_back(
ab.cfg["id"], ab.cfg["id"],
ab.cfg["name"].t_str(), ab.cfg["name"].t_str(),
name, name,
ab.cfg["description"].t_str() ); ab.cfg["description"].t_str() );
if ( active_list ) return true;
active_list->push_back(true);
} }
} }
else else
{ {
// See if an inactive name was specified. // See if an inactive name was specified.
const config::attribute_value& inactive_value = const config::attribute_value& inactive_value =
gender_value(ab.cfg, gender_, "name_inactive", gender_value(ab.cfg, gender, "name_inactive",
"female_name_inactive", "name_inactive"); "female_name_inactive", "name_inactive");
const t_string& name = !inactive_value.blank() ? inactive_value.t_str() : 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()) { if (!name.empty()) {
res.emplace_back( res.emplace_back(
@ -305,9 +302,38 @@ std::vector<std::tuple<std::string, t_string, t_string, t_string>> unit::ability
default_value(ab.cfg, "name_inactive", "name").t_str(), default_value(ab.cfg, "name_inactive", "name").t_str(),
name, name,
default_value(ab.cfg, "description_inactive", "description").t_str() ); default_value(ab.cfg, "description_inactive", "description").t_str() );
active_list->push_back(false); return true;
} }
} }
return false;
}
}
std::vector<std::tuple<std::string, t_string, t_string, t_string>> unit::ability_tooltips() const
{
std::vector<std::tuple<std::string, t_string,t_string,t_string>> res;
for (const config::any_child &ab : this->abilities_.all_children_range())
{
add_ability_tooltip(ab, gender_, res, true);
}
return res;
}
std::vector<std::tuple<std::string, t_string, t_string, t_string>> unit::ability_tooltips(boost::dynamic_bitset<>& active_list, const map_location& loc) const
{
std::vector<std::tuple<std::string, t_string,t_string,t_string>> 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; return res;
} }

View file

@ -1574,17 +1574,28 @@ public:
} }
/** /**
* Gets the names and descriptions of this unit's abilities. * Gets the names and descriptions of this unit's abilities. Location-independent variant
* with all abilities shown as active.
* *
* @param active_list If nullptr, then all abilities are forced active. If not, this vector * @returns A list of quadruples consisting of (in order) id, base name,
* will be the same length as the returned one and will indicate whether or * male or female name as appropriate for the unit, and description.
* not the corresponding ability is active.
*
* @returns A list of triples consisting of (in order) id, base name, male or female
* name as appropriate for the unit, and description.
*/ */
std::vector<std::tuple<std::string, t_string, t_string, t_string>> std::vector<std::tuple<std::string, t_string, t_string, t_string>>
ability_tooltips(boost::dynamic_bitset<>* active_list = nullptr) const; ability_tooltips() const;
/**
* Gets the names and descriptions of this unit's abilities.
*
* @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 quadruples consisting of (in order) id, base name,
* male or female name as appropriate for the unit, and description.
*/
std::vector<std::tuple<std::string, t_string, t_string, t_string>>
ability_tooltips(boost::dynamic_bitset<>& active_list, const map_location& loc) const;
/** Get a list of all abilities by ID. */ /** Get a list of all abilities by ID. */
std::vector<std::string> get_ability_list() const; std::vector<std::string> get_ability_list() const;