16 #define GETTEXT_DOMAIN "wesnoth-lib" 52 , attacker_data_(attacker, bc.get_attacker_combatant(), bc.get_attacker_stats())
53 , defender_data_(defender, bc.get_defender_combatant(), bc.get_defender_stats())
65 std::ostringstream ss;
70 ss << std::fixed << std::setprecision(1) << 100.0 * prob <<
'%';
79 const std::string widget_id_prefix = attacker.
stats_.
is_attacker ?
"attacker" :
"defender";
81 const auto get_prefixed_widget_id = [&widget_id_prefix](
const std::string&
id) {
82 return (
formatter() << widget_id_prefix <<
"_" <<
id).str();
86 const auto set_label_helper = [&](
const std::string&
id,
const std::string& value) {
87 find_widget<label>(&
window, get_prefixed_widget_id(
id),
false).
set_label(value);
90 const auto hide_label_helper = [&](
const std::string&
id) {
105 set_label_helper(
"chance_unscathed", ss.str());
108 drawing& graph_widget = find_widget<drawing>(&
window, get_prefixed_widget_id(
"hp_graph"),
false);
116 set_label_helper(
"base_damage",
_(
"No usable weapon"));
119 hide_label_helper(
"tod_modifier");
120 hide_label_helper(
"leadership_modifier");
121 hide_label_helper(
"slowed_modifier");
131 std::optional<decltype(ctx)> opp_ctx;
142 auto set_dmg_effect = std::find_if(dmg_effect.begin(), dmg_effect.end(),
147 if(set_dmg_effect == dmg_effect.end()) {
148 ss << weapon->damage() <<
" (<i>" << weapon->name() <<
"</i>)";
150 assert(set_dmg_effect->ability);
151 ss << set_dmg_effect->value <<
" (<i>" << (*set_dmg_effect->ability)[
"name"] <<
"</i>)";
155 for(
const auto&
e : dmg_effect) {
164 ss <<
" (<i>" << (*
e.ability)[
"name"] <<
"</i>)";
169 for(
const auto&
e : dmg_effect) {
175 ss <<
"." << ((
e.value % 100) / 10);
177 ss << (
e.value % 10);
181 ss <<
" (<i>" << (*
e.ability)[
"name"] <<
"</i>)";
185 set_label_helper(
"base_damage", ss.str());
190 const int resistance_modifier = defender.
unit_->damage_from(*weapon, !attacker.
stats_.
is_attacker, defender.
unit_->get_location(), opp_weapon);
191 if(resistance_modifier != 100) {
193 if(resistance_modifier < 100) {
194 ss <<
_(
"Defender resistance vs") <<
" ";
196 ss <<
_(
"Defender vulnerability vs") <<
" ";
199 if(resistance_modifier < 100) {
200 ss <<
_(
"Attacker resistance vs") <<
" ";
202 ss <<
_(
"Attacker vulnerability vs") <<
" ";
208 set_label_helper(
"resis_label", ss.str());
213 set_label_helper(
"resis", ss.str());
226 if(tod_modifier != 0) {
229 hide_label_helper(
"tod_modifier");
235 if(leadership_bonus != 0) {
238 hide_label_helper(
"leadership_modifier");
243 set_label_helper(
"slowed_modifier",
"/ 2");
245 hide_label_helper(
"slowed_modifier");
249 const int base_damage = weapon->damage();
261 set_label_helper(
"total_damage", ss.str());
269 set_label_helper(
"chance_to_hit", ss.str());
279 const int hp_sep = 30;
282 const int percent_sep = 50;
285 const int bar_space =
graph_width - hp_sep - percent_sep - 4;
301 auto [hp, prob] = probability;
307 row_color = {229, 0, 0};
311 else if(hp < static_cast<int>(attacker.
stats_.
hp)) {
314 row_color = {154, 154, 154};
316 row_color = {244, 201, 0};
322 row_color = {8, 202, 0};
327 shape[
"y"] = 2 + (fs + 2) * i;
328 shape[
"w"] =
"(text_width)";
329 shape[
"h"] =
"(text_height)";
330 shape[
"font_size"] = 12;
331 shape[
"color"] =
"255, 255, 255, 255";
332 shape[
"text_alignment"] =
"(text_alignment)";
339 shape[
"y"] = 2 + (fs + 2) * i;
340 shape[
"w"] =
"(text_width)";
341 shape[
"h"] =
"(text_height)";
342 shape[
"font_size"] = 12;
343 shape[
"color"] =
"255, 255, 255, 255";
344 shape[
"text_alignment"] =
"(text_alignment)";
348 const int bar_len = std::max(static_cast<int>((prob * (bar_space - 4)) + 0.5), 2);
350 const SDL_Rect bar_rect_1 {
358 shape[
"x"] = bar_rect_1.x;
359 shape[
"y"] = bar_rect_1.y;
360 shape[
"w"] = bar_rect_1.w;
361 shape[
"h"] = bar_rect_1.h;
377 for(
int i = 0; i < static_cast<int>(hp_dist.size()); ++
i) {
378 const double prob = hp_dist[
i];
382 temp_vec.emplace_back(
i, prob);
387 std::sort(temp_vec.begin(), temp_vec.end(), [](
const auto& pair1,
const auto& pair2) {
388 return pair1.second > pair2.second;
392 std::copy_n(temp_vec.begin(), std::min<int>(
graph_max_rows, temp_vec.size()), std::back_inserter(res));
395 std::sort(res.begin(), res.end(), [](
const auto& pair1,
const auto& pair2) {
396 return pair1.first > pair2.first;
const_attack_ptr weapon
The weapon used by the unit to attack the opponent, or nullptr if there is none.
window(const builder_window::window_resolution &definition)
< Needs to be initialized in show.
std::string to_rgba_string() const
Returns the stored color as an "R,G,B,A" string.
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
double untouched
Resulting chance we were not hit by this opponent (important if it poisons)
std::vector< double > hp_dist
Resulting probability distribution (might be not as large as max_hp)
combatant_data defender_data_
hp_probability_vector get_hitpoint_probabilities(const std::vector< double > &hp_dist) const
This class represents a single unit of a specific type.
static std::string get_probability_string(const double prob)
std::vector< std::pair< int, double > > hp_probability_vector
unsigned int hp
Hitpoints of the unit at the beginning of the battle.
void set_variable(const std::string &key, wfl::variant &&value)
int under_leadership(const unit &u, const map_location &loc, const_attack_ptr weapon, const_attack_ptr opp_weapon)
Tests if the unit at loc is currently affected by leadership.
const color_t good_dmg_color
A drawing is widget with a fixed size and gives access to the canvas of the widget in the window inst...
void set_data(window &window, const combatant_data &attacker, const combatant_data &defender) const
static const unsigned int graph_max_rows
bool is_slowed
True if the unit is slowed at the beginning of the battle.
void draw_hp_graph(drawing &hp_graph, const combatant_data &attacker, const combatant_data &defender) const
static std::string _(const char *str)
Definitions for the interface to Wesnoth Markup Language (WML).
unsigned int chance_to_hit
Effective chance to hit as a percentage (all factors accounted for).
const color_t weapon_color
void append_drawing_data(const ::config &cfg)
std::shared_ptr< const unit > unit_const_ptr
std::string span_color(const color_t &color)
Returns a Pango formatting string using the provided color_t object.
const color_t bad_dmg_color
int damage
Effective damage of the weapon (all factors accounted for).
This file contains the settings handling of the widget library.
canvas & get_drawing_canvas()
const std::string unicode_multiplication_sign
The basic class for representing 8-bit RGB or RGBA colour values.
Computes the statistics of a battle between an attacker and a defender unit.
const battle_context_unit_stats & stats_
unit_alignments::type alignment() const
The alignment of this unit.
A simple canvas which can be drawn upon.
const combatant & combatant_
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
std::string signed_percent(int val)
Convert into a percentage (using the Unicode "−" and +0% convention.
config & add_child(config_key_type key)
attack_predictions(battle_context &bc, unit_const_ptr attacker, unit_const_ptr defender)
bool is_fearless() const
Gets whether this unit is fearless - ie, unaffected by time of day.
const std::string weapon_numbers_sep
int combat_modifier(const unit_map &units, const gamemap &map, const map_location &loc, unit_alignments::type alignment, bool is_fearless)
Returns the amount that a unit's damage should be multiplied by due to the current time of day...
const map_location & get_location() const
The current map location this unit is at.
symbol_table string_table
Abstract base class for all modal dialogs.
static const unsigned int graph_width
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.0, passing by yellow.
unsigned int num_blows
Effective number of blows, takes swarm into account.
bool is_attacker
True if the unit is the attacker.
static const unsigned int graph_height
bool petrifies
Attack petrifies opponent when it hits.
A config object defines a single node in a WML file, with access to child nodes.
std::shared_ptr< const attack_type > const_attack_ptr
combatant_data attacker_data_
base class of top level items, the only item which needs to store the final canvases to draw on...
unit_const_ptr unit_
never null