56 #define LOG_AIT LOG_STREAM(info, log_aitesting)
60 #define ERR_NG LOG_STREAM(err, log_engine)
61 #define LOG_NG LOG_STREAM(info, log_engine)
62 #define DBG_NG LOG_STREAM(debug, log_engine)
65 #define LOG_RG LOG_STREAM(info, log_enginerefac)
70 , end_turn_requested_(false)
72 , replay_controller_()
118 if(scroll_team == 0) {
123 if((loc.
x >= 0) && (loc.
y >= 0)) {
125 LOG_NG <<
"Found bad stored ui location " <<
map_start_ <<
" using side starting location " << loc;
127 LOG_NG <<
"Found bad stored ui location";
132 gui_->set_prevent_draw(
false);
133 gui_->queue_repaint();
135 gui_->fade_to({0,0,0,0}, std::chrono::milliseconds{500});
137 gui_->set_fade({0,0,0,0});
150 for(
const config&
s :
level.child_range(
"sound_source")) {
155 ERR_NG <<
"Error when parsing sound_source config: bad lexical cast.";
156 ERR_NG <<
"sound_source config was: " <<
s.debug();
157 ERR_NG <<
"Skipping this sound source...";
184 _(
"This multiplayer game uses an alternative random mode, if you don’t know what this message means, then "
185 "most likely someone is cheating or someone reloaded a corrupt game."));
191 const int sides =
static_cast<int>(
get_teams().size());
192 const int max = side_num + sides;
194 for (; side_num != max; ++side_num) {
195 int side_num_mod =
modulo(side_num, sides, 1);
196 if(!
gamestate().board_.get_team(side_num_mod).is_empty()) {
197 return { side_num_mod, side_num_mod != side_num };
200 return { side_num,
true };
269 int next_player_number_temp =
gamestate_->next_player_number_;
277 auto [next_player_number, new_turn] =
skip_empty_sides(next_player_number_temp);
292 gamestate_->player_number_ = next_player_number;
301 gui_->invalidate_game_status();
319 boost::dynamic_bitset<> local_players;
322 for(std::size_t
i = 0;
i < local_players.size(); ++
i) {
336 for(std::size_t
i = 0;
i < local_players.size(); ++
i) {
345 replay_controller_ = std::make_unique<replay_controller>(*
this,
false, ex.
level, [
this]() { on_replay_end(false); });
372 pump().
fire(is_victory ?
"local_victory" :
"local_defeat");
392 "type",
"termination",
393 "condition",
"game over",
394 "result", is_victory ? level_result::victory : level_result::defeat,
406 const std::string& end_music =
select_music(is_victory);
419 LOG_NG <<
"in playsingle_controller::play_scenario()...";
422 for(
const config& m :
level.child_range(
"music")) {
432 for(
const auto& iter :
level.child_range(
"story")) {
452 return level_result::type::observer_end;
462 if(
e.message ==
"") {
464 _(
"A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"),
468 _(
"This game has been ended.\nReason: ") +
e.message +
_(
"\nDo you want to save the game?"),
473 return level_result::type::quit;
484 using namespace std::chrono_literals;
485 std::this_thread::sleep_for(10ms);
515 LOG_NG <<
"human finished turn...";
559 gui_->queue_rerender();
560 std::string message =
_(
"It is now $name|’s turn");
603 gui_->get_theme().refresh_title2(
"button-endturn",
"title2");
613 gui_->get_theme().refresh_title2(
"button-endturn",
"title");
616 gui_->queue_rerender();
621 LOG_NG <<
"beginning end-of-scenario linger";
644 LOG_NG <<
"ending end-of-scenario linger";
658 gui_->set_route(
nullptr);
659 gui_->unhighlight_reach();
708 gui_->get_chat_manager().add_chat_message(std::time(
nullptr),
"Wesnoth", 0,
709 "This side is in an idle state. To proceed with the game, the host must assign it to another controller.",
719 ERR_NG <<
"Networked team encountered by playsingle_controller.";
724 if(name ==
"ai_user_interact") {
796 return !
t.get_disallow_observers() && !
t.is_empty();
798 return t.is_local_human() && !
t.is_idle();
804 const int num_teams =
get_teams().size();
807 for(
int i = 0;
i < num_teams;
i++) {
822 if(side_num !=
gui_->viewing_team().side() ||
gui_->show_everything()) {
834 ERR_NG <<
"received invalid reset replay";
872 }
else if(is_unit_test) {
876 e.proceed_to_next_level =
false;
877 e.is_victory =
false;
Managing the AIs lifecycle - headers TODO: Refactor history handling and internal commands.
void carryover_show_gold(game_state &state, bool hidden, bool is_observer, bool is_test)
calculates the amount of gold carried over for each team, stores the data in the team object and show...
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(const std::string &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.