Пример #1
0
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();
}
Пример #2
0
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();
	}
}
Пример #3
0
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;
}
Пример #4
0
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();
}