The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
dialogs.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2016 by David White <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 /**
16  * @file
17  * Various dialogs: advance_unit, show_objectives, save+load game
18  */
19 
20 #include "global.hpp"
21 
22 #include "actions/attack.hpp"
23 #include "actions/undo.hpp"
24 #include "dialogs.hpp"
25 #include "format_time_summary.hpp"
26 #include "game_display.hpp"
27 #include "game_preferences.hpp"
29 #include "gui/dialogs/message.hpp"
30 #include "gui/widgets/window.hpp"
31 #include "gettext.hpp"
32 #include "help/help.hpp"
33 #include "help/help_button.hpp"
34 #include "language.hpp"
35 #include "log.hpp"
36 #include "map/map.hpp"
37 #include "map/exception.hpp"
38 #include "marked-up_text.hpp"
39 #include "menu_events.hpp"
40 #include "mouse_handler_base.hpp"
41 #include "minimap.hpp"
42 #include "recall_list_manager.hpp"
43 #include "replay.hpp"
44 #include "replay_helper.hpp"
45 #include "resources.hpp"
46 #include "savegame.hpp"
47 #include "save_index.hpp"
48 #include "strftime.hpp"
49 #include "synced_context.hpp"
50 #include "terrain/type_data.hpp"
51 #include "units/unit.hpp"
52 #include "units/animation.hpp"
53 #include "units/helper.hpp"
54 #include "units/types.hpp"
55 #include "wml_separators.hpp"
56 #include "widgets/progressbar.hpp"
57 #include "wml_exception.hpp"
58 #include "formula/string_utils.hpp"
63 #include "wesnothd_connection.hpp"
64 #include <boost/make_shared.hpp>
65 #include <boost/shared_ptr.hpp>
66 
67 //#ifdef _WIN32
68 //#include "locale.h"
69 //#endif
70 
71 #include <clocale>
72 
73 static lg::log_domain log_engine("engine");
74 #define LOG_NG LOG_STREAM(info, log_engine)
75 #define ERR_NG LOG_STREAM(err, log_engine)
76 
77 static lg::log_domain log_display("display");
78 #define LOG_DP LOG_STREAM(info, log_display)
79 
80 #define ERR_G LOG_STREAM(err, lg::general)
81 
82 static lg::log_domain log_config("config");
83 #define ERR_CF LOG_STREAM(err, log_config)
84 
85 namespace dialogs
86 {
87 
88 namespace
89 {
90 
91 class delete_recall_unit : public gui::dialog_button_action
92 {
93 public:
94  delete_recall_unit(display& disp, gui::filter_textbox& filter, const boost::shared_ptr<std::vector<unit_const_ptr > >& units) : disp_(disp), filter_(filter), units_(units) {}
95 private:
96  gui::dialog_button_action::RESULT button_pressed(int menu_selection);
97 
101 };
102 
103 template<typename T> void dump(const T & units)
104 {
105  log_scope2(log_display, "dump()")
106 
107  LOG_DP << "size: " << units.size() << "\n";
108  size_t idx = 0;
109  for (const unit_const_ptr & u_ptr : units) {
110  LOG_DP << "unit[" << (idx++) << "]: " << u_ptr->id() << " name = '" << u_ptr->name() << "'\n";
111  }
112 }
113 
114 gui::dialog_button_action::RESULT delete_recall_unit::button_pressed(int menu_selection)
115 {
116  const size_t index = size_t(filter_.get_index(menu_selection));
117 
118  LOG_DP << "units_:\n"; dump(*units_);
119  if(index < units_->size()) {
120  const unit_const_ptr & u_ptr = units_->at(index);
121  const unit & u = *u_ptr;
122 
123  //If the unit is of level > 1, or is close to advancing,
124  //we warn the player about it
125  std::stringstream message;
126  if (u.loyal()) {
127  // TRANSLATORS: this string ends with a space
128  message << _("This unit is loyal and requires no upkeep. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
129  : _("Do you really want to dismiss her?"));
130  } else if(u.level() > 1) {
131  // TRANSLATORS: this string ends with a space
132  message << _("This unit is an experienced one, having advanced levels. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
133  : _("Do you really want to dismiss her?"));
134 
135  } else if(u.experience() > u.max_experience()/2) {
136  // TRANSLATORS: this string ends with a space
137  message << _("This unit is close to advancing a level. ") << (u.gender() == unit_race::MALE ? _("Do you really want to dismiss him?")
138  : _("Do you really want to dismiss her?"));
139  }
140 
141  if(!message.str().empty()) {
142  const int res = gui2::show_message(disp_.video(), _("Dismiss Unit"), message.str(), gui2::tmessage::yes_no_buttons);
143  if(res == gui2::twindow::CANCEL) {
144  return gui::CONTINUE_DIALOG;
145  }
146  }
147  // Remove the item from our dialog's list
148  units_->erase(units_->begin() + index);
149 
150  // Remove the item from filter_textbox memory
151  filter_.delete_item(menu_selection);
152 
153  LOG_DP << "Dismissing a unit, side = " << u.side() << " id = '" << u.id() << "'\n";
154  LOG_DP << "That side's recall list:\n";
155  dump((*resources::teams)[u.side() -1].recall_list());
156 
157  // Find the unit in the recall list.
158  unit_ptr dismissed_unit = (*resources::teams)[u.side() -1].recall_list().find_if_matches_id(u.id());
159  assert(dismissed_unit);
160 
161  // Record the dismissal, then delete the unit.
162  synced_context::run_and_throw("disband", replay_helper::get_disband(dismissed_unit->id()));
163 
164  return gui::DELETE_ITEM;
165  } else {
166  return gui::CONTINUE_DIALOG;
167  }
168 }
169 
170 } //anon namespace
171 
173 {
175 
176  const std::vector<std::string>& options = u->advances_to();
177 
178  std::vector<std::string> lang_options;
179 
180  boost::shared_ptr<std::vector<unit_const_ptr> > sample_units(boost::make_shared<std::vector<unit_const_ptr> >());
181  for(std::vector<std::string>::const_iterator op = options.begin(); op != options.end(); ++op) {
182  sample_units->push_back(::get_advanced_unit(*u, *op));
183  const unit& type = *sample_units->back();
184 
185 #ifdef LOW_MEM
186  lang_options.push_back(IMAGE_PREFIX
187  + static_cast<std::string const &>(type.absolute_image())
188  + COLUMN_SEPARATOR + type.type_name());
189 #else
190  lang_options.push_back(IMAGE_PREFIX + type.absolute_image() + u->image_mods() + COLUMN_SEPARATOR + type.type_name());
191 #endif
192  preferences::encountered_units().insert(*op);
193  }
194 
195  bool always_display = false;
196  for (const config &mod : u->get_modification_advances())
197  {
198  if (mod["always_display"].to_bool()) always_display = true;
199  sample_units->push_back(::get_amla_unit(*u, mod));
200  const unit& type = *sample_units->back();
201  if (!mod["image"].empty()) {
202  lang_options.push_back(IMAGE_PREFIX + mod["image"].str() + COLUMN_SEPARATOR + mod["description"].str());
203  } else {
204 #ifdef LOW_MEM
205  lang_options.push_back(IMAGE_PREFIX
206  + static_cast<std::string const &>(type.absolute_image())
207  + COLUMN_SEPARATOR + mod["description"].str());
208 #else
209  lang_options.push_back(IMAGE_PREFIX + type.absolute_image() + u->image_mods() + COLUMN_SEPARATOR + mod["description"].str());
210 #endif
211  }
212  }
213 
214  assert(!lang_options.empty());
215 
216  if (lang_options.size() > 1 || always_display)
217  {
218  units_list_preview_pane unit_preview(sample_units);
219  std::vector<gui::preview_pane*> preview_panes;
220  preview_panes.push_back(&unit_preview);
221 
222  gui::dialog advances = gui::dialog(resources::screen->video(),
223  _("Advance Unit"),
224  _("What should our victorious unit become?"),
225  gui::OK_ONLY);
226  advances.set_menu(lang_options);
227  advances.set_panes(preview_panes);
228  return advances.show();
229  }
230  return 0;
231 }
232 
233 bool animate_unit_advancement(const map_location &loc, size_t choice, const bool &fire_event, const bool animate)
234 {
235  const events::command_disabler cmd_disabler;
236 
238  if (u == resources::units->end()) {
239  LOG_DP << "animate_unit_advancement suppressed: invalid unit\n";
240  return false;
241  } else if (!u->advances()) {
242  LOG_DP << "animate_unit_advancement suppressed: unit does not advance\n";
243  return false;
244  }
245 
246  const std::vector<std::string>& options = u->advances_to();
247  std::vector<config> mod_options = u->get_modification_advances();
248 
249  if(choice >= options.size() + mod_options.size()) {
250  LOG_DP << "animate_unit_advancement suppressed: invalid option\n";
251  return false;
252  }
253 
254  // When the unit advances, it fades to white, and then switches
255  // to the new unit, then fades back to the normal color
256 
257  if (animate && !resources::screen->video().update_locked()) {
258  unit_animator animator;
259  bool with_bars = true;
260  animator.add_animation(&*u,"levelout", u->get_location(), map_location(), 0, with_bars);
261  animator.start_animations();
262  animator.wait_for_end();
263  }
264 
265  if(choice < options.size()) {
266  // chosen_unit is not a reference, since the unit may disappear at any moment.
267  std::string chosen_unit = options[choice];
268  ::advance_unit(loc, chosen_unit, fire_event);
269  } else {
270  const config &mod_option = mod_options[choice - options.size()];
271  ::advance_unit(loc, "", fire_event, &mod_option);
272  }
273 
274  u = resources::units->find(loc);
276 
277  if (animate && u != resources::units->end() && !resources::screen->video().update_locked()) {
278  unit_animator animator;
279  animator.add_animation(&*u, "levelin", u->get_location(), map_location(), 0, true);
280  animator.start_animations();
281  animator.wait_for_end();
282  animator.set_all_standing();
285  events::pump();
286  }
287 
290 
291  return true;
292 }
293 
295 {
296  const std::string heading = std::string(1,HEADING_PREFIX) +
297  _("Type") + COLUMN_SEPARATOR + // 0
298  _("Name") + COLUMN_SEPARATOR + // 1
299  _("Moves") + COLUMN_SEPARATOR + // 2
300  _("Status") + COLUMN_SEPARATOR + // 3
301  _("HP") + COLUMN_SEPARATOR + // 4
302  _("Level^Lvl.") + COLUMN_SEPARATOR + // 5
303  _("XP") + COLUMN_SEPARATOR + // 6
304  _("unit list^Traits"); // 7
305 
309  sorter.set_xp_sort(6).set_alpha_sort(7);
310 
311  std::vector<std::string> items;
312  items.push_back(heading);
313 
314  std::vector<map_location> locations_list;
315  boost::shared_ptr<std::vector<unit_const_ptr> > units_list = boost::make_shared<std::vector<unit_const_ptr> >();
316 
317  int selected = 0;
318 
319  const unit_map& units = gui.get_units();
320 
321  for(unit_map::const_iterator i = units.begin(); i != units.end(); ++i) {
322  if (i->side() != gui.viewing_side())
323  continue;
324 
325  std::stringstream row;
326  // If a unit is already selected on the map, we do the same in the unit list dialog
327  if (gui.selected_hex() == i->get_location()) {
328  row << DEFAULT_ITEM;
329  selected = units_list->size();
330  }
331  // If unit is leader, show name in special color, e.g. gold/silver
332  /** @todo TODO: hero just has overlay "misc/hero-icon.png" - needs an ability to query */
333 
334  if (i->can_recruit() ) {
335  row << "<205,173,0>"; // gold3
336  }
337  row << i->type_name() << COLUMN_SEPARATOR;
338  if (i->can_recruit() ) {
339  row << "<205,173,0>"; // gold3
340  }
341  row << i->name() << COLUMN_SEPARATOR;
342 
343  // display move left (0=red, moved=yellow, not moved=green)
344  if (i->movement_left() == 0) {
345  row << font::RED_TEXT;
346  } else if (i->movement_left() < i->total_movement() ) {
347  row << "<255,255,0>";
348  } else {
349  row << font::GREEN_TEXT;
350  }
351  row << i->movement_left() << '/' << i->total_movement() << COLUMN_SEPARATOR;
352 
353  // show icons if unit is slowed, poisoned, petrified, invisible:
354  if(i->get_state(unit::STATE_PETRIFIED))
355  row << IMAGE_PREFIX << "misc/petrified.png" << IMG_TEXT_SEPARATOR;
356  if(i->get_state(unit::STATE_POISONED))
357  row << IMAGE_PREFIX << "misc/poisoned.png" << IMG_TEXT_SEPARATOR;
358  if(i->get_state(unit::STATE_SLOWED))
359  row << IMAGE_PREFIX << "misc/slowed.png" << IMG_TEXT_SEPARATOR;
360  if(i->invisible(i->get_location(),false))
361  row << IMAGE_PREFIX << "misc/invisible.png";
362  row << COLUMN_SEPARATOR;
363 
364  // Display HP
365  // see also unit_preview_pane in dialogs.cpp
366  row << font::color2markup(i->hp_color());
367  row << i->hitpoints() << '/' << i->max_hitpoints() << COLUMN_SEPARATOR;
368 
369  // Show units of level (0=gray, 1 normal, 2 bold, 2+ bold&wbright)
370  int level = i->level();
371  if(level < 1) {
372  row << "<150,150,150>";
373  } else if(level == 1) {
374  row << font::NORMAL_TEXT;
375  } else if(level == 2) {
376  row << font::BOLD_TEXT;
377  } else if(level > 2 ) {
378  row << font::BOLD_TEXT << "<255,255,255>";
379  }
380  row << level << COLUMN_SEPARATOR;
381 
382  // Display XP
383  row << font::color2markup(i->xp_color());
384  row << i->experience() << "/";
385  if (i->can_advance()) {
386  row << i->max_experience();
387  } else {
388  row << "-";
389  }
390  row << COLUMN_SEPARATOR;
391 
392  // TODO: show 'loyal' in green / xxx in red // how to handle translations ??
393  row << utils::join(i->trait_names(), ", ");
394  items.push_back(row.str());
395 
396  locations_list.push_back(i->get_location());
397  units_list->push_back(i.get_shared_ptr());
398  }
399 
400  {
401  dialogs::units_list_preview_pane unit_preview(units_list);
402  unit_preview.set_selection(selected);
403 
404  gui::dialog umenu(gui.video(), _("Unit List"), "", gui::NULL_DIALOG);
405  umenu.set_menu(items, &sorter);
406  umenu.add_pane(&unit_preview);
407  //sort by type name
408  umenu.get_menu().sort_by(0);
409 
410  umenu.add_button(new gui::standard_dialog_button(gui.video(), _("Scroll To"), 0, false),
412  umenu.add_button(new gui::standard_dialog_button(gui.video(), _("Close"), 1, true),
414  umenu.set_basic_behavior(gui::OK_CANCEL);
415  selected = umenu.show();
416  } // this will kill the dialog before scrolling
417 
418  if(selected >= 0 && selected < int(locations_list.size())) {
419  const map_location& loc = locations_list[selected];
421  gui.select_hex(loc);
422  }
423 }
424 
425 void show_objectives(const std::string &scenarioname, const std::string &objectives)
426 {
427  static const std::string no_objectives(_("No objectives available"));
428  gui2::show_transient_message(resources::screen->video(), scenarioname,
429  (objectives.empty() ? no_objectives : objectives), "", true);
430 }
431 
432 int recruit_dialog(display& disp, std::vector< const unit_type* >& units, const std::vector< std::string >& items, int side, const std::string& title_suffix)
433 {
435  units, nullptr, side);
436  std::vector<gui::preview_pane*> preview_panes;
437  preview_panes.push_back(&unit_preview);
438 
440  sorter.set_alpha_sort(1);
441 
442  gui::dialog rmenu(disp.video(), _("Recruit") + title_suffix,
443  _("Select unit:") + std::string("\n"),
446  rmenu.add_button(new help::help_button(disp.video(), "recruit_and_recall"),
448 
450  units_display_style.scale_images(font::relative_size(72), font::relative_size(72));
451 
452  gui::menu* units_menu = new gui::menu(disp.video(), items, false, -1,
453  gui::dialog::max_menu_width, &sorter, &units_display_style, false);
454 
455  units_menu->sort_by(1); // otherwise it's unsorted by default
456 
457  rmenu.set_menu(units_menu);
458  rmenu.set_panes(preview_panes);
459  return rmenu.show();
460 }
461 
462 
463 #ifdef LOW_MEM
464 int recall_dialog(display& disp, const boost::shared_ptr<std::vector< unit_const_ptr > > & units, int /*side*/, const std::string& title_suffix, const int team_recall_cost)
465 #else
466 int recall_dialog(display& disp, const boost::shared_ptr<std::vector< unit_const_ptr > > & units, int side, const std::string& title_suffix, const int team_recall_cost)
467 #endif
468 {
469  std::vector<std::string> options, options_to_filter;
470 
471  std::ostringstream heading;
472  heading << HEADING_PREFIX << COLUMN_SEPARATOR << _("Type")
473  << COLUMN_SEPARATOR << _("Name")
474  << COLUMN_SEPARATOR << _("Level^Lvl.")
475  << COLUMN_SEPARATOR << _("XP");
476  heading << COLUMN_SEPARATOR << _("Traits");
477 
479  sorter.set_alpha_sort(1).set_alpha_sort(2);
480  sorter.set_level_sort(3,4).set_xp_sort(4).set_alpha_sort(5);
481 
482  options.push_back(heading.str());
483  options_to_filter.push_back(options.back());
484 
485  for (const unit_const_ptr & u : *units)
486  {
487  std::stringstream option, option_to_filter;
488  std::string name = u->name();
489  if (name.empty()) name = utils::unicode_em_dash;
490 
491  option << IMAGE_PREFIX << u->absolute_image();
492 
493  #ifndef LOW_MEM
494  option << "~RC(" << u->team_color() << '>'
495  << team::get_side_color_index(side) << ')';
496 
497  if(u->can_recruit()) {
498  option << "~BLIT(" << unit::leader_crown() << ")";
499  }
500 
501  for(const std::string& overlay : u->overlays())
502  {
503  option << "~BLIT(" << overlay << ")";
504  }
505  #endif
506 
507  option << COLUMN_SEPARATOR;
508  int cost = u->recall_cost();
509  if(cost < 0) {
510  cost = team_recall_cost;
511  }
512  option << u->type_name() << "\n";
513  if(cost > team_recall_cost) {
514  option << font::NORMAL_TEXT << "<255,0,0>";
515  }
516  else if(cost == team_recall_cost) {
517  option << font::NORMAL_TEXT;
518  }
519  else if(cost < team_recall_cost) {
520  option << font::NORMAL_TEXT << "<0,255,0>";
521  }
522  option << cost << " Gold" << COLUMN_SEPARATOR
523  << name << COLUMN_SEPARATOR;
524 
525  // Show units of level (0=gray, 1 normal, 2 bold, 2+ bold&wbright)
526  const int level = u->level();
527  if(level < 1) {
528  option << "<150,150,150>";
529  } else if(level == 1) {
530  option << font::NORMAL_TEXT;
531  } else if(level == 2) {
532  option << font::BOLD_TEXT;
533  } else if(level > 2 ) {
534  option << font::BOLD_TEXT << "<255,255,255>";
535  }
536  option << level << COLUMN_SEPARATOR;
537 
538  option << font::color2markup(u->xp_color()) << u->experience() << "/";
539  if (u->can_advance())
540  option << u->max_experience();
541  else
542  option << "-";
543 
544  option_to_filter << u->type_name() << " " << name << " " << u->level();
545 
546  option << COLUMN_SEPARATOR;
547  for(const t_string& trait : u->trait_names()) {
548  option << trait << '\n';
549  option_to_filter << " " << trait;
550  }
551 
552  options.push_back(option.str());
553  options_to_filter.push_back(option_to_filter.str());
554  }
555 
556  gui::dialog rmenu(disp.video(), _("Recall") + title_suffix,
557  _("Select unit:") + std::string("\n"),
559 
561  units_display_style.scale_images(font::relative_size(72), font::relative_size(72));
562 
563  gui::menu* units_menu = new gui::menu(disp.video(), options, false, -1,
564  gui::dialog::max_menu_width, &sorter, &units_display_style, false);
565 
566  rmenu.set_menu(units_menu);
567 
569  _("Filter: "), options, options_to_filter, 1, rmenu, 200);
570  rmenu.set_textbox(filter);
571 
572  delete_recall_unit recall_deleter(disp, *filter, units);
573  gui::dialog_button_info delete_button(&recall_deleter,_("Dismiss Unit"));
574  rmenu.add_button(delete_button);
575 
576  rmenu.add_button(new help::help_button(disp.video(), "recruit_and_recall"),
578 
579  dialogs::units_list_preview_pane unit_preview(units, filter);
580  rmenu.add_pane(&unit_preview);
581 
582  //sort by level
583  static int sort_by = 3;
584  static bool sort_reversed = false;
585 
586  if(sort_by >= 0) {
587  rmenu.get_menu().sort_by(sort_by);
588  // "reclick" on the sorter to reverse the order
589  if(sort_reversed) {
590  rmenu.get_menu().sort_by(sort_by);
591  }
592  }
593 
594  int res = rmenu.show();
595  res = filter->get_index(res);
596 
597  sort_by = rmenu.get_menu().get_sort_by();
598  sort_reversed = rmenu.get_menu().get_sort_reversed();
599 
600  return res;
601 }
602 
603 namespace {
604  static const int unit_preview_border = 10;
605 }
606 
608  image(),
609  name(),
610  type_name(),
611  race(),
612  level(0),
613  alignment(),
614  traits(),
615  abilities(),
616  hitpoints(0),
617  max_hitpoints(0),
618  experience(0),
619  max_experience(0),
620  hp_color(),
621  xp_color(),
622  movement_left(0),
623  total_movement(0),
624  attacks(),
625  overlays()
626 {
627 }
628 
630  gui::preview_pane(display::get_singleton()->video()), index_(0),
631  details_button_(display::get_singleton()->video(), _("Profile"),
632  gui::button::TYPE_PRESS, "button_normal/button_small_H22", gui::button::MINIMUM_SPACE),
633  filter_(filter), weapons_(type == SHOW_ALL), left_(on_left_side)
634 {
635  unsigned w = font::relative_size(weapons_ ? 200 : 190);
636 // advance test
637  unsigned h = font::relative_size(weapons_ ? 440 : 140);
638  set_measurements(w, h);
639 }
640 
641 
643 {
645  h.push_back(&details_button_);
646  return h;
647 }
648 
650 {
651  return !weapons_;
652 }
653 
655 {
656  return left_;
657 }
658 
660 {
661  index = std::min<int>(static_cast<int>(size())-1,index);
662  if (filter_) {
663  index = filter_->get_index(index);
664  }
665  if(index != index_) {
666  index_ = index;
667  set_dirty();
668  if (index >= 0) {
670  }
671  }
672 }
673 
675 {
676  if(index_ < 0 || index_ >= int(size())) {
677  return;
678  }
679 
680  const details det = get_details();
681 
682  const bool right_align = left_side();
683 
684  SDL_Rect const &loc = location();
685  const SDL_Rect area = sdl::create_rect(loc.x + unit_preview_border
686  , loc.y + unit_preview_border
687  , loc.w - unit_preview_border * 2
688  , loc.h - unit_preview_border * 2);
689 
690 #ifdef SDL_GPU
691  GPU_SetClip(get_render_target(), area.x, area.y, area.w, area.h);
692 
693  sdl::timage unit_image = det.image;
694  // TODO: port this to SDL_gpu
695 // if (!left_)
696 // unit_image = image::reverse_image(unit_image);
697 
698  SDL_Rect image_rect = sdl::create_rect(area.x, area.y, 0, 0);
699 
700  if(!unit_image.null()) {
701  SDL_Rect rect = sdl::create_rect(
702  right_align
703  ? area.x
704  : area.x + area.w - unit_image.width()
705  , area.y
706  , unit_image.width()
707  , unit_image.height());
708 
709  video().draw_texture(unit_image, rect.x, rect.y);
710  image_rect = rect;
711 
712  if(!det.overlays.empty()) {
713  for(const std::string& overlay : det.overlays) {
714  sdl::timage oi = image::get_texture(overlay);
715 
716  if(!oi.null()) {
717  continue;
718  }
719 
720  if(oi.width() > rect.w || oi.height() > rect.h) {
721  oi.set_scale(float(rect.w) / oi.width(), float(rect.h) / oi.height());
722  }
723 
724  video().draw_texture(oi, rect.x, rect.y);
725  }
726  }
727  }
728 
729  // Place the 'unit profile' button
730  const SDL_Rect button_loc = sdl::create_rect(
731  right_align
732  ? area.x
733  : area.x + area.w - details_button_.location().w
734  , image_rect.y + image_rect.h
736  , details_button_.location().h);
737  details_button_.set_location(button_loc);
738 
739  SDL_Rect description_rect = sdl::create_rect(image_rect.x
740  , image_rect.y + image_rect.h + details_button_.location().h
741  , 0
742  , 0);
743 
744  if(det.name.empty() == false) {
745  std::stringstream desc;
746  desc << font::BOLD_TEXT << det.name;
747  const std::string description = desc.str();
748  description_rect = font::text_area(description, font::SIZE_NORMAL);
749  sdl::timage img = font::draw_text_to_texture(area,
751  desc.str());
752  video().draw_texture(img, right_align ? image_rect.x :
753  image_rect.x + image_rect.w - description_rect.w,
754  image_rect.y + image_rect.h + details_button_.location().h);
755  }
756 
757  std::stringstream text;
758  text << font::unit_type << det.type_name << "\n"
759  << font::race
760  << (right_align && !weapons_ ? det.race+" " : " "+det.race) << "\n"
761  << _("level") << " " << det.level << "\n"
762  << det.alignment << "\n"
763  << det.traits << "\n";
764 
765  for(std::vector<t_string>::const_iterator a = det.abilities.begin(); a != det.abilities.end(); ++a) {
766  if(a != det.abilities.begin()) {
767  text << ", ";
768  }
769  text << (*a);
770  }
771  text << "\n";
772 
773  // Use same coloring as in generate_report.cpp:
774  text << det.hp_color << _("HP: ")
775  << det.hitpoints << "/" << det.max_hitpoints << "\n";
776 
777  text << det.xp_color << _("XP: ")
778  << det.experience << "/" << det.max_experience << "\n";
779 
780  if(weapons_) {
781  text << _("Moves: ")
782  << det.movement_left << "/" << det.total_movement << "\n";
783 
784  for(std::vector<attack_type>::const_iterator at_it = det.attacks.begin();
785  at_it != det.attacks.end(); ++at_it) {
786  // see generate_report() in generate_report.cpp
787  text << font::weapon
788  << at_it->damage()
790  << at_it->num_attacks()
791  << " " << at_it->name() << "\n";
792  text << font::weapon_details
793  << " " << string_table["range_" + at_it->range()]
795  << string_table["type_" + at_it->type()] << "\n";
796 
797  std::string accuracy_parry = at_it->accuracy_parry_description();
798  if(accuracy_parry.empty() == false) {
799  text << font::weapon_details << " " << accuracy_parry << "\n";
800  }
801 
802  std::string special = at_it->weapon_specials();
803  if (!special.empty()) {
804  text << font::weapon_details << " " << special << "\n";
805  }
806  }
807  }
808 
809  // we don't remove empty lines, so all fields stay at the same place
810  const std::vector<std::string> lines = utils::split(text.str(), '\n',
812 
813 
814  int ypos = area.y;
815 
816  if(weapons_) {
817  ypos += image_rect.h + description_rect.h + details_button_.location().h;
818  }
819 
820  for(std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {
821  int xpos = area.x;
822  if(right_align && !weapons_) {
823  const SDL_Rect& line_area = font::text_area(*line,font::SIZE_SMALL);
824  // right align, but if too long, don't hide line's beginning
825  if (line_area.w < area.w)
826  xpos = area.x + area.w - line_area.w;
827  }
828 
829  sdl::timage img = font::draw_text_to_texture(location(),font::SIZE_SMALL,font::NORMAL_COLOR,*line);
830  video().draw_texture(img, xpos, ypos);
831  ypos += img.height();
832  }
833 
834  GPU_UnsetClip(get_render_target());
835 #else
836  surface& screen(video().getSurface());
837  const clip_rect_setter clipper(screen, &area);
838 
839  surface unit_image = det.image;
840  if (!left_)
841  unit_image = image::reverse_image(unit_image);
842 
843  SDL_Rect image_rect = sdl::create_rect(area.x, area.y, 0, 0);
844 
845  if(unit_image != nullptr) {
846  SDL_Rect rect = sdl::create_rect(
847  right_align
848  ? area.x
849  : area.x + area.w - unit_image->w
850  , area.y
851  , unit_image->w
852  , unit_image->h);
853 
854  sdl_blit(unit_image,nullptr,screen,&rect);
855  image_rect = rect;
856 
857  if(!det.overlays.empty()) {
858  for(const std::string& overlay : det.overlays) {
859  surface os = image::get_image(overlay);
860 
861  if(!os) {
862  continue;
863  }
864 
865  if(os->w > rect.w || os->h > rect.h) {
866  os = scale_surface(os, rect.w, rect.h, false);
867  }
868 
869  sdl_blit(os, nullptr, screen, &rect);
870  }
871  }
872  }
873 
874  // Place the 'unit profile' button
875  const SDL_Rect button_loc = sdl::create_rect(
876  right_align
877  ? area.x
878  : area.x + area.w - details_button_.location().w
879  , image_rect.y + image_rect.h
881  , details_button_.location().h);
882  details_button_.set_location(button_loc);
884 
885  SDL_Rect description_rect = sdl::create_rect(image_rect.x
886  , image_rect.y + image_rect.h + details_button_.location().h
887  , 0
888  , 0);
889 
890  if(det.name.empty() == false) {
891  std::stringstream desc;
892  desc << font::BOLD_TEXT << det.name;
893  const std::string description = desc.str();
894  description_rect = font::text_area(description, font::SIZE_NORMAL);
895  description_rect = font::draw_text(&video(), area,
897  desc.str(), right_align ? image_rect.x :
898  image_rect.x + image_rect.w - description_rect.w,
899  image_rect.y + image_rect.h + details_button_.location().h);
900  }
901 
902  std::stringstream text;
903  text << font::unit_type << det.type_name << "\n"
904  << font::race
905  << (right_align && !weapons_ ? det.race+" " : " "+det.race) << "\n"
906  << _("level") << " " << det.level << "\n"
907  << det.alignment << "\n"
908  << det.traits << "\n";
909 
910  for(std::vector<t_string>::const_iterator a = det.abilities.begin(); a != det.abilities.end(); ++a) {
911  if(a != det.abilities.begin()) {
912  text << ", ";
913  }
914  text << (*a);
915  }
916  text << "\n";
917 
918  // Use same coloring as in generate_report.cpp:
919  text << det.hp_color << _("HP: ")
920  << det.hitpoints << "/" << det.max_hitpoints << "\n";
921 
922  text << det.xp_color << _("XP: ")
923  << det.experience << "/" << det.max_experience << "\n";
924 
925  if(weapons_) {
926  text << _("Moves: ")
927  << det.movement_left << "/" << det.total_movement << "\n";
928 
929  for(std::vector<attack_type>::const_iterator at_it = det.attacks.begin();
930  at_it != det.attacks.end(); ++at_it) {
931  // see generate_report() in generate_report.cpp
932  text << font::weapon
933  << at_it->damage()
935  << at_it->num_attacks()
936  << " " << at_it->name() << "\n";
937  text << font::weapon_details
938  << " " << string_table["range_" + at_it->range()]
940  << string_table["type_" + at_it->type()] << "\n";
941 
942  std::string accuracy_parry = at_it->accuracy_parry_description();
943  if(accuracy_parry.empty() == false) {
944  text << font::weapon_details << " " << accuracy_parry << "\n";
945  }
946 
947  std::string special = at_it->weapon_specials();
948  if (!special.empty()) {
949  text << font::weapon_details << " " << special << "\n";
950  }
951  }
952  }
953 
954  // we don't remove empty lines, so all fields stay at the same place
955  const std::vector<std::string> lines
956  = utils::split(text.str(), '\n', utils::STRIP_SPACES);
957 
958 
959  int ypos = area.y;
960 
961  if(weapons_) {
962  ypos += image_rect.h + description_rect.h + details_button_.location().h;
963  }
964 
965  for(std::vector<std::string>::const_iterator line = lines.begin(); line != lines.end(); ++line) {
966  int xpos = area.x;
967  if(right_align && !weapons_) {
968  const SDL_Rect& line_area = font::text_area(*line,font::SIZE_SMALL);
969  // right align, but if too long, don't hide line's beginning
970  if (line_area.w < area.w)
971  xpos = area.x + area.w - line_area.w;
972  }
973 
974  SDL_Rect cur_area = font::draw_text(&video(),location(),font::SIZE_SMALL,font::NORMAL_COLOR,*line,xpos,ypos);
975  ypos += cur_area.h;
976  }
977 #endif
978 }
979 
980 
982  unit_preview_pane(nullptr, type, on_left_side),
983  units_(boost::make_shared<const std::vector<unit_const_ptr> >(1, u))
984 {
985 }
986 
988  const gui::filter_textbox* filter, TYPE type, bool on_left_side) :
989  unit_preview_pane(filter, type, on_left_side),
990  units_(units)
991 {
992 }
993 
995 {
996  return units_->size();
997 }
998 
1000 {
1001  const unit &u = *units_->at(index_);
1002  details det;
1003 
1004  /** Get an SDL surface, ready for display for place where we need a still-image of the unit. */
1005  image::locator image_loc;
1006 
1007 #ifdef LOW_MEM
1008  image_loc = image::locator(u.absolute_image());
1009 #else
1010  std::string mods=u.image_mods();
1011  if(!mods.empty()){
1012  image_loc = image::locator(u.absolute_image(),mods);
1013  } else {
1014  image_loc = image::locator(u.absolute_image());
1015  }
1016 #endif
1017  det.image = image::get_image(image_loc, image::UNSCALED);
1018  /***/
1019 
1020  det.name = u.name();
1021  det.type_name = u.type_name();
1022  det.race = u.race()->name(u.gender());
1023  det.level = u.level();
1025  det.traits = utils::join(u.trait_names(), ", ");
1026 
1027  // The triples are base name, male/female name, description.
1028  const std::vector<boost::tuple<t_string,t_string,t_string> > &abilities = u.ability_tooltips();
1029  for(std::vector<boost::tuple<t_string,t_string,t_string> >::const_iterator a = abilities.begin();
1030  a != abilities.end(); ++a) {
1031  det.abilities.push_back(a->get<1>());
1032  }
1033 
1034  det.hitpoints = u.hitpoints();
1035  det.max_hitpoints = u.max_hitpoints();
1037 
1038  det.experience = u.experience();
1039  det.max_experience = u.max_experience();
1041 
1042  det.movement_left = u.movement_left();
1043  det.total_movement= u.total_movement();
1044 
1045  det.attacks = u.attacks();
1046 
1047  if(u.can_recruit()) {
1048  det.overlays.push_back(unit::leader_crown());
1049  };
1050 
1051  for(const std::string& overlay : u.overlays()) {
1052  det.overlays.push_back(overlay);
1053  }
1054 
1055  return det;
1056 }
1057 
1059 {
1060  assert(resources::screen);
1061  if (details_button_.pressed() && index_ >= 0 && index_ < int(size())) {
1063  }
1064 }
1065 
1067  std::vector<const unit_type*>& unit_types, const gui::filter_textbox* filter,
1068  int side, TYPE type, bool on_left_side)
1069  : unit_preview_pane(filter, type, on_left_side),
1070  unit_types_(&unit_types), side_(side)
1071 {}
1072 
1074 {
1075  return (unit_types_!=nullptr) ? unit_types_->size() : 0;
1076 }
1077 
1079 {
1080  const unit_type* t = (*unit_types_)[index_];
1081  details det;
1082 
1083  if (t==nullptr)
1084  return det;
1085 
1086  // Make sure the unit type is built with enough data for our needs.
1088 
1089  std::string mod = "~RC(" + t->flag_rgb() + ">" + team::get_side_color_index(side_) + ")";
1090  det.image = image::get_image(t->image()+mod);
1091 
1092  det.name = "";
1093  det.type_name = t->type_name();
1094  det.level = t->level();
1095  det.alignment = unit_type::alignment_description(t->alignment(), t->genders().front());
1096  det.race = t->race()->name(t->genders().front());
1097 
1098  //FIXME: This probably must be move into a unit_type function
1099  for (const config &tr : t->possible_traits())
1100  {
1101  if (tr["availability"] != "musthave") continue;
1102 
1103  const std::string gender_string = t->genders().front()== unit_race::FEMALE ?
1104  "female_name" : "male_name";
1105  t_string name = tr[gender_string];
1106  if (name.empty()) {
1107  name = tr["name"];
1108  }
1109  if (!name.empty()) {
1110  if (!det.traits.empty()) {
1111  det.traits += ", ";
1112  }
1113  det.traits += name;
1114  }
1115  }
1116 
1117  det.abilities = t->abilities();
1118 
1119  det.hitpoints = t->hitpoints();
1120  det.max_hitpoints = t->hitpoints();
1121  det.hp_color = "<33,225,0>"; // from unit::hp_color()
1122 
1123  det.experience = 0;
1124  det.max_experience = t->experience_needed();
1125  det.xp_color = "<0,160,225>"; // from unit::xp_color()
1126 
1127  // Check if AMLA color is needed
1128  // FIXME: not sure if it's fully accurate (but not very important for unit_type)
1129  // xp_color also need a simpler function for doing this
1130  for (const config &adv : t->modification_advancements())
1131  {
1132  if (!adv["strict_amla"].to_bool() || !t->can_advance()) {
1133  det.xp_color = "<170,0,255>"; // from unit::xp_color()
1134  break;
1135  }
1136  }
1137 
1138  det.movement_left = 0;
1139  det.total_movement= t->movement();
1140 
1141  det.attacks = t->attacks();
1142  return det;
1143 }
1144 
1146 {
1147  assert(resources::screen);
1148  if (details_button_.pressed() && index_ >= 0 && index_ < int(size())) {
1149  const unit_type* type = (*unit_types_)[index_];
1150  if (type != nullptr)
1152  }
1153 }
1154 
1156 {
1157  if (video.faked()) {
1158  while (!conn.finished()) {
1159  conn.poll();
1160  SDL_Delay(1);
1161  }
1162  }
1163  else {
1164  gui2::tnetwork_transmission(conn, msg1, msg2).show(video);
1165  }
1166 }
1167 
1169 {
1171  size_t total() override { return conn_.bytes_to_read(); }
1172  virtual size_t current() override { return conn_.bytes_read(); }
1173  virtual bool finished() override { return conn_.has_data_received(); }
1174  virtual void cancel() override { }
1175  virtual void poll() override { conn_.poll(); }
1177 };
1178 
1179 bool network_receive_dialog(CVideo& video, const std::string& msg, config& cfg, twesnothd_connection& wesnothd_connection)
1180 {
1181  read_wesnothd_connection_data gui_data(wesnothd_connection);
1182  network_transmission_dialog(video, gui_data, msg, _("Waiting"));
1183  return wesnothd_connection.receive_data(cfg);
1184 }
1185 
1187 {
1189  virtual bool finished() override { return conn_.handshake_finished(); }
1190  virtual void cancel() override { }
1191  virtual void poll() override { conn_.poll(); }
1193 };
1194 
1195 std::unique_ptr<twesnothd_connection> network_connect_dialog(CVideo& video, const std::string& msg, const std::string& hostname, int port)
1196 {
1197  std::unique_ptr<twesnothd_connection> res(new twesnothd_connection(hostname, std::to_string(port)));
1198  connect_wesnothd_connection_data gui_data(*res);
1199  network_transmission_dialog(video, gui_data, msg, _("Connecting"));
1200  return std::move(res);
1201 
1202 }
1203 
1204 } // end namespace dialogs
std::string image_mods() const
Definition: unit.cpp:2430
read_wesnothd_connection_data(twesnothd_connection &conn)
Definition: dialogs.cpp:1170
basic_sorter & set_alpha_sort(int column)
Definition: menu.cpp:48
void advance_unit(map_location loc, const std::string &advance_to, const bool &fire_event, const config *mod_option)
Function which will advance the unit at loc to 'advance_to'.
Definition: attack.cpp:1573
SDL_Rect text_area(const std::string &text, int size, int style)
Calculate the size of a text (in pixels) if it were to be drawn.
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
virtual void poll() override
Definition: dialogs.cpp:1175
void GPU_UnsetClip(GPU_Target *target)
Definition: SDL_gpu.c:1833
int total_movement() const
Definition: unit.hpp:218
void sort_by(int column)
Definition: menu.cpp:783
sdl_handler_vector handler_members()
Definition: dialogs.cpp:642
const std::string & id() const
Definition: unit.hpp:148
char const IMG_TEXT_SEPARATOR
virtual void select_hex(map_location hex)
Definition: display.cpp:1792
unit_iterator end()
Definition: map.hpp:311
std::unique_ptr< twesnothd_connection > network_connect_dialog(CVideo &video, const std::string &msg, const std::string &hostname, int port)
Definition: dialogs.cpp:1195
std::string const & gender_string(unit_race::GENDER gender)
Definition: race.cpp:151
std::string absolute_image() const
The name of the file to game_display (used in menus).
Definition: unit.cpp:2262
std::size_t bytes_read() const
void start_animations()
Definition: animation.cpp:1346
const std::string & team_color() const
Definition: unit.hpp:202
virtual bool finished() override
Definition: dialogs.cpp:1173
bool invalidate(const map_location &loc)
Function to invalidate a specific tile for redrawing.
Definition: display.cpp:3536
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:112
int max_hitpoints() const
Definition: unit.hpp:169
const std::vector< t_string > & abilities() const
Definition: types.hpp:166
int get_index(int selection) const
const std::string weapon_details_sep
Definition: unit.hpp:95
const std::string race
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:163
int movement() const
Definition: types.hpp:128
Dialog that tracks network transmissions.
int recall_dialog(display &disp, const boost::shared_ptr< std::vector< unit_const_ptr > > &units, int side, const std::string &title_suffix, const int team_recall_cost)
Definition: dialogs.cpp:466
GLint level
Definition: glew.h:1220
const t_string & name() const
The unit name for display.
Definition: unit.hpp:158
const t_string & type_name() const
The unit type name.
Definition: unit.hpp:153
const t_string & name(GENDER gender=MALE) const
Definition: race.hpp:34
int experience() const
Definition: unit.hpp:171
int recruit_dialog(display &disp, std::vector< const unit_type * > &units, const std::vector< std::string > &items, int side, const std::string &title_suffix)
Definition: dialogs.cpp:432
config::const_child_itors modification_advancements() const
Definition: types.hpp:100
unit_types_preview_pane(std::vector< const unit_type * > &unit_types, const gui::filter_textbox *filterbox=nullptr, int side=1, TYPE type=SHOW_ALL, bool left_side=true)
Definition: dialogs.cpp:1066
Various functions that implement attacks and attack calculations.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
std::vector< boost::tuple< t_string, t_string, t_string > > ability_tooltips(std::vector< bool > *active_list=nullptr) const
Tuple of: neutral ability name, gendered ability name, description.
Definition: abilities.cpp:261
int hitpoints() const
Definition: unit.hpp:168
surface reverse_image(const surface &surf)
function to reverse an image.
Definition: image.cpp:1165
bool show(CVideo &video, const unsigned auto_close_time=0)
Shows the window.
Definition: dialog.cpp:34
Definition: video.hpp:58
const details get_details() const
Definition: dialogs.cpp:999
game_display * screen
Definition: resources.cpp:27
std::size_t bytes_to_read() const
int relative_size(int size)
Definition: font.hpp:72
static const style & default_style
This file contains the window object, this object is a top level container which has the event manage...
void add_button(dialog_button *const btn, BUTTON_LOCATION loc)
CVideo & video() const
Definition: widget.hpp:83
General purpose widgets.
void invalidate_unit()
Function to invalidate that unit status displayed on the sidebar.
REMOVE_EMPTY : remove empty elements.
bool receive_data(config &result)
connect_wesnothd_connection_data(twesnothd_connection &conn)
Definition: dialogs.cpp:1188
unit_iterator begin()
Definition: map.hpp:308
unit_ptr get_advanced_unit(const unit &u, const std::string &advance_to)
Returns the advanced version of a unit (with traits and items retained).
Definition: attack.cpp:1541
unit_type_data unit_types
Definition: types.cpp:1314
const unit_race * race() const
Never returns nullptr, but may point to the null race.
Definition: types.hpp:218
const std::string & image() const
Definition: types.hpp:138
STL namespace.
void show_transient_message(CVideo &video, const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup, const bool restore_background)
Shows a transient message to the user.
Replay control code.
#define h
int side() const
Definition: unit.hpp:201
SDL_Color xp_color() const
Colors for the unit's XP.
Definition: unit.cpp:1075
const std::vector< std::string > items
surface scale_surface(const surface &surf, int w, int h)
Definition: utils.cpp:443
void show_unit_description(CVideo &video, const unit &u)
Definition: help.cpp:59
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2706
static lg::log_domain log_display("display")
int show(int xloc, int yloc)
int level() const
Definition: types.hpp:126
GLuint GLenum option
Definition: glew.h:2815
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
GLdouble GLdouble t
Definition: glew.h:1366
int advance_unit_dialog(const map_location &loc)
Lets the user to select a unit advancement.
Definition: dialogs.cpp:172
static imgsel_style bluebg_style
Definition: menu.hpp:118
char const IMAGE_PREFIX
bool can_advance() const
Definition: types.hpp:173
units_list_preview_pane(unit_const_ptr u, TYPE type=SHOW_ALL, bool left_side=true)
Definition: dialogs.cpp:981
const int SIZE_NORMAL
Definition: font.hpp:58
void set_measurements(int w, int h)
Definition: widget.cpp:129
STRIP_SPACES : strips leading and trailing blank spaces.
gui::filter_textbox & filter_
Definition: dialogs.cpp:99
const config & options()
void set_dirty(bool dirty=true)
Definition: widget.cpp:217
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
char const DEFAULT_ITEM
static const std::string & leader_crown()
The path to the leader crown overlay.
Definition: unit.cpp:234
const std::string & flag_rgb() const
Definition: types.hpp:147
GLuint GLuint end
Definition: glew.h:1221
std::size_t poll()
Handle all pending asynchonous events and return.
A class that represents a TCP/IP connection to the wesnothd server.
const std::vector< std::string > & overlays() const
Definition: unit.hpp:260
std::vector< team > * teams
Definition: resources.cpp:29
const char GREEN_TEXT
unit_type::ALIGNMENT alignment() const
Definition: unit.hpp:368
bool animate_unit_advancement(const map_location &loc, size_t choice, const bool &fire_event, const bool animate)
Actually levels a unit up.
Definition: dialogs.cpp:233
#define LOG_DP
Definition: dialogs.cpp:78
unit_ptr get_amla_unit(const unit &u, const config &mod_option)
Returns the AMLA-advanced version of a unit (with traits and items retained).
Definition: attack.cpp:1564
Dialog is closed with the cancel button.
Definition: window.hpp:126
GLubyte GLubyte GLubyte GLubyte w
Definition: glew.h:1858
void set_menu(menu *const m)
std::string selected
Definition: game_config.cpp:84
void show_message(CVideo &video, const std::string &title, const std::string &message, const std::string &button_caption, const bool auto_close, const bool message_use_markup)
Shows a message to the user.
Definition: message.cpp:143
unit_preview_pane(const gui::filter_textbox *filter=nullptr, TYPE type=SHOW_ALL, bool left_side=true)
Definition: dialogs.cpp:629
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
void show_unit_list(display &gui)
Definition: dialogs.cpp:294
Show unit-stats in a side-pane to unit-list, recall-list, etc.
Definition: dialogs.hpp:58
const std::vector< unit_race::GENDER > & genders() const
The returned vector will not be empty, provided this has been built to the HELP_INDEXED status...
Definition: types.hpp:198
bool can_recruit() const
Definition: unit.hpp:207
void build_unit_type(const unit_type &ut, unit_type::BUILD_STATUS status) const
Makes sure the provided unit_type is built to the specified level.
Definition: types.hpp:326
const std::string unicode_em_dash
unit_race::GENDER gender() const
Definition: unit.hpp:203
virtual void cancel() override
Definition: dialogs.cpp:1174
#define log_scope2(domain, description)
Definition: log.hpp:186
static lg::log_domain log_engine("engine")
bool pressed()
Definition: button.cpp:770
int movement_left() const
Returns how far a unit can move this turn (zero if incapacitated).
Definition: unit.hpp:220
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3525
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
int viewing_side() const
Definition: display.hpp:103
GPU_Rect GPU_SetClip(GPU_Target *target, Sint16 x, Sint16 y, Uint16 w, Uint16 h)
Definition: SDL_gpu.c:1822
const std::vector< attack_type > & attacks() const
Definition: unit.hpp:271
void pump()
Definition: events.cpp:336
Various uncategorised dialogs.
Definition: dialogs.cpp:85
const unit_map & get_units() const
Definition: display.hpp:121
std::string join(T const &v, const std::string &s=",")
Generates a new string joining container items in a list.
Encapsulates the map of the game.
Definition: location.hpp:38
std::string color2markup(const SDL_Color &color)
Create string of color-markup, such as "<255,255,0>" for yellow.
bool handshake_finished() const
True if connected and no high-level operation is in progress.
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.
virtual size_t current() override
Definition: dialogs.cpp:1172
bool network_receive_dialog(CVideo &video, const std::string &msg, config &cfg, twesnothd_connection &wesnothd_connection)
Definition: dialogs.cpp:1179
std::vector< std::string > overlays
Definition: dialogs.hpp:79
GLuint res
Definition: glew.h:9258
void scroll_to_tile(const map_location &loc, SCROLL_TYPE scroll_type=ONSCREEN, bool check_fogged=true, bool force=true)
Scroll such that location loc is on-screen.
Definition: display.cpp:2434
boost::shared_ptr< const std::vector< unit_const_ptr > > units_
Definition: dialogs.hpp:120
config::const_child_itors possible_traits() const
Definition: types.hpp:182
const std::string weapon_details
GLuint index
Definition: glew.h:1782
gui::button details_button_
Definition: dialogs.hpp:93
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:5910
size_t i
Definition: function.cpp:1057
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:112
bool loyal() const
Definition: unit.cpp:1515
int level() const
Definition: unit.hpp:175
std::set< std::string > & encountered_units()
DIALOG_RESULT
Definition: show_dialog.hpp:33
bool fire_event(const tevent event, std::vector< std::pair< twidget *, tevent > > &event_chain, twidget *dispatcher, twidget *widget, F functor)
Helper function for fire_event.
boost::shared_ptr< std::vector< unit_const_ptr > > units_
Definition: dialogs.cpp:100
static config get_disband(const std::string &unit_id)
basic_sorter & set_numeric_sort(int column)
Definition: menu.cpp:54
void add_animation(const unit *animated_unit, const unit_animation *animation, const map_location &src=map_location::null_location(), bool with_bars=false, const std::string &text="", const Uint32 text_color=0)
Definition: animation.cpp:1294
void scale_images(int max_width, int max_height)
Definition: menu_style.cpp:64
GLuint const GLchar * name
Definition: glew.h:1782
int hitpoints() const
Definition: types.hpp:123
int experience_needed(bool with_acceleration=true) const
Definition: types.cpp:514
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
GLsizeiptr size
Definition: glew.h:1649
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
static bool run_and_throw(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
bool faked() const
Definition: video.hpp:166
const char RED_TEXT
GLenum GLenum GLvoid * row
Definition: glew.h:3805
bool can_advance() const
Definition: unit.hpp:323
void set_selection(int index)
Definition: dialogs.cpp:659
char const HEADING_PREFIX
int max_experience() const
Definition: unit.hpp:172
char const COLUMN_SEPARATOR
const std::string weapon_numbers_sep
basic_sorter & set_level_sort(int level_column, int xp_column)
Definition: menu.cpp:66
const std::vector< t_string > & trait_names() const
Definition: unit.hpp:280
int recall_cost() const
Definition: unit.hpp:177
SDL_Color hp_color() const
Colors for the unit's current hitpoints.
Definition: unit.cpp:1065
void set_all_standing()
Definition: animation.cpp:1453
virtual size_t size() const =0
static const int max_menu_width
std::vector< const unit_type * > * unit_types_
Definition: dialogs.hpp:136
symbol_table string_table
Definition: language.cpp:65
display & disp_
Definition: dialogs.cpp:98
const details get_details() const
Definition: dialogs.cpp:1078
std::vector< attack_type > attacks() const
Definition: types.cpp:484
basic_sorter & set_xp_sort(int column)
Definition: menu.cpp:60
GLint GLvoid * img
Definition: glew.h:1353
virtual const details get_details() const =0
Various functions that implement the undoing (and redoing) of in-game commands.
bool left_side() const
Definition: dialogs.cpp:654
this module manages the cache of images.
Definition: image.cpp:75
Standard logging facilities (interface).
std::vector< t_string > abilities
Definition: dialogs.hpp:73
CVideo & video()
Gets the underlying screen object.
Definition: display.hpp:202
std::vector< attack_type > attacks
Definition: dialogs.hpp:78
Container associating units to locations.
Definition: map.hpp:90
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
const gui::filter_textbox * filter_
Definition: dialogs.hpp:102
static std::string get_side_color_index(int side)
Definition: team.cpp:840
const char BOLD_TEXT
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
unit_iterator find(size_t id)
Definition: map.cpp:285
SDL_Rect const & location() const
Definition: widget.cpp:144
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:112
const std::string weapon
static void network_transmission_dialog(CVideo &video, gui2::tnetwork_transmission::connection_data &conn, const std::string &msg1, const std::string &msg2)
Definition: dialogs.cpp:1155
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
static std::string alignment_description(ALIGNMENT align, unit_race::GENDER gender=unit_race::MALE)
void delete_item(int selection)
const std::string unit_type
const unit_race * race() const
Never returns nullptr, but may point to the null race.
Definition: unit.hpp:371
GLsizei const GLcharARB ** string
Definition: glew.h:4503
unit_map * units
Definition: resources.cpp:35
Shows a yes and no button.
Definition: message.hpp:75
static lg::log_domain log_config("config")
bool empty() const
Definition: tstring.hpp:166
const char NORMAL_TEXT
preview_pane(CVideo &video)
bool show_above() const
Definition: dialogs.cpp:649
void show_objectives(const std::string &scenarioname, const std::string &objectives)
Definition: dialogs.cpp:425
const map_location & selected_hex() const
Definition: display.hpp:292
void set_panes(std::vector< preview_pane * > panes)
void wait_for_end() const
Definition: animation.cpp:1399
const int SIZE_SMALL
Definition: font.hpp:62