The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
playsingle_controller.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2016 by Joerg Hinrichs <[email protected]>
3  wesnoth playlevel Copyright (C) 2003 by David White <[email protected]>
4  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 /**
17  * @file
18  * Logic for single-player game.
19  */
20 
22 
23 #include "actions/undo.hpp"
24 #include "ai/manager.hpp"
25 #include "ai/game_info.hpp"
26 #include "ai/testing.hpp"
27 #include "config_assign.hpp"
28 #include "dialogs.hpp"
29 #include "display_chat_manager.hpp"
30 #include "game_end_exceptions.hpp"
31 #include "game_events/manager.hpp"
32 #include "game_events/pump.hpp"
33 #include "game_preferences.hpp"
34 #include "gettext.hpp"
37 #include "log.hpp"
38 #include "map/label.hpp"
39 #include "marked-up_text.hpp"
40 #include "playturn.hpp"
42 #include "replay_helper.hpp"
43 #include "resources.hpp"
44 #include "savegame.hpp"
45 #include "sound.hpp"
46 #include "synced_context.hpp"
47 #include "formula/string_utils.hpp"
48 #include "events.hpp"
49 #include "save_blocker.hpp"
51 #include "soundsource.hpp"
52 #include "statistics.hpp"
54 #include "units/unit.hpp"
55 #include "units/animation.hpp"
56 #include "util.hpp"
58 #include "whiteboard/manager.hpp"
59 #include "hotkey/hotkey_item.hpp"
60 
61 static lg::log_domain log_aitesting("aitesting");
62 #define LOG_AIT LOG_STREAM(info, log_aitesting)
63 //If necessary, this define can be replaced with `#define LOG_AIT std::cout` to restore previous behavior
64 
65 static lg::log_domain log_engine("engine");
66 #define ERR_NG LOG_STREAM(err, log_engine)
67 #define LOG_NG LOG_STREAM(info, log_engine)
68 
69 static lg::log_domain log_enginerefac("enginerefac");
70 #define LOG_RG LOG_STREAM(info, log_enginerefac)
71 
73  saved_game& state_of_game,
74  const config& game_config, const tdata_cache & tdata,
75  CVideo& video, bool skip_replay)
76  : play_controller(level, state_of_game, game_config, tdata, video, skip_replay)
77  , cursor_setter(cursor::NORMAL)
78  , textbox_info_()
79  , replay_sender_(*resources::recorder)
80  , network_reader_([this](config& cfg) {return recieve_from_wesnothd(cfg);})
81  , turn_data_(replay_sender_, network_reader_)
82  , end_turn_(END_TURN_NONE)
83  , skip_next_turn_(false)
84  , replay_()
85 {
86  hotkey_handler_.reset(new hotkey_handler(*this, saved_game_)); //upgrade hotkey handler to the sp (whiteboard enabled) version
87 
88 
89  // game may need to start in linger mode
90  linger_ = this->is_regular_game_end();
91 
92  ai::game_info ai_info;
93  ai::manager::set_ai_info(ai_info);
95 
96  plugins_context_->set_accessor_string("level_result", std::bind(&playsingle_controller::describe_result, this));
97  plugins_context_->set_accessor_int("turn", std::bind(&play_controller::turn, this));
98 }
99 
101 {
102  if(!is_regular_game_end()) {
103  return "NONE";
104  }
105  else if(get_end_level_data_const().is_victory){
106  return "VICTORY";
107  }
108  else {
109  return "DEFEAT";
110  }
111 }
112 
114 {
117 }
118 
120  LOG_NG << "Initializing GUI... " << (SDL_GetTicks() - ticks()) << "\n";
122 
123  if(gamestate().first_human_team_ != -1) {
124  gui_->scroll_to_tile(gamestate().board_.map().starting_position(gamestate().first_human_team_ + 1), game_display::WARP);
125  }
126  gui_->scroll_to_tile(gamestate().board_.map().starting_position(1), game_display::WARP);
127 
128  update_locker lock_display(gui_->video(), is_skipping_replay());
129  gui_->draw();
132 }
133 
134 
136 {
137  // At the beginning of the scenario, save a snapshot as replay_start
140  }
141  start_game();
143  // This won't cause errors later but we should notify the user about it in case he didn't knew it.
145  gui_->video(),
146  // TODO: find a better title
147  _("Game Error"),
148  _("This multiplayer game uses an alternative random mode, if you don't know what this message means, then most likely someone is cheating or someone reloaded a corrupt game.")
149  );
150  }
151  return;
152 }
153 
155 {
156  LOG_NG << "starting main loop\n" << (SDL_GetTicks() - ticks()) << "\n";
157 
158 
159  // Avoid autosaving after loading, but still
160  // allow the first turn to have an autosave.
162  if(gamestate().board_.teams().empty())
163  {
164  ERR_NG << "Playing game with 0 teams." << std::endl;
165  }
166  while(true) {
167  try {
168  play_turn();
169  if (is_regular_game_end()) {
171  return;
172  }
173  gamestate_->player_number_ = 1;
174  }
175  catch(const reset_gamestate_exception& ex) {
176  //
177  // TODO:
178  //
179  // The MP replay feature still doesn't work properly (causes OOS)
180  // because:
181  //
182  // 1) The undo stack is not reset along with the gamestate (fixed).
183  // 2) The server_request_number_ is not reset along with the
184  // gamestate (fixed).
185  // 3) chat and other unsynced actions are inserted in the middle of
186  // the replay bringing the replay_pos in unorder (fixed).
187  // 4) untracked changes in side controllers are lost when resetting
188  // gamestate (fixed).
189  // 5) The game should have a stricter check for whether the loaded
190  // game is actually a parent of this game.
191  // 6) If an action was undone after a game was saved it can cause
192  // OOS if the undone action is in the snapshot of the saved
193  // game (luckily this is never the case for autosaves).
194  //
195  std::vector<bool> local_players(gamestate().board_.teams().size(), true);
196  //Preserve side controllers, becasue we won't get the side controoller updates again when replaying.
197  for(size_t i = 0; i < local_players.size(); ++i) {
198  local_players[i] = gamestate().board_.teams()[i].is_local();
199  }
200  reset_gamestate(*ex.level, (*ex.level)["replay_pos"]);
201  for(size_t i = 0; i < local_players.size(); ++i) {
202  (*resources::teams)[i].set_local(local_players[i]);
203  }
205  replay_.reset(new replay_controller(*this, false, ex.level));
206  if(ex.start_replay) {
207  replay_->play_replay();
208  }
209  }
210  } //end for loop
211 }
212 
214 {
215  LOG_NG << "in playsingle_controller::play_scenario()...\n";
216 
217  // Start music.
218  for(const config &m : level.child_range("music")) {
220  }
222 
223  if(!this->is_skipping_replay()) {
224  show_story(gui_->video(), get_scenario_name(), level.child_range("story"));
225  }
226  gui_->labels().read(level);
227 
228  // Read sound sources
229  assert(soundsources_manager_ != nullptr);
230  for (const config &s : level.child_range("sound_source")) {
231  try {
233  soundsources_manager_->add(spec);
234  } catch (bad_lexical_cast &) {
235  ERR_NG << "Error when parsing sound_source config: bad lexical cast." << std::endl;
236  ERR_NG << "sound_source config was: " << s.debug() << std::endl;
237  ERR_NG << "Skipping this sound source..." << std::endl;
238  }
239  }
240  LOG_NG << "entering try... " << (SDL_GetTicks() - ticks()) << "\n";
241  try {
243  // clears level config;
245 
246  if (!is_regular_game_end() && !linger_) {
248  }
250  exit(0);
251  }
252  const bool is_victory = get_end_level_data_const().is_victory;
253 
254  if(gamestate().gamedata_.phase() <= game_data::PRESTART) {
256  0, 0, gui_->video().getx(), gui_->video().gety(), 0, 0, 0, 1.0,
257  gui_->video().getSurface()
258  );
259  update_rect(0, 0, gui_->video().getx(), gui_->video().gety());
260  }
261 
263 
264  const end_level_data& end_level = get_end_level_data_const();
265  if (!end_level.transient.custom_endlevel_music.empty()) {
266  if (!is_victory) {
268  } else {
270  }
271  }
272 
273  if (gamestate().board_.teams().empty())
274  {
275  //store persistent teams
277 
278  return LEVEL_RESULT::VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event
279  }
280  if(linger_) {
281  LOG_NG << "resuming from loaded linger state...\n";
282  //as carryover information is stored in the snapshot, we have to re-store it after loading a linger state
284  if(!is_observer()) {
286  }
287  return LEVEL_RESULT::VICTORY;
288  }
289  pump().fire(is_victory ? "victory" : "defeat");
290  { // Block for set_scontext_synced_base
292  pump().fire("scenario end");
293  }
294  if(end_level.proceed_to_next_level) {
296  }
297  if(is_observer()) {
298  gui2::show_transient_message(gui_->video(), _("Game Over"), _("The game is over."));
299  return LEVEL_RESULT::OBSERVER_END;
300  }
301  // If we're a player, and the result is victory/defeat, then send
302  // a message to notify the server of the reason for the game ending.
304  ("info", config_of
305  ("type", "termination")
306  ("condition", "game over")
307  ("result", is_victory ? "victory" : "defeat")
308  ));
309  // Play victory music once all victory events
310  // are finished, if we aren't observers.
311  //
312  // Some scenario authors may use 'continue'
313  // result for something that is not story-wise
314  // a victory, so let them use [music] tags
315  // instead should they want special music.
316  const std::string& end_music = is_victory ? select_victory_music() : select_defeat_music();
317  if(end_music.empty() != true) {
318  sound::play_music_once(end_music);
319  }
321  return is_victory ? LEVEL_RESULT::VICTORY : LEVEL_RESULT::DEFEAT;
322  } catch(const game::load_game_exception &) {
323  // Loading a new game is effectively a quit.
324  //
325  if ( game::load_game_exception::game != "" ) {
327  }
328  throw;
329  } catch(wesnothd_error& e) {
330 
331  scoped_savegame_snapshot snapshot(*this);
333  save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO);
334  if(dynamic_cast<ingame_wesnothd_error*>(&e)) {
335  return LEVEL_RESULT::QUIT;
336  } else {
337  throw;
338  }
339  }
340 
341  return LEVEL_RESULT::QUIT;
342 }
343 
345 {
346  while(!should_return_to_play_side()) {
348  gui_->draw();
349  SDL_Delay(10);
350  }
351 }
352 
354 {
355  if (!skip_next_turn_) {
357  }
358  if(replay_.get() != nullptr) {
359  REPLAY_RETURN res = replay_->play_side_impl();
360  if(res == REPLAY_FOUND_END_TURN) {
362  }
363  if (player_type_changed_) {
364  replay_.reset();
365  }
366  } else if((current_team().is_local_human() && current_team().is_proxy_human())) {
367  LOG_NG << "is human...\n";
368  // If a side is dead end the turn, but play at least side=1's
369  // turn in case all sides are dead
370  if (gamestate().board_.side_units(current_side()) == 0 && !(gamestate().board_.units().size() == 0 && current_side() == 1)) {
372  }
373 
375  if (end_turn_ == END_TURN_NONE) {
376  play_human_turn();
377  }
380  }
381  LOG_NG << "human finished turn...\n";
382 
383  } else if(current_team().is_local_ai() || (current_team().is_local_human() && current_team().is_droid())) {
384  play_ai_turn();
385  } else if(current_team().is_network()) {
387  } else if(current_team().is_local_human() && current_team().is_idle()) {
388  end_turn_enable(false);
391  if (end_turn_ == END_TURN_NONE) {
392  play_idle_loop();
393  }
394  }
395  else {
396  // we should have skipped over empty controllers before so this shouldn't be possible
397  ERR_NG << "Found invalid side controller " << current_team().controller().to_string() << " (" << current_team().proxy_controller().to_string() << ") for side " << current_team().side() << "\n";
398  }
399 }
400 
402 {
403  log_scope("player turn");
404  assert(!linger_);
406  return;
407  }
408 
409  if(init_side_done_now_) {
410  scoped_savegame_snapshot snapshot(*this);
413  }
414 
415  if(preferences::turn_bell()) {
417  }
418 }
419 
422  blindfold b(*gui_, true); //apply a blindfold for the duration of this dialog
423  gui_->redraw_everything();
424  gui_->recalculate_minimap();
425  std::string message = _("It is now $name|’s turn");
426  utils::string_map symbols;
427  symbols["name"] = gamestate().board_.teams()[current_side() - 1].side_name();
428  message = utils::interpolate_variables_into_string(message, &symbols);
430  }
431 }
432 
434 {
436  {
437  return;
438  }
439  try
440  {
442  }
443  catch (const return_to_play_side_exception&)
444  {
445  }
446 }
447 
450 
452  execute_gotos();
453  }
454 
455  end_turn_enable(true);
456  while(!should_return_to_play_side()) {
459  gui_->draw();
460  }
461 
462 }
463 
465 {
466  LOG_NG << "beginning end-of-scenario linger\n";
467  linger_ = true;
468 
469  // If we need to set the status depending on the completion state
470  // the key to it is here.
471  gui_->set_game_mode(game_display::LINGER);
472 
473  // change the end-turn button text to its alternate label
474  gui_->get_theme().refresh_title2("button-endturn", "title2");
475  gui_->invalidate_theme();
476  gui_->redraw_everything();
477 
478  // End all unit moves
480  try {
481  // Same logic as single-player human turn, but
482  // *not* the same as multiplayer human turn.
483  end_turn_enable(true);
485  while(end_turn_ == END_TURN_NONE) {
486  play_slice();
487  gui_->draw();
488  }
489  } catch(const game::load_game_exception &) {
490  // Loading a new game is effectively a quit.
491  if ( game::load_game_exception::game != "" ) {
493  }
494  throw;
495  }
496 
497  // revert the end-turn button text to its normal label
498  gui_->get_theme().refresh_title2("button-endturn", "title");
499  gui_->invalidate_theme();
500  gui_->redraw_everything();
501  gui_->set_game_mode(game_display::RUNNING);
502 
503  LOG_NG << "ending end-of-scenario linger\n";
504 }
505 
507 {
508  gui_->enable_menu("endturn", enable);
510 }
511 
512 
514 {
515  // Clear moves from the GUI.
516  gui_->set_route(nullptr);
517  gui_->unhighlight_reach();
518 }
519 
521 {
522  LOG_NG << "is ai...\n";
523 
524  end_turn_enable(false);
525  gui_->recalculate_minimap();
526 
528 
529  // Correct an oddball case where a human could have left delayed shroud
530  // updates on before giving control to the AI. (The AI does not bother
531  // with the undo stack, so it cannot delay shroud updates.)
532  team & cur_team = current_team();
533  if ( !cur_team.auto_shroud_updates() ) {
534  // We just took control, so the undo stack is empty. We still need
535  // to record this change for the replay though.
537  }
538  undo_stack().clear();
539 
541  try {
542  try {
545  }
546  }
547  catch (return_to_play_side_exception&) {
548  }
551  player_type_changed_ = true;
552  }
553  }
554  catch(...) {
556  throw;
557  }
560  }
562  gui_->recalculate_minimap();
563  gui_->invalidate_unit();
564  gui_->invalidate_game_status();
565  gui_->invalidate_all();
566  gui_->draw();
567 }
568 
569 
570 /**
571  * Will handle sending a networked notification in descendent classes.
572  */
574 {
575  gui_->get_chat_manager().add_chat_message(time(nullptr), "Wesnoth", 0,
576  "This side is in an idle state. To proceed with the game, the host must assign it to another controller.",
578 }
579 
580 /**
581  * Will handle networked turns in descendent classes.
582  */
584 {
585  // There should be no networked sides in single-player.
586  ERR_NG << "Networked team encountered by playsingle_controller." << std::endl;
587 }
588 
589 
591  if (name == "ai_user_interact"){
592  play_slice(false);
593  }
594 }
595 
596 
597 
599  if (linger_)
601  else if (!is_browsing() && menu_handler_.end_turn(current_side())){
603  }
604 }
605 
607  skip_next_turn_ = true;
609 }
610 
612 {
613  const team &t = gamestate().board_.teams()[gui_->viewing_team()];
614 
615  if (!is_regular_game_end() && !is_browsing() && t.objectives_changed()) {
618  }
619 }
620 
621 
623 {
624  // mouse_handler expects at least one team for linger mode to work.
625  assert(is_regular_game_end());
626  if (get_end_level_data_const().transient.linger_mode && !gamestate().board_.teams().empty()) {
627  linger();
628  }
629 }
630 
632 {
633  //We cannot add [end_turn] to the recorder while executing another action.
635  if(end_turn_ == END_TURN_REQUIRED && current_team().is_local())
636  {
637  //TODO: we shodul also send this immideateley.
640  }
641 
642  assert(end_turn_ == END_TURN_SYNCED);
643  skip_next_turn_ = false;
644 }
645 
647 {
648  if(replay_ && replay_->is_controlling_view()) {
649  replay_->update_viewing_player();
650  }
651  //Update viewing team in case it has changed during the loop.
652  else if(int side_num = play_controller::find_last_visible_team()) {
653  if(side_num != this->gui_->viewing_side()) {
654  update_gui_to_player(side_num - 1);
655  }
656  }
657 }
658 
660 {
661  if(replay_ && replay_->allow_reset_replay()) {
662  replay_->stop_replay();
663  throw reset_gamestate_exception(replay_->get_reset_state(), false);
664  }
665  else {
666  ERR_NG << "recieved invalid reset replay\n";
667  }
668 }
669 
671 {
672  replay_.reset(new replay_controller(*this, gamestate().has_human_sides(), boost::shared_ptr<config>( new config(saved_game_.replay_start())), std::bind(&playsingle_controller::on_replay_end, this, is_unit_test)));
673  if(is_unit_test) {
674  replay_->play_replay();
675  }
676 }
677 
679 {
681  return true;
682  }
683  else if (end_turn_ == END_TURN_NONE || replay_.get() != 0 || current_team().is_network()) {
684  return false;
685  }
686  else {
687  return true;
688  }
689 }
690 
692 {
693  if(is_unit_test) {
694  replay_->return_to_play_side();
695  if(!is_regular_game_end()) {
697  e.proceed_to_next_level = false;
698  e.is_victory = false;
700  }
701  }
702 }
bool disable_auto_moves()
void clear()
Clears the stack of undoable (and redoable) actions.
Definition: undo.cpp:226
void set_all_units_user_end_turn()
Definition: game_board.cpp:85
static void add_observer(events::observer *event_observer)
Adds observer of game events.
Definition: manager.cpp:355
An error occured during when trying to coommunicate with the wesnothd server.
bool is_network() const
Definition: team.hpp:262
child_itors child_range(const std::string &key)
Definition: config.cpp:613
GLboolean enable
Definition: glew.h:2589
bool turn_bell()
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
virtual const unit_map & units() const
Definition: game_board.hpp:99
int ticks() const
static bool run_and_store(const std::string &commandname, const config &data, bool use_undo=true, bool show=true, synced_command::error_handler_function error_handler=default_error_function)
size_t size() const
Definition: map.hpp:314
std::string interpolate_variables_into_string(const std::string &str, const string_map *const symbols)
Function which will interpolate variables, starting with '$' in the string 'str' with the equivalent ...
static std::string game
Definition: game_errors.hpp:89
const end_level_data & get_end_level_data_const() const
void heal_all_survivors()
Definition: game_board.cpp:91
void end_turn()
Definition: replay.cpp:298
GLint level
Definition: glew.h:1220
events::mouse_handler mouse_handler_
virtual void handle_generic_event(const std::string &name)
config & replay_start()
Definition: saved_game.hpp:104
Definition: video.hpp:58
Class for autosaves.
Definition: savegame.hpp:219
const int INFINITE_AUTO_SAVES
bool save_game_interactive(CVideo &video, const std::string &message, gui::DIALOG_TYPE dialog_type)
Save a game interactively through the savegame dialog.
Definition: savegame.cpp:366
const t_string & objectives() const
Definition: team.hpp:244
PROXY_CONTROLLER proxy_controller() const
Definition: team.hpp:282
PROCESS_DATA_RESULT sync_network()
Definition: playturn.cpp:64
static lg::log_domain log_aitesting("aitesting")
virtual bool recieve_from_wesnothd(config &) const
bool objectives_changed() const
Definition: team.hpp:245
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
Gather statistics important for AI testing and output them.
And endturn was required eigher by the player, by the ai or by [end_turn].
void enable_replay(bool is_unit_test=false)
bool fire(const std::string &event, const entity_location &loc1=entity_location::null_entity, const entity_location &loc2=entity_location::null_entity, const config &data=config())
Function to fire an event.
Definition: pump.cpp:471
void play_slice(bool is_delay_enabled=true)
virtual const std::vector< team > & teams() const
Definition: game_board.hpp:97
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.
Class for "normal" midgame saves.
Definition: savegame.hpp:188
boost::scoped_ptr< soundsource::manager > soundsources_manager_
config & set_snapshot(config snapshot)
Definition: saved_game.cpp:451
void play_music_once(const std::string &file)
Definition: sound.cpp:472
bool is_skipping_replay() const
static void log_game_end()
Definition: testing.cpp:103
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
bool exit_at_end
Definition: game_config.cpp:63
bool empty() const
Definition: config.cpp:1105
GLdouble GLdouble t
Definition: glew.h:1366
no linger overlay, show fog and shroud.
persist_manager persist_
const std::string & select_victory_music() const
void send_data()
Definition: playturn.cpp:83
An extension of play_controller::hotkey_handler, which has support for SP wesnoth features like white...
events::menu_handler menu_handler_
virtual void do_idle_notification()
Will handle sending a networked notification in descendent classes.
boost::shared_ptr< config > level
void make_human()
Definition: team.hpp:273
REPLAY_RETURN
Definition: replay.hpp:155
GLdouble GLdouble GLdouble b
Definition: glew.h:6966
-file pathfind.hpp
std::string turn_bell
saved_game & saved_game_
static void clear_ais()
Clears all the AIs.
Definition: manager.cpp:705
game_events::t_pump & pump()
void end_turn_enable(bool enable)
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:50
bool end_turn(int side_num)
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
std::map< std::string, t_string > string_map
bool auto_shroud_updates() const
Definition: team.hpp:335
int current_side() const
Returns the number of the side whose turn it is.
void draw_solid_tinted_rectangle(int x, int y, int w, int h, int r, int g, int b, double alpha, surface target)
Fills a specified rectangle area of a surface with a given color and opacity.
Definition: rect.cpp:117
void show_story(CVideo &video, const std::string &scenario_name, const config::const_child_itors &story)
Shows an introduction sequence using story WML.
Definition: interface.cpp:37
bool is_regular_game_end() const
bool disable_autosave
Definition: game_config.cpp:64
static void set_ai_info(const game_info &info)
Sets AI information.
Definition: manager.cpp:339
size_t turn() const
t_string get_scenario_name()
void play_music_config(const config &music_node)
Definition: sound.cpp:552
playsingle_controller(const config &level, saved_game &state_of_game, const config &game_config, const tdata_cache &tdata, CVideo &video, bool skip_replay)
virtual void init_gui()
Managing the AIs lifecycle - headers.
#define LOG_NG
replay * recorder
Definition: resources.cpp:30
static void play_turn(side_number side)
Plays a turn for the specified side using its active AI.
Definition: manager.cpp:781
static lg::log_domain log_enginerefac("enginerefac")
bool is_observer() const
void reset_objectives_changed() const
Definition: team.hpp:242
virtual void play_network_turn()
Will handle networked turns in descendent classes.
static void log_game_start()
Definition: testing.cpp:90
Templates and utility-routines for strings and numbers.
LEVEL_RESULT play_scenario(const config &level)
bool is_browsing() const override
void raise_draw_event()
Definition: events.cpp:565
hotkey::command_executor * get_hotkey_command_executor()
Get (optionally) a command executor to handle context menu events.
void update_gui_to_player(const int team_index, const bool observe=false)
Changes the UI for this client to the passed side index.
std::string describe_result() const
void on_replay_end(bool is_unit_test)
Sound source info class.
void set_end_level_data(const end_level_data &data)
GLuint res
Definition: glew.h:9258
transient_end_level transient
void execute_gotos(mouse_handler &mousehandler, int side_num)
Game information for the AI.
#define ERR_NG
Game configuration data as global variables.
Definition: build_info.cpp:38
Exception used to signal that the user has decided to abort a game, and to load another game instead...
Definition: game_errors.hpp:62
void reset_gamestate(const config &level, int replay_pos)
Define the game's event mechanism.
#define log_scope(description)
Definition: log.hpp:185
size_t i
Definition: function.cpp:1057
bool proceed_to_next_level
whether to proceed to the next scenario, equals is_victory in sp.
Additional information on the game outcome which can be provided by WML.
actions::undo_list & undo_stack()
int side() const
Definition: team.hpp:193
void set_defeat_music_list(const std::string &list)
static void save(LexState *ls, int c)
Definition: llex.cpp:51
GLuint const GLchar * name
Definition: glew.h:1782
CONTROLLER controller() const
Definition: team.hpp:256
compression::format save_compression_format()
boost::scoped_ptr< game_state > gamestate_
void play_bell(const std::string &files)
Definition: sound.cpp:826
static void remove_observer(events::observer *event_observer)
Removes an observer of game events.
Definition: manager.cpp:363
Storyscreen controller (wrapper interface).
boost::scoped_ptr< replay_controller > replay_
const GLdouble * m
Definition: glew.h:6968
game_state & gamestate()
game_classification & classification()
Definition: saved_game.hpp:54
game_board board_
Definition: game_state.hpp:49
config to_config() const
Builds the snapshot config from members and their respective configs.
Various functions that implement the undoing (and redoing) of in-game commands.
const cursor::setter cursor_setter
Standard logging facilities (interface).
void autosave(const bool disable_autosave, const int autosave_max, const int infinite_autosaves)
Definition: savegame.cpp:586
GLsizei GLenum GLuint GLuint GLsizei char * message
Definition: glew.h:2499
void set_victory_music_list(const std::string &list)
boost::scoped_ptr< game_display > gui_
#define e
const std::string & select_defeat_music() const
void commit_music_changes()
Definition: sound.cpp:621
virtual bool is_networked_mp() const
void remove_snapshot()
Definition: saved_game.cpp:466
std::string custom_endlevel_music
Custom short music played at the end.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
virtual bool should_return_to_play_side()
static lg::log_domain log_engine("engine")
GLdouble s
Definition: glew.h:1358
void update_rect(const SDL_Rect &)
Definition: dummy_video.cpp:27
Thrown when a lexical_cast fails.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
void show_objectives(const std::string &scenarioname, const std::string &objectives)
Definition: dialogs.cpp:425
int find_last_visible_team() const
returns 0 if no such team was found.
An [end_turn] was added to the replay.
bool init_side_done_now_
Whether we did init sides in this session (false = we did init sides before we reloaded the game)...