67 #include <boost/make_shared.hpp>
71 #define LOG_AIT LOG_STREAM(info, log_aitesting)
75 #define LOG_NG LOG_STREAM(info, log_engine)
76 #define DBG_NG LOG_STREAM(debug, log_engine)
79 #define ERR_DP LOG_STREAM(err, log_display)
82 #define LOG_RG LOG_STREAM(info, log_enginerefac)
85 #define DBG_EE LOG_STREAM(debug, log_engine_enemies)
92 typedef boost::container::flat_set<std::string> stringset;
94 static stringset attrs = boost::assign::list_of
102 (
"victory_when_enemies_defeated")
103 (
"remove_from_carryover_on_defeat")
105 (
"experience_modifier")
107 .convert_to_container<stringset>();
109 static stringset tags = boost::assign::list_of
112 .convert_to_container<stringset>();
116 dst[attr] = src[attr];
149 CVideo& video,
bool skip_replay)
153 , ticks_(SDL_GetTicks())
157 , saved_game_(state_of_game)
158 , tooltips_manager_()
159 , whiteboard_manager_()
162 , help_manager_(&game_config)
163 , mouse_handler_(nullptr, *this)
164 , menu_handler_(nullptr, *this, game_config)
166 , soundsources_manager_()
170 , statistics_context_(new
statistics::scenario_context(level[
"name"]))
171 , replay_(new
replay(state_of_game.get_replay()))
172 , skip_replay_(skip_replay)
174 , init_side_done_now_(false)
175 , victory_when_enemies_defeated_(level[
"victory_when_enemies_defeated"].to_bool(true))
176 , remove_from_carryover_on_defeat_(level[
"remove_from_carryover_on_defeat"].to_bool(true))
180 , ignore_replay_errors_(false)
181 , player_type_changed_(false)
229 LOG_NG <<
"initializing game_state..." << (SDL_GetTicks() -
ticks()) << std::endl;
244 LOG_NG <<
"initializing whiteboard..." << (SDL_GetTicks() -
ticks()) << std::endl;
249 LOG_NG <<
"loading units..." << (SDL_GetTicks() -
ticks()) << std::endl;
253 LOG_NG <<
"initializing theme... " << (SDL_GetTicks() -
ticks()) << std::endl;
257 LOG_NG <<
"building terrain rules... " << (SDL_GetTicks() -
ticks()) << std::endl;
260 if (!
gui_->video().faked()) {
262 gui_->get_theme().modify_label(
"time-icon",
_ (
"time left for current turn"));
264 gui_->get_theme().modify_label(
"time-icon",
_ (
"current local time"));
272 LOG_NG <<
"done initializing display... " << (SDL_GetTicks() -
ticks()) << std::endl;
274 LOG_NG <<
"building gamestate to gui and whiteboard... " << (SDL_GetTicks() -
ticks()) << std::endl;
282 if(
gamestate().first_human_team_ != -1) {
352 LOG_NG <<
"initializing managers... " << (SDL_GetTicks() -
ticks()) << std::endl;
358 LOG_NG <<
"done initializing managers... " << (SDL_GetTicks() -
ticks()) << std::endl;
397 tm.set_start_gold(tm.gold());
455 if(!
gamestate().tod_manager_.has_turn_event_fired())
463 pump().
fire(
"side " + side_num +
" turn");
464 pump().
fire(
"side turn " + turn_num);
465 pump().
fire(
"side " + side_num +
" turn " + turn_num);
491 pump().
fire(
"side " + side_num +
" turn refresh");
492 pump().
fire(
"turn " + turn_num +
" refresh");
493 pump().
fire(
"side " + side_num +
" turn " + turn_num +
" refresh");
510 gui_->invalidate_all();
531 gui_->labels().write(cfg);
553 pump().
fire(
"side "+ side_num +
" turn end");
554 pump().
fire(
"side turn " + turn_num +
" end");
555 pump().
fire(
"side " + side_num +
" turn " + turn_num +
" end");
572 pump().
fire(
"turn " + turn_num +
" end");
621 ERR_DP <<
"unknown textbox mode" << std::endl;
629 std::set<std::string> dictionary;
635 if(!
gui_->fogged(loc) &&
637 dictionary.insert(u.name());
645 dictionary.insert(commands.begin(), commands.end());
652 dictionary.insert(
t.current_player());
657 dictionary.insert(o);
662 dictionary.insert(
w);
668 for(std::map<std::string, std::string>::const_iterator iter = friends.begin(); iter != friends.end(); ++iter){
669 dictionary.insert((*iter).first);
679 ERR_DP <<
"unknown textbox mode" << std::endl;
701 int n = (num - min) % mod;
729 for(
int i = 0;
i < num_teams;
i++) {
770 if(event.key.keysym.sym == SDLK_ESCAPE) {
772 }
else if(event.key.keysym.sym == SDLK_TAB) {
774 }
else if(event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == SDLK_KP_ENTER) {
781 if (event.key.keysym.sym == SDLK_TAB) {
790 if(event.key.keysym.sym >=
'1' && event.key.keysym.sym <=
'7') {
791 const int new_path_turns = (
event.type == SDL_KEYDOWN) ?
792 event.key.keysym.sym -
'1' : 0;
813 }
else if (event.key.keysym.sym == SDLK_TAB) {
815 if (!keys[SDLK_TAB]) {
944 bool continue_level, found_player, found_network_player, invalidate_all;
945 std::set<unsigned> not_defeated;
949 if (invalidate_all) {
950 gui_->invalidate_all();
953 if (continue_level) {
957 if (found_player || found_network_player) {
965 DBG_EE <<
"found_player: " << found_player << std::endl;
966 DBG_EE <<
"found_network_player: " << found_network_player << std::endl;
973 if (
gui_->video().non_interactive()) {
975 for (
unsigned l : not_defeated) {
977 if (ai.empty()) ai =
"default ai";
978 LOG_AIT <<
l <<
" (using " << ai <<
") ";
984 DBG_EE <<
"throwing end level exception..." << std::endl;
994 if (
gui_->video().non_interactive()) {
1000 message <<
_(
"The game is out of sync. It might not make much sense to continue. Do you want to save your game?");
1001 message <<
"\n\n" <<
_(
"Error details:") <<
"\n\n" <<
msg;
1010 gui_->set_team(team_index, observe);
1011 gui_->recalculate_minimap();
1012 gui_->invalidate_all();
1013 gui_->draw(
true,
true);
1079 catch(
const return_to_play_side_exception&)
1102 for (
int side =
gamestate().board_.teams().size(); side != 0; --side )
1114 gui_->recalculate_minimap();
1128 gui_->recalculate_minimap();
1140 std::set<std::string>
res =
gui_->observers();
1144 res.insert(
t.current_player());
1153 gui_->parse_team_overlays();
1184 gui_->invalidate_game_status();
1189 if(
gui_->video().non_interactive()) {
1214 if(
gui_->video().non_interactive()) {
1235 LOG_NG <<
"firing time over event...\n";
1238 LOG_NG <<
"done firing time over event...\n";
1240 if (
gamestate().tod_manager_.is_time_left()) {
1244 if(
gui_->video().non_interactive()) {
1245 LOG_AIT <<
"time over (draw)\n";
1261 : controller_(controller)
1268 controller_.saved_game_.remove_snapshot();
static const config & get_theme(const config &game_config, std::string theme_name)
void clear()
Clears the stack of undoable (and redoable) actions.
play_controller * controller
play_controller(const config &level, saved_game &state_of_game, const config &game_config, const tdata_cache &tdata, CVideo &video, bool skip_replay)
bool player_type_changed_
void do_search(const std::string &new_search)
void set_current_paths(const pathfind::paths &new_paths)
events::mouse_handler & get_mouse_handler_base()
Get a reference to a mouse handler member a derived class uses.
static void log_turn_start(unsigned int side)
static void log_turn_end(unsigned int side)
void set_preference_display_settings()
::tod_manager * tod_manager
bool is_team_visible(int team_num, bool observer) const
static lg::log_domain log_engine_enemies("engine/enemies")
map_location last_selected
the last location where a select event fired.
int get_path_turns() const
The class for loading a savefile.
void save_replay_auto(const std::string &filename)
bool victory_when_enemies_defeated_
While any instance of this class exists, attempts to save the game via any call to play_controller wi...
game_classification * classification
Various functions implementing vision (through fog of war and shroud).
const mp_game_settings & get_mp_settings()
void do_final_checkup(bool dont_throw=false)
boost::scoped_ptr< plugins_context > plugins_context_
events::mouse_handler mouse_handler_
static void copy_persistent(const config &src, config &dst)
Copies [scenario] attributes/tags that are not otherwise stored in C++ structs/clases.
const mp_game_settings * mp_settings
virtual void process_oos(const std::string &msg) const
Asks the user whether to continue on an OOS error.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
bool get_disallow_observers() const
const time_of_day & get_time_of_day(int for_turn=0) const
Returns global time of day for the passed turn.
replay_recorder_base & get_replay()
std::string default_victory_music
void set_scope_active(scope s, bool set)
static void log_victory(std::set< unsigned int > teams)
static void on_unblock(play_controller *controller, void(play_controller::*callback)())
std::string sounds
List of "ambient" sounds associated with this time_of_day, Played at the beginning of turn...
const int INFINITE_AUTO_SAVES
bool is_enemy(int n) const
bool save_game_interactive(CVideo &video, const std::string &message, gui::DIALOG_TYPE dialog_type)
Save a game interactively through the savegame dialog.
void do_command(const std::string &str)
virtual void update_viewing_player()=0
gui::floating_textbox & get_textbox()
void set_gui(game_display *gui)
void undo()
Undoes the top action on the undo stack.
bool can_use_synced_wml_menu() const
void process_focus_keydown_event(const SDL_Event &event)
Process keydown (only when the general map display does not have focus).
static lg::log_domain log_aitesting("aitesting")
Gather statistics important for AI testing and output them.
boost::scoped_ptr< pathfind::manager > pathfind_manager_
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.
void play_slice(bool is_delay_enabled=true)
boost::scoped_ptr< hotkey_handler > hotkey_handler_
void new_side_turn(int side)
Performs some initializations and error checks when starting a new side-turn.
static lg::log_domain log_engine("engine")
virtual const std::vector< team > & teams() const
Class for "normal" midgame saves.
persist_manager * persist
void check_victory()
Checks to see if a side has won.
boost::scoped_ptr< soundsource::manager > soundsources_manager_
config & set_snapshot(config snapshot)
bool is_skipping_replay() const
void append_children(const config &cfg)
Adds children from cfg.
void init(CVideo &video, const config &level)
bool ignore_replay_errors_
static lg::log_domain log_display("display")
void write_music_play_list(config &snapshot)
bool is_proxy_human() const
static void clear_resources()
This file implements all the hotkey handling and menu details for play controller.
void select_hex(const map_location &hex, const bool browse, const bool highlight=true, const bool fire_event=true)
const std::string & select_victory_music() const
const tdata_cache & tdata_
bool can_undo() const
True if there are actions that can be undone.
void reset_turn_stats(const std::string &save_id)
void process_keydown_event(const SDL_Event &event)
Process keydown (always).
map_location get_selected_hex() const
config::attribute_value & get_variable(const std::string &varname)
throws invalid_variablename_exception if varname is no valid variable name.
events::menu_handler menu_handler_
void play_sound(const std::string &files, channel_group group, unsigned int repeats)
void process_keyup_event(const SDL_Event &event)
Process keyup (always).
~scoped_savegame_snapshot()
bool enemies_visible() const
void set_phase(PHASE phase)
boost::scoped_ptr< game_lua_kernel > lua_kernel_
An exception-safe means of making sure that unblock() gets called after try_block().
int side_upkeep(int side_num) const
void do_consolesave(const std::string &filename)
Object which defines a time of day with associated bonuses, image, sounds etc.
std::vector< std::string > defeat_music_
game_events::t_pump & pump()
This class stores all the data for a single 'side' (in game nomenclature).
A small explanation about what's going on here: Each action has access to two game_info objects First...
scoped_savegame_snapshot(const play_controller &controller)
std::string default_defeat_music
static UNUSEDNOWARN std::string _(const char *str)
static int modulo(int num, int mod, int min)
void throw_quit_game_exception()
void save_game_auto(const std::string &filename)
int current_side() const
Returns the number of the side whose turn it is.
bool add_start_if_not_there_yet()
std::vector< team > * teams
std::vector< team > teams_
bool is_regular_game_end() const
void update_savegame_snapshot() const
void set_path_turns(const int path_turns)
virtual void check_time_over()
Implements a quit confirmation dialog.
filter_context * filter_con
boost::scoped_ptr< game_events::manager > events_manager_
GLubyte GLubyte GLubyte GLubyte w
void add_color_info(const config &v)
virtual bool should_return_to_play_side()
bool ignore_replay_errors
This class is the frontend of the whiteboard framework for the rest of the Wesnoth code...
void recalculate_fog(int side)
Function that recalculates the fog of war.
config & add_child(const std::string &key)
void maybe_do_init_side()
Called by turn_info::process_network_data() or init_side() to call do_init_side() if necessary...
bool is_local_human() const
Object which temporarily resets a unit's movement.
Managing the AIs lifecycle - headers.
bool is_lingering() const
void check_victory(bool &, bool &, bool &, bool &, std::set< unsigned > &, bool)
void set_gui(game_display *gui)
void spend_gold(const int amount)
std::set< std::string > all_players() const
static const map_location & null_location()
bool can_redo() const
True if there are actions that can be redone.
Error used for any general game error, e.g.
const std::set< map_location > & villages() const
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
static void display(CVideo &video, std::function< void()> f)
game_events::manager * game_events
bool is_browsing() const override
void deactivate_all_scopes()
virtual plugins_context * get_plugins_context()
Get (optionally) a plugins context a derived class uses.
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.
void do_init_side()
Called by replay handler or init_side() to do actual work for turn change.
Encapsulates the map of the game.
void calculate_healing(int side, bool update_display)
Calculates healing for all units for the given side.
int mp_countdown_init_time
virtual ~play_controller()
Various functions related to the creation of units (recruits, recalls, and placed units)...
void set_end_level_data(const end_level_data &data)
static void progress(const char *stage_name=nullptr)
void write(config &cfg) const
soundsource::manager * soundsources
void redo()
Redoes the top action on the redo stack.
Game configuration data as global variables.
unit_map::iterator selected_unit()
static std::string get_active_ai_identifier_for_side(side_number side)
Gets AI algorithm identifier for active AI of the given side.
const config & game_config_
void operator()(const config &)
void reset_gamestate(const config &level, int replay_pos)
Define the game's event mechanism.
void encounter_all_content(const game_board &gameboard_)
#define log_scope(description)
const util::scoped_ptr< gui::textbox > & box() const
void tab(const std::set< std::string > &dictionary)
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
bool proceed_to_next_level
whether to proceed to the next scenario, equals is_victory in sp.
const std::vector< team > & get_teams_const() const
boost::scoped_ptr< tooltips::manager > tooltips_manager_
Additional information on the game outcome which can be provided by WML.
int support() const
Calculate total support capacity, based on support_per_village.
actions::undo_list & undo_stack()
std::map< std::string, std::string > get_acquaintances_nice(const std::string &filter)
void set_defeat_music_list(const std::string &list)
static void save(LexState *ls, int c)
static lg::log_domain log_enginerefac("enginerefac")
Class for replay saves (either manually or automatically).
compression::format save_compression_format()
const game_classification & get_classification()
bool clear_shroud(int side, bool reset_fog, bool fire_events)
Function that will clear shroud (and fog) based on current unit positions.
boost::scoped_ptr< game_state > gamestate_
void set_game_display(game_display *)
boost::shared_ptr< wb::manager > get_whiteboard()
n_unit::id_manager & unit_id_manager()
Various functions that implement healing of units (when a side turn starts).
game_classification & classification()
bool have_keyboard_focus()
Derived classes should override this to return false when arrow keys should not scroll the map...
boost::shared_ptr< wb::manager > whiteboard_manager_
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.
Standard logging facilities (interface).
void autosave(const bool disable_autosave, const int autosave_max, const int infinite_autosaves)
game_display & get_display()
Get a reference to a display member a derived class uses.
const std::function< std::string(const config &, const std::string &) > get_str
Object which contains all the possible locations a unit can move to, with associated best routes to t...
game_lua_kernel * lua_kernel
config * get_next_action()
GLsizei GLenum GLuint GLuint GLsizei char * message
void fire_preload()
preload events cannot be synced
void set_victory_music_list(const std::string &list)
boost::shared_ptr< wb::manager > whiteboard
boost::scoped_ptr< game_display > gui_
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
std::vector< std::string > victory_music_
actions::undo_list * undo_stack
const std::string & select_defeat_music() const
void set_side(int side_number)
const play_controller & controller_
virtual soundsource::manager * get_soundsource_man()
Get (optionally) a soundsources manager a derived class uses.
bool next_turn(game_data *vars)
Function to move to the next turn.
A config object defines a single node in a WML file, with access to child nodes.
Class that keeps track of all the keys on the keyboard.
const pathfind::paths & current_paths() const
mp_game_settings & mp_settings()
Multiplayer parameters for this game.
void delete_all_wml_hotkeys()
deletes all wml hotkeys, should be called after a game has ended
std::vector< std::string > get_commands_list()
void close(game_display &gui)
pathfind::manager * tunnels
GLsizei const GLcharARB ** string
bool save_game_automatic(CVideo &video, bool ask_for_overwrite=false, const std::string &filename="")
Saves a game without user interaction, unless the file exists and it should be asked to overwrite it...
virtual void check_objectives()=0
int find_last_visible_team() const
returns 0 if no such team was found.
virtual void play_side_impl()
boost::scoped_ptr< replay > replay_
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_
TEXTBOX_MODE mode() const
void do_ai_formula(const std::string &str, int side_num, mouse_handler &mousehandler)
virtual void sync_end_turn()