The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
multiplayer_connect.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 /**
16  * @file
17  * Prepare to join a multiplayer-game.
18  */
19 #include "multiplayer_connect.hpp"
20 
21 #include "ai/configuration.hpp"
22 #include "dialogs.hpp"
23 #include "display_chat_manager.hpp"
24 #include "game_preferences.hpp"
25 #include "gettext.hpp"
26 #include "log.hpp"
27 #include "map/map.hpp"
28 #include "mp_ui_alerts.hpp"
30 #include "wml_separators.hpp"
31 
32 #include "utils/functional.hpp"
33 
34 static lg::log_domain log_mp_connect("mp/connect");
35 #define DBG_MP LOG_STREAM(debug, log_mp_connect)
36 #define LOG_MP LOG_STREAM(info, log_mp_connect)
37 
38 namespace mp {
39 
40 std::vector<std::string> controller_options_names(
41  const std::vector<ng::controller_option>& controller_options)
42 {
43  std::vector<std::string> names;
44  for (const ng::controller_option& option : controller_options) {
45  names.push_back(option.second);
46  }
47 
48  return names;
49 }
50 
51 static std::string get_income_string(int income)
52 {
53 
54  std::stringstream buf;
55  if (income < 0) {
56  buf << _("(") << income << _(")");
57  } else if (income > 0) {
58  buf << _("+") << income;
59  } else {
60  buf << _("Normal");
61  }
62  return buf.str();
63 }
64 
66  parent_(&parent),
67  engine_(engine),
68  gold_lock_(engine_->cfg()["gold_lock"].to_bool(
69  parent_->force_lock_settings())),
70  income_lock_(engine_->cfg()["income_lock"].to_bool(
71  parent_->force_lock_settings())),
72  team_lock_(engine_->cfg()["team_lock"].to_bool(
73  parent_->force_lock_settings())),
74  color_lock_(engine_->cfg()["color_lock"].to_bool(
75  parent_->force_lock_settings())),
76  changed_(false),
77  label_player_number_(parent.video(), std::to_string(engine_->index() + 1),
79  label_original_controller_(parent.video(), engine_->reserved_for(),
80  font::SIZE_SMALL),
81  label_gold_(parent.video(), std::to_string(engine_->gold()), font::SIZE_SMALL, font::LOBBY_COLOR),
82  label_income_(parent.video(), get_income_string(engine_->income()), font::SIZE_SMALL,
83  font::LOBBY_COLOR),
84  combo_controller_(new gui::combo_drag(parent.video(),
85  std::vector<std::string>(), parent.combo_control_group_)),
86  combo_ai_algorithm_(parent.video(), std::vector<std::string>()),
87  combo_faction_(parent.video(), std::vector<std::string>()),
88  label_leader_name_(parent.video(), engine_->cfg()["name"], font::SIZE_SMALL),
89  combo_leader_(parent.video(), std::vector<std::string>()),
90  combo_gender_(parent.video(), std::vector<std::string>()),
91  combo_team_(parent.video(), engine_->player_teams()),
92  combo_color_(parent.video(), engine->get_colors()),
93  slider_gold_(parent.video()),
94  slider_income_(parent.video())
95 {
96  DBG_MP << "initializing side" << std::endl;
97 
99  slider_gold_.set_max(800);
101  slider_gold_.set_value(engine_->cfg()["gold"].to_int(100));
103 
107  slider_income_.set_value(engine_->cfg()["income"]);
109 
119 
121  // Gold, income, team, and color are only suggestions.
122  // (Unless explicitly locked).
129  }
130 
131  update_ui();
132 }
133 
135  parent_(a.parent_),
136  engine_(a.engine_),
137  gold_lock_(a.gold_lock_),
138  income_lock_(a.income_lock_),
139  team_lock_(a.team_lock_),
140  color_lock_(a.color_lock_),
141  changed_(a.changed_),
142  label_player_number_(a.label_player_number_),
143  label_original_controller_(a.label_original_controller_),
144  label_gold_(a.label_gold_),
145  label_income_(a.label_income_),
146  combo_controller_(a.combo_controller_),
147  combo_ai_algorithm_(a.combo_ai_algorithm_),
148  combo_faction_(a.combo_faction_),
149  label_leader_name_(a.label_leader_name_),
150  combo_leader_(a.combo_leader_),
151  combo_gender_(a.combo_gender_),
152  combo_team_(a.combo_team_),
153  combo_color_(a.combo_color_),
154  slider_gold_(a.slider_gold_),
155  slider_income_(a.slider_income_)
156 {
157 }
158 
160 {
161 }
162 
164 {
165  int drop_target;
166  if ((drop_target = combo_controller_->get_drop_target()) > -1) {
167  if (engine_->swap_sides_on_drop_target(drop_target)) {
168  changed_ = true;
169  parent_->sides_[drop_target].changed_ = true;
170 
171  update_ui();
172  parent_->sides_[drop_target].update_ui();
173  }
174  } else if (combo_controller_->changed() &&
175  combo_controller_->selected() >= 0) {
176 
177  changed_ = engine_->controller_changed(combo_controller_->selected());
178  update_controller_ui();
179  }
180  if (combo_controller_->hidden()) {
181  combo_controller_->hide(false);
182  }
183 
184  if (parent_->params().saved_game) {
185  return;
186  }
187 
188  if (combo_color_.changed() && combo_color_.selected() >= 0) {
189  engine_->set_color(combo_color_.selected());
190  update_faction_combo();
191  engine_->flg().reset_leader_combo(combo_leader_, engine_->get_color());
192  engine_->flg().reset_gender_combo(combo_gender_, engine_->get_color());
193  changed_ = true;
194  }
195  if (combo_faction_.changed() && combo_faction_.selected() >= 0) {
196  engine_->flg().set_current_faction(combo_faction_.selected());
197  engine_->flg().reset_leader_combo(combo_leader_, engine_->get_color());
198  engine_->flg().reset_gender_combo(combo_gender_, engine_->get_color());
199  changed_ = true;
200  }
201  if (combo_ai_algorithm_.changed() && combo_ai_algorithm_.selected() >= 0) {
202  engine_->set_ai_algorithm(
203  parent_->ai_algorithms_[combo_ai_algorithm_.selected()]->id);
204  changed_ = true;
205  }
206  if (combo_leader_.changed() && combo_leader_.selected() >= 0) {
207  engine_->flg().set_current_leader(combo_leader_.selected());
208  engine_->flg().reset_gender_combo(combo_gender_, engine_->get_color());
209  changed_ = true;
210  }
211  if (combo_gender_.changed() && combo_gender_.selected() >= 0) {
212  engine_->flg().set_current_gender(combo_gender_.selected());
213  changed_ = true;
214  }
215  if (combo_team_.changed() && combo_team_.selected() >= 0) {
216  engine_->set_team(combo_team_.selected());
217  changed_ = true;
218  }
219  if (slider_gold_.value() != engine_->gold() && slider_gold_.enabled()) {
220  engine_->set_gold(slider_gold_.value());
221  changed_ = true;
222  label_gold_.set_text(std::to_string(engine_->gold()));
223  }
224  if (slider_income_.value() != engine_->income() && slider_income_.enabled()) {
225  engine_->set_income(slider_income_.value());
226  changed_ = true;
227  label_income_.set_text(get_income_string(engine_->income()));
228  }
229 }
230 
232 {
233  if (changed_) {
234  changed_ = false;
235  return true;
236  }
237 
238  return false;
239 }
240 
242 {
243  update_faction_combo();
244  engine_->flg().reset_leader_combo(combo_leader_, engine_->get_color());
245  engine_->flg().reset_gender_combo(combo_gender_, engine_->get_color());
246 
247  update_controller_ui();
248 
249  combo_team_.set_selected(engine_->team());
250  combo_color_.set_selected(engine_->color());
251  slider_gold_.set_value(engine_->gold());
252  label_gold_.set_text(std::to_string(engine_->gold()));
253  slider_income_.set_value(engine_->income());
254  std::stringstream buf;
255  if (engine_->income() < 0) {
256  buf << _("(") << engine_->income() << _(")");
257  } else if (engine_->income() > 0) {
258  buf << _("+") << engine_->income();
259  } else {
260  buf << _("Normal");
261  }
262  label_income_.set_text(buf.str());
263 }
264 
266 {
267  // Offset value to align labels in y-axis.
268  int label_y_offset = (combo_leader_.height() - label_leader_name_.height()) / 2;
269 
270  pane.add_widget(&label_player_number_, 0, 5 + pos);
271 
272  pane.add_widget(combo_controller_.get(), 20, 5 + pos);
273  pane.add_widget(&label_original_controller_, 20 +
274  (combo_controller_->width() - label_original_controller_.width()) / 2,
275  35 + pos + label_y_offset);
276  pane.add_widget(&combo_ai_algorithm_, 20, 35 + pos);
277 
278  pane.add_widget(&combo_faction_, 135, 5 + pos);
279  pane.add_widget(&label_leader_name_, 135 +
280  (combo_faction_.width() - label_leader_name_.width()) / 2,
281  35 + pos + label_y_offset);
282 
283  pane.add_widget(&combo_leader_, 250, 5 + pos);
284  pane.add_widget(&combo_gender_, 250, 35 + pos);
285 
286  pane.add_widget(&combo_team_, 365, 5 + pos);
287  pane.add_widget(&combo_color_, 365, 35 + pos);
288 
289  pane.add_widget(&slider_gold_, 475, 5 + pos);
290  pane.add_widget(&label_gold_, 475 + 5, 35 + pos + label_y_offset);
291 
292  pane.add_widget(&slider_income_, 475 + slider_gold_.width(), 5 + pos);
293  pane.add_widget(&label_income_, 475 + 5 + slider_gold_.width(),
294  35 + pos + label_y_offset);
295 }
296 
298 {
299  std::vector<std::string> factions;
300  for (const config* faction : engine_->flg().choosable_factions()) {
301  const std::string& name = (*faction)["name"];
302  const std::string& icon = (*faction)["image"];
303  if (!icon.empty()) {
304  std::string rgb = (*faction)["flag_rgb"];
305  if (rgb.empty()) {
306  rgb = "magenta";
307  }
308  factions.push_back(IMAGE_PREFIX + icon + "~RC(" + rgb + ">" + engine_->get_color() + ")" + COLUMN_SEPARATOR + name);
309  } else {
310  factions.push_back(name);
311  }
312  }
313 
314  combo_faction_.enable(factions.size() > 1 && !parent_->params().saved_game);
315 
316  combo_faction_.set_items(factions);
317  combo_faction_.set_selected(engine_->flg().current_faction_index());
318 }
319 
321 {
322  // Update controllers combo.
323  combo_controller_->set_items(controller_options_names(
324  engine_->controller_options()));
325  combo_controller_->set_selected(engine_->current_controller_index());
326  combo_controller_->enable(engine_->controller_options().size() > 1);
327 
328  // Update AI algorithm combo.
329  assert(!parent_->ai_algorithms_.empty());
330  int sel = 0;
331  int i = 0;
332  std::vector<std::string> ais;
333  for (const ai::description* desc : parent_->ai_algorithms_) {
334  ais.push_back(desc->text);
335  if (desc->id == engine_->ai_algorithm()) {
336  sel = i;
337  }
338  i++;
339  }
340  combo_ai_algorithm_.set_items(ais);
341  combo_ai_algorithm_.set_selected(sel);
342  // Ensures that the visually selected AI
343  // is the one that will be loaded.
344  engine_->set_ai_algorithm(parent_->ai_algorithms_[sel]->id);
345 
346  // Adjust the visibility of AI algorithm combo
347  // and original controller label.
348  if (!parent_->hidden()) {
349  if (engine_->controller() == ng::CNTR_COMPUTER) {
350  // Computer selected, show AI combo.
351  combo_ai_algorithm_.hide(false);
352 
353  label_original_controller_.hide(true);
354  } else {
355  // Computer de-selected, hide AI combo.
356  combo_ai_algorithm_.hide(true);
357 
358  label_original_controller_.hide(false);
359  label_original_controller_.set_text(engine_->reserved_for());
360  }
361  } else {
362  combo_ai_algorithm_.hide(true);
363  }
364 }
365 
366 connect::connect(CVideo& v, twesnothd_connection* wesnothd_connection, const std::string& game_name,
367  const config& game_config, chat& c, config& gamelist,
368  ng::connect_engine& engine) :
369  mp::ui(v, wesnothd_connection, _("Game Lobby: ") + game_name, game_config, c, gamelist),
370  ai_algorithms_(),
371  sides_(),
372  engine_(engine),
374  type_title_label_(video(), _("Player/Type"), font::SIZE_SMALL,
375  font::LOBBY_COLOR),
376  faction_name_title_label_(video(), _("Faction/Name"), font::SIZE_SMALL,
377  font::LOBBY_COLOR),
378  leader_gender_title_label_(video(), _("Leader/Gender"), font::SIZE_SMALL,
379  font::LOBBY_COLOR),
380  team_color_title_label_(video(), _("Team/Color"), font::SIZE_SMALL,
381  font::LOBBY_COLOR),
382  gold_title_label_(video(), _("Gold"), font::SIZE_SMALL,
383  font::LOBBY_COLOR),
384  income_title_label_(video(), _("Income"), font::SIZE_SMALL,
385  font::LOBBY_COLOR),
386  scroll_pane_(video()),
387  launch_(video(), _("I’m Ready")),
388  cancel_(video(), engine_.first_scenario() ? _("Cancel") : _("Quit")),
389  combo_control_group_(new gui::drop_group_manager())
390 {
391  DBG_MP << "setting up connect dialog" << std::endl;
392 
393  // Load game exception occured.
394  if (engine_.level().empty()) {
396  return;
397  }
398 
399  if (get_result() == QUIT || get_result() == CREATE) {
400  return;
401  }
402  if (engine_.scenario()["id"].empty()) {
403  throw config::error(_("The scenario is invalid because it has no id."));
404  }
405 
407 
408  // Sides.
410  sides_.push_back(side(*this, s));
411  }
412  if (sides_.empty() && !game_config::debug) {
413  throw config::error(
414  _("The scenario is invalid because it has no sides."));
415  }
416 
417  // Add side widgets to scroll pane.
418  int side_pos_y_offset = 0;
419  for (side& s : sides_) {
420  if (!s.engine()->allow_player() && !game_config::debug) {
421  continue;
422  }
423 
424  s.add_widgets_to_scrollpane(scroll_pane_, side_pos_y_offset);
425  side_pos_y_offset += 60;
426  }
427 
428  append_to_title(" — " + engine_.scenario()["name"].t_str());
431 
433 
434  plugins_context_.reset(new plugins_context("Multiplayer Connect"));
435 
436  //These structure initializers create a lobby::process_data_event
437  plugins_context_->set_callback("launch", std::bind(&connect::plugin_event_helper, this, process_event_data (true, false)));
438  plugins_context_->set_callback("quit", std::bind(&connect::plugin_event_helper, this, process_event_data (false, true)));
439  plugins_context_->set_callback("chat", std::bind(&connect::send_chat_message, this, std::bind(get_str, _1, "message"), false), true);
440 }
441 
443 {
444 }
445 
447 {
448  process_event_impl(data);
449  return get_result() == mp::ui::CONTINUE;
450 }
451 
453 {
455  data.quit = cancel_.pressed();
456  data.launch = launch_.pressed();
457 
458  process_event_impl(data);
459 }
460 
462 {
463  bool changed = false;
464 
465  for (side& s : sides_) {
466  s.process_event();
467  if (s.changed()) {
468  changed = true;
469  }
470  }
471 
472  if (data.quit) {
473  if (wesnothd_connection_) {
474  config cfg;
475  cfg.add_child("leave_game");
476  send_to_server(cfg);
477  }
478 
479  set_result(QUIT);
480  return;
481  }
482 
483  if (data.launch) {
484  if (engine_.can_start_game()) {
486  }
487  }
488 
489  // If something has changed in the level config,
490  // send it to the network.
491  if (changed) {
494  }
495 }
496 
497 void connect::hide_children(bool hide)
498 {
499  DBG_MP << (hide ? "hiding" : "showing" ) <<
500  " children widgets" << std::endl;
501 
502  ui::hide_children(hide);
503 
504  waiting_label_.hide(hide);
505  scroll_pane_.hide(hide); // Scroll pane contents are automatically hidden.
506 
510 
511  if (!params().saved_game) {
512  gold_title_label_.hide(hide);
514  }
515 
516  launch_.hide(hide);
517  cancel_.hide(hide);
518 }
519 
520 void connect::layout_children(const SDL_Rect& rect)
521 {
522  ui::layout_children(rect);
523 
524  SDL_Rect ca = client_area();
525 
526  gui::button* left_button = &launch_;
527  gui::button* right_button = &cancel_;
528 #ifdef OK_BUTTON_ON_RIGHT
529  std::swap(left_button,right_button);
530 #endif
531  size_t left = ca.x;
532  size_t right = ca.x + ca.w;
533  size_t top = ca.y;
534  size_t bottom = ca.y + ca.h;
535 
536  // Buttons.
537  right_button->set_location(right - right_button->width(),
538  bottom - right_button->height());
539  left_button->set_location(right - right_button->width() -
540  left_button->width()- gui::ButtonHPadding, bottom -
541  left_button->height());
542 
543  type_title_label_.set_location(left + 30, top + 35);
544  faction_name_title_label_.set_location((left + 145), top + 35);
545  leader_gender_title_label_.set_location((left + 260), top + 35);
546  team_color_title_label_.set_location((left + 375), top + 35);
547  gold_title_label_.set_location((left + 493), top + 35);
548  income_title_label_.set_location((left + 560), top + 35);
549 
551  bottom - left_button->height() + 4);
552 
553  SDL_Rect scroll_pane_rect;
554  scroll_pane_rect.x = ca.x;
555  scroll_pane_rect.y = ca.y + 50;
556  scroll_pane_rect.w = ca.w;
557  scroll_pane_rect.h = launch_.location().y - scroll_pane_rect.y -
559 
560  scroll_pane_.set_location(scroll_pane_rect);
561 }
562 
564 {
566 
567  bool was_able_to_start = engine_.can_start_game();
568  std::pair<bool, bool> result = engine_.process_network_data(data);
569 
570  if (result.first) {
571  set_result(QUIT);
572  }
573 
574  for (side& s : sides_) {
575  s.update_ui();
576  }
577 
578  update_playerlist_state(result.second); //result.second is the silent flag
579  if (!was_able_to_start && engine_.can_start_game()) {
580  DBG_MP << "play party full sound" << std::endl;
582  }
583 }
584 
586 {
587  DBG_MP << "updating player list state" << std::endl;
588 
591  ? _("Waiting for players to join...")
592  : _("Waiting for players to choose factions..."));
594 
595  // If the "gamelist_" variable has users, use it.
596  // Else, extracts the user list from the actual player list.
597  if (gamelist().child("user")) {
598  ui::gamelist_updated(silent);
599  } else {
600  // Updates the player list
601  std::vector<std::string> playerlist;
602  for (const std::string& user : engine_.connected_users()) {
603  playerlist.push_back(user);
604  }
605  set_user_list(playerlist, silent);
606  set_user_menu_items(playerlist);
607  }
608 }
609 
610 } // end namespace mp
611 
static std::string get_income_string(int income)
bool can_start_game() const
gui::label leader_gender_title_label_
void ready_for_start()
const std::string & set_text(const std::string &text)
Definition: label.cpp:35
ng::side_engine_ptr engine_
virtual void enable(bool new_val=true)
Definition: widget.cpp:204
Graphical text output.
const GLfloat * c
Definition: glew.h:12741
int pos
Definition: formula.cpp:800
AI parameters.
void set_value(int value)
Definition: slider.cpp:87
static l_noret error(LoadState *S, const char *why)
Definition: lundump.cpp:29
boost::scoped_ptr< plugins_context > plugins_context_
void process_event_impl(const process_event_data &)
void set_max(int value)
Definition: slider.cpp:77
Definition: video.hpp:58
virtual void enable(bool new_val=true)
Definition: button.cpp:386
virtual void layout_children(const SDL_Rect &rect)
Lays the children out.
result get_result()
Returns the result of the current widget.
General purpose widgets.
void set_increment(int increment)
Definition: slider.cpp:107
STL namespace.
Scrollpane.
Definition: scrollpane.hpp:30
const config & level() const
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
GLuint GLenum option
Definition: glew.h:2815
bool empty() const
Definition: config.cpp:1105
gui::label type_title_label_
virtual void set_location(SDL_Rect const &rect)
Definition: scrollpane.cpp:57
bool plugin_event_helper(const process_event_data &)
connect(CVideo &v, twesnothd_connection *wesnothd_connection, const std::string &game_name, const config &game_config, chat &c, config &gamelist, ng::connect_engine &engine)
void update_and_send_diff(bool update_time_of_day=false)
char const IMAGE_PREFIX
const std::set< std::string > & connected_users() const
std::string id
bool sides_available() const
void add_widgets_to_scrollpane(gui::scrollpane &pane, int pos)
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.
void set_measurements(int w, int h)
Definition: widget.cpp:129
const int ButtonHPadding
Definition: show_dialog.cpp:43
This module controls the multiplayer lobby.
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
gui::scrollpane scroll_pane_
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().
std::vector< side_engine_ptr > & side_engines()
static std::vector< description * > get_available_ais()
Returns a list of available AIs.
virtual void hide(bool value=true)
Definition: widget.cpp:162
virtual void process_event()
const GLdouble * v
Definition: glew.h:1359
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:7319
static lg::log_domain log_mp_connect("mp/connect")
ng::connect_engine & engine_
config & add_child(const std::string &key)
Definition: config.cpp:743
virtual void enable(bool new_val=true)
Definition: slider.cpp:51
GLenum GLuint GLsizei const char * buf
Definition: glew.h:2498
void send_to_server(const config &cfg) override
bool pressed()
Definition: button.cpp:770
gui::label waiting_label_
CVideo & video()
GLuint const GLuint * names
Definition: glew.h:2552
void append_to_title(const std::string &name)
lu_byte right
Definition: lparser.cpp:1020
void send_chat_message(const std::string &message, bool allies_only=false)
gui::label gold_title_label_
GLint left
Definition: glew.h:5907
SDL_Rect client_area() const
gui::drop_group_manager_ptr combo_control_group_
Game configuration data as global variables.
Definition: build_info.cpp:38
GLuint index
Definition: glew.h:1782
void set_user_list(const std::vector< std::string > &, bool silent)
Sets the user list.
const SDL_Color LOBBY_COLOR
Definition: font.cpp:566
config & gamelist()
Returns the current gamelist.
virtual void process_network_data(const config &data)
Processes any pending network data.
size_t i
Definition: function.cpp:1057
std::vector< std::string > controller_options_names(const std::vector< ng::controller_option > &controller_options)
std::vector< ai::description * > ai_algorithms_
virtual void hide(bool value=true)
Definition: scrollpane.cpp:64
GLuint const GLchar * name
Definition: glew.h:1782
const int SIZE_LARGE
Definition: font.hpp:66
std::pair< ng::controller, std::string > controller_option
void set_user_menu_items(const std::vector< std::string > &list)
virtual void layout_children(const SDL_Rect &rect)
Lays the children out.
gui::label team_color_title_label_
gui::label income_title_label_
char const COLUMN_SEPARATOR
virtual void hide_children(bool hide=true)
Hides or shows all gui::widget children of this widget.
Managing the AIs configuration - headers.
void swap(game_board &one, game_board &other)
Definition: game_board.cpp:56
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
Standard logging facilities (interface).
void set_min(int value)
Definition: slider.cpp:67
const std::function< std::string(const config &, const std::string &) > get_str
Definition: context.cpp:121
GLint GLint bottom
Definition: glew.h:5907
twesnothd_connection * wesnothd_connection_
virtual void set_location(SDL_Rect const &rect)
Definition: widget.cpp:85
this class memorizes a chat session.
void update_playerlist_state(bool silent=true)
int width() const
Definition: widget.cpp:134
#define DBG_MP
SDL_Rect const & location() const
Definition: widget.cpp:144
const int ButtonVPadding
Definition: show_dialog.cpp:44
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLdouble s
Definition: glew.h:1358
gui::label faction_name_title_label_
void add_widget(widget *w, int x, int y, int z_order=0)
Definition: scrollpane.cpp:71
GLsizei const GLcharARB ** string
Definition: glew.h:4503
a base class for the different multiplayer base dialogs: game list, create game, wait game...
side(connect &parent, ng::side_engine_ptr engine)
const int SIZE_SMALL
Definition: font.hpp:62
std::pair< bool, bool > process_network_data(const config &data)
virtual void gamelist_updated(bool silent=true)
Called each time the gamelist_ variable is updated.
int height() const
Definition: widget.cpp:139
const mp_game_settings & params()