Play Controller: formatting cleanup
This commit is contained in:
parent
fef1310890
commit
a5344ae52a
2 changed files with 381 additions and 216 deletions
|
@ -26,30 +26,30 @@
|
|||
#include "actions/vision.hpp"
|
||||
#include "ai/manager.hpp"
|
||||
#include "ai/testing.hpp"
|
||||
#include "preferences/credentials.hpp"
|
||||
#include "display_chat_manager.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "game_events/menu_item.hpp"
|
||||
#include "game_events/pump.hpp"
|
||||
#include "preferences/game.hpp"
|
||||
#include "game_state.hpp"
|
||||
#include "hotkey/hotkey_item.hpp"
|
||||
#include "hotkey/hotkey_handler.hpp"
|
||||
#include "map/label.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "gui/dialogs/loading_screen.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "hotkey/command_executor.hpp"
|
||||
#include "hotkey/hotkey_handler.hpp"
|
||||
#include "hotkey/hotkey_item.hpp"
|
||||
#include "log.hpp"
|
||||
#include "map/label.hpp"
|
||||
#include "pathfind/teleport.hpp"
|
||||
#include "preferences/credentials.hpp"
|
||||
#include "preferences/display.hpp"
|
||||
#include "preferences/game.hpp"
|
||||
#include "random.hpp"
|
||||
#include "replay.hpp"
|
||||
#include "reports.hpp"
|
||||
#include "resources.hpp"
|
||||
#include "savegame.hpp"
|
||||
#include "saved_game.hpp"
|
||||
#include "save_blocker.hpp"
|
||||
#include "saved_game.hpp"
|
||||
#include "savegame.hpp"
|
||||
#include "scripting/game_lua_kernel.hpp"
|
||||
#include "scripting/plugins/context.hpp"
|
||||
#include "sound.hpp"
|
||||
|
@ -58,15 +58,14 @@
|
|||
#include "synced_context.hpp"
|
||||
#include "terrain/type_data.hpp"
|
||||
#include "tooltips.hpp"
|
||||
#include "units/unit.hpp"
|
||||
#include "units/id.hpp"
|
||||
#include "whiteboard/manager.hpp"
|
||||
|
||||
#include "units/unit.hpp"
|
||||
#include "utils/functional.hpp"
|
||||
#include "whiteboard/manager.hpp"
|
||||
|
||||
static lg::log_domain log_aitesting("aitesting");
|
||||
#define LOG_AIT LOG_STREAM(info, log_aitesting)
|
||||
//If necessary, this define can be replaced with `#define LOG_AIT std::cout` to restore previous behavior
|
||||
// If necessary, this define can be replaced with `#define LOG_AIT std::cout` to restore previous behavior
|
||||
|
||||
static lg::log_domain log_engine("engine");
|
||||
#define LOG_NG LOG_STREAM(info, log_engine)
|
||||
|
@ -87,25 +86,22 @@ static lg::log_domain log_engine_enemies("engine/enemies");
|
|||
static void copy_persistent(const config& src, config& dst)
|
||||
{
|
||||
static const std::set<std::string> attrs {
|
||||
"description",
|
||||
"name",
|
||||
"victory_when_enemies_defeated",
|
||||
"remove_from_carryover_on_defeat",
|
||||
"disallow_recall",
|
||||
"experience_modifier",
|
||||
"require_scenario"};
|
||||
"description",
|
||||
"name",
|
||||
"victory_when_enemies_defeated",
|
||||
"remove_from_carryover_on_defeat",
|
||||
"disallow_recall",
|
||||
"experience_modifier",
|
||||
"require_scenario"
|
||||
};
|
||||
|
||||
static const std::set<std::string> tags {
|
||||
"terrain_graphics",
|
||||
"lua"};
|
||||
static const std::set<std::string> tags{"terrain_graphics", "lua"};
|
||||
|
||||
for (const std::string& attr : attrs)
|
||||
{
|
||||
for(const std::string& attr : attrs) {
|
||||
dst[attr] = src[attr];
|
||||
}
|
||||
|
||||
for (const std::string& tag : tags)
|
||||
{
|
||||
for(const std::string& tag : tags) {
|
||||
dst.append_children(src, tag);
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +124,11 @@ static void clear_resources()
|
|||
resources::classification = nullptr;
|
||||
}
|
||||
|
||||
play_controller::play_controller(const config& level, saved_game& state_of_game,
|
||||
const config& game_config, const ter_data_cache& tdata, bool skip_replay)
|
||||
play_controller::play_controller(const config& level,
|
||||
saved_game& state_of_game,
|
||||
const config& game_config,
|
||||
const ter_data_cache& tdata,
|
||||
bool skip_replay)
|
||||
: controller_base(game_config)
|
||||
, observer()
|
||||
, quit_confirmation()
|
||||
|
@ -169,7 +168,6 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
|
|||
resources::controller = this;
|
||||
resources::persist = &persist_;
|
||||
resources::recorder = replay_.get();
|
||||
|
||||
resources::classification = &saved_game_.classification();
|
||||
|
||||
persist_.start_transaction();
|
||||
|
@ -177,11 +175,13 @@ play_controller::play_controller(const config& level, saved_game& state_of_game,
|
|||
join();
|
||||
|
||||
game_config::add_color_info(level);
|
||||
|
||||
hotkey::deactivate_all_scopes();
|
||||
hotkey::set_scope_active(hotkey::SCOPE_GAME);
|
||||
|
||||
try {
|
||||
init(level);
|
||||
} catch (...) {
|
||||
} catch(...) {
|
||||
clear_resources();
|
||||
throw;
|
||||
}
|
||||
|
@ -219,6 +219,7 @@ void play_controller::init(const config& level)
|
|||
|
||||
gamestate_->ai_manager_.add_observer(this);
|
||||
gamestate_->init(level, *this);
|
||||
|
||||
resources::tunnels = gamestate().pathfind_manager_.get();
|
||||
|
||||
LOG_NG << "initializing whiteboard..." << (SDL_GetTicks() - ticks()) << std::endl;
|
||||
|
@ -236,22 +237,27 @@ void play_controller::init(const config& level)
|
|||
|
||||
LOG_NG << "building terrain rules... " << (SDL_GetTicks() - ticks()) << std::endl;
|
||||
gui2::dialogs::loading_screen::progress(loading_stage::build_terrain);
|
||||
|
||||
gui_.reset(new game_display(gamestate().board_, whiteboard_manager_, *gamestate().reports_, theme_cfg, level));
|
||||
|
||||
map_start_ = map_location(level.child_or_empty("display").child_or_empty("location"));
|
||||
if (!gui_->video().faked()) {
|
||||
if (saved_game_.mp_settings().mp_countdown)
|
||||
gui_->get_theme().modify_label("time-icon", _ ("time left for current turn"));
|
||||
else
|
||||
gui_->get_theme().modify_label("time-icon", _ ("current local time"));
|
||||
|
||||
if(!gui_->video().faked()) {
|
||||
if(saved_game_.mp_settings().mp_countdown) {
|
||||
gui_->get_theme().modify_label("time-icon", _("time left for current turn"));
|
||||
} else {
|
||||
gui_->get_theme().modify_label("time-icon", _("current local time"));
|
||||
}
|
||||
}
|
||||
|
||||
gui2::dialogs::loading_screen::progress(loading_stage::init_display);
|
||||
|
||||
mouse_handler_.set_gui(gui_.get());
|
||||
menu_handler_.set_gui(gui_.get());
|
||||
|
||||
LOG_NG << "done initializing display... " << (SDL_GetTicks() - ticks()) << std::endl;
|
||||
|
||||
LOG_NG << "building gamestate to gui and whiteboard... " << (SDL_GetTicks() - ticks()) << std::endl;
|
||||
|
||||
// This *needs* to be created before the show_intro and show_map_scene
|
||||
// as that functions use the manager state_of_game
|
||||
// Has to be done before registering any events!
|
||||
|
@ -260,15 +266,12 @@ void play_controller::init(const config& level)
|
|||
|
||||
if(gamestate().first_human_team_ != -1) {
|
||||
gui_->set_team(gamestate().first_human_team_);
|
||||
}
|
||||
else if(is_observer()) {
|
||||
} else if(is_observer()) {
|
||||
// Find first team that is allowed to be observed.
|
||||
// If not set here observer would be without fog until
|
||||
// the first turn of observable side
|
||||
for (const team& t : gamestate().board_.teams())
|
||||
{
|
||||
if (!t.get_disallow_observers())
|
||||
{
|
||||
for(const team& t : gamestate().board_.teams()) {
|
||||
if(!t.get_disallow_observers()) {
|
||||
gui_->set_team(t.side() - 1);
|
||||
}
|
||||
}
|
||||
|
@ -276,17 +279,21 @@ void play_controller::init(const config& level)
|
|||
|
||||
init_managers();
|
||||
gui2::dialogs::loading_screen::progress(loading_stage::start_game);
|
||||
//loadscreen_manager->reset();
|
||||
|
||||
// loadscreen_manager->reset();
|
||||
gamestate().gamedata_.set_phase(game_data::PRELOAD);
|
||||
gamestate().lua_kernel_->load_game(level);
|
||||
|
||||
plugins_context_.reset(new plugins_context("Game"));
|
||||
plugins_context_->set_callback("save_game", [this](const config& cfg) { save_game_auto(cfg["filename"]); }, true);
|
||||
plugins_context_->set_callback("save_replay", [this](const config& cfg) { save_replay_auto(cfg["filename"]); }, true);
|
||||
plugins_context_->set_callback(
|
||||
"save_game", [this](const config& cfg) { save_game_auto(cfg["filename"]); }, true);
|
||||
plugins_context_->set_callback(
|
||||
"save_replay", [this](const config& cfg) { save_replay_auto(cfg["filename"]); }, true);
|
||||
plugins_context_->set_callback("quit", throw_end_level(), false);
|
||||
plugins_context_->set_accessor_string("scenario_name", [this](config) { return get_scenario_name(); });
|
||||
});
|
||||
//Do this after the loadingscreen, so that ita happens in the main thread.
|
||||
|
||||
// Do this after the loadingscreen, so that ita happens in the main thread.
|
||||
gui_->join();
|
||||
gui_->initialize_ui();
|
||||
}
|
||||
|
@ -304,9 +311,9 @@ void play_controller::reset_gamestate(const config& level, int replay_pos)
|
|||
|
||||
gui_->labels().set_team(nullptr);
|
||||
|
||||
/* First destroy the old game state, then create the new one.
|
||||
This is necessary to ensure that while the old AI manager is being destroyed,
|
||||
all its member objects access the old manager instead of the new. */
|
||||
// First destroy the old game state, then create the new one.
|
||||
// This is necessary to ensure that while the old AI manager is being destroyed,
|
||||
// all its member objects access the old manager instead of the new.
|
||||
gamestate_.reset();
|
||||
gamestate_.reset(new game_state(level, *this, tdata_));
|
||||
resources::gameboard = &gamestate().board_;
|
||||
|
@ -324,7 +331,9 @@ void play_controller::reset_gamestate(const config& level, int replay_pos)
|
|||
|
||||
gui_->reset_reports(*gamestate().reports_);
|
||||
gui_->change_display_context(&gamestate().board_);
|
||||
|
||||
saved_game_.get_replay().set_pos(replay_pos);
|
||||
|
||||
gamestate().gamedata_.set_phase(game_data::PRELOAD);
|
||||
gamestate().lua_kernel_->load_game(level);
|
||||
}
|
||||
|
@ -356,11 +365,12 @@ void play_controller::fire_prestart()
|
|||
|
||||
// Fire these right before prestart events, to catch only the units sides
|
||||
// have started with.
|
||||
for (const unit& u : gamestate().board_.units()) {
|
||||
for(const unit& u : gamestate().board_.units()) {
|
||||
pump().fire("unit_placed", map_location(u.get_location()));
|
||||
}
|
||||
|
||||
pump().fire("prestart");
|
||||
|
||||
// prestart event may modify start turn with WML, reflect any changes.
|
||||
gamestate().gamedata_.get_variable("turn_number") = int(turn());
|
||||
}
|
||||
|
@ -369,15 +379,17 @@ void play_controller::fire_start()
|
|||
{
|
||||
gamestate().gamedata_.set_phase(game_data::START);
|
||||
pump().fire("start");
|
||||
|
||||
// start event may modify start turn with WML, reflect any changes.
|
||||
gamestate().gamedata_.get_variable("turn_number") = int(turn());
|
||||
|
||||
check_objectives();
|
||||
// prestart and start events may modify the initial gold amount,
|
||||
// reflect any changes.
|
||||
for (team& tm : gamestate().board_.teams_)
|
||||
{
|
||||
|
||||
// prestart and start events may modify the initial gold amount, reflect any changes.
|
||||
for(team& tm : gamestate().board_.teams_) {
|
||||
tm.set_start_gold(tm.gold());
|
||||
}
|
||||
|
||||
gamestate_->init_side_done() = false;
|
||||
gamestate().gamedata_.set_phase(game_data::PLAY);
|
||||
}
|
||||
|
@ -393,9 +405,8 @@ void play_controller::init_side_begin()
|
|||
mouse_handler_.set_side(current_side());
|
||||
|
||||
// If we are observers we move to watch next team if it is allowed
|
||||
if ((is_observer() && !current_team().get_disallow_observers())
|
||||
|| (current_team().is_local_human() && !this->is_replay()))
|
||||
{
|
||||
if((is_observer() && !current_team().get_disallow_observers())
|
||||
|| (current_team().is_local_human() && !this->is_replay())) {
|
||||
update_gui_to_player(current_side() - 1);
|
||||
}
|
||||
|
||||
|
@ -411,18 +422,19 @@ void play_controller::maybe_do_init_side()
|
|||
// For all other sides it is recorded in replay and replay handler has to handle
|
||||
// calling do_init_side() functions.
|
||||
//
|
||||
if (gamestate_->init_side_done()) {
|
||||
// We already executed do_init_side this can for example happe if we reload a game,
|
||||
if(gamestate_->init_side_done()) {
|
||||
// We already executed do_init_side this can for example happen if we reload a game,
|
||||
// but also if we changed control of a side during it's turn
|
||||
return;
|
||||
}
|
||||
if (!current_team().is_local()) {
|
||||
|
||||
if(!current_team().is_local()) {
|
||||
// We are in a mp game and execute do_init_side as soon as we receive [init_side] from the current player
|
||||
// (see replay.cpp)
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_replay()) {
|
||||
if(is_replay()) {
|
||||
// We are in a replay and execute do_init_side as soon as we reach the next [init_side] in the replay data
|
||||
// (see replay.cpp)
|
||||
return;
|
||||
|
@ -436,6 +448,7 @@ void play_controller::do_init_side()
|
|||
{
|
||||
set_scontext_synced sync;
|
||||
log_scope("player turn");
|
||||
|
||||
// In case we might end up calling sync:network during the side turn events,
|
||||
// and we don't want do_init_side to be called when a player drops.
|
||||
gamestate_->init_side_done() = true;
|
||||
|
@ -447,8 +460,7 @@ void play_controller::do_init_side()
|
|||
gamestate().gamedata_.get_variable("side_number") = current_side();
|
||||
|
||||
// We might have skipped some sides because they were empty so it is not enough to check for side_num==1
|
||||
if(!gamestate().tod_manager_.has_turn_event_fired())
|
||||
{
|
||||
if(!gamestate().tod_manager_.has_turn_event_fired()) {
|
||||
pump().fire("turn_" + turn_num);
|
||||
pump().fire("new_turn");
|
||||
gamestate().tod_manager_.turn_event_fired();
|
||||
|
@ -463,15 +475,14 @@ void play_controller::do_init_side()
|
|||
// and the player should get income now.
|
||||
// Healing/income happen if it's not the first turn of processing,
|
||||
// or if we are loading a game.
|
||||
if (turn() > 1) {
|
||||
if(turn() > 1) {
|
||||
gamestate().board_.new_turn(current_side());
|
||||
current_team().new_turn();
|
||||
|
||||
// If the expense is less than the number of villages owned
|
||||
// times the village support capacity,
|
||||
// then we don't have to pay anything at all
|
||||
int expense = gamestate().board_.side_upkeep(current_side()) -
|
||||
current_team().support();
|
||||
int expense = gamestate().board_.side_upkeep(current_side()) - current_team().support();
|
||||
if(expense > 0) {
|
||||
current_team().spend_gold(expense);
|
||||
}
|
||||
|
@ -489,6 +500,7 @@ void play_controller::do_init_side()
|
|||
|
||||
// Make sure vision is accurate.
|
||||
actions::clear_shroud(current_side(), true);
|
||||
|
||||
init_side_end();
|
||||
check_victory();
|
||||
sync.do_final_checkup();
|
||||
|
@ -498,12 +510,14 @@ void play_controller::init_side_end()
|
|||
{
|
||||
const time_of_day& tod = gamestate().tod_manager_.get_time_of_day();
|
||||
|
||||
if (current_side() == 1 || !init_side_done_now_)
|
||||
if(current_side() == 1 || !init_side_done_now_) {
|
||||
sound::play_sound(tod.sounds, sound::SOUND_SOURCES);
|
||||
|
||||
if (!is_skipping_replay() && current_team().get_scroll_to_leader() && !map_start_.valid()){
|
||||
gui_->scroll_to_leader(current_side(), game_display::ONSCREEN,false);
|
||||
}
|
||||
|
||||
if(!is_skipping_replay() && current_team().get_scroll_to_leader() && !map_start_.valid()) {
|
||||
gui_->scroll_to_leader(current_side(), game_display::ONSCREEN, false);
|
||||
}
|
||||
|
||||
map_start_ = map_location();
|
||||
whiteboard_manager_->on_init_side();
|
||||
}
|
||||
|
@ -517,7 +531,7 @@ config play_controller::to_config() const
|
|||
|
||||
gui_->write(cfg.add_child("display"));
|
||||
|
||||
//Write the soundsources.
|
||||
// Write the soundsources.
|
||||
soundsources_manager_->write_sourcespecs(cfg);
|
||||
|
||||
gui_->labels().write(cfg);
|
||||
|
@ -530,11 +544,12 @@ void play_controller::finish_side_turn()
|
|||
{
|
||||
whiteboard_manager_->on_finish_side_turn(current_side());
|
||||
|
||||
{ //Block for set_scontext_synced
|
||||
{ // Block for set_scontext_synced
|
||||
set_scontext_synced sync(1);
|
||||
// Ending the turn commits all moves.
|
||||
undo_stack().clear();
|
||||
gamestate().board_.end_turn(current_side());
|
||||
|
||||
const std::string turn_num = std::to_string(turn());
|
||||
const std::string side_num = std::to_string(current_side());
|
||||
|
||||
|
@ -542,9 +557,10 @@ void play_controller::finish_side_turn()
|
|||
actions::clear_shroud(current_side());
|
||||
|
||||
pump().fire("side_turn_end");
|
||||
pump().fire("side_"+ side_num + "_turn_end");
|
||||
pump().fire("side_" + side_num + "_turn_end");
|
||||
pump().fire("side_turn_" + turn_num + "_end");
|
||||
pump().fire("side_" + side_num + "_turn_" + turn_num + "_end");
|
||||
|
||||
// This is where we refog, after all of a side's events are done.
|
||||
actions::recalculate_fog(current_side());
|
||||
check_victory();
|
||||
|
@ -560,20 +576,23 @@ void play_controller::finish_turn()
|
|||
{
|
||||
set_scontext_synced sync(2);
|
||||
const std::string turn_num = std::to_string(turn());
|
||||
|
||||
pump().fire("turn_end");
|
||||
pump().fire("turn_" + turn_num + "_end");
|
||||
|
||||
sync.do_final_checkup();
|
||||
}
|
||||
|
||||
bool play_controller::enemies_visible() const
|
||||
{
|
||||
// If we aren't using fog/shroud, this is easy :)
|
||||
if(current_team().uses_fog() == false && current_team().uses_shroud() == false)
|
||||
if(current_team().uses_fog() == false && current_team().uses_shroud() == false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// See if any enemies are visible
|
||||
for (const unit& u : gamestate().board_.units()) {
|
||||
if (current_team().is_enemy(u.side()) && !gui_->fogged(u.get_location())) {
|
||||
for(const unit& u : gamestate().board_.units()) {
|
||||
if(current_team().is_enemy(u.side()) && !gui_->fogged(u.get_location())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -661,9 +680,9 @@ static int modulo(int num, int mod, int min)
|
|||
{
|
||||
assert(mod > 0);
|
||||
int n = (num - min) % mod;
|
||||
if (n < 0)
|
||||
if(n < 0)
|
||||
n += mod;
|
||||
//n is now in [0, mod)
|
||||
// n is now in [0, mod)
|
||||
n = n + min;
|
||||
return n;
|
||||
// the following properties are easy to verify:
|
||||
|
@ -676,8 +695,7 @@ bool play_controller::is_team_visible(int team_num, bool observer) const
|
|||
const team& t = gamestate().board_.get_team(team_num);
|
||||
if(observer) {
|
||||
return !t.get_disallow_observers() && !t.is_empty();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return t.is_local_human() && !t.is_idle();
|
||||
}
|
||||
}
|
||||
|
@ -724,7 +742,7 @@ game_display& play_controller::get_display()
|
|||
|
||||
void play_controller::process_keydown_event(const SDL_Event& event)
|
||||
{
|
||||
if (event.key.keysym.sym == SDLK_TAB) {
|
||||
if(event.key.keysym.sym == SDLK_TAB) {
|
||||
whiteboard_manager_->set_invert_behavior(true);
|
||||
}
|
||||
}
|
||||
|
@ -734,8 +752,7 @@ void play_controller::process_keyup_event(const SDL_Event& event)
|
|||
// If the user has pressed 1 through 9, we want to show
|
||||
// how far the unit can move in that many turns
|
||||
if(event.key.keysym.sym >= '1' && event.key.keysym.sym <= '9') {
|
||||
const int new_path_turns = (event.type == SDL_KEYDOWN) ?
|
||||
event.key.keysym.sym - '1' : 0;
|
||||
const int new_path_turns = (event.type == SDL_KEYDOWN) ? event.key.keysym.sym - '1' : 0;
|
||||
|
||||
if(new_path_turns != mouse_handler_.get_path_turns()) {
|
||||
mouse_handler_.set_path_turns(new_path_turns);
|
||||
|
@ -746,25 +763,24 @@ void play_controller::process_keyup_event(const SDL_Event& event)
|
|||
// if it's not the unit's turn, we reset its moves
|
||||
unit_movement_resetter move_reset(*u, u->side() != current_side());
|
||||
|
||||
mouse_handler_.set_current_paths(pathfind::paths(*u, false,
|
||||
true, gamestate().board_.teams_[gui_->viewing_team()],
|
||||
mouse_handler_.get_path_turns()));
|
||||
mouse_handler_.set_current_paths(pathfind::paths(*u, false, true,
|
||||
gamestate().board_.teams_[gui_->viewing_team()], mouse_handler_.get_path_turns()));
|
||||
|
||||
gui_->highlight_reach(mouse_handler_.current_paths());
|
||||
} else {
|
||||
mouse_handler_.select_hex(mouse_handler_.get_selected_hex(), false, false, false);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (event.key.keysym.sym == SDLK_TAB) {
|
||||
} else if(event.key.keysym.sym == SDLK_TAB) {
|
||||
CKey keys;
|
||||
if (!keys[SDLK_TAB]) {
|
||||
if(!keys[SDLK_TAB]) {
|
||||
whiteboard_manager_->set_invert_behavior(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
replay& play_controller::get_replay() {
|
||||
replay& play_controller::get_replay()
|
||||
{
|
||||
assert(replay_);
|
||||
return *replay_.get();
|
||||
}
|
||||
|
@ -781,7 +797,7 @@ void play_controller::save_game()
|
|||
savegame::ingame_savegame save(saved_game_, preferences::save_compression_format());
|
||||
save.save_game_interactive("", savegame::savegame::OK_CANCEL);
|
||||
} else {
|
||||
save_blocker::on_unblock(this,&play_controller::save_game);
|
||||
save_blocker::on_unblock(this, &play_controller::save_game);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -803,7 +819,7 @@ void play_controller::save_replay()
|
|||
savegame::replay_savegame save(saved_game_, preferences::save_compression_format());
|
||||
save.save_game_interactive("", savegame::savegame::OK_CANCEL);
|
||||
} else {
|
||||
save_blocker::on_unblock(this,&play_controller::save_replay);
|
||||
save_blocker::on_unblock(this, &play_controller::save_replay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -822,7 +838,7 @@ void play_controller::save_map()
|
|||
save_blocker::save_unblocker unblocker;
|
||||
menu_handler_.save_map();
|
||||
} else {
|
||||
save_blocker::on_unblock(this,&play_controller::save_map);
|
||||
save_blocker::on_unblock(this, &play_controller::save_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,8 +873,12 @@ bool play_controller::can_redo() const
|
|||
const std::string& play_controller::select_music(bool victory) const
|
||||
{
|
||||
const std::vector<std::string>& music_list = victory
|
||||
? (gamestate_->get_game_data()->get_victory_music().empty() ? game_config::default_victory_music : gamestate_->get_game_data()->get_victory_music())
|
||||
: (gamestate_->get_game_data()->get_defeat_music().empty() ? game_config::default_defeat_music : gamestate_->get_game_data()->get_defeat_music());
|
||||
? (gamestate_->get_game_data()->get_victory_music().empty()
|
||||
? game_config::default_victory_music
|
||||
: gamestate_->get_game_data()->get_victory_music())
|
||||
: (gamestate_->get_game_data()->get_defeat_music().empty()
|
||||
? game_config::default_defeat_music
|
||||
: gamestate_->get_game_data()->get_defeat_music());
|
||||
|
||||
if(music_list.empty()) {
|
||||
// Since this function returns a reference, we can't return a temporary empty string.
|
||||
|
@ -866,31 +886,39 @@ const std::string& play_controller::select_music(bool victory) const
|
|||
return empty_str;
|
||||
}
|
||||
|
||||
return music_list[randomness::rng::default_instance().get_random_int(0, music_list.size()-1)];
|
||||
return music_list[randomness::rng::default_instance().get_random_int(0, music_list.size() - 1)];
|
||||
}
|
||||
|
||||
void play_controller::check_victory()
|
||||
{
|
||||
if(linger_)
|
||||
{
|
||||
if(linger_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_regular_game_end()) {
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool continue_level, found_player, found_network_player, invalidate_all;
|
||||
std::set<unsigned> not_defeated;
|
||||
|
||||
gamestate().board_.check_victory(continue_level, found_player, found_network_player, invalidate_all, not_defeated, remove_from_carryover_on_defeat_);
|
||||
gamestate().board_.check_victory(
|
||||
continue_level,
|
||||
found_player,
|
||||
found_network_player,
|
||||
invalidate_all,
|
||||
not_defeated,
|
||||
remove_from_carryover_on_defeat_
|
||||
);
|
||||
|
||||
if (continue_level) {
|
||||
return ;
|
||||
if(continue_level) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (found_player || found_network_player) {
|
||||
if(found_player || found_network_player) {
|
||||
pump().fire("enemies_defeated");
|
||||
if (is_regular_game_end()) {
|
||||
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -899,24 +927,30 @@ void play_controller::check_victory()
|
|||
DBG_EE << "found_player: " << found_player << std::endl;
|
||||
DBG_EE << "found_network_player: " << found_network_player << std::endl;
|
||||
|
||||
if (!victory_when_enemies_defeated_ && (found_player || found_network_player)) {
|
||||
if(!victory_when_enemies_defeated_ && (found_player || found_network_player)) {
|
||||
// This level has asked not to be ended by this condition.
|
||||
return;
|
||||
}
|
||||
|
||||
if (gui_->video().non_interactive()) {
|
||||
if(gui_->video().non_interactive()) {
|
||||
LOG_AIT << "winner: ";
|
||||
for (unsigned l : not_defeated) {
|
||||
|
||||
for(unsigned l : not_defeated) {
|
||||
std::string ai = ai::manager::get_singleton().get_active_ai_identifier_for_side(l);
|
||||
if (ai.empty()) ai = "default ai";
|
||||
if(ai.empty()) {
|
||||
ai = "default ai";
|
||||
}
|
||||
|
||||
LOG_AIT << l << " (using " << ai << ") ";
|
||||
}
|
||||
|
||||
LOG_AIT << std::endl;
|
||||
ai_testing::log_victory(not_defeated);
|
||||
}
|
||||
|
||||
DBG_EE << "throwing end level exception..." << std::endl;
|
||||
//Also proceed to the next scenario when another player survived.
|
||||
|
||||
// Also proceed to the next scenario when another player survived.
|
||||
end_level_data el_data;
|
||||
el_data.proceed_to_next_level = found_player || found_network_player;
|
||||
el_data.is_victory = found_player;
|
||||
|
@ -925,10 +959,13 @@ void play_controller::check_victory()
|
|||
|
||||
void play_controller::process_oos(const std::string& msg) const
|
||||
{
|
||||
if (gui_->video().non_interactive()) {
|
||||
if(gui_->video().non_interactive()) {
|
||||
throw game::game_error(msg);
|
||||
}
|
||||
if (game_config::ignore_replay_errors) return;
|
||||
|
||||
if(game_config::ignore_replay_errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::stringstream message;
|
||||
message << _("The game is out of sync. It might not make much sense to continue. Do you want to save your game?");
|
||||
|
@ -961,7 +998,7 @@ void play_controller::do_consolesave(const std::string& filename)
|
|||
|
||||
void play_controller::update_savegame_snapshot() const
|
||||
{
|
||||
//note: this writes to level_ if this is not a replay.
|
||||
// note: this writes to level_ if this is not a replay.
|
||||
this->saved_game_.set_snapshot(to_config());
|
||||
}
|
||||
|
||||
|
@ -995,6 +1032,7 @@ bool play_controller::is_browsing() const
|
|||
if(linger_ || !gamestate_->init_side_done() || gamestate().gamedata_.phase() != game_data::PLAY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const team& t = current_team();
|
||||
return !t.is_local_human() || !t.is_proxy_human();
|
||||
}
|
||||
|
@ -1004,12 +1042,10 @@ void play_controller::play_slice_catch()
|
|||
if(should_return_to_play_side()) {
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
|
||||
try {
|
||||
play_slice();
|
||||
}
|
||||
catch(const return_to_play_side_exception&)
|
||||
{
|
||||
} catch(const return_to_play_side_exception&) {
|
||||
assert(should_return_to_play_side());
|
||||
}
|
||||
}
|
||||
|
@ -1018,8 +1054,7 @@ void play_controller::start_game()
|
|||
{
|
||||
fire_preload();
|
||||
|
||||
if(!gamestate().start_event_fired_)
|
||||
{
|
||||
if(!gamestate().start_event_fired_) {
|
||||
gamestate().start_event_fired_ = true;
|
||||
map_start_ = map_location();
|
||||
resources::recorder->add_start_if_not_there_yet();
|
||||
|
@ -1028,11 +1063,12 @@ void play_controller::start_game()
|
|||
set_scontext_synced sync;
|
||||
|
||||
fire_prestart();
|
||||
if (is_regular_game_end()) {
|
||||
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const team& t : gamestate().board_.teams()) {
|
||||
for(const team& t : gamestate().board_.teams()) {
|
||||
actions::clear_shroud(t.side(), false, false);
|
||||
}
|
||||
|
||||
|
@ -1040,21 +1076,21 @@ void play_controller::start_game()
|
|||
LOG_NG << "first_time..." << (is_skipping_replay() ? "skipping" : "no skip") << "\n";
|
||||
|
||||
fire_start();
|
||||
if (is_regular_game_end()) {
|
||||
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sync.do_final_checkup();
|
||||
gui_->recalculate_minimap();
|
||||
|
||||
// Initialize countdown clock.
|
||||
for (const team& t : gamestate().board_.teams())
|
||||
{
|
||||
if (saved_game_.mp_settings().mp_countdown) {
|
||||
for(const team& t : gamestate().board_.teams()) {
|
||||
if(saved_game_.mp_settings().mp_countdown) {
|
||||
t.set_countdown_time(1000 * saved_game_.mp_settings().mp_countdown_init_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
init_gui();
|
||||
gamestate().gamedata_.set_phase(game_data::PLAY);
|
||||
gui_->recalculate_minimap();
|
||||
|
@ -1064,18 +1100,19 @@ void play_controller::start_game()
|
|||
bool play_controller::can_use_synced_wml_menu() const
|
||||
{
|
||||
const team& viewing_team = get_teams_const()[gui_->viewing_team()];
|
||||
return gui_->viewing_team() == gui_->playing_team() && !events::commands_disabled && viewing_team.is_local_human() && !is_lingering() && !is_browsing();
|
||||
return gui_->viewing_team() == gui_->playing_team() && !events::commands_disabled && viewing_team.is_local_human()
|
||||
&& !is_lingering() && !is_browsing();
|
||||
}
|
||||
|
||||
std::set<std::string> play_controller::all_players() const
|
||||
{
|
||||
std::set<std::string> res = gui_->observers();
|
||||
for (const team& t : get_teams_const())
|
||||
{
|
||||
if (t.is_human()) {
|
||||
for(const team& t : get_teams_const()) {
|
||||
if(t.is_human()) {
|
||||
res.insert(t.current_player());
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1090,6 +1127,7 @@ void play_controller::play_side()
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// This flag can be set by derived classes (in overridden functions).
|
||||
player_type_changed_ = false;
|
||||
|
||||
|
@ -1101,9 +1139,9 @@ void play_controller::play_side()
|
|||
return;
|
||||
}
|
||||
|
||||
} while (player_type_changed_);
|
||||
// Keep looping if the type of a team (human/ai/networked)
|
||||
// has changed mid-turn
|
||||
} while(player_type_changed_);
|
||||
|
||||
// Keep looping if the type of a team (human/ai/networked) has changed mid-turn
|
||||
sync_end_turn();
|
||||
}
|
||||
|
||||
|
@ -1122,15 +1160,15 @@ void play_controller::play_turn()
|
|||
int last_player_number = gamestate_->player_number_;
|
||||
int next_player_number = gamestate_->next_player_number_;
|
||||
|
||||
while(gamestate_->player_number_ <= int(gamestate().board_.teams().size()))
|
||||
{
|
||||
while(gamestate_->player_number_ <= int(gamestate().board_.teams().size())) {
|
||||
gamestate_->next_player_number_ = gamestate_->player_number_ + 1;
|
||||
next_player_number = gamestate_->next_player_number_;
|
||||
last_player_number = gamestate_->player_number_;
|
||||
|
||||
// If a side is empty skip over it.
|
||||
if (!current_team().is_empty()) {
|
||||
if(!current_team().is_empty()) {
|
||||
init_side_begin();
|
||||
|
||||
if(gamestate_->init_side_done()) {
|
||||
// This is the case in a reloaded game where the side was initialized before saving the game.
|
||||
init_side_end();
|
||||
|
@ -1138,29 +1176,34 @@ void play_controller::play_turn()
|
|||
|
||||
ai_testing::log_turn_start(current_side());
|
||||
play_side();
|
||||
//ignore any changes to next_player_number_ that happen after the [end_turn] is sended to the server, otherwise we will get OOS.
|
||||
// ignore any changes to next_player_number_ that happen after the [end_turn] is sent to the server,
|
||||
// otherwise we will get OOS.
|
||||
next_player_number = gamestate_->next_player_number_;
|
||||
assert(next_player_number <= 2 * int(gamestate().board_.teams().size()));
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
//note: play_side() send the [end_turn] to the sever and finish_side_turn() callsie the side turn end events.
|
||||
// this means that during the side turn end events the clients think it is still the last sides turn while
|
||||
// the server thinks that it is already the next plyers turn. i don'T think this is a problem though.
|
||||
// note: play_side() send the [end_turn] to the sever and finish_side_turn() calls the side turn end
|
||||
// events.
|
||||
// this means that during the side turn end events the clients think it is still the last sides turn
|
||||
// while the server thinks that it is already the next plyers turn. i don'T think this is a problem
|
||||
// though.
|
||||
finish_side_turn();
|
||||
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(gui_->video().non_interactive()) {
|
||||
LOG_AIT << " Player " << current_side() << ": " <<
|
||||
current_team().villages().size() << " Villages" <<
|
||||
std::endl;
|
||||
LOG_AIT << " Player " << current_side() << ": " << current_team().villages().size() << " Villages"
|
||||
<< std::endl;
|
||||
ai_testing::log_turn_end(current_side());
|
||||
}
|
||||
}
|
||||
|
||||
gamestate_->player_number_ = next_player_number;
|
||||
}
|
||||
|
||||
// If the loop exits due to the last team having been processed.
|
||||
gamestate_->player_number_ = last_player_number;
|
||||
|
||||
|
@ -1169,7 +1212,7 @@ void play_controller::play_turn()
|
|||
// Time has run out
|
||||
check_time_over();
|
||||
|
||||
if (!is_regular_game_end()) {
|
||||
if(!is_regular_game_end()) {
|
||||
gamestate_->player_number_ = modulo(next_player_number, gamestate().board_.teams().size(), 1);
|
||||
}
|
||||
}
|
||||
|
@ -1180,11 +1223,14 @@ void play_controller::check_time_over()
|
|||
|
||||
if(!time_left) {
|
||||
LOG_NG << "firing time over event...\n";
|
||||
|
||||
set_scontext_synced_base sync;
|
||||
pump().fire("time_over");
|
||||
|
||||
LOG_NG << "done firing time over event...\n";
|
||||
|
||||
// If turns are added while handling 'time over' event.
|
||||
if (gamestate().tod_manager_.is_time_left()) {
|
||||
if(gamestate().tod_manager_.is_time_left()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1194,9 +1240,11 @@ void play_controller::check_time_over()
|
|||
}
|
||||
|
||||
check_victory();
|
||||
if (is_regular_game_end()) {
|
||||
|
||||
if(is_regular_game_end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
end_level_data e;
|
||||
e.proceed_to_next_level = false;
|
||||
e.is_victory = false;
|
||||
|
@ -1228,7 +1276,7 @@ void play_controller::toggle_skipping_replay()
|
|||
{
|
||||
skip_replay_ = !skip_replay_;
|
||||
const std::shared_ptr<gui::button> skip_animation_button = get_display().find_action_button("skip-animation");
|
||||
if (skip_animation_button) {
|
||||
if(skip_animation_button) {
|
||||
skip_animation_button->set_check(skip_replay_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "controller_base.hpp"
|
||||
#include "floating_label.hpp"
|
||||
#include "game_end_exceptions.hpp"
|
||||
#include "game_state.hpp"
|
||||
#include "help/help.hpp"
|
||||
#include "hotkey/command_executor.hpp"
|
||||
#include "menu_events.hpp"
|
||||
|
@ -25,7 +26,6 @@
|
|||
#include "persist_manager.hpp"
|
||||
#include "terrain/type_data.hpp"
|
||||
#include "tod_manager.hpp"
|
||||
#include "game_state.hpp"
|
||||
|
||||
#include <set>
|
||||
|
||||
|
@ -39,34 +39,41 @@ struct mp_game_settings;
|
|||
class game_classification;
|
||||
struct unit_experience_accelerator;
|
||||
|
||||
namespace actions {
|
||||
class undo_list;
|
||||
namespace actions
|
||||
{
|
||||
class undo_list;
|
||||
}
|
||||
|
||||
namespace game_events {
|
||||
class manager;
|
||||
class wml_event_pump;
|
||||
class wml_menu_item;
|
||||
namespace game_events
|
||||
{
|
||||
class manager;
|
||||
class wml_event_pump;
|
||||
class wml_menu_item;
|
||||
} // namespace game_events
|
||||
|
||||
namespace soundsource {
|
||||
class manager;
|
||||
namespace soundsource
|
||||
{
|
||||
class manager;
|
||||
} // namespace soundsource
|
||||
|
||||
namespace statistics {
|
||||
struct scenario_context;
|
||||
namespace statistics
|
||||
{
|
||||
struct scenario_context;
|
||||
} // namespace statistics
|
||||
|
||||
namespace pathfind {
|
||||
class manager;
|
||||
namespace pathfind
|
||||
{
|
||||
class manager;
|
||||
}
|
||||
|
||||
namespace tooltips {
|
||||
struct manager;
|
||||
namespace tooltips
|
||||
{
|
||||
struct manager;
|
||||
} // namespace tooltips
|
||||
|
||||
namespace wb {
|
||||
class manager; // whiteboard manager
|
||||
namespace wb
|
||||
{
|
||||
class manager; // whiteboard manager
|
||||
} // namespace wb
|
||||
|
||||
// Holds gamestate related objects
|
||||
|
@ -75,14 +82,22 @@ class game_state;
|
|||
class play_controller : public controller_base, public events::observer, public quit_confirmation
|
||||
{
|
||||
public:
|
||||
play_controller(const config& level, saved_game& state_of_game,
|
||||
const config& game_config,
|
||||
const ter_data_cache& tdata, bool skip_replay);
|
||||
/** Declaration for opaque pointer paradigm. */
|
||||
class hotkey_handler;
|
||||
|
||||
play_controller(const config& level,
|
||||
saved_game& state_of_game,
|
||||
const config& game_config,
|
||||
const ter_data_cache& tdata,
|
||||
bool skip_replay);
|
||||
|
||||
virtual ~play_controller();
|
||||
|
||||
//event handler, overridden from observer
|
||||
//there is nothing to handle in this class actually but that might change in the future
|
||||
virtual void handle_generic_event(const std::string& /*name*/) override {}
|
||||
// event handler, overridden from observer
|
||||
// there is nothing to handle in this class actually but that might change in the future
|
||||
virtual void handle_generic_event(const std::string& /*name*/) override
|
||||
{
|
||||
}
|
||||
|
||||
bool can_undo() const;
|
||||
bool can_redo() const;
|
||||
|
@ -97,6 +112,7 @@ public:
|
|||
void save_replay();
|
||||
void save_replay_auto(const std::string& filename);
|
||||
void save_map();
|
||||
|
||||
replay& get_replay();
|
||||
|
||||
void init_side_begin();
|
||||
|
@ -115,7 +131,6 @@ public:
|
|||
|
||||
virtual void force_end_turn() = 0;
|
||||
virtual void check_objectives() = 0;
|
||||
|
||||
virtual void on_not_observer() = 0;
|
||||
|
||||
/**
|
||||
|
@ -125,41 +140,58 @@ public:
|
|||
*/
|
||||
virtual void process_oos(const std::string& msg) const;
|
||||
|
||||
void set_end_level_data(const end_level_data& data) {
|
||||
void set_end_level_data(const end_level_data& data)
|
||||
{
|
||||
gamestate().end_level_data_ = data;
|
||||
}
|
||||
void reset_end_level_data() {
|
||||
|
||||
void reset_end_level_data()
|
||||
{
|
||||
gamestate().end_level_data_ = boost::none;
|
||||
}
|
||||
bool is_regular_game_end() const {
|
||||
|
||||
bool is_regular_game_end() const
|
||||
{
|
||||
return gamestate().end_level_data_.get_ptr() != nullptr;
|
||||
}
|
||||
const end_level_data& get_end_level_data_const() const {
|
||||
|
||||
const end_level_data& get_end_level_data_const() const
|
||||
{
|
||||
return *gamestate().end_level_data_;
|
||||
}
|
||||
const std::vector<team>& get_teams_const() const {
|
||||
|
||||
const std::vector<team>& get_teams_const() const
|
||||
{
|
||||
return gamestate().board_.teams_;
|
||||
}
|
||||
|
||||
const unit_map& get_units_const() const {
|
||||
const unit_map& get_units_const() const
|
||||
{
|
||||
return gamestate().board_.units();
|
||||
}
|
||||
|
||||
const gamemap& get_map_const() const{
|
||||
const gamemap& get_map_const() const
|
||||
{
|
||||
return gamestate().board_.map();
|
||||
}
|
||||
const tod_manager& get_tod_manager_const() const{
|
||||
return gamestate().tod_manager_;
|
||||
}
|
||||
|
||||
bool is_observer() const {
|
||||
const tod_manager& get_tod_manager_const() const
|
||||
{
|
||||
return gamestate().tod_manager_;
|
||||
}
|
||||
|
||||
bool is_observer() const
|
||||
{
|
||||
return gamestate().board_.is_observer();
|
||||
}
|
||||
|
||||
game_state& gamestate() {
|
||||
game_state& gamestate()
|
||||
{
|
||||
return *gamestate_;
|
||||
}
|
||||
const game_state& gamestate() const {
|
||||
|
||||
const game_state& gamestate() const
|
||||
{
|
||||
return *gamestate_;
|
||||
}
|
||||
|
||||
|
@ -170,35 +202,64 @@ public:
|
|||
*/
|
||||
void check_victory();
|
||||
|
||||
std::size_t turn() const {return gamestate().tod_manager_.turn();}
|
||||
std::size_t turn() const
|
||||
{
|
||||
return gamestate().tod_manager_.turn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of the side whose turn it is.
|
||||
*
|
||||
* Numbering starts at one.
|
||||
*/
|
||||
int current_side() const { return gamestate_->player_number_; }
|
||||
int current_side() const
|
||||
{
|
||||
return gamestate_->player_number_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the snapshot config from members and their respective configs.
|
||||
*/
|
||||
config to_config() const;
|
||||
|
||||
bool is_skipping_replay() const { return skip_replay_; }
|
||||
bool is_skipping_replay() const
|
||||
{
|
||||
return skip_replay_;
|
||||
}
|
||||
|
||||
void toggle_skipping_replay();
|
||||
bool is_linger_mode() const { return linger_; }
|
||||
|
||||
bool is_linger_mode() const
|
||||
{
|
||||
return linger_;
|
||||
}
|
||||
|
||||
void do_autosave();
|
||||
|
||||
void do_consolesave(const std::string& filename);
|
||||
|
||||
events::mouse_handler& get_mouse_handler_base() override;
|
||||
events::menu_handler& get_menu_handler() { return menu_handler_; }
|
||||
|
||||
events::menu_handler& get_menu_handler()
|
||||
{
|
||||
return menu_handler_;
|
||||
}
|
||||
|
||||
std::shared_ptr<wb::manager> get_whiteboard() const;
|
||||
|
||||
const mp_game_settings& get_mp_settings();
|
||||
|
||||
game_classification& get_classification();
|
||||
int get_server_request_number() const { return gamestate().server_request_number_; }
|
||||
void increase_server_request_number() { ++gamestate().server_request_number_; }
|
||||
|
||||
int get_server_request_number() const
|
||||
{
|
||||
return gamestate().server_request_number_;
|
||||
}
|
||||
|
||||
void increase_server_request_number()
|
||||
{
|
||||
++gamestate().server_request_number_;
|
||||
}
|
||||
|
||||
game_events::wml_event_pump& pump();
|
||||
|
||||
|
@ -206,16 +267,24 @@ public:
|
|||
|
||||
virtual soundsource::manager* get_soundsource_man() override;
|
||||
virtual plugins_context* get_plugins_context() override;
|
||||
|
||||
hotkey::command_executor* get_hotkey_command_executor() override;
|
||||
|
||||
actions::undo_list& get_undo_stack() { return undo_stack(); }
|
||||
actions::undo_list& get_undo_stack()
|
||||
{
|
||||
return undo_stack();
|
||||
}
|
||||
|
||||
bool is_browsing() const override;
|
||||
bool is_lingering() const { return linger_; }
|
||||
bool is_lingering() const
|
||||
{
|
||||
return linger_;
|
||||
}
|
||||
|
||||
class hotkey_handler;
|
||||
|
||||
virtual bool is_replay() { return false; }
|
||||
virtual bool is_replay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
t_string get_scenario_name() const
|
||||
{
|
||||
|
@ -239,12 +308,14 @@ public:
|
|||
|
||||
void maybe_throw_return_to_play_side() const
|
||||
{
|
||||
if(should_return_to_play_side() && !linger_ ) {
|
||||
if(should_return_to_play_side() && !linger_) {
|
||||
throw return_to_play_side_exception();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void play_side_impl() {}
|
||||
virtual void play_side_impl()
|
||||
{
|
||||
}
|
||||
|
||||
void play_side();
|
||||
|
||||
|
@ -252,8 +323,14 @@ public:
|
|||
const team& current_team() const;
|
||||
|
||||
bool can_use_synced_wml_menu() const;
|
||||
|
||||
std::set<std::string> all_players() const;
|
||||
int ticks() const { return ticks_; }
|
||||
|
||||
int ticks() const
|
||||
{
|
||||
return ticks_;
|
||||
}
|
||||
|
||||
game_display& get_display() override;
|
||||
|
||||
void update_savegame_snapshot() const;
|
||||
|
@ -262,35 +339,56 @@ public:
|
|||
*/
|
||||
void update_gui_to_player(const int team_index, const bool observe = false);
|
||||
|
||||
virtual bool is_networked_mp() const { return false; }
|
||||
virtual void send_to_wesnothd(const config&, const std::string& = "unknown") const { }
|
||||
virtual bool receive_from_wesnothd(config&) const { return false; }
|
||||
virtual bool is_networked_mp() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void send_to_wesnothd(const config&, const std::string& = "unknown") const
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool receive_from_wesnothd(config&) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void show_objectives() const;
|
||||
|
||||
protected:
|
||||
struct scoped_savegame_snapshot
|
||||
{
|
||||
scoped_savegame_snapshot(const play_controller& controller);
|
||||
~scoped_savegame_snapshot();
|
||||
|
||||
const play_controller& controller_;
|
||||
};
|
||||
|
||||
friend struct scoped_savegame_snapshot;
|
||||
|
||||
void play_slice_catch();
|
||||
|
||||
void process_keydown_event(const SDL_Event& event) override;
|
||||
void process_keyup_event(const SDL_Event& event) override;
|
||||
|
||||
void init_managers();
|
||||
///preload events cannot be synced
|
||||
|
||||
/// preload events cannot be synced
|
||||
void fire_preload();
|
||||
void fire_prestart();
|
||||
void fire_start();
|
||||
|
||||
void start_game();
|
||||
|
||||
virtual void init_gui();
|
||||
|
||||
void finish_side_turn();
|
||||
void finish_turn(); //this should not throw an end turn or end level exception
|
||||
void finish_turn(); // this should not throw an end turn or end level exception
|
||||
|
||||
bool enemies_visible() const;
|
||||
|
||||
bool is_team_visible(int team_num, bool observer) const;
|
||||
|
||||
/// returns 0 if no such team was found.
|
||||
int find_last_visible_team() const;
|
||||
|
||||
|
@ -298,22 +396,22 @@ private:
|
|||
const int ticks_;
|
||||
|
||||
protected:
|
||||
//gamestate
|
||||
// gamestate
|
||||
const ter_data_cache& tdata_;
|
||||
std::unique_ptr<game_state> gamestate_;
|
||||
config level_;
|
||||
saved_game& saved_game_;
|
||||
|
||||
//managers
|
||||
// managers
|
||||
std::unique_ptr<tooltips::manager> tooltips_manager_;
|
||||
|
||||
//whiteboard manager
|
||||
// whiteboard manager
|
||||
std::shared_ptr<wb::manager> whiteboard_manager_;
|
||||
|
||||
//plugins context
|
||||
// plugins context
|
||||
std::unique_ptr<plugins_context> plugins_context_;
|
||||
|
||||
//more managers
|
||||
// more managers
|
||||
font::floating_label_context labels_manager_;
|
||||
help::help_manager help_manager_;
|
||||
events::mouse_handler mouse_handler_;
|
||||
|
@ -322,33 +420,45 @@ protected:
|
|||
std::unique_ptr<soundsource::manager> soundsources_manager_;
|
||||
persist_manager persist_;
|
||||
|
||||
//other objects
|
||||
// other objects
|
||||
std::unique_ptr<game_display> gui_;
|
||||
const std::unique_ptr<unit_experience_accelerator> xp_mod_;
|
||||
const std::unique_ptr<const statistics::scenario_context> statistics_context_;
|
||||
actions::undo_list& undo_stack() { return *gamestate().undo_stack_; }
|
||||
const actions::undo_list& undo_stack() const { return *gamestate().undo_stack_; }
|
||||
|
||||
actions::undo_list& undo_stack()
|
||||
{
|
||||
return *gamestate().undo_stack_;
|
||||
}
|
||||
|
||||
const actions::undo_list& undo_stack() const
|
||||
{
|
||||
return *gamestate().undo_stack_;
|
||||
}
|
||||
|
||||
std::unique_ptr<replay> replay_;
|
||||
|
||||
bool skip_replay_;
|
||||
bool linger_;
|
||||
|
||||
/**
|
||||
* Whether we did init sides in this session
|
||||
* (false = we did init sides before we reloaded the game).
|
||||
*/
|
||||
bool init_side_done_now_;
|
||||
//the displayed location when we load a game.
|
||||
|
||||
// the displayed location when we load a game.
|
||||
map_location map_start_;
|
||||
|
||||
const std::string& select_music(bool victory) const;
|
||||
|
||||
void reset_gamestate(const config& level, int replay_pos);
|
||||
|
||||
private:
|
||||
|
||||
void init(const config& level);
|
||||
|
||||
bool victory_when_enemies_defeated_;
|
||||
bool remove_from_carryover_on_defeat_;
|
||||
|
||||
std::vector<std::string> victory_music_;
|
||||
std::vector<std::string> defeat_music_;
|
||||
|
||||
|
@ -356,9 +466,16 @@ private:
|
|||
|
||||
protected:
|
||||
mutable bool ignore_replay_errors_;
|
||||
|
||||
bool player_type_changed_;
|
||||
virtual void sync_end_turn() {}
|
||||
|
||||
virtual void sync_end_turn()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void check_time_over();
|
||||
|
||||
virtual void update_viewing_player() = 0;
|
||||
|
||||
void play_turn();
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue