16 #define GETTEXT_DOMAIN "wesnoth-lib"
49 , attacker_data_(attacker, bc.get_attacker_combatant(), bc.get_attacker_stats())
50 , defender_data_(defender, bc.get_defender_combatant(), bc.get_defender_stats())
62 std::ostringstream ss;
67 ss << std::fixed << std::setprecision(1) << 100.0 * prob <<
'%';
76 const std::string widget_id_prefix = attacker.
stats_.
is_attacker ?
"attacker" :
"defender";
78 const auto get_prefixed_widget_id = [&widget_id_prefix](
const std::string&
id) {
79 return (
formatter() << widget_id_prefix <<
"_" <<
id).str();
83 const auto set_label_helper = [&,
this](
const std::string&
id,
const std::string& value) {
85 label& lbl = this->find_widget<label>(get_prefixed_widget_id(
id));
89 const auto hide_label_helper = [&,
this](
const std::string&
id) {
91 label& lbl = this->find_widget<label>(get_prefixed_widget_id(
id));
93 label& lbl2 = this->find_widget<label>(get_prefixed_widget_id(
id) +
"_label");
107 set_label_helper(
"chance_unscathed", ss.str());
110 drawing& graph_widget = find_widget<drawing>(get_prefixed_widget_id(
"hp_graph"));
118 set_label_helper(
"base_damage",
_(
"No usable weapon"));
121 hide_label_helper(
"tod_modifier");
122 hide_label_helper(
"leadership_modifier");
123 hide_label_helper(
"slowed_modifier");
133 utils::optional<decltype(ctx)> opp_ctx;
144 auto set_dmg_effect = std::find_if(dmg_effect.
begin(), dmg_effect.
end(),
149 if(set_dmg_effect == dmg_effect.
end()) {
150 ss << weapon->damage() <<
" (" <<
markup::italic(weapon->name()) <<
")";
152 assert(set_dmg_effect->ability);
153 ss << set_dmg_effect->value <<
" (" <<
markup::italic((*set_dmg_effect->ability)[
"name"]) <<
")";
157 for(
const auto&
e : dmg_effect) {
171 for(
const auto&
e : dmg_effect) {
177 ss <<
"." << ((
e.value % 100) / 10);
179 ss << (
e.value % 10);
187 set_label_helper(
"base_damage", ss.str());
192 const int resistance_modifier = defender.
unit_->damage_from(*weapon, !attacker.
stats_.
is_attacker, defender.
unit_->get_location(), opp_weapon);
193 if(resistance_modifier != 100) {
195 if(resistance_modifier < 100) {
196 ss <<
_(
"Defender resistance vs") <<
" ";
198 ss <<
_(
"Defender vulnerability vs") <<
" ";
201 if(resistance_modifier < 100) {
202 ss <<
_(
"Attacker resistance vs") <<
" ";
204 ss <<
_(
"Attacker vulnerability vs") <<
" ";
208 std::pair<std::string, std::string> types = weapon->damage_type();
209 std::string type_bis = types.second;
210 if (!type_bis.empty()) {
215 set_label_helper(
"resis_label", ss.str());
220 set_label_helper(
"resis", ss.str());
234 if(tod_modifier != 0) {
237 hide_label_helper(
"tod_modifier");
243 if(leadership_bonus != 0) {
246 hide_label_helper(
"leadership_modifier");
251 set_label_helper(
"slowed_modifier",
"/ 2");
253 hide_label_helper(
"slowed_modifier");
257 const int base_damage = weapon->damage();
269 set_label_helper(
"total_damage", ss.str());
277 set_label_helper(
"chance_to_hit", ss.str());
287 const int hp_sep = 30;
290 const int percent_sep = 50;
293 const int bar_space =
graph_width - hp_sep - percent_sep - 4;
309 auto [hp, prob] = probability;
315 row_color = {229, 0, 0};
319 else if(hp <
static_cast<int>(attacker.
stats_.
hp)) {
322 row_color = {154, 154, 154};
324 row_color = {244, 201, 0};
330 row_color = {8, 202, 0};
335 shape[
"y"] = 2 + (
fs + 2) *
i;
336 shape[
"w"] =
"(text_width)";
337 shape[
"h"] =
"(text_height)";
338 shape[
"font_size"] = 12;
339 shape[
"color"] =
"255, 255, 255, 255";
340 shape[
"text_alignment"] =
"(text_alignment)";
347 shape[
"y"] = 2 + (
fs + 2) *
i;
348 shape[
"w"] =
"(text_width)";
349 shape[
"h"] =
"(text_height)";
350 shape[
"font_size"] = 12;
351 shape[
"color"] =
"255, 255, 255, 255";
352 shape[
"text_alignment"] =
"(text_alignment)";
356 const int bar_len = std::max(
static_cast<int>((prob * (bar_space - 4)) + 0.5), 2);
358 const SDL_Rect bar_rect_1 {
366 shape[
"x"] = bar_rect_1.x;
367 shape[
"y"] = bar_rect_1.y;
368 shape[
"w"] = bar_rect_1.w;
369 shape[
"h"] = bar_rect_1.h;
385 for(
int i = 0; i < static_cast<int>(hp_dist.size()); ++
i) {
386 const double prob = hp_dist[
i];
390 temp_vec.emplace_back(
i, prob);
395 std::sort(temp_vec.begin(), temp_vec.end(), [](
const auto& pair1,
const auto& pair2) {
396 return pair1.second > pair2.second;
400 std::copy_n(temp_vec.begin(), std::min<int>(
graph_max_rows, temp_vec.size()), std::back_inserter(res));
403 std::sort(res.begin(), res.end(), [](
const auto& pair1,
const auto& pair2) {
404 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_