The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
attack_prediction_display.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2016 by Joerg Hinrichs <[email protected]>
3  wesnoth playturn Copyright (C) 2003 by David White <[email protected]>
4  Part of the Battle for Wesnoth Project http://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 
17 
18 #include "actions/attack.hpp"
19 #include "attack_prediction.hpp"
20 #include "gettext.hpp"
21 #include "game_board.hpp"
22 #include "game_display.hpp"
23 #include "language.hpp"
24 #include "marked-up_text.hpp"
25 #include "resources.hpp"
26 #include "sdl/alpha.hpp"
27 #include "units/unit.hpp"
28 #include "units/abilities.hpp"
29 
30 // Conversion routine for both unscathed and damage change percentage.
31 static void format_prob(char str_buf[10], double prob)
32 {
33 
34  if(prob > 0.9995) {
35  snprintf(str_buf, 10, "100 %%");
36  } else if(prob >= 0.1) {
37  snprintf(str_buf, 10, "%4.1f %%", 100.0 * prob);
38  } else {
39  snprintf(str_buf, 10, " %3.1f %%", 100.0 * prob);
40  }
41 
42  str_buf[9] = '\0'; //prevents _snprintf error
43 }
44 
45 
50 
52  const map_location &attacker_loc, const map_location &defender_loc) :
53  gui::preview_pane(resources::screen->video()),
54  attacker_loc_(attacker_loc),
55  defender_loc_(defender_loc),
56  attacker_(*resources::units->find(attacker_loc)),
57  defender_(*resources::units->find(defender_loc)),
58  attacker_label_(),
59  defender_label_(),
60  attacker_label_width_(0),
61  defender_label_width_(0),
62  attacker_left_strings_(),
63  attacker_right_strings_(),
64  defender_left_strings_(),
65  defender_right_strings_(),
66  attacker_strings_width_(0),
67  attacker_left_strings_width_(0),
68  attacker_right_strings_width_(0),
69  defender_strings_width_(0),
70  defender_left_strings_width_(0),
71  defender_right_strings_width_(0),
72  units_strings_height_(0),
73  hp_distrib_string_(),
74  attacker_hp_distrib_(),
75  defender_hp_distrib_(),
76  hp_distrib_string_width_(0),
77  attacker_hp_distrib_width_(0),
78  defender_hp_distrib_width_(0),
79  attacker_hp_distrib_height_(0),
80  defender_hp_distrib_height_(0),
81  hp_distribs_height_(0),
82  attacker_width_(0),
83  defender_width_(0),
84  units_width_(0),
85  dialog_width_(0),
86  dialog_height_(0)
87 {
88  // Predict the battle outcome.
89  combatant attacker_combatant(bc.get_attacker_stats());
90  combatant defender_combatant(bc.get_defender_stats());
91  attacker_combatant.fight(defender_combatant);
92 
93  const battle_context_unit_stats& attacker_stats = bc.get_attacker_stats();
94  const battle_context_unit_stats& defender_stats = bc.get_defender_stats();
95 
96  // Create the hitpoints distribution graphics.
97  std::vector<std::pair<int, double> > hp_prob_vector;
98  get_hp_prob_vector(attacker_combatant.hp_dist, hp_prob_vector);
99  get_hp_distrib_surface(hp_prob_vector, attacker_stats, defender_stats, attacker_hp_distrib_,
101  get_hp_prob_vector(defender_combatant.hp_dist, hp_prob_vector);
102  get_hp_distrib_surface(hp_prob_vector, defender_stats, attacker_stats, defender_hp_distrib_,
105 
106  // Build the strings and compute the layout.
107  attacker_label_ = _("Attacker");
108  defender_label_ = _("Defender");
109  attacker_label_width_ = font::line_width(attacker_label_, font::SIZE_PLUS, TTF_STYLE_BOLD);
111 
112  // Get the units strings.
113  get_unit_strings(attacker_stats, attacker_, attacker_loc_, static_cast<float>(attacker_combatant.untouched),
114  defender_, defender_loc_, defender_stats.weapon,
117 
118  get_unit_strings(defender_stats, defender_, defender_loc_, static_cast<float>(defender_combatant.untouched),
119  attacker_, attacker_loc_, attacker_stats.weapon,
122 
125 
126  hp_distrib_string_ = _("Expected Battle Result (HP)");
128 
131  attacker_width_ = std::max<int>(attacker_width_, attacker_hp_distrib_width_);
133  defender_width_ = std::max<int>(defender_width_, hp_distrib_string_width_);
134  defender_width_ = std::max<int>(defender_width_, defender_hp_distrib_width_);
135  units_width_ = std::max<int>(attacker_width_, defender_width_);
136 
137  dialog_width_ = 2 * units_width_ + inter_units_gap_;
138  dialog_height_ = 15 + 24 + units_strings_height_ + 14 + 19 + hp_distribs_height_ + 18;
139 
140  // Set the dialog size.
141  set_measurements(dialog_width_, dialog_height_);
142 }
143 
145  const unit& u, const map_location& u_loc, float u_unscathed,
146  const unit& opp, const map_location& opp_loc, const attack_type *opp_weapon,
147  std::vector<std::string>& left_strings, std::vector<std::string>& right_strings,
148  int& left_strings_width, int& right_strings_width, int& strings_width)
149 {
150  std::stringstream str;
151  char str_buf[10];
152 
153  // With a weapon.
154  if(stats.weapon != nullptr) {
155 
156  // Set specials context (for safety, it should not have changed normally).
157  const attack_type *weapon = stats.weapon;
158  weapon->set_specials_context(u_loc, opp_loc, stats.is_attacker, opp_weapon);
159 
160  // Get damage modifiers.
161  unit_ability_list dmg_specials = weapon->get_specials("damage");
162  unit_abilities::effect dmg_effect(dmg_specials, weapon->damage(), stats.backstab_pos);
163 
164  // Get the SET damage modifier, if any.
165  const unit_abilities::individual_effect *set_dmg_effect = nullptr;
167  for(i = dmg_effect.begin(); i != dmg_effect.end(); ++i) {
168  if(i->type == unit_abilities::SET) {
169  set_dmg_effect = &*i;
170  break;
171  }
172  }
173 
174  // Either user the SET modifier or the base weapon damage.
175  if(set_dmg_effect == nullptr) {
176  left_strings.push_back(weapon->name());
177  str.str("");
178  str << weapon->damage();
179  right_strings.push_back(str.str());
180  } else {
181  assert(set_dmg_effect->ability);
182 
183  left_strings.push_back((*set_dmg_effect->ability)["name"]);
184  str.str("");
185  str << set_dmg_effect->value;
186  right_strings.push_back(str.str());
187  }
188 
189  // Process the ADD damage modifiers.
190  for(i = dmg_effect.begin(); i != dmg_effect.end(); ++i) {
191  if(i->type == unit_abilities::ADD) {
192  left_strings.push_back((*i->ability)["name"]);
193  str.str("");
194  if(i->value >= 0) str << "+" << i->value;
195  else str << i->value;
196  right_strings.push_back(str.str());
197  }
198  }
199 
200  // Process the MUL damage modifiers.
201  for(i = dmg_effect.begin(); i != dmg_effect.end(); ++i) {
202  if(i->type == unit_abilities::MUL) {
203  left_strings.push_back((*i->ability)["name"]);
204  str.str("");
205  str << "× " << (i->value / 100);
206  if(i->value % 100) {
207  str << "." << ((i->value % 100) / 10);
208  if(i->value % 10) str << (i->value % 10);
209  }
210  right_strings.push_back(str.str());
211  }
212  }
213 
214  // Time of day modifier.
215  int tod_modifier = combat_modifier(resources::gameboard->units(), resources::gameboard->map(), u_loc, u.alignment(), u.is_fearless());
216  if(tod_modifier != 0) {
217  left_strings.push_back(_("Time of day"));
218  str.str("");
219  str << utils::signed_percent(tod_modifier);
220  right_strings.push_back(str.str());
221  }
222 
223  // Leadership bonus.
224  int leadership_bonus = 0;
225  under_leadership(*resources::units, u_loc, &leadership_bonus);
226  if(leadership_bonus != 0) {
227  left_strings.push_back(_("Leadership"));
228  str.str("");
229  str << utils::signed_percent(leadership_bonus);
230  right_strings.push_back(str.str());
231  }
232 
233 
234  // Resistance modifier.
235  int resistance_modifier = opp.damage_from(*weapon, !stats.is_attacker, opp_loc);
236  if(resistance_modifier != 100) {
237  str.str("");
238  if(stats.is_attacker) str << _("Defender");
239  else str << _("Attacker");
240  if(resistance_modifier < 100) str << _(" resistance vs ");
241  else str << _(" vulnerability vs ");
242  str << string_table["type_" + weapon->type()];
243  left_strings.push_back(str.str());
244  str.str("");
245  str << "× " << (resistance_modifier / 100) << "." << ((resistance_modifier % 100) / 10);
246  right_strings.push_back(str.str());
247  }
248 
249  // Slowed penalty.
250  if(stats.is_slowed) {
251  left_strings.push_back(_("Slowed"));
252  right_strings.push_back("/ 2");
253  }
254 
255  // Total damage.
256  left_strings.push_back(_("Total damage"));
257  str.str("");
258  str << stats.damage << utils::unicode_en_dash << stats.num_blows << " (" << stats.chance_to_hit << "%)";
259  right_strings.push_back(str.str());
260 
261  // Without a weapon.
262  } else {
263  left_strings.push_back(_("No usable weapon"));
264  right_strings.push_back("");
265  }
266 
267  // Unscathed probability.
268  left_strings.push_back(_("Chance of being unscathed"));
269  format_prob(str_buf, u_unscathed);
270  right_strings.push_back(str_buf);
271 
272 #if 0 // might not be in English!
273  // Fix capitalization of left strings.
274  for(int i = 0; i < (int) left_strings.size(); i++)
275  if(left_strings[i].size() > 0) left_strings[i][0] = toupper(left_strings[i][0]);
276 #endif
277 
278  // Compute the width of the strings.
279  left_strings_width = get_strings_max_length(left_strings);
280  right_strings_width = get_strings_max_length(right_strings);
281  strings_width = left_strings_width + inter_column_gap_ + right_strings_width;
282 }
283 
284 int battle_prediction_pane::get_strings_max_length(const std::vector<std::string>& strings)
285 {
286  int max_len = 0;
287 
288  for(int i = 0; i < static_cast<int>(strings.size()); i++)
289  max_len = std::max<int>(font::line_width(strings[i], font::SIZE_NORMAL), max_len);
290 
291  return max_len;
292 }
293 
294 void battle_prediction_pane::get_hp_prob_vector(const std::vector<double>& hp_dist,
295  std::vector<std::pair<int, double> >& hp_prob_vector)
296 {
297  hp_prob_vector.clear();
298 
299  // First, we sort the probabilities in ascending order.
300  std::vector<std::pair<double, int> > prob_hp_vector;
301  int i;
302 
303  for(i = 0; i < static_cast<int>(hp_dist.size()); i++) {
304  double prob = hp_dist[i];
305 
306  // We keep only values above 0.1%.
307  if(prob > 0.001)
308  prob_hp_vector.push_back(std::pair<double, int>(prob, i));
309  }
310 
311  std::sort(prob_hp_vector.begin(), prob_hp_vector.end());
312 
313  // We store a few of the highest probability hitpoint values.
314  int nb_elem = std::min<int>(max_hp_distrib_rows_, prob_hp_vector.size());
315 
316  for(i = prob_hp_vector.size() - nb_elem;
317  i < static_cast<int>(prob_hp_vector.size()); i++) {
318 
319  hp_prob_vector.push_back(std::pair<int, double>
320  (prob_hp_vector[i].second, prob_hp_vector[i].first));
321  }
322 
323  // Then, we sort the hitpoint values in ascending order.
324  std::sort(hp_prob_vector.begin(), hp_prob_vector.end());
325 }
326 
328 {
329  // We must align both damage lines.
330  int damage_line_skip = std::max<int>(attacker_left_strings_.size(), defender_left_strings_.size()) - 2;
331 
332  draw_unit(0, damage_line_skip,
335 
336  draw_unit(units_width_ + inter_units_gap_, damage_line_skip,
339 }
340 
341 void battle_prediction_pane::draw_unit(int x_off, int damage_line_skip, int left_strings_width,
342  const std::vector<std::string>& left_strings,
343  const std::vector<std::string>& right_strings,
344  const std::string& label, int label_width,
345  surface& hp_distrib, int hp_distrib_width)
346 {
348  int i;
349 
350  // NOTE. A preview pane is not made to be used alone and it is not
351  // centered in the middle of the dialog. We "fix" this problem by moving
352  // the clip rectangle 10 pixels to the right. This is a kludge and it
353  // should be removed by 1) writing a custom dialog handler, or
354  // 2) modify preview_pane so that it accepts {left, middle, right} as
355  // layout possibilities.
356 
357  // Get clip rectangle and center it
358  SDL_Rect clip_rect = location();
359  clip_rect.x += 10;
360 
361  // Current vertical offset. We draw the dialog line-by-line, starting at the top.
362  int y_off = 15;
363 
364  // Draw unit label.
365  font::draw_text_line(screen, clip_rect, font::SIZE_15, font::NORMAL_COLOR, label,
366  clip_rect.x + x_off + (units_width_ - label_width) / 2, clip_rect.y + y_off, 0, TTF_STYLE_BOLD);
367 
368  y_off += 24;
369 
370  // Draw unit left and right strings except the last two (total damage and unscathed probability).
371  for(i = 0; i < static_cast<int>(left_strings.size()) - 2; i++) {
372  font::draw_text_line(screen, clip_rect, font::SIZE_NORMAL, font::NORMAL_COLOR, left_strings[i],
373  clip_rect.x + x_off, clip_rect.y + y_off + (font::SIZE_NORMAL + inter_line_gap_) * i,
374  0, TTF_STYLE_NORMAL);
375 
376  font::draw_text_line(screen, clip_rect, font::SIZE_NORMAL, font::NORMAL_COLOR, right_strings[i],
377  clip_rect.x + x_off + left_strings_width + inter_column_gap_,
378  clip_rect.y + y_off + (font::SIZE_NORMAL + inter_line_gap_) * i, 0, TTF_STYLE_NORMAL);
379  }
380 
381  // Ensure both damage lines are aligned.
382  y_off += damage_line_skip * (font::SIZE_NORMAL + inter_line_gap_) + 14;
383 
384  // Draw total damage and unscathed probability.
385  for(i = 0; i < 2; i++) {
386  const std::string& left_string = left_strings[left_strings.size() - 2 + i];
387  const std::string& right_string = right_strings[right_strings.size() - 2 + i];
388 
389  font::draw_text_line(screen, clip_rect, font::SIZE_NORMAL, font::NORMAL_COLOR, left_string,
390  clip_rect.x + x_off, clip_rect.y + y_off + (font::SIZE_NORMAL + inter_line_gap_) * i,
391  0, TTF_STYLE_NORMAL);
392 
393  font::draw_text_line(screen, clip_rect, font::SIZE_NORMAL, font::NORMAL_COLOR, right_string,
394  clip_rect.x + x_off + left_strings_width + inter_column_gap_,
395  clip_rect.y + y_off + (font::SIZE_NORMAL + inter_line_gap_) * i, 0, TTF_STYLE_NORMAL);
396  }
397 
398  y_off += 2 * (font::SIZE_NORMAL + inter_line_gap_) + 14;
399 
400  // Draw hitpoints distribution string.
402  clip_rect.x + x_off + (units_width_ - hp_distrib_string_width_) / 2, clip_rect.y + y_off);
403 
404  y_off += 19;
405 
406  // Draw hitpoints distributions.
407  video().blit_surface(clip_rect.x + x_off + (units_width_ - hp_distrib_width) / 2, clip_rect.y + y_off, hp_distrib);
408 }
409 
410 void battle_prediction_pane::get_hp_distrib_surface(const std::vector<std::pair<int, double> >& hp_prob_vector,
411  const battle_context_unit_stats& stats,
412  const battle_context_unit_stats& opp_stats,
413  surface& surf, int& width, int& height)
414 {
415  // Font size. If you change this, you must update the separator space.
416  int fs = font::SIZE_SMALL;
417 
418  // Space before HP separator.
419  int hp_sep = 24 + 6;
420 
421  // Bar space between both separators.
422  int bar_space = 150;
423 
424  // Space after percentage separator.
425  int percent_sep = 43 + 6;
426 
427  // Surface width and height.
428  width = 30 + 2 + bar_space + 2 + percent_sep;
429  height = 5 + (fs + 2) * hp_prob_vector.size();
430 
431  // Create the surface.
432  surf = create_neutral_surface(width, height);
433 
434  // Disable alpha channel to avoid problem with sdl_blit
435  SDL_SetAlpha(surf, 0, SDL_ALPHA_OPAQUE);
436 
437  SDL_Rect clip_rect = sdl::create_rect(0, 0, width, height);
438  Uint32 grey_color = SDL_MapRGBA(surf->format, 0xb7, 0xc1, 0xc1, SDL_ALPHA_OPAQUE);
439 
440  Uint32 background_color = SDL_MapRGBA(surf->format, 25, 25, 25, SDL_ALPHA_OPAQUE);
441  sdl::fill_rect(surf, &clip_rect, background_color);
442 
443  // Draw the surrounding borders and separators.
444  SDL_Rect top_border_rect = sdl::create_rect(0, 0, width, 2);
445  sdl::fill_rect(surf, &top_border_rect, grey_color);
446 
447  SDL_Rect bottom_border_rect = sdl::create_rect(0, height - 2, width, 2);
448  sdl::fill_rect(surf, &bottom_border_rect, grey_color);
449 
450  SDL_Rect left_border_rect = sdl::create_rect(0, 0, 2, height);
451  sdl::fill_rect(surf, &left_border_rect, grey_color);
452 
453  SDL_Rect right_border_rect = sdl::create_rect(width - 2, 0, 2, height);
454  sdl::fill_rect(surf, &right_border_rect, grey_color);
455 
456  SDL_Rect hp_sep_rect = sdl::create_rect(hp_sep, 0, 2, height);
457  sdl::fill_rect(surf, &hp_sep_rect, grey_color);
458 
459  SDL_Rect percent_sep_rect = sdl::create_rect(width - percent_sep - 2, 0, 2, height);
460  sdl::fill_rect(surf, &percent_sep_rect, grey_color);
461 
462  // Draw the rows (lower HP values are at the bottom).
463  for(int i = 0; i < static_cast<int>(hp_prob_vector.size()); i++) {
464  char str_buf[10];
465 
466  // Get the HP and probability.
467  int hp = hp_prob_vector[hp_prob_vector.size() - i - 1].first;
468  double prob = hp_prob_vector[hp_prob_vector.size() - i - 1].second;
469 
470  SDL_Color row_color;
471 
472  // Death line is red.
473  if(hp == 0) {
474  SDL_Color color = {0xe5, 0, 0, SDL_ALPHA_OPAQUE};
475  row_color = color;
476  }
477 
478  // Below current hitpoints value is orange.
479  else if(hp < static_cast<int>(stats.hp)) {
480  // Stone is grey.
481  if(opp_stats.petrifies) {
482  SDL_Color color = {0x9a, 0x9a, 0x9a, SDL_ALPHA_OPAQUE};
483  row_color = color;
484  } else {
485  SDL_Color color = {0xf4, 0xc9, 0, SDL_ALPHA_OPAQUE};
486  row_color = color;
487  }
488  }
489 
490  // Current hitpoints value and above is green.
491  else {
492  SDL_Color color = {0x08, 0xca, 0, SDL_ALPHA_OPAQUE};
493  row_color = color;
494  }
495 
496  // Print HP, aligned right.
497  snprintf(str_buf, 10, "%d", hp);
498  str_buf[9] = '\0'; //prevents _snprintf error
499  int hp_width = font::line_width(str_buf, fs);
500 
501  // Draw bars.
502  font::draw_text_line(surf, clip_rect, fs, font::NORMAL_COLOR, str_buf,
503  hp_sep - hp_width - 2, 2 + (fs + 2) * i, 0, TTF_STYLE_NORMAL);
504 
505  int bar_len = std::max<int>(static_cast<int>((prob * (bar_space - 4)) + 0.5), 2);
506 
507  SDL_Rect bar_rect_1 = sdl::create_rect(hp_sep + 4, 6 + (fs + 2) * i, bar_len, 8);
508  sdl::fill_rect(surf, &bar_rect_1, blend_rgba(surf, row_color.r, row_color.g, row_color.b, row_color.a, 100));
509 
510  SDL_Rect bar_rect_2 = sdl::create_rect(hp_sep + 4, 7 + (fs + 2) * i, bar_len, 6);
511  sdl::fill_rect(surf, &bar_rect_2, blend_rgba(surf, row_color.r, row_color.g, row_color.b, row_color.a, 66));
512 
513  SDL_Rect bar_rect_3 = sdl::create_rect(hp_sep + 4, 8 + (fs + 2) * i, bar_len, 4);
514  sdl::fill_rect(surf, &bar_rect_3, blend_rgba(surf, row_color.r, row_color.g, row_color.b, row_color.a, 33));
515 
516  SDL_Rect bar_rect_4 = sdl::create_rect(hp_sep + 4, 9 + (fs + 2) * i, bar_len, 2);
517  sdl::fill_rect(surf, &bar_rect_4, blend_rgba(surf, row_color.r, row_color.g, row_color.b, row_color.a, 0));
518 
519  // Draw probability percentage, aligned right.
520  format_prob(str_buf, prob);
521  int prob_width = font::line_width(str_buf, fs);
522  font::draw_text_line(surf, clip_rect, fs, font::NORMAL_COLOR, str_buf,
523  width - prob_width - 4, 2 + (fs + 2) * i, 0, TTF_STYLE_NORMAL);
524  }
525 }
526 
528 {
529  // Get the selected weapon, if any.
530  const size_t index = size_t(selection);
531 
532  if(index < bc_vector_.size()) {
534  std::vector<gui::preview_pane*> preview_panes;
535  preview_panes.push_back(&battle_pane);
536 
537  gui::show_dialog(resources::screen->video(), nullptr, _("Damage Calculations"), "", gui::OK_ONLY, nullptr, &preview_panes);
538  }
539 
540  return gui::CONTINUE_DIALOG;
541 }
std::vector< std::string > defender_left_strings_
const t_string & name() const
Definition: attack_type.hpp:35
int get_strings_max_length(const std::vector< std::string > &strings)
void get_hp_prob_vector(const std::vector< double > &hp_dist, std::vector< std::pair< int, double > > &hp_prob_vector)
surface create_neutral_surface(int w, int h)
Definition: utils.cpp:150
void fill_rect(surface &dst, SDL_Rect *dst_rect, const Uint32 color)
Fill a rectangle on a given surface.
Definition: rect.hpp:143
Definition: unit.hpp:95
void set_specials_context(const map_location &unit_loc, const map_location &other_loc, bool attacking, const attack_type *other_attack) const
Sets the context under which specials will be checked for being active.
Definition: abilities.cpp:677
unsigned int hp
Hitpoints of the unit at the beginning of the battle.
Definition: attack.hpp:72
Various functions that implement attacks and attack calculations.
game_display * screen
Definition: resources.cpp:27
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
bool is_slowed
True if the unit is slowed at the beginning of the battle.
Definition: attack.hpp:55
const attack_type * weapon
The weapon used by the unit to attack the opponent, or nullptr if there is none.
Definition: attack.hpp:51
void blit_surface(int x, int y, surface surf, SDL_Rect *srcrect=nullptr, SDL_Rect *clip_rect=nullptr)
Definition: video.cpp:290
const int SIZE_PLUS
Definition: font.hpp:65
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
unsigned int chance_to_hit
Effective chance to hit as a percentage (all factors accounted for).
Definition: attack.hpp:74
static void format_prob(char str_buf[10], double prob)
const int SIZE_NORMAL
Definition: font.hpp:58
const map_location & defender_loc_
void set_measurements(int w, int h)
Definition: widget.cpp:129
bool backstab_pos
True if the attacker is in position to backstab the defender (this is used to determine whether to ap...
Definition: attack.hpp:61
battle_prediction_pane(const battle_context &bc, const map_location &attacker_loc, const map_location &defender_loc)
std::vector< std::string > attacker_left_strings_
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
int damage
Effective damage of the weapon (all factors accounted for).
Definition: attack.hpp:75
void get_unit_strings(const battle_context_unit_stats &stats, const unit &u, const map_location &u_loc, float u_unscathed, const unit &opp, const map_location &opp_loc, const attack_type *opp_weapon, std::vector< std::string > &left_strings, std::vector< std::string > &right_strings, int &left_strings_width, int &right_strings_width, int &strings_width)
const SDL_Rect * clip_rect() const
Definition: widget.cpp:104
unit_type::ALIGNMENT alignment() const
Definition: unit.hpp:368
const std::vector< battle_context > & bc_vector_
const std::string unicode_en_dash
const int SIZE_15
Definition: font.hpp:64
game_board * gameboard
Definition: resources.cpp:20
void draw_unit(int x_off, int damage_line_skip, int left_strings_width, const std::vector< std::string > &left_strings, const std::vector< std::string > &right_strings, const std::string &label, int label_width, surface &hp_distrib, int hp_distrib_width)
const battle_context_unit_stats & get_defender_stats() const
This method returns the statistics of the defender.
Definition: attack.hpp:163
Computes the statistics of a battle between an attacker and a defender unit.
Definition: attack.hpp:135
int show_dialog(CVideo &video, surface image, const std::string &caption, const std::string &message, DIALOG_TYPE type, const std::vector< std::string > *menu_items, const std::vector< preview_pane * > *preview_panes, const std::string &text_widget_label, std::string *text_widget_text, const int text_widget_max_chars, std::vector< check_item > *options, int xloc, int yloc, const dialog_frame::style *dialog_style, std::vector< dialog_button_info > *action_buttons, const menu::sorter *sorter, menu::style *menu_style)
void fight(combatant &opponent, bool levelup_considered=true)
Simulate a fight! Can be called multiple times for cumulative calculations.
void get_hp_distrib_surface(const std::vector< std::pair< int, double > > &hp_prob_vector, const battle_context_unit_stats &stats, const battle_context_unit_stats &opp_stats, surface &surf, int &width, int &height)
Structure describing the statistics of a unit involved in the battle.
Definition: attack.hpp:49
int damage_from(const attack_type &attack, bool attacker, const map_location &loc) const
Definition: unit.hpp:274
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
surf
Definition: filter.cpp:143
const std::string & type() const
Definition: attack_type.hpp:37
GLuint color
Definition: glew.h:5801
Encapsulates the map of the game.
Definition: location.hpp:38
All combat-related info.
SDL_Rect draw_text(surface &dst, const SDL_Rect &area, int size, const SDL_Color &color, const std::string &txt, int x, int y, bool use_tooltips, int style)
Function to draw text on a surface.
GLsizei const GLchar ** strings
Definition: glew.h:1812
surface & get_screen_surface()
return the screen surface or the surface used for map_screenshot.
Definition: display.hpp:205
GLuint index
Definition: glew.h:1782
std::string signed_percent(int val)
Convert into a percentage (using the Unicode "−" and +0% convention.
size_t i
Definition: function.cpp:1057
static int sort(lua_State *L)
Definition: ltablib.cpp:246
DIALOG_RESULT
Definition: show_dialog.hpp:33
unit_ability_list get_specials(const std::string &special) const
Returns the currently active specials as an ability list, given the current context (see set_specials...
Definition: abilities.cpp:587
GLint GLint GLint GLint GLint GLint GLsizei GLsizei height
Definition: glew.h:1220
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
Definition: rect.cpp:28
int damage() const
Definition: attack_type.hpp:45
GLsizeiptr size
Definition: glew.h:1649
std::vector< std::string > defender_right_strings_
SDL_Rect draw_text_line(surface &gui_surface, const SDL_Rect &area, int size, const SDL_Color &color, const std::string &text, int x, int y, bool use_tooltips, int style)
Definition: font.cpp:892
bool find(E event, F functor)
Tests whether an event handler is available.
const map_location & attacker_loc_
symbol_table string_table
Definition: language.cpp:65
bool is_fearless() const
Definition: unit.hpp:306
GLint * first
Definition: glew.h:1496
unsigned int num_blows
Effective number of blows, takes swarm into account.
Definition: attack.hpp:79
std::vector< std::string > attacker_right_strings_
const battle_context_unit_stats & get_attacker_stats() const
This method returns the statistics of the attacker.
Definition: attack.hpp:160
GLint GLint GLint GLint GLint GLint GLsizei width
Definition: glew.h:1220
bool is_attacker
True if the unit is the attacker.
Definition: attack.hpp:53
SDL_Rect const & location() const
Definition: widget.cpp:144
const std::string weapon
int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha)
Definition: alpha.cpp:18
bool petrifies
Attack petrifies opponent when it hits.
Definition: attack.hpp:58
Compatibility layer for using SDL 1.2 and 2.0.
map_location under_leadership(const unit_map &units, const map_location &loc, int *bonus)
function which tests if the unit at loc is currently affected by leadership.
Definition: attack.cpp:1635
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Uint32 blend_rgba(const surface &surf, unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned char drop)
This method blends a RGBA color.
Definition: utils.cpp:356
int line_width(const std::string &line, int font_size, int style)
Determine the width of a line of text given a certain font size.
Definition: font.cpp:969
unit_map * units
Definition: resources.cpp:35
std::vector< individual_effect >::const_iterator const_iterator
Definition: abilities.hpp:48
const int SIZE_SMALL
Definition: font.hpp:62
int combat_modifier(const unit_map &units, const gamemap &map, const map_location &loc, unit_type::ALIGNMENT alignment, bool is_fearless)
Returns the amount that a unit's damage should be multiplied by due to the current time of day...
Definition: attack.cpp:1649