The Battle for Wesnoth  1.19.8+dev
helper.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  by David White <dave@whitevine.net>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Support functions for dealing with units.
19  */
20 
21 #include "units/unit.hpp"
22 #include "units/helper.hpp"
23 #include "units/types.hpp"
24 #include "play_controller.hpp"
25 #include "serialization/markup.hpp"
26 
27 namespace unit_helper {
28 
30 {
31  return u.advances_to().size() + u.get_modification_advances().size();
32 }
33 
35 {
36  if(!u.valid()) {
37  return false;
38  }
39  return u->advances() && number_of_possible_advances(*u) > 0;
40 }
41 
42 /**
43  * Maps resistance <= -60 (resistance value <= -60%) to intense red.
44  * Maps resistance >= 60 (resistance value >= 60%) to intense green.
45  * Intermediate values are affinely mapped to the red-to-green scale,
46  * with 0 (0%) being mapped to yellow.
47  * Compare attack_info_percent_color() in reports.cpp.
48  */
49 std::string resistance_color(const int resistance)
50 {
51  // Passing false to select the more saturated red-to-green scale.
52  return game_config::red_to_green(50.0 + resistance * 5.0 / 6.0, false).to_hex_string();
53 }
54 
55 static std::string unit_level_tooltip(const int level, const std::vector<std::string> &adv_to_types, const std::vector<config> &adv_to_mods)
56 {
57  std::ostringstream tooltip;
58  tooltip << _("Level: ") << markup::bold(level) << "\n";
59  const bool has_advancements = !adv_to_types.empty() || !adv_to_mods.empty();
60  if(has_advancements) {
61  tooltip << _("Advancements:") << "\n\t";
62  if(!adv_to_types.empty())
63  tooltip << markup::bold(utils::join(adv_to_types, "\n\t"));
64  if(!adv_to_mods.empty()) {
65  if(!adv_to_types.empty())
66  tooltip << "\n\t";
67  std::vector<std::string> descriptions;
68  for(const config& adv : adv_to_mods)
69  descriptions.push_back(adv["description"].str());
70  tooltip << markup::bold(utils::join(descriptions, "\n\t"));
71  }
72  } else {
73  tooltip << _("No advancement");
74  }
75  return tooltip.str();
76 }
77 
78 std::string unit_level_tooltip(const unit &u)
79 {
81 }
82 
83 std::string unit_level_tooltip(const unit_type &type)
84 {
85  const auto mod_adv_iters = type.modification_advancements();
86  const std::vector<config> mod_advancements(mod_adv_iters.begin(), mod_adv_iters.end());
87 
88  return unit_level_tooltip(type.level(), type.advances_to(), mod_advancements);
89 }
90 
91 std::string maybe_inactive(const std::string& str, bool active)
92 {
93  return (active ? str : markup::span_color(font::INACTIVE_COLOR, str));
94 }
95 
96 std::string format_cost_string(int unit_recall_cost, const int team_recall_cost)
97 {
98  std::stringstream str;
99 
100  if(unit_recall_cost < 0) {
101  unit_recall_cost = team_recall_cost;
102  }
103 
104  if(unit_recall_cost > team_recall_cost) {
105  str << markup::img("themes/gold.png") << markup::span_color(font::BAD_COLOR, unit_recall_cost);
106  } else if(unit_recall_cost == team_recall_cost) {
107  str << markup::img("themes/gold.png") << unit_recall_cost;
108  } else if(unit_recall_cost < team_recall_cost) {
109  str << markup::img("themes/gold.png~GS()") << markup::span_color(font::GREEN_COLOR, unit_recall_cost);
110  }
111 
112  return str.str();
113 }
114 
115 std::string format_cost_string(int unit_cost)
116 {
117  return formatter() << markup::img("themes/gold.png") << unit_cost;
118 }
119 
120 std::string format_level_string(const int level, bool recallable)
121 {
122  if(!recallable) {
123  // Same logic as when recallable, but always in inactive_color.
125  (level < 2 ? std::to_string(level) : markup::bold(level)));
126  } else if(level < 1) {
128  } else if(level == 1) {
129  return std::to_string(level);
130  } else if(level == 2) {
131  return markup::bold(level);
132  } else if(level == 3) {
133  return markup::span_color(color_t(0xe2, 0xb7, 0x76), markup::bold(level));
134  } else {
135  return markup::span_color(color_t(0xdd, 0x66, 0x00), markup::bold(level));
136  }
137 }
138 
139 std::string format_movement_string(const int moves_left, const int moves_max)
140 {
141  if(moves_left == 0) {
142  return markup::span_color(font::BAD_COLOR, moves_left, "/", moves_max);
143  } else if(moves_left > moves_max) {
144  return markup::span_color(font::YELLOW_COLOR, moves_left, "/", moves_max);
145  } else {
146  return markup::span_color(font::GREEN_COLOR, moves_left, "/", moves_max);
147  }
148 }
149 
150 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
std::ostringstream wrapper.
Definition: formatter.hpp:40
A single unit type that the player may recruit.
Definition: types.hpp:43
This class represents a single unit of a specific type.
Definition: unit.hpp:133
static std::string _(const char *str)
Definition: gettext.hpp:93
int level() const
The current level of this unit.
Definition: unit.hpp:559
std::vector< config > get_modification_advances() const
Gets any non-typed advanced options set by modifications.
Definition: unit.cpp:1854
const advances_to_t & advances_to() const
Gets the possible types this unit can advance to on level-up.
Definition: unit.hpp:244
const std::vector< std::string > advances_to_translated() const
Gets the names of the possible types this unit can advance to on level-up.
Definition: unit.cpp:1226
std::string tooltip
Shown when hovering over an entry in the filter's drop-down list.
Definition: manager.cpp:203
const color_t YELLOW_COLOR
const color_t BAD_COLOR
const color_t GREEN_COLOR
const color_t INACTIVE_COLOR
color_t red_to_green(double val, bool for_text)
Return a color corresponding to the value val red for val=0.0 to green for val=100....
std::string img(const std::string &src, const std::string &align, bool floating)
Generates a Help markup tag corresponding to an image.
Definition: markup.cpp:31
std::string bold(Args &&... data)
Applies bold Pango markup to the input.
Definition: markup.hpp:138
std::string span_color(const color_t &color, Args &&... data)
Applies Pango markup to the input specifying its display color.
Definition: markup.hpp:87
static std::string unit_level_tooltip(const int level, const std::vector< std::string > &adv_to_types, const std::vector< config > &adv_to_mods)
Definition: helper.cpp:55
bool will_certainly_advance(const unit_map::iterator &u)
Encapsulates the logic for deciding whether an iterator u points to a unit that can advance.
Definition: helper.cpp:34
std::string resistance_color(const int resistance)
Maps resistance <= -60 (resistance value <= -60%) to intense red.
Definition: helper.cpp:49
std::string format_level_string(const int level, bool recallable)
Definition: helper.cpp:120
std::string format_cost_string(int unit_recall_cost, const int team_recall_cost)
Definition: helper.cpp:96
std::string maybe_inactive(const std::string &str, bool active)
Definition: helper.cpp:91
int number_of_possible_advances(const unit &u)
Determines the total number of available advancements (of any kind) for a given unit.
Definition: helper.cpp:29
std::string format_movement_string(const int moves_left, const int moves_max)
Definition: helper.cpp:139
std::string join(const T &v, const std::string &s=",")
Generates a new string joining container items in a list.
int moves_left
Definition: pathfind.cpp:156
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Definition: color.cpp:88
bool valid() const
Definition: map.hpp:273