16 #define GETTEXT_DOMAIN "wesnoth-lib"
50 , attacker_data_(std::move(attacker), bc.get_attacker_combatant(), bc.get_attacker_stats())
51 , defender_data_(std::move(defender), bc.get_defender_combatant(), bc.get_defender_stats())
63 std::ostringstream ss;
68 ss << std::fixed << std::setprecision(1) << 100.0 * prob <<
'%';
77 const std::string widget_id_prefix = attacker.
stats_.
is_attacker ?
"attacker" :
"defender";
79 const auto get_prefixed_widget_id = [&widget_id_prefix](
const std::string&
id) {
80 return (
formatter() << widget_id_prefix <<
"_" <<
id).str();
84 const auto set_label_helper = [&,
this](
const std::string&
id,
const std::string& value) {
86 label& lbl = this->find_widget<label>(get_prefixed_widget_id(
id));
90 const auto hide_label_helper = [&,
this](
const std::string&
id) {
92 label& lbl = this->find_widget<label>(get_prefixed_widget_id(
id));
94 label& lbl2 = this->find_widget<label>(get_prefixed_widget_id(
id) +
"_label");
108 set_label_helper(
"chance_unscathed", ss.str());
111 drawing& graph_widget = find_widget<drawing>(get_prefixed_widget_id(
"hp_graph"));
119 set_label_helper(
"base_damage",
_(
"No usable weapon"));
122 hide_label_helper(
"tod_modifier");
123 hide_label_helper(
"leadership_modifier");
124 hide_label_helper(
"slowed_modifier");
134 utils::optional<decltype(ctx)> opp_ctx;
145 auto set_dmg_effect = std::find_if(dmg_effect.
begin(), dmg_effect.
end(),
150 if(set_dmg_effect == dmg_effect.
end()) {
151 ss << weapon->damage() <<
" (" <<
markup::italic(weapon->name()) <<
")";
153 assert(set_dmg_effect->ability);
154 ss << set_dmg_effect->value <<
" (" <<
markup::italic((*set_dmg_effect->ability)[
"name"]) <<
")";
158 for(
const auto&
e : dmg_effect) {
172 for(
const auto&
e : dmg_effect) {
178 ss <<
"." << ((
e.value % 100) / 10);
180 ss << (
e.value % 10);
188 set_label_helper(
"base_damage", ss.str());
193 const int resistance_modifier = defender.
unit_->damage_from(*weapon, !attacker.
stats_.
is_attacker, defender.
unit_->get_location(), opp_weapon);
194 if(resistance_modifier != 100) {
196 if(resistance_modifier < 100) {
197 ss <<
_(
"Defender resistance vs") <<
" ";
199 ss <<
_(
"Defender vulnerability vs") <<
" ";
202 if(resistance_modifier < 100) {
203 ss <<
_(
"Attacker resistance vs") <<
" ";
205 ss <<
_(
"Attacker vulnerability vs") <<
" ";
209 std::pair<std::string, std::string> types = weapon->damage_type();
210 std::string type_bis = types.second;
211 if (!type_bis.empty()) {
216 set_label_helper(
"resis_label", ss.str());
221 set_label_helper(
"resis", ss.str());
235 if(tod_modifier != 0) {
238 hide_label_helper(
"tod_modifier");
244 if(leadership_bonus != 0) {
247 hide_label_helper(
"leadership_modifier");
252 set_label_helper(
"slowed_modifier",
"/ 2");
254 hide_label_helper(
"slowed_modifier");
258 const int base_damage = weapon->damage();
270 set_label_helper(
"total_damage", ss.str());
278 set_label_helper(
"chance_to_hit", ss.str());
288 const int hp_sep = 30;
291 const int percent_sep = 50;
294 const int bar_space =
graph_width - hp_sep - percent_sep - 4;
310 auto [hp, prob] = probability;
316 row_color = {229, 0, 0};
320 else if(hp <
static_cast<int>(attacker.
stats_.
hp)) {
323 row_color = {154, 154, 154};
325 row_color = {244, 201, 0};
331 row_color = {8, 202, 0};
336 shape[
"y"] = 2 + (
fs + 2) *
i;
337 shape[
"w"] =
"(text_width)";
338 shape[
"h"] =
"(text_height)";
339 shape[
"font_size"] = 12;
340 shape[
"color"] =
"255, 255, 255, 255";
341 shape[
"text_alignment"] =
"(text_alignment)";
348 shape[
"y"] = 2 + (
fs + 2) *
i;
349 shape[
"w"] =
"(text_width)";
350 shape[
"h"] =
"(text_height)";
351 shape[
"font_size"] = 12;
352 shape[
"color"] =
"255, 255, 255, 255";
353 shape[
"text_alignment"] =
"(text_alignment)";
357 const int bar_len = std::max(
static_cast<int>((prob * (bar_space - 4)) + 0.5), 2);
359 const SDL_Rect bar_rect_1 {
367 shape[
"x"] = bar_rect_1.x;
368 shape[
"y"] = bar_rect_1.y;
369 shape[
"w"] = bar_rect_1.w;
370 shape[
"h"] = bar_rect_1.h;
386 for(
int i = 0; i < static_cast<int>(hp_dist.size()); ++
i) {
387 const double prob = hp_dist[
i];
391 temp_vec.emplace_back(
i, prob);
396 std::sort(temp_vec.begin(), temp_vec.end(), [](
const auto& pair1,
const auto& pair2) {
397 return pair1.second > pair2.second;
401 std::copy_n(temp_vec.begin(), std::min<int>(
graph_max_rows, temp_vec.size()), std::back_inserter(res));
404 std::sort(res.begin(), res.end(), [](
const auto& pair1,
const auto& pair2) {
405 return pair1.first > pair2.first;
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.
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.
Computes the statistics of a battle between an attacker and a defender unit.
A config object defines a single node in a WML file, with access to child nodes.
config & add_child(config_key_type key)
A simple canvas which can be drawn upon.
void set_variable(const std::string &key, wfl::variant &&value)
static const unsigned int graph_width
attack_predictions(battle_context &bc, unit_const_ptr attacker, unit_const_ptr defender)
void draw_hp_graph(drawing &hp_graph, const combatant_data &attacker, const combatant_data &defender)
static const unsigned int graph_height
void set_data(const combatant_data &attacker, const combatant_data &defender)
static const unsigned int graph_max_rows
virtual void pre_show() override
Actions to be taken before showing the window.
combatant_data attacker_data_
hp_probability_vector get_hitpoint_probabilities(const std::vector< double > &hp_dist) const
combatant_data defender_data_
Abstract base class for all modal dialogs.
void append_drawing_data(const ::config &cfg)
canvas & get_drawing_canvas()
const_iterator end() const
const_iterator begin() const
This class represents a single unit of a specific type.
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string _(const char *str)
unit_alignments::type alignment() const
The alignment of this unit.
const map_location & get_location() const
The current map location this unit is at.
bool is_fearless() const
Gets whether this unit is fearless - ie, unaffected by time of day.
symbol_table string_table
const std::string unicode_multiplication_sign
const color_t good_dmg_color
const color_t weapon_color
const std::string weapon_numbers_sep
const color_t bad_dmg_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....
REGISTER_DIALOG(editor_edit_unit)
static std::string get_probability_string(const double prob)
std::vector< std::pair< int, double > > hp_probability_vector
std::string italic(Args &&... data)
std::string span_color(const color_t &color, Args &&... data)
std::string signed_percent(int val)
Convert into a percentage (using the Unicode "−" and +0% convention.
std::shared_ptr< const unit > unit_const_ptr
std::shared_ptr< const attack_type > const_attack_ptr
unsigned int num_blows
Effective number of blows, takes swarm into account.
bool petrifies
Attack petrifies opponent when it hits.
unsigned int hp
Hitpoints of the unit at the beginning of the battle.
bool is_attacker
True if the unit is the attacker.
const_attack_ptr weapon
The weapon used by the unit to attack the opponent, or nullptr if there is none.
bool is_slowed
True if the unit is slowed at the beginning of the battle.
int damage
Effective damage of the weapon (all factors accounted for).
unsigned int chance_to_hit
Effective chance to hit as a percentage (all factors accounted for).
The basic class for representing 8-bit RGB or RGBA colour values.
std::string to_rgba_string() const
Returns the stored color as an "R,G,B,A" string.
std::vector< double > hp_dist
Resulting probability distribution (might be not as large as max_hp)
double untouched
Resulting chance we were not hit by this opponent (important if it poisons)
const battle_context_unit_stats & stats_
unit_const_ptr unit_
never null
const combatant & combatant_