The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
multiplayer_wait.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2007 - 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 #include "global.hpp"
16 
17 #include "dialogs.hpp"
18 #include "gettext.hpp"
19 #include "game_config_manager.hpp"
20 #include "game_preferences.hpp"
22 #include "image.hpp"
23 #include "log.hpp"
24 #include "marked-up_text.hpp"
25 #include "mp_game_utils.hpp"
26 #include "multiplayer_wait.hpp"
27 #include "statistics.hpp"
28 #include "saved_game.hpp"
29 #include "mp_ui_alerts.hpp"
31 #include "sdl/rect.hpp"
32 #include "units/types.hpp"
33 #include "wml_exception.hpp"
34 #include "wml_separators.hpp"
35 #include "formula/string_utils.hpp"
36 #include "video.hpp"
37 
38 #include "utils/functional.hpp"
39 
40 static lg::log_domain log_network("network");
41 #define DBG_NW LOG_STREAM(debug, log_network)
42 #define LOG_NW LOG_STREAM(info, log_network)
43 
44 static lg::log_domain log_enginerefac("enginerefac");
45 #define LOG_RG LOG_STREAM(info, log_enginerefac)
46 #define ERR_RG LOG_STREAM(err, log_enginerefac)
47 
48 static lg::log_domain log_mp("mp/main");
49 #define DBG_MP LOG_STREAM(debug, log_mp)
50 #define ERR_MP LOG_STREAM(err, log_mp)
51 
52 
53 namespace {
54 
55 const SDL_Rect leader_pane_position = {-260,-370,260,370};
56 const int leader_pane_border = 10;
57 
58 }
59 
60 namespace mp {
61 
63  ng::flg_manager& flg, const std::string& color) :
64  gui::preview_pane(v),
65  flg_(flg),
66  color_(color),
67  combo_leader_(v, std::vector<std::string>()),
68  combo_gender_(v, std::vector<std::string>())
69 {
72 
73  set_location(leader_pane_position);
74 }
75 
77 {
78  if (combo_leader_.changed() && combo_leader_.selected() >= 0) {
79  flg_.set_current_leader(combo_leader_.selected());
80 
81  flg_.reset_gender_combo(combo_gender_, color_);
82 
83  set_dirty();
84  }
85 
86  if (combo_gender_.changed() && combo_gender_.selected() >= 0) {
87  flg_.set_current_gender(combo_gender_.selected());
88 
89  set_dirty();
90  }
91 }
92 
94 {
95  bg_restore();
96 
98 
99  SDL_Rect const &loc = location();
100  const SDL_Rect area = sdl::create_rect(loc.x + leader_pane_border,
101  loc.y + leader_pane_border,loc.w - leader_pane_border * 2,
102  loc.h - leader_pane_border * 2);
103  const clip_rect_setter clipper(screen, &area);
104 
105  std::string faction = flg_.current_faction()["faction"];
106 
107  const std::string recruits = flg_.current_faction()["recruit"];
108  const std::vector<std::string> recruit_list = utils::split(recruits);
109  std::ostringstream recruit_string;
110 
111  if (!faction.empty() && faction[0] == font::IMAGE) {
112  std::string::size_type p = faction.find_first_of(COLUMN_SEPARATOR);
113  if (p != std::string::npos && p < faction.size())
114  faction = faction.substr(p+1);
115  }
116 
118 
119  const unit_type *ut = unit_types.find(flg_.current_leader());
120 
121  if (ut) {
122  const unit_type &utg = ut->get_gender_unit_type(flg_.current_gender());
123 
124  image = utg.image() + ng::get_RC_suffix(utg.flag_rgb(), color_);
125  }
126 
127  for(std::vector<std::string>::const_iterator itor = recruit_list.begin();
128  itor != recruit_list.end(); ++itor) {
129 
130  const unit_type *rt = unit_types.find(*itor);
131  if (!rt) continue;
132 
133  if (itor != recruit_list.begin())
134  recruit_string << ", ";
135  recruit_string << rt->type_name();
136  }
137 
138  SDL_Rect image_rect = {area.x,area.y,0,0};
139 
140  surface unit_image(image::get_image(image));
141 
142  if (!unit_image.null()) {
143  image_rect.w = unit_image->w;
144  image_rect.h = unit_image->h;
145  sdl_blit(unit_image, nullptr, screen, &image_rect);
146  }
147 
149  faction, area.x + 110, area.y + 60);
150  const SDL_Rect leader_rect = font::draw_text(&video(), area,
151  font::SIZE_SMALL, font::NORMAL_COLOR, _("Leader: "), area.x,
152  area.y + 110);
153  const SDL_Rect gender_rect = font::draw_text(&video(), area,
154  font::SIZE_SMALL, font::NORMAL_COLOR, _("Gender: "), area.x,
155  leader_rect.y + 30 + (leader_rect.h - combo_leader_.height()) / 2);
157  font::NORMAL_COLOR, _("Recruits: ") + recruit_string.str(), area.x,
158  area.y + 132 + 30 + (leader_rect.h - combo_leader_.height()) / 2,
159  area.w);
160  combo_leader_.set_location(leader_rect.x + leader_rect.w + 16,
161  leader_rect.y + (leader_rect.h - combo_leader_.height()) / 2);
162  combo_gender_.set_location(leader_rect.x + leader_rect.w + 16,
163  gender_rect.y + (gender_rect.h - combo_gender_.height()) / 2);
164 }
165 
167 {
168  return false;
169 }
170 
172 {
173  return false;
174 }
175 
177 {
178  if (selection >= 0) {
179  flg_.set_current_faction(selection);
180 
181  flg_.reset_leader_combo(combo_leader_, color_);
182  flg_.reset_gender_combo(combo_gender_, color_);
183 
184  set_dirty();
185  }
186 }
187 
190  h.push_back(&combo_leader_);
191  h.push_back(&combo_gender_);
192  return h;
193 }
194 
195 
196 wait::wait(CVideo& v, twesnothd_connection* wesnothd_connection, const config& cfg, saved_game& state,
197  mp::chat& c, config& gamelist, const bool first_scenario) :
198  ui(v, wesnothd_connection, _("Game Lobby"), cfg, c, gamelist),
199  cancel_button_(video(), first_scenario ? _("Cancel") : _("Quit")),
200  start_label_(video(), _("Waiting for game to start..."), font::SIZE_SMALL, font::LOBBY_COLOR),
201  game_menu_(video(), std::vector<std::string>(), false, -1, -1, nullptr, &gui::menu::bluebg_style),
202  level_(),
203  state_(state),
204  first_scenario_(first_scenario),
205  stop_updates_(false)
206 {
209 
210  plugins_context_.reset(new plugins_context("Multiplayer Wait"));
211 
212  //These structure initializers create a lobby::process_data_event
213  plugins_context_->set_callback("quit", std::bind(&wait::process_event_impl, this, true), false);
214  plugins_context_->set_callback("chat", std::bind(&wait::send_chat_message, this, std::bind(get_str, _1, "message"), false), true);
215 }
216 
218 {
219  try {
220  if (get_result() == QUIT) {
221  state_ = saved_game();
222  state_.classification().campaign_type = game_classification::CAMPAIGN_TYPE::MULTIPLAYER;
223  }
224  } catch (...) {}
225 }
226 
228 {
230 }
231 
233 {
234  if (quit) {
235  set_result(QUIT);
236  }
237 }
238 
239 void wait::join_game(bool observe)
240 {
241  const bool download_res = download_level_data();
242  if (!download_res) {
243  DBG_MP << "mp wait: could not download level data, quitting...";
244  set_result(QUIT);
245  return;
246  } else if (level_["started"].to_bool()) {
247  set_result(PLAY);
248  return;
249  }
250 
251  if (first_scenario_) {
252  state_ = saved_game();
254 
255  if(state_.classification().campaign_type != game_classification::CAMPAIGN_TYPE::MULTIPLAYER) {
256  ERR_MP << "Mp wait recieved a game that is not a multiplayer game\n";
257  }
258  // Make sure that we have the same config as host, if possible.
260  }
261 
262  // Add the map name to the title.
263  append_to_title(": " + get_scenario()["name"].t_str());
264 
266  if (!observe) {
267  //search for an appropriate vacant slot. If a description is set
268  //(i.e. we're loading from a saved game), then prefer to get the side
269  //with the same description as our login. Otherwise just choose the first
270  //available side.
271  const config *side_choice = nullptr;
272  int side_num = -1, nb_sides = 0;
273  for (const config &sd : get_scenario().child_range("side"))
274  {
275  DBG_MP << "*** side " << nb_sides << "***\n" << sd.debug() << "***\n";
276 
277  if (sd["controller"] == "reserved" && sd["current_player"] == preferences::login())
278  {
279  side_choice = &sd;
280  side_num = nb_sides;
281  break;
282  }
283  if (sd["controller"] == "human" && sd["player_id"].empty())
284  {
285  if (!side_choice) { // found the first empty side
286  side_choice = &sd;
287  side_num = nb_sides;
288  }
289  if (sd["current_player"] == preferences::login()) {
290  side_choice = &sd;
291  side_num = nb_sides;
292  break; // found the preferred one
293  }
294  }
295  if (sd["player_id"] == preferences::login())
296  {
297  //We already own a side in this game.
298  generate_menu();
299  return;
300  }
301  ++nb_sides;
302  }
303  if (!side_choice) {
304  size_t count = 0;
305  for(config::child_itors its = get_scenario().child_range("side"); its.second != its.first; ++its.first) {
306  ++count;
307  }
308  DBG_MP << "could not find a side, all " << count << " sides were unsuitable\n";
309  set_result(QUIT);
310  return;
311  }
312 
313  bool allow_changes = (*side_choice)["allow_changes"].to_bool(true);
314 
315  //if the client is allowed to choose their team, instead of having
316  //it set by the server, do that here.
317  if(allow_changes) {
318  events::event_context context;
319 
320  const config &era = level_.child("era");
321  /** @todo Check whether we have the era. If we don't inform the user. */
322  if (!era)
323  throw config::error(_("No era information found."));
324  config::const_child_itors possible_sides = era.child_range("multiplayer_side");
325  if (possible_sides.first == possible_sides.second) {
326  set_result(QUIT);
327  throw config::error(_("No multiplayer sides found"));
328  }
329 
330  const std::string color = (*side_choice)["color"].str();
331 
332  std::vector<const config*> era_factions;
333  for (const config &side : possible_sides) {
334  era_factions.push_back(&side);
335  }
336 
337  const bool is_mp = state_.classification().is_normal_mp_game();
338  const bool lock_settings =
339  get_scenario()["force_lock_settings"].to_bool(!is_mp);
340  const bool use_map_settings =
341  level_.child("multiplayer")["mp_use_map_settings"].to_bool();
342  const bool saved_game =
343  level_.child("multiplayer")["savegame"].to_bool();
344 
345  ng::flg_manager flg(era_factions, *side_choice, lock_settings, use_map_settings,
346  saved_game);
347 
348  std::vector<std::string> choices;
349  for (const config *s : flg.choosable_factions())
350  {
351  const config &side = *s;
352  const std::string &name = side["name"];
353  const std::string &icon = side["image"];
354 
355  if (!icon.empty()) {
356  std::string rgb = side["flag_rgb"];
357  if (rgb.empty())
358  rgb = "magenta";
359 
360  choices.push_back(IMAGE_PREFIX + icon + "~RC(" + rgb + ">" +
361  color + ")" + COLUMN_SEPARATOR + name);
362  } else {
363  choices.push_back(name);
364  }
365  }
366 
367 
368  std::vector<gui::preview_pane* > preview_panes;
369  leader_preview_pane leader_selector(video(), flg, color);
370  preview_panes.push_back(&leader_selector);
371 
372  const int faction_choice = gui::show_dialog(video(), nullptr,
373  _("Choose your faction:"), _("Starting position: ") +
374  std::to_string(side_num + 1), gui::OK_CANCEL,
375  &choices, &preview_panes);
376  if(faction_choice < 0) {
377  set_result(QUIT);
378  return;
379  }
380 
381  config faction;
382  config& change = faction.add_child("change_faction");
383  change["change_faction"] = true;
384  change["name"] = preferences::login();
385  change["faction"] = flg.current_faction()["id"];
386  change["leader"] = flg.current_leader();
387  change["gender"] = flg.current_gender();
388  send_to_server(faction);
389  }
390 
391  }
392 
393  generate_menu();
394 }
395 
397 {
398  if (const config &stats = level_.child("statistics")) {
400  statistics::read_stats(stats);
401  }
403 
404  LOG_NW << "starting game\n";
406 }
407 
408 void wait::layout_children(const SDL_Rect& rect)
409 {
410  ui::layout_children(rect);
411 
412  const SDL_Rect ca = client_area();
413  int y = ca.y + ca.h - cancel_button_.height();
414 
415  game_menu_.set_location(ca.x, ca.y + title().height());
416  game_menu_.set_measurements(ca.w, y - ca.y - title().height()
421  start_label_.set_location(ca.x, y + 4);
422 }
423 
424 void wait::hide_children(bool hide)
425 {
426  ui::hide_children(hide);
427 
428  cancel_button_.hide(hide);
429  game_menu_.hide(hide);
430 }
431 
433 {
435 
436  if(!data["message"].empty()) {
438  , _("Response")
439  , data["message"]);
440  }
441  if (data["failed"].to_bool()) {
442  set_result(QUIT);
443  return;
444  } else if(data.child("stop_updates")) {
445  stop_updates_ = true;
446  } else if(data.child("start_game")) {
447  LOG_NW << "received start_game message\n";
448  set_result(PLAY);
449  return;
450  } else if(data.child("leave_game")) {
451  set_result(QUIT);
452  return;
453  } else if (const config &c = data.child("scenario_diff")) {
454  LOG_NW << "received diff for scenario... applying...\n";
455  /** @todo We should catch config::error and then leave the game. */
457  generate_menu();
458  } else if(const config &change = data.child("change_controller")) {
459  LOG_NW << "received change controller" << std::endl;
460  LOG_RG << "multiplayer_wait: [change_controller]" << std::endl;
461  LOG_RG << data.debug() << std::endl;
462  //const int side = lexical_cast<int>(change["side"]);
463 
464  if (config & sidetochange = get_scenario().find_child("side", "side", change["side"])) {
465  LOG_RG << "found side : " << sidetochange.debug() << std::endl;
466  sidetochange.merge_with(change);
467  LOG_RG << "changed to : " << sidetochange.debug() << std::endl;
468  } else {
469  LOG_RG << "change_controller didn't find any side!" << std::endl;
470  }
471  } else if(data.has_child("scenario") || data.has_child("snapshot") || data.child("next_scenario")) {
472  level_ = first_scenario_ ? data : data.child("next_scenario");
473  LOG_NW << "got some sides. Current number of sides = "
474  << get_scenario().child_count("side") << ','
475  << data.child_count("side") << '\n';
476  generate_menu();
477  }
478 }
479 
481 {
482  //allow the host to overwrite it, this is needed because only the host knows the ai_algorithm.
483  if(const config::attribute_value* desc = side.get("user_description")) {
484  return desc->str();
485  }
486 
487  std::string controller_type = side["controller"].str();
488  std::string reservation = side["reserved_for"].str();
489  std::string owner = side["player_id"].str();
490 
491  if(controller_type == "ai") {
492  return _("Computer Player");
493  }
494  else if (controller_type == "null") {
495  return _("(Empty slot)");
496  }
497  else if (controller_type == "reserved") {
498  utils::string_map symbols;
499  symbols["playername"] = reservation;
500  return vgettext("(Reserved for $playername)",symbols);
501  }
502  else if(owner.empty()) {
503  return _("(Vacant slot)");
504  }
505  else if (controller_type == "human" || controller_type == "network") {
506  return owner;
507  }
508  else {
509  ERR_RG << "Found unknown controller type:" << controller_type << std::endl;
510  return _("(empty)");
511  }
512 }
513 
515 {
516  if (stop_updates_)
517  return;
518 
519  std::vector<std::string> details;
520  std::set<std::string> playerlist;
521 
522  for (const config &sd : get_scenario().child_range("side"))
523  {
524  if (!sd["allow_player"].to_bool(true)) {
525  continue;
526  }
527 
528  std::string description = generate_user_description(sd);
529 
530  t_string side_name = sd["faction_name"];
531  std::string leader_type = sd["type"];
532  std::string gender_id = sd["gender"];
533 
534  // Hack: if there is a unit which can recruit, use it as a
535  // leader. Necessary to display leader information when loading
536  // saves.
537  for (const config &side_unit : sd.child_range("unit"))
538  {
539  if (side_unit["canrecruit"].to_bool()) {
540  leader_type = side_unit["type"].str();
541  break;
542  }
543  }
544 
545  if(!sd["player_id"].empty())
546  playerlist.insert(sd["player_id"]);
547 
548  std::string leader_name;
549  std::string leader_image;
550 
551  const unit_type *ut = unit_types.find(leader_type);
552 
553  if (ut) {
554  const unit_type &utg = ut->get_gender_unit_type(gender_id);
555 
556  leader_name = utg.type_name();
557 #ifdef LOW_MEM
558  leader_image = utg.image();
559 #else
560  std::string RCcolor = sd["color"];
561 
562  if (RCcolor.empty())
563  RCcolor = sd["side"].str();
564  leader_image = utg.image() + std::string("~RC(") + utg.flag_rgb() + ">" + RCcolor + ")";
565 #endif
566  } else {
567  leader_image = ng::random_enemy_picture;
568  }
569  if (!leader_image.empty()) {
570  // Dumps the "image" part of the faction name, if any,
571  // to replace it by a picture of the actual leader
572  if(side_name.str()[0] == font::IMAGE) {
573  std::string::size_type p =
574  side_name.str().find_first_of(COLUMN_SEPARATOR);
575  if(p != std::string::npos && p < side_name.size()) {
576  side_name = IMAGE_PREFIX + leader_image + COLUMN_SEPARATOR + side_name.str().substr(p+1);
577  }
578  } else {
579  // no image prefix, just add the leader image
580  // (assuming that there is also no COLUMN_SEPARATOR)
581  side_name = IMAGE_PREFIX + leader_image + COLUMN_SEPARATOR + side_name.str();
582  }
583  }
584 
585  std::stringstream str;
586  str << sd["side"] << ". " << COLUMN_SEPARATOR;
587  str << description << COLUMN_SEPARATOR << side_name << COLUMN_SEPARATOR;
588  // Mark parentheses translatable for languages like Japanese
589  if(!leader_name.empty())
590  str << _("(") << leader_name << _(")");
591  str << COLUMN_SEPARATOR;
592  // Don't show gold for saved games
593  if (sd["allow_changes"].to_bool())
594  str << sd["gold"] << ' ' << _n("multiplayer_starting_gold^Gold", "multiplayer_starting_gold^Gold", sd["gold"].to_int()) << COLUMN_SEPARATOR;
595 
596  int income_amt = sd["income"];
597  if(income_amt != 0){
598  str << _("(") << _("Income") << ' ';
599  if(income_amt > 0)
600  str << _("+");
601  str << sd["income"] << _(")");
602  }
603 
604  str << COLUMN_SEPARATOR << t_string::from_serialized(sd["user_team_name"].str());
605 
606  str << COLUMN_SEPARATOR << get_color_string(sd["color"].str());
607  details.push_back(str.str());
608  }
609 
610  game_menu_.set_items(details);
611 
612  // Uses the actual connected player list if we do not have any
613  // "gamelist" user data
614  if (!gamelist().child("user")) {
615  set_user_list(std::vector<std::string>(playerlist.begin(), playerlist.end()), true);
616  }
617 }
618 
620 {
621  assert(wesnothd_connection_);
622  DBG_MP << "download_level_data()\n";
623  if (!first_scenario_) {
624  // Ask for the next scenario data.
625  send_to_server(config("load_next_scenario"));
626  }
627  bool has_scenario_and_controllers = false;
628  while (!has_scenario_and_controllers) {
629  config revc;
630  bool data_res = dialogs::network_receive_dialog(
631  video(), _("Getting game data..."), revc, *wesnothd_connection_);
632 
633  if (!data_res) {
634  DBG_MP << "download_level_data bad results\n";
635  return false;
636  }
637  check_response(data_res, revc);
638  if (revc.child("leave_game")) {
639  return false;
640  }
641  else if(config& next_scenario = revc.child("next_scenario")) {
642  level_.swap(next_scenario);
643  }
644  else if(revc.has_attribute("version")) {
645  level_.swap(revc);
646  has_scenario_and_controllers = true;
647  }
648  else if(config& controllers = revc.child("controllers")) {
649  int index = 0;
650  for (const config& controller : controllers.child_range("controller")) {
651  if(config& side = get_scenario().child("side", index)) {
652  side["is_local"] = controller["is_local"];
653  }
654  ++index;
655  }
656  has_scenario_and_controllers = true;
657  }
658 
659  }
660 
661  DBG_MP << "download_level_data() success.\n";
662 
663  return true;
664 }
665 
667 {
668 
669  if(config& scenario = level_.child("scenario"))
670  return scenario;
671  else if(config& snapshot = level_.child("snapshot"))
672  return snapshot;
673  else
674  return level_;
675 }
676 
678 {
679  if(const config& scenario = level_.child("scenario"))
680  return scenario;
681  else if(const config& snapshot = level_.child("snapshot"))
682  return snapshot;
683  else
684  return level_;
685 }
686 
687 } // namespace mp
688 
void generate_menu()
const std::vector< const config * > & choosable_factions() const
Definition: flg_manager.hpp:63
surface get_image(const image::locator &i_locator, TYPE type)
function to get the surface corresponding to an image.
Definition: image.cpp:878
child_itors child_range(const std::string &key)
Definition: config.cpp:613
bool null() const
Definition: utils.hpp:104
void set_numeric_keypress_selection(bool value)
Definition: menu.cpp:761
const unit_type & get_gender_unit_type(std::string gender) const
Definition: types.cpp:439
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:112
std::string era()
std::vector< events::sdl_handler * > sdl_handler_vector
Definition: events.hpp:163
leader_preview_pane(CVideo &v, ng::flg_manager &flg, const std::string &color)
Graphical text output.
const GLfloat * c
Definition: glew.h:12741
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
gui::button cancel_button_
const char IMAGE
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
boost::scoped_ptr< plugins_context > plugins_context_
Definition: video.hpp:58
void game_has_begun()
game_display * screen
Definition: resources.cpp:27
#define LOG_RG
virtual void layout_children(const SDL_Rect &rect)
Lays the children out.
result get_result()
Returns the result of the current widget.
static lg::log_domain log_mp("mp/main")
General purpose widgets.
GLenum GLsizei GLenum GLenum const GLvoid * image
Definition: glew.h:3783
void fresh_stats()
Definition: statistics.cpp:617
unit_type_data unit_types
Definition: types.cpp:1314
const std::string & image() const
Definition: types.hpp:138
SDL_Color color_
Definition: font.cpp:605
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.
#define h
void process_event_impl(bool)
std::string get_color_string(int id)
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1220
const int SIZE_PLUS
Definition: font.hpp:65
void level_to_gamestate(const config &level, saved_game &state)
std::string debug() const
Definition: config.cpp:1438
virtual void layout_children(const SDL_Rect &rect)
Lays the children out.
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
FLG stands for faction, leader and gender.
Definition: flg_manager.hpp:32
const SDL_Color NORMAL_COLOR
Definition: font.cpp:564
-file util.hpp
virtual void process_network_data(const config &data)
Processes any pending network data.
surface & getSurface()
Definition: dummy_video.cpp:22
std::pair< const_child_iterator, const_child_iterator > const_child_itors
Definition: config.hpp:214
Variant for storing WML attributes.
Definition: config.hpp:223
char const IMAGE_PREFIX
static lg::log_domain log_network("network")
virtual void process_network_data(const config &data)
Processes any pending network data.
virtual void hide_children(bool hide=true)
Hides or shows all gui::widget children of this widget.
#define ERR_RG
#define ERR_MP
void set_measurements(int w, int h)
Definition: widget.cpp:129
sdl_handler_vector handler_members()
This module controls the multiplayer lobby.
bool has_child(const std::string &key) const
Determine whether a config has a child or not.
Definition: config.cpp:651
virtual void process_event()
void set_dirty(bool dirty=true)
Definition: widget.cpp:217
static game_config_manager * get()
void swap(config &cfg)
Definition: config.cpp:1518
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
const std::string & flag_rgb() const
Definition: types.hpp:147
std::map< std::string, t_string > string_map
void reset_leader_combo(gui::combo &combo_leader, const std::string &color) const
A class that represents a TCP/IP connection to the wesnothd server.
result set_result(result res)
Sets the result of this dialog, to be checked by get_result().
static lg::log_domain log_enginerefac("enginerefac")
const std::string & current_gender() const
Definition: flg_manager.hpp:73
saved_game & state_
virtual void hide(bool value=true)
Definition: widget.cpp:162
#define LOG_NW
void add_color_info(const config &v)
const GLdouble * v
Definition: glew.h:1359
const gui::label & title() const
bool download_level_data()
static UNUSEDNOWARN std::string _n(const char *str1, const char *str2, int n)
Definition: gettext.hpp:86
config & add_child(const std::string &key)
Definition: config.cpp:743
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 read_stats(const config &cfg)
Definition: statistics.cpp:607
void send_to_server(const config &cfg) override
void check_response(bool res, const config &data)
void set_max_width(const int new_max_width)
Definition: menu.cpp:485
bool pressed()
Definition: button.cpp:770
void reset_gender_combo(gui::combo &combo_gender, const std::string &color) const
gui::menu game_menu_
void apply_diff(const config &diff, bool track=false)
A function to apply a diff config onto this config object.
Definition: config.cpp:1252
GLfloat GLfloat p
Definition: glew.h:12766
CVideo & video()
GLuint GLuint GLsizei count
Definition: glew.h:1221
GLuint color
Definition: glew.h:5801
std::string get_RC_suffix(const std::string &unit_color, const std::string &color)
Definition: flg_manager.cpp:38
void append_to_title(const std::string &name)
virtual void set_items(const std::vector< std::string > &items, bool strip_spaces=true, bool keep_viewport=false)
Set new items to show and redraw/recalculate everything.
Definition: menu.cpp:446
std::string login()
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.
bool network_receive_dialog(CVideo &video, const std::string &msg, config &cfg, twesnothd_connection &wesnothd_connection)
Definition: dialogs.cpp:1179
void send_chat_message(const std::string &message, bool allies_only=false)
std::map< std::string, tfilter >::iterator itor
Definition: filter.cpp:199
SDL_Rect client_area() const
GLuint index
Definition: glew.h:1782
SDL_Rect draw_wrapped_text(CVideo *gui, const SDL_Rect &area, int font_size, const SDL_Color &color, const std::string &text, int x, int y, int max_width)
Draw text on the screen, fit text to maximum width, no markup, no tooltips.
void set_user_list(const std::vector< std::string > &, bool silent)
Sets the user list.
const SDL_Color LOBBY_COLOR
Definition: font.cpp:566
std::pair< child_iterator, child_iterator > child_itors
Definition: config.hpp:213
config & gamelist()
Returns the current gamelist.
static t_string from_serialized(const std::string &string)
Definition: tstring.hpp:135
const config & current_faction() const
Definition: flg_manager.hpp:69
gui::label start_label_
unsigned child_count(const std::string &key) const
Definition: config.cpp:635
virtual void hide(bool value=true)
Definition: scrollarea.cpp:78
const std::string random_enemy_picture("units/random-dice.png")
static std::string generate_user_description(const config &side)
std::string vgettext(const char *msgid, const utils::string_map &symbols)
GLuint const GLchar * name
Definition: glew.h:1782
const attribute_value * get(const std::string &key) const
Returns a pointer to the attribute with the given key or nullptr if it does not exist.
Definition: config.cpp:935
const std::string & current_leader() const
Definition: flg_manager.hpp:71
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
void load_game_config_for_game(const game_classification &classification)
Contains the SDL_Rect helper code.
void bg_restore() const
Definition: widget.cpp:251
bool has_attribute(const std::string &key) const
Definition: config.cpp:514
char const COLUMN_SEPARATOR
game_classification & classification()
Definition: saved_game.hpp:54
void join_game(bool observe)
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
wait(CVideo &v, twesnothd_connection *wesnothd_connection, const config &cfg, saved_game &state, chat &c, config &gamelist, const bool first_scenario=true)
Standard logging facilities (interface).
const std::function< std::string(const config &, const std::string &) > get_str
Definition: context.cpp:121
twesnothd_connection * wesnothd_connection_
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
const unit_type * find(const std::string &key, unit_type::BUILD_STATUS status=unit_type::FULL) const
Finds a unit_type by its id() and makes sure it is built to the specified level.
Definition: types.cpp:1155
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.
this class memorizes a chat session.
int width() const
Definition: widget.cpp:134
SDL_Rect const & location() const
Definition: widget.cpp:144
const std::string & str() const
Definition: tstring.hpp:170
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
Definition: utils.hpp:112
const int ButtonVPadding
Definition: show_dialog.cpp:44
virtual void hide_children(bool hide=true)
Hides or shows all gui::widget children of this widget.
config & get_scenario()
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
std::string::size_type size() const
Definition: tstring.hpp:167
GLdouble s
Definition: glew.h:1358
const bool first_scenario_
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void set_max_height(const int new_max_height)
Set a new max height for this menu.
Definition: menu.cpp:477
a base class for the different multiplayer base dialogs: game list, create game, wait game...
const int SIZE_SMALL
Definition: font.hpp:62
virtual void gamelist_updated(bool silent=true)
Called each time the gamelist_ variable is updated.
int height() const
Definition: widget.cpp:139
#define DBG_MP