55 #define LOG_AIT LOG_STREAM(info, log_aitesting)
59 #define ERR_NG LOG_STREAM(err, log_engine)
60 #define LOG_NG LOG_STREAM(info, log_engine)
61 #define DBG_NG LOG_STREAM(debug, log_engine)
64 #define LOG_RG LOG_STREAM(info, log_enginerefac)
69 , end_turn_requested_(false)
71 , replay_controller_()
117 if(scroll_team == 0) {
124 LOG_NG <<
"Found bad stored ui location " <<
map_start_ <<
" using side starting location " <<
loc;
126 LOG_NG <<
"Found bad stored ui location";
131 gui_->set_prevent_draw(
false);
132 gui_->queue_repaint();
134 gui_->fade_to({0,0,0,0}, std::chrono::milliseconds{500});
136 gui_->set_fade({0,0,0,0});
149 for(
const config&
s :
level.child_range(
"sound_source")) {
154 ERR_NG <<
"Error when parsing sound_source config: bad lexical cast.";
155 ERR_NG <<
"sound_source config was: " <<
s.debug();
156 ERR_NG <<
"Skipping this sound source...";
183 _(
"This multiplayer game uses an alternative random mode, if you don’t know what this message means, then "
184 "most likely someone is cheating or someone reloaded a corrupt game."));
190 const int sides =
static_cast<int>(
get_teams().size());
191 const int max = side_num + sides;
193 for (; side_num != max; ++side_num) {
194 int side_num_mod =
modulo(side_num, sides, 1);
195 if(!
gamestate().board_.get_team(side_num_mod).is_empty()) {
196 return { side_num_mod, side_num_mod != side_num };
199 return { side_num,
true };
268 int next_player_number_temp =
gamestate_->next_player_number_;
276 auto [next_player_number, new_turn] =
skip_empty_sides(next_player_number_temp);
291 gamestate_->player_number_ = next_player_number;
300 gui_->invalidate_game_status();
318 boost::dynamic_bitset<> local_players;
321 for(std::size_t
i = 0;
i < local_players.size(); ++
i) {
335 for(std::size_t
i = 0;
i < local_players.size(); ++
i) {
344 replay_controller_ = std::make_unique<replay_controller>(*
this,
false, ex.
level, [
this]() { on_replay_end(false); });
371 pump().
fire(is_victory ?
"local_victory" :
"local_defeat");
391 "type",
"termination",
392 "condition",
"game over",
393 "result", is_victory ? level_result::victory : level_result::defeat,
405 const std::string& end_music =
select_music(is_victory);
416 LOG_NG <<
"in playsingle_controller::play_scenario()...";
419 for(
const config& m :
level.child_range(
"music")) {
429 for(
const auto& iter :
level.child_range(
"story")) {
449 return level_result::type::observer_end;
459 if(
e.message ==
"") {
461 _(
"A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"),
465 _(
"This game has been ended.\nReason: ") +
e.message +
_(
"\nDo you want to save the game?"),
470 return level_result::type::quit;
481 using namespace std::chrono_literals;
482 std::this_thread::sleep_for(10ms);
512 LOG_NG <<
"human finished turn...";
556 gui_->queue_rerender();
557 std::string message =
_(
"It is now $name|’s turn");
600 gui_->get_theme().refresh_title2(
"button-endturn",
"title2");
610 gui_->get_theme().refresh_title2(
"button-endturn",
"title");
613 gui_->queue_rerender();
618 LOG_NG <<
"beginning end-of-scenario linger";
635 LOG_NG <<
"ending end-of-scenario linger";
649 gui_->set_route(
nullptr);
650 gui_->unhighlight_reach();
699 gui_->get_chat_manager().add_chat_message(std::time(
nullptr),
"Wesnoth", 0,
700 "This side is in an idle state. To proceed with the game, the host must assign it to another controller.",
710 ERR_NG <<
"Networked team encountered by playsingle_controller.";
715 if(name ==
"ai_user_interact") {
787 return !
t.get_disallow_observers() && !
t.is_empty();
789 return t.is_local_human() && !
t.is_idle();
795 const int num_teams =
get_teams().size();
798 for(
int i = 0;
i < num_teams;
i++) {
813 if(side_num !=
gui_->viewing_team().side() ||
gui_->show_everything()) {
825 ERR_NG <<
"received invalid reset replay";
863 }
else if(is_unit_test) {
867 e.proceed_to_next_level =
false;
868 e.is_victory =
false;
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
void clear()
Clears the stack of undoable (and redoable) actions.
static manager & get_singleton()
void play_turn(side_number side)
Plays a turn for the specified side using its active AI.
static void log_game_end()
static void log_game_start()
A config object defines a single node in a WML file, with access to child nodes.
void append_children(const config &cfg)
Adds children from cfg.
virtual void play_slice()
void execute_gotos(mouse_handler &mousehandler, int side_num)
bool end_turn(int side_num)
virtual const std::vector< team > & teams() const override
void heal_all_survivors()
void set_all_units_user_end_turn()
void set_end_turn_forced(bool v)
void set_phase(PHASE phase)
@ GAME_ENDED
The game has ended and the user is observing the final state "lingering" The game can be saved here.
@ TURN_PLAYING
The User is controlling the game and invoking actions The game can be saved here.
@ TURN_ENDED
The turn_end, side_turn_end etc [events] are fired next phase: TURN_STARTING_WAITING (default),...
@ TURN_STARTING_WAITING
we are waiting for the turn to start.
@ GAME_ENDING
The victory etc.
static PHASE read_phase(const config &cfg)
bool end_turn_forced() const
@ RUNNING
no linger overlay, show fog and shroud.
pump_result_t 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.
static void display(const std::string &scenario_name, const config &story)
virtual void set_button_state()
const std::string & select_music(bool victory) const
config to_config() const
Builds the snapshot config from members and their respective configs.
std::vector< team > & get_teams()
std::unique_ptr< hotkey_handler > hotkey_handler_
std::unique_ptr< game_state > gamestate_
void show_objectives() const
events::menu_handler menu_handler_
void fire_preload()
preload events cannot be synced
bool is_linger_mode() const
actions::undo_list & undo_stack()
const unit_map & get_units() const
void set_end_level_data(const end_level_data &data)
void reset_gamestate(const config &level, int replay_pos)
bool is_skipping_story() const
bool is_regular_game_end() const
saved_game & get_saved_game()
hotkey::command_executor * get_hotkey_command_executor() override
Optionally get a command executor to handle context menu events.
std::unique_ptr< game_display > gui_
void maybe_do_init_side()
Called by turn_info::process_network_data() or init_side() to call do_init_side() if necessary.
bool is_browsing() const override
virtual void send_to_wesnothd(const config &, const std::string &="unknown") const
std::unique_ptr< soundsource::manager > soundsources_manager_
const end_level_data & get_end_level_data() const
int current_side() const
Returns the number of the side whose turn it is.
virtual bool is_networked_mp() const
bool is_skipping_replay() const
bool did_tod_sound_this_turn_
const gamemap & get_map() const
bool did_autosave_this_turn_
Whether we did init sides in this session (false = we did init sides before we reloaded the game).
bool player_type_changed_
true when the controller of the currently playing side has changed.
void update_gui_to_player(const int team_index, const bool observe=false)
Changes the UI for this client to the passed side index.
events::mouse_handler mouse_handler_
const auto & timer() const
std::unique_ptr< plugins_context > plugins_context_
game_events::wml_event_pump & pump()
void finish_side_turn_events()
std::shared_ptr< wb::manager > whiteboard_manager_
virtual void check_time_over()
t_string get_scenario_name() const
virtual void play_human_turn()
void end_turn_enable(bool enable)
virtual void play_network_turn()
Will handle networked turns in descendent classes.
void set_player_type_changed()
virtual void init_gui() override
void on_replay_end(bool is_unit_test)
std::string describe_result() const
std::unique_ptr< replay_controller > replay_controller_
non-null when replay mode in active, is used in singleplayer and for the "back to turn" feature in mu...
bool ai_fallback_
true when the current side is actually an ai side but was taken over by a human (usually for debuggin...
void sync_end_turn() override
virtual void check_objectives() override
ses_result skip_empty_sides(int side_num)
Calculates the current side, starting at side_num that is non-empty.
bool is_team_visible(int team_num, bool observer) const
void force_end_turn() override
level_result::type play_scenario(const config &level)
virtual bool should_return_to_play_side() const override
~playsingle_controller()
Defined here to reduce file includes.
void update_viewing_player() override
playsingle_controller(const config &level, saved_game &state_of_game)
virtual void handle_generic_event(const std::string &name) override
virtual void do_idle_notification()
Will handle sending a networked notification in descendent classes.
bool end_turn_requested_
true iff the user has pressed the end turn button this turn.
void play_scenario_main_loop()
int find_viewing_side() const override
returns 0 if no such team was found.
virtual void play_idle_loop()
void play_scenario_init(const config &level)
virtual void after_human_turn()
void enable_replay(bool is_unit_test=false)
virtual void maybe_linger()
static config get_auto_shroud(bool turned_on)
Records that the player has toggled automatic shroud updates.
void end_turn(int next_player_number)
Exception used to escape form the ai or ui code to playsingle_controller::play_side.
game_classification & classification()
const config & get_replay_starting_point()
statistics_record::campaign_stats_t & statistics()
void autosave(const bool disable_autosave, const int autosave_max, const int infinite_autosaves)
Class for "normal" midgame saves.
Exception used to signal that the user has decided to abortt a game, and to load another game instead...
bool save_game_interactive(const std::string &message, DIALOG_TYPE dialog_type)
Save a game interactively through the savegame dialog.
static bool run_and_store(const std::string &commandname, const config &data, action_spectator &spectator=get_default_spectator())
This class stores all the data for a single 'side' (in game nomenclature).
const std::string & side_name() const
bool auto_shroud_updates() const
Contains the exception interfaces used to signal completion of a scenario, campaign or turn.
static std::string _(const char *str)
An extension of play_controller::hotkey_handler, which has support for SP wesnoth features like white...
Standard logging facilities (interface).
#define log_scope(description)
constexpr T modulo(T num, int mod, T min=0)
void show_transient_message(const std::string &title, const std::string &message, const std::string &image, const bool message_use_markup, const bool title_use_markup)
Shows a transient message to the user.
const int INFINITE_AUTO_SAVES
void play_music_config(const config &music_node, bool allow_interrupt_current_track, int i)
void play_music_once(const std::string &file)
void commit_music_changes()
void play_bell(const std::string &files)
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
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 ...
std::string get_unknown_exception_type()
Utility function for finding the type of thing caught with catch(...).
std::map< std::string, t_string > string_map
bool headless()
The game is running headless.
bool testing()
The game is running unit tests.
static lg::log_domain log_engine("engine")
static lg::log_domain log_aitesting("ai/testing")
static lg::log_domain log_enginerefac("enginerefac")
Define the game's event mechanism.
Thrown when a lexical_cast fails.
Additional information on the game outcome which can be provided by WML.
bool proceed_to_next_level
whether to proceed to the next scenario, equals is_victory in sp.
transient_end_level transient
Error used for any general game error, e.g.
We received invalid data from wesnothd during a game This means we cannot continue with the game but ...
Encapsulates the map of the game.
std::shared_ptr< config > stats_
std::shared_ptr< config > level
void read(const config &cfg, bool append=false)
void clear_current_scenario()
Delete the current scenario from the stats.
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
bool carryover_report
Should a summary of the scenario outcome be displayed?
bool linger_mode
Should linger mode be invoked?
An error occurred during when trying to communicate with the wesnothd server.
static map_location::direction s
Gather statistics important for AI testing and output them.
Various functions that implement the undoing (and redoing) of in-game commands.