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.
* 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

View file

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

View file

@ -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<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();
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());
}

View file

@ -265,39 +265,36 @@ namespace {
gender == unit_race::MALE ? male_key : female_key,
default_key);
}
}
std::vector<std::tuple<std::string, t_string, t_string, t_string>> unit::ability_tooltips(boost::dynamic_bitset<>* active_list) const
{
std::vector<std::tuple<std::string, t_string,t_string,t_string>> 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<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()) {
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<std::tuple<std::string, t_string, t_string, t_string>> 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<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;
}

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
* will be the same length as the returned one and will indicate whether or
* 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.
* @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 = 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. */
std::vector<std::string> get_ability_list() const;