void play_controller::show_objectives() const { const team& t = gamestate().board_.teams()[gui_->viewing_team()]; static const std::string no_objectives(_("No objectives available")); std::string objectives = t.objectives(); gui2::show_transient_message(gui_->video(), get_scenario_name(), (objectives.empty() ? no_objectives : objectives), "", true); t.reset_objectives_changed(); }
void playsingle_controller::check_objectives() { const team &t = gamestate().board_.teams()[gui_->viewing_team()]; if (!is_regular_game_end() && !is_browsing() && t.objectives_changed()) { dialogs::show_objectives(get_scenario_name().str(), t.objectives()); t.reset_objectives_changed(); } }
LEVEL_RESULT playsingle_controller::play_scenario(const config& level) { LOG_NG << "in playsingle_controller::play_scenario()...\n"; // Start music. BOOST_FOREACH(const config &m, level.child_range("music")) { sound::play_music_config(m); } sound::commit_music_changes(); if(!this->is_skipping_replay()) { show_story(gui_->video(), get_scenario_name(), level.child_range("story")); } gui_->labels().read(level); // Read sound sources assert(soundsources_manager_ != NULL); BOOST_FOREACH(const config &s, level.child_range("sound_source")) { try { soundsource::sourcespec spec(s); soundsources_manager_->add(spec); } catch (bad_lexical_cast &) { ERR_NG << "Error when parsing sound_source config: bad lexical cast." << std::endl; ERR_NG << "sound_source config was: " << s.debug() << std::endl; ERR_NG << "Skipping this sound source..." << std::endl; } } LOG_NG << "entering try... " << (SDL_GetTicks() - ticks()) << "\n"; try { play_scenario_init(); // clears level config; this->saved_game_.remove_snapshot(); if (!is_regular_game_end() && !linger_) { play_scenario_main_loop(); } if (game_config::exit_at_end) { exit(0); } const bool is_victory = get_end_level_data_const().is_victory; if(gamestate().gamedata_.phase() <= game_data::PRESTART) { sdl::draw_solid_tinted_rectangle( 0, 0, gui_->video().getx(), gui_->video().gety(), 0, 0, 0, 1.0, gui_->video().getSurface() ); update_rect(0, 0, gui_->video().getx(), gui_->video().gety()); } ai_testing::log_game_end(); const end_level_data& end_level = get_end_level_data_const(); if (!end_level.transient.custom_endlevel_music.empty()) { if (!is_victory) { set_defeat_music_list(end_level.transient.custom_endlevel_music); } else { set_victory_music_list(end_level.transient.custom_endlevel_music); } } if (gamestate().board_.teams().empty()) { //store persistent teams saved_game_.set_snapshot(config()); return LEVEL_RESULT::VICTORY; // this is probably only a story scenario, i.e. has its endlevel in the prestart event } if(linger_) { LOG_NG << "resuming from loaded linger state...\n"; //as carryover information is stored in the snapshot, we have to re-store it after loading a linger state saved_game_.set_snapshot(config()); if(!is_observer()) { persist_.end_transaction(); } return LEVEL_RESULT::VICTORY; } pump().fire(is_victory ? "victory" : "defeat"); { // Block for set_scontext_synced_base set_scontext_synced_base sync; pump().fire("scenario end"); } if(end_level.proceed_to_next_level) { gamestate().board_.heal_all_survivors(); } if(is_observer()) { gui2::show_transient_message(gui_->video(), _("Game Over"), _("The game is over.")); return LEVEL_RESULT::OBSERVER_END; } // If we're a player, and the result is victory/defeat, then send // a message to notify the server of the reason for the game ending. network::send_data(config_of ("info", config_of ("type", "termination") ("condition", "game over") ("result", is_victory ? "victory" : "defeat") )); // Play victory music once all victory events // are finished, if we aren't observers. // // Some scenario authors may use 'continue' // result for something that is not story-wise // a victory, so let them use [music] tags // instead should they want special music. const std::string& end_music = is_victory ? select_victory_music() : select_defeat_music(); if(end_music.empty() != true) { sound::play_music_once(end_music); } persist_.end_transaction(); return is_victory ? LEVEL_RESULT::VICTORY : LEVEL_RESULT::DEFEAT; } catch(const game::load_game_exception &) { // Loading a new game is effectively a quit. // if ( game::load_game_exception::game != "" ) { saved_game_ = saved_game(); } throw; } catch(network::error& e) { bool disconnect = false; if(e.socket) { e.disconnect(); disconnect = true; } scoped_savegame_snapshot snapshot(*this); savegame::ingame_savegame save(saved_game_, *gui_, preferences::save_compression_format()); save.save_game_interactive(gui_->video(), _("A network disconnection has occurred, and the game cannot continue. Do you want to save the game?"), gui::YES_NO); if(disconnect) { throw network::error(); } else { return LEVEL_RESULT::QUIT; } } return LEVEL_RESULT::QUIT; }
void play_controller::init(CVideo& video, const config& level) { gui2::dialogs::loading_screen::display(video, [this, &video, &level]() { gui2::dialogs::loading_screen::progress("load level"); LOG_NG << "initializing game_state..." << (SDL_GetTicks() - ticks()) << std::endl; gamestate_.reset(new game_state(level, *this, tdata_)); resources::gameboard = &gamestate().board_; resources::gamedata = &gamestate().gamedata_; resources::tod_manager = &gamestate().tod_manager_; resources::units = &gamestate().board_.units_; resources::filter_con = &gamestate(); resources::undo_stack = &undo_stack(); resources::game_events = gamestate().events_manager_.get(); resources::lua_kernel = gamestate().lua_kernel_.get(); gamestate_->init(level, *this); resources::tunnels = gamestate().pathfind_manager_.get(); LOG_NG << "initializing whiteboard..." << (SDL_GetTicks() - ticks()) << std::endl; gui2::dialogs::loading_screen::progress("init whiteboard"); whiteboard_manager_.reset(new wb::manager()); resources::whiteboard = whiteboard_manager_; LOG_NG << "loading units..." << (SDL_GetTicks() - ticks()) << std::endl; gui2::dialogs::loading_screen::progress("load units"); preferences::encounter_all_content(gamestate().board_); LOG_NG << "initializing theme... " << (SDL_GetTicks() - ticks()) << std::endl; gui2::dialogs::loading_screen::progress("init theme"); const config& theme_cfg = controller_base::get_theme(game_config_, level["theme"]); LOG_NG << "building terrain rules... " << (SDL_GetTicks() - ticks()) << std::endl; gui2::dialogs::loading_screen::progress("build terrain"); gui_.reset(new game_display(gamestate().board_, video, whiteboard_manager_, *gamestate().reports_, gamestate().tod_manager_, theme_cfg, level)); 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("init display"); mouse_handler_.set_gui(gui_.get()); menu_handler_.set_gui(gui_.get()); resources::screen = 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! gamestate().set_game_display(gui_.get()); gui2::dialogs::loading_screen::progress("init lua"); if(gamestate().first_human_team_ != -1) { gui_->set_team(gamestate().first_human_team_); } 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 size_t i; for (i=0; i < gamestate().board_.teams().size(); ++i) { if (!gamestate().board_.teams()[i].get_disallow_observers()) { gui_->set_team(i); } } } init_managers(); gui2::dialogs::loading_screen::progress("start game"); //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("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. gui_->join(); }