The Battle for Wesnoth  1.17.0-dev
play_controller.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2006 - 2021
3  by Joerg Hinrichs <joerg.hinrichs@alice-dsl.de>
4  Copyright (C) 2003 by David White <dave@whitevine.net>
5  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY.
13 
14  See the COPYING file for more details.
15 */
16 
17 #pragma once
18 
19 #include "controller_base.hpp"
20 #include "game_end_exceptions.hpp"
21 #include "help/help.hpp"
23 #include "menu_events.hpp"
24 #include "mouse_events.hpp"
25 #include "persist_manager.hpp"
26 #include "tod_manager.hpp"
27 #include "game_state.hpp"
28 #include <optional>
29 
30 #include <set>
31 
32 class game_display;
33 class game_data;
34 class team;
35 class unit;
36 class replay;
37 class replay_controller;
38 class saved_game;
39 struct mp_game_settings;
42 
43 namespace actions {
44  class undo_list;
45 }
46 
47 namespace font {
48  struct floating_label_context;
49 }
50 
51 namespace game_events {
52  class manager;
53  class wml_event_pump;
54  class wml_menu_item;
55 } // namespace game_events
56 
57 namespace soundsource {
58  class manager;
59 } // namespace soundsource
60 
61 namespace statistics {
62  struct scenario_context;
63 } // namespace statistics
64 
65 namespace pathfind {
66  class manager;
67 }
68 
69 namespace tooltips {
70  struct manager;
71 } // namespace tooltips
72 
73 namespace wb {
74  class manager; // whiteboard manager
75 } // namespace wb
76 
77 // Holds gamestate related objects
78 class game_state;
79 
81 {
82 public:
83  play_controller(const config& level, saved_game& state_of_game, bool skip_replay);
84  virtual ~play_controller();
85 
86  //event handler, overridden from observer
87  //there is nothing to handle in this class actually but that might change in the future
88  virtual void handle_generic_event(const std::string& /*name*/) override {}
89 
90  bool can_undo() const;
91  bool can_redo() const;
92 
93  void undo();
94  void redo();
95 
96  void load_game();
97 
98  void save_game();
99  void save_game_auto(const std::string& filename);
100  void save_replay();
101  void save_replay_auto(const std::string& filename);
102  void save_map();
103  replay& get_replay();
104 
105  void init_side_begin();
106 
107  /**
108  * Called by turn_info::process_network_data() or init_side() to call do_init_side() if necessary.
109  */
110  void maybe_do_init_side();
111 
112  /**
113  * Called by replay handler or init_side() to do actual work for turn change.
114  */
115  void do_init_side();
116 
117  void init_side_end();
118 
119  virtual void force_end_turn() = 0;
120  virtual void check_objectives() = 0;
121 
122  virtual void on_not_observer() = 0;
123 
124  /**
125  * Asks the user whether to continue on an OOS error.
126  *
127  * @throw quit_game_exception If the user wants to abort.
128  */
129  virtual void process_oos(const std::string& msg) const;
130 
132  {
133  gamestate().end_level_data_ = data;
134  }
135 
137  {
138  gamestate().end_level_data_.reset();
139  }
140 
141  bool is_regular_game_end() const
142  {
143  return gamestate().end_level_data_.has_value();
144  }
145 
147  {
148  return *gamestate().end_level_data_;
149  }
150 
151  std::vector<team>& get_teams()
152  {
153  return gamestate().board_.teams();
154  }
155 
156  const std::vector<team>& get_teams() const
157  {
158  return gamestate().board_.teams();
159  }
160 
161  const unit_map& get_units() const
162  {
163  return gamestate().board_.units();
164  }
165 
167  {
168  return gamestate().board_.units();
169  }
170 
171  const gamemap& get_map() const
172  {
173  return gamestate().board_.map();
174  }
175 
177  {
178  return gamestate().tod_manager_;
179  }
180 
181  bool is_observer() const
182  {
183  return gamestate().board_.is_observer();
184  }
185 
186  bool do_healing() const
187  {
188  return gamestate().do_healing_;
189  }
190 
191  void set_do_healing(bool do_healing)
192  {
193  gamestate().do_healing_ = do_healing;
194  }
195 
197  {
198  return *gamestate_;
199  }
200 
201  const game_state& gamestate() const
202  {
203  return *gamestate_;
204  }
205 
206  /**
207  * Checks to see if a side has won.
208  *
209  * This will also remove control of villages from sides with dead leaders.
210  */
211  void check_victory();
212 
213  std::size_t turn() const {return gamestate().tod_manager_.turn();}
214 
215  /**
216  * Returns the number of the side whose turn it is.
217  *
218  * Numbering starts at one.
219  */
220  int current_side() const { return gamestate_->player_number_; }
221 
222  /**
223  * Builds the snapshot config from members and their respective configs.
224  */
225  config to_config() const;
226 
227  bool is_skipping_replay() const { return skip_replay_; }
228  void toggle_skipping_replay();
229  bool is_linger_mode() const { return linger_; }
230  void do_autosave();
231 
232  bool is_skipping_story() const { return skip_story_; }
233 
234  void do_consolesave(const std::string& filename);
235 
236  events::mouse_handler& get_mouse_handler_base() override;
237  events::menu_handler& get_menu_handler() { return menu_handler_; }
238 
239  std::shared_ptr<wb::manager> get_whiteboard() const;
240  const mp_game_settings& get_mp_settings();
241  game_classification& get_classification();
242  int get_server_request_number() const { return gamestate().server_request_number_; }
243  void increase_server_request_number() { ++gamestate().server_request_number_; }
244 
246 
247  int get_ticks() const;
248 
249  virtual soundsource::manager* get_soundsource_man() override;
250  virtual plugins_context* get_plugins_context() override;
251  hotkey::command_executor* get_hotkey_command_executor() override;
252 
254 
255  bool is_browsing() const override;
256  bool is_lingering() const { return linger_; }
257 
258  class hotkey_handler;
259 
260  virtual replay_controller * get_replay_controller() const { return nullptr; }
261  bool is_replay() const { return get_replay_controller() != nullptr; }
262 
264  {
265  return level_["name"].t_str();
266  }
267 
268  bool get_disallow_recall() const
269  {
270  return level_["disallow_recall"].to_bool();
271  }
272 
273  std::string get_loaded_resources() const
274  {
275  return level_["loaded_resources"].str();
276  }
277 
278  std::string theme() const
279  {
280  return gamestate_->get_game_data()->get_theme();
281  }
282 
283  virtual bool should_return_to_play_side() const
284  {
285  return is_regular_game_end();
286  }
287 
289  {
290  if(should_return_to_play_side() && !linger_ ) {
292  }
293  }
294 
295  virtual void play_side_impl() {}
296 
297  void play_side();
298 
299  team& current_team();
300  const team& current_team() const;
301 
302  bool can_use_synced_wml_menu() const;
303  std::set<std::string> all_players() const;
304  int ticks() const { return ticks_; }
305  game_display& get_display() override;
306 
307  void update_savegame_snapshot() const;
308  /**
309  * Changes the UI for this client to the passed side index.
310  */
311  void update_gui_to_player(const int team_index, const bool observe = false);
312 
313  virtual bool is_networked_mp() const { return false; }
314  virtual void send_to_wesnothd(const config&, const std::string& = "unknown") const { }
315  virtual bool receive_from_wesnothd(config&) const { return false; }
316  /** Reevaluate [show_if] conditions and build a new objectives string. */
317  void refresh_objectives() const;
318  void show_objectives() const;
319 
321  {
325  };
326 
327  saved_game& get_saved_game() { return saved_game_; }
328 
329 protected:
331  void play_slice_catch();
332  bool have_keyboard_focus() override;
333  void process_focus_keydown_event(const SDL_Event& event) override;
334  void process_keydown_event(const SDL_Event& event) override;
335  void process_keyup_event(const SDL_Event& event) override;
336 
337  void init_managers();
338  /** preload events cannot be synced */
339  void fire_preload();
340  void fire_prestart();
341  void fire_start();
342  void start_game();
343  virtual void init_gui();
344  void finish_side_turn();
345  void finish_turn(); //this should not throw an end turn or end level exception
346  bool enemies_visible() const;
347 
348  void enter_textbox();
349  void textbox_move_vertically(bool up);
350  void tab();
351 
352 
353  bool is_team_visible(int team_num, bool observer) const;
354  /** returns 0 if no such team was found. */
355  int find_last_visible_team() const;
356 
357 private:
358  const int ticks_;
359 
360 protected:
361  //gamestate
362  std::unique_ptr<game_state> gamestate_;
365 
366  //managers
367  std::unique_ptr<tooltips::manager> tooltips_manager_;
368 
369  //whiteboard manager
370  std::shared_ptr<wb::manager> whiteboard_manager_;
371 
372  //plugins context
373  std::unique_ptr<plugins_context> plugins_context_;
374 
375  //more managers
376  std::unique_ptr<font::floating_label_context> labels_manager_;
380  std::unique_ptr<hotkey_handler> hotkey_handler_;
381  std::unique_ptr<soundsource::manager> soundsources_manager_;
383 
384  //other objects
385  std::unique_ptr<game_display> gui_;
386  const std::unique_ptr<unit_experience_accelerator> xp_mod_;
387  const std::unique_ptr<const statistics::scenario_context> statistics_context_;
388  actions::undo_list& undo_stack() { return *gamestate().undo_stack_; }
389  const actions::undo_list& undo_stack() const { return *gamestate().undo_stack_; }
390  std::unique_ptr<replay> replay_;
391 
394  bool linger_;
395  /**
396  * Whether we did init sides in this session
397  * (false = we did init sides before we reloaded the game).
398  */
400  //the displayed location when we load a game.
402  const std::string& select_music(bool victory) const;
403 
404  void reset_gamestate(const config& level, int replay_pos);
405 
406 private:
407 
408  void init(const config& level);
409 
410  /**
411  * This shows a warning dialog if either [scenario]next_scenario or any [endlevel]next_scenario would lead to an "Unknown Scenario" dialog.
412  */
413  void check_next_scenario_is_known();
414 
417  std::vector<std::string> victory_music_;
418  std::vector<std::string> defeat_music_;
419 
421 
422 protected:
423  mutable bool ignore_replay_errors_;
425  virtual void sync_end_turn() {}
426  virtual void check_time_over();
427  virtual void update_viewing_player() = 0;
428  void play_turn();
429 };
virtual replay_controller * get_replay_controller() const
virtual bool should_return_to_play_side() const
std::unique_ptr< soundsource::manager > soundsources_manager_
help::help_manager help_manager_
saved_game & get_saved_game()
This class represents a single unit of a specific type.
Definition: unit.hpp:121
std::unique_ptr< game_display > gui_
bool victory_when_enemies_defeated_
const unit_map & get_units() const
Collection of helper functions relating to Pango formatting.
events::mouse_handler mouse_handler_
std::unique_ptr< plugins_context > plugins_context_
bool is_skipping_replay() const
std::unique_ptr< replay > replay_
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
std::unique_ptr< hotkey_handler > hotkey_handler_
void set_do_healing(bool do_healing)
const gamemap & get_map() const
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
bool do_healing() const
Contains the exception interfaces used to signal completion of a scenario, campaign or turn...
controller_base framework: controller_base is roughly analogous to a "dialog" class in a GUI toolkit ...
persist_manager persist_
std::unique_ptr< tooltips::manager > tooltips_manager_
events::menu_handler menu_handler_
bool get_disallow_recall() const
int get_server_request_number() const
std::unique_ptr< game_state > gamestate_
bool is_lingering() const
saved_game & saved_game_
std::vector< std::string > defeat_music_
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:72
struct utils::detail::formula_initer init
const std::unique_ptr< const statistics::scenario_context > statistics_context_
bool is_linger_mode() const
Implements a quit confirmation dialog.
bool is_regular_game_end() const
Encapsulates the map of the game.
Definition: map.hpp:171
std::vector< team > & get_teams()
std::string theme() const
void pump()
Definition: events.cpp:473
bool is_observer() const
Encapsulates the map of the game.
Definition: location.hpp:38
Domain specific events.
Definition: action_wml.cpp:87
actions::undo_list & get_undo_stack()
void set_end_level_data(const end_level_data &data)
tooltips.
virtual bool is_networked_mp() const
map_location map_start_
const actions::undo_list & undo_stack() const
hotkey::scope_changer scope_
std::shared_ptr< wb::manager > whiteboard_manager_
The help implementation caches data parsed from the game_config.
Definition: help.hpp:41
t_string get_scenario_name() const
Additional information on the game outcome which can be provided by WML.
std::unique_ptr< font::floating_label_context > labels_manager_
actions::undo_list & undo_stack()
const end_level_data & get_end_level_data() const
virtual void handle_generic_event(const std::string &) override
std::string observer
virtual bool receive_from_wesnothd(config &) const
bool is_replay() const
Class to store the actions that a player can undo and redo.
Definition: undo.hpp:34
void maybe_throw_return_to_play_side() const
game_state & gamestate()
const std::unique_ptr< unit_experience_accelerator > xp_mod_
const tod_manager & get_tod_manager() const
events::menu_handler & get_menu_handler()
int current_side() const
Returns the number of the side whose turn it is.
bool is_skipping_story() const
const game_state & gamestate() const
Container associating units to locations.
Definition: map.hpp:98
std::string get_loaded_resources() const
std::vector< std::string > victory_music_
actions::undo_list * undo_stack
Definition: resources.cpp:33
std::size_t turn() const
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
const std::vector< team > & get_teams() const
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
Definition: display.hpp:49
virtual void play_side_impl()
bool init_side_done_now_
Whether we did init sides in this session (false = we did init sides before we reloaded the game)...
bool remove_from_carryover_on_defeat_
void increase_server_request_number()
unit_map & get_units()
virtual void sync_end_turn()