Пример #1
0
possible_end_play_signal playmp_controller::play_idle_loop()
{
	LOG_NG << "playmp::play_human_turn...\n";

	remove_blindfold();

	while (!end_turn_)
	{
		turn_info_send send_safe(turn_data_);
		config cfg;
		if(network_reader_.read(cfg)) {
			turn_info::PROCESS_DATA_RESULT res;
			HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg, skip_replay_) );

			if (res == turn_info::PROCESS_RESTART_TURN || res == turn_info::PROCESS_RESTART_TURN_TEMPORARY_LOCAL)
			{
				end_turn_struct ets = {static_cast<unsigned>(gui_->playing_side())};
				return possible_end_play_signal(ets);
				//throw end_turn_exception(gui_->playing_side());
			}
		}

		HANDLE_END_PLAY_SIGNAL ( play_slice() );
		HANDLE_END_PLAY_SIGNAL ( check_end_level() );

		if (!linger_) {
			SDL_Delay(1);
		}

		gui_->draw();
	}
	return boost::none;
}
Пример #2
0
void playsingle_controller::handle_generic_event(const std::string& name){
	if (name == "ai_user_interact"){
		play_slice(false);
	}
	if (end_turn_){
		throw end_turn_exception();
	}
}
void playsingle_controller::play_idle_loop()
{
	while(!end_turn_) {
		play_slice();
		gui_->draw();
		SDL_Delay(10);
	}
}
Пример #4
0
void playmp_controller::play_network_turn(){
	LOG_NG << "is networked...\n";

	gui_->set_theme_object_active("undo", false);
	gui_->set_theme_object_active("endturn", false);
	turn_info turn_data(player_number_, replay_sender_, undo_stack_);
	turn_data.host_transfer().attach_handler(this);

	for(;;) {

		if (!network_processing_stopped_){
			bool turn_ended = false;
			config cfg;

			network::connection from = network::null_connection;

			if (data_backlog_.empty() == false) {
				cfg = data_backlog_.front();
				data_backlog_.pop_front();

			} else if (!received_data_cfg_.empty()) {
				cfg = received_data_cfg_.front();
				received_data_cfg_.erase(received_data_cfg_.begin());
				from = lobby->transit.conn();
			}

			if (!cfg.empty()) {
				if (skip_replay_ && replay_last_turn_ <= turn()) {
					skip_replay_ = false;
				}
				const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg, from, data_backlog_, skip_replay_);
				if (result == turn_info::PROCESS_RESTART_TURN) {
					player_type_changed_ = true;
					return;
				} else if (result == turn_info::PROCESS_END_TURN) {
					turn_ended = true;
					break;
				}
			}
			if (turn_ended) {
				break;
			}
		}

		play_slice();
		check_end_level();

		if (!network_processing_stopped_){
			turn_data.send_data();
		}

		gui_->draw();
	}

	turn_data.host_transfer().detach_handler(this);
	LOG_NG << "finished networked...\n";
	return;
}
Пример #5
0
possible_end_play_signal playmp_controller::play_network_turn(){
	LOG_NG << "is networked...\n";

	end_turn_enable(false);
	turn_data_.send_data();

	for(;;) {

		if (!network_processing_stopped_){
			config cfg;
			if(network_reader_.read(cfg)) {
				if (replay_last_turn_ <= turn()){
					if (skip_replay_) {
						skip_replay_ = false;
					}
				}
				turn_info::PROCESS_DATA_RESULT result;
				HANDLE_END_PLAY_SIGNAL ( result = turn_data_.process_network_data(cfg, skip_replay_) );
				if(player_type_changed_ == true)
				{
					//we received a player change/quit during waiting in get_user_choice/synced_context::pull_remote_user_input
					return boost::none;
				}
				if (result == turn_info::PROCESS_RESTART_TURN || result == turn_info::PROCESS_RESTART_TURN_TEMPORARY_LOCAL) {
					player_type_changed_ = true;
					return boost::none;
				} else if (result == turn_info::PROCESS_END_TURN) {
					break;
				}
			}
			/*
				we might have data left in replay that we recieved during prestart events. (or maybe other events.)
			*/
			else if(!recorder.at_end())
			{
				bool was_skipping = recorder.is_skipping();
				recorder.set_skip(skip_replay_);
				if(do_replay() == REPLAY_FOUND_END_TURN)
				{
					break;
				}
				recorder.set_skip(was_skipping);
			}
		}

		HANDLE_END_PLAY_SIGNAL( play_slice() );
		HANDLE_END_PLAY_SIGNAL( check_end_level() );

		if (!network_processing_stopped_){
			turn_data_.send_data();
		}

		gui_->draw();
	}

	LOG_NG << "finished networked...\n";
	return boost::none;
}
void playsingle_controller::linger()
{
	LOG_NG << "beginning end-of-scenario linger\n";
	browse_ = true;
	linger_ = true;

	// If we need to set the status depending on the completion state
	// the key to it is here.
	gui_->set_game_mode(game_display::LINGER_SP);

	// this is actually for after linger mode is over -- we don't
	// want to stay stuck in linger state when the *next* scenario
	// is over.
	set_completion setter(gamestate_,"running");

	// change the end-turn button text to its alternate label
	gui_->get_theme().refresh_title2("button-endturn", "title2");
	gui_->invalidate_theme();
	gui_->redraw_everything();

	// End all unit moves
	for (unit_map::iterator u = units_.begin(); u != units_.end(); ++u) {
		u->set_user_end_turn(true);
	}

	start_pass_scenario_anim(get_end_level_data().result);

	try {
		// Same logic as single-player human turn, but
		// *not* the same as multiplayer human turn.
		gui_->enable_menu("endturn", true);
		while(!end_turn_) {
			// Reset the team number to make sure we're the right team.
			player_number_ = first_player_;
			play_slice();
			gui_->draw();
		}
	} catch(game::load_game_exception& lge) {
		// Loading a new game is effectively a quit.
		if (lge.game != "") {
			gamestate_ = game_state();
		}
		throw lge;
	}

	if (gui_->pass_scenario_anim_id() != -1) {
		gui_->erase_screen_anim(gui_->pass_scenario_anim_id());
	}

	// revert the end-turn button text to its normal label
	gui_->get_theme().refresh_title2("button-endturn", "title");
	gui_->invalidate_theme();
	gui_->redraw_everything();
	gui_->set_game_mode(game_display::RUNNING);

	LOG_NG << "ending end-of-scenario linger\n";
}
Пример #7
0
possible_end_play_signal playsingle_controller::play_idle_loop()
{
    while(!end_turn_) {
        HANDLE_END_PLAY_SIGNAL( play_slice() );
        gui_->draw();
        SDL_Delay(10);
    }
    return boost::none;
}
void playsingle_controller::play_human_turn() {
	show_turn_dialog();
	execute_gotos();

	while(!end_turn_) {
		play_slice();
		check_end_level();
		gui_->draw();
	}
}
void playsingle_controller::linger()
{
	mouse_handler_.do_right_click(false);

	browse_ = true;
	linger_ = true;

	// If we need to set the status depending on the completion state
	// the key to it is here.
	gui_->set_game_mode(game_display::LINGER_SP);

	// this is actually for after linger mode is over -- we don't
	// want to stay stuck in linger state when the *next* scenario
	// is over.
	set_completion setter(gamestate_,"running");

	// change the end-turn button text to its alternate label
	gui_->redraw_everything();

	// button be reconstruct.
	if (lobby->chat.ready()) {
		refresh_chat_button(*gui_, "misc/network-disconnected.png");
	}

	start_pass_scenario_anim(get_end_level_data().result);

	try {
		// Same logic as single-player human turn, but
		// *not* the same as multiplayer human turn.
		gui_->set_theme_object_active("endturn", true);
		while(!end_turn_) {
			// Reset the team number to make sure we're the right team.
			player_number_ = first_player_;
			play_slice();
			gui_->draw();
		}
	} catch(game::load_game_exception& lge) {
		// Loading a new game is effectively a quit.
		if (lge.game != "") {
			gamestate_ = game_state();
		}
		throw lge;
	}

	if (gui_->pass_scenario_anim_id() != -1) {
		gui_->erase_area_anim(gui_->pass_scenario_anim_id());
	}

	// revert the end-turn button text to its normal label
	gui_->redraw_everything();
	gui_->set_game_mode(game_display::RUNNING);

	LOG_NG << "ending end-of-scenario linger\n";
}
void playsingle_controller::handle_generic_event(const std::string& name)
{
	if (name == "ai_user_interact"){
		play_slice(false);
	}
/*
	// why remark, reference http://www.freeors.com/bbs/forum.php?mod=viewthread&tid=21952&page=1&extra=#pid30175
	if (end_turn_){
		throw end_turn_exception();
	}
*/
}
possible_end_play_signal replay_controller::try_run_to_completion() {
	for (;;) {
		HANDLE_END_PLAY_SIGNAL( play_slice() );
		if (recorder.at_end()) {
			return boost::none;
		} else {
			if (!is_playing_) {
				PROPOGATE_END_PLAY_SIGNAL( play_replay() );
			}
		}
	}
}
Пример #12
0
void playmp_controller::play_network_turn(){
	LOG_NG << "is networked...\n";

	gui_->enable_menu("endturn", false);
	turn_info turn_data(player_number_, replay_sender_, undo_stack_);
	turn_data.host_transfer().attach_handler(this);

	for(;;) {

		if (!network_processing_stopped_){
			bool have_data = false;
			config cfg;

			network::connection from = network::null_connection;

			if(data_backlog_.empty() == false) {
				have_data = true;
				cfg = data_backlog_.front();
				data_backlog_.pop_front();
			} else {
				from = network::receive_data(cfg);
				have_data = from != network::null_connection;
			}

			if(have_data) {
				if (skip_replay_ && replay_last_turn_ <= turn()){
						skip_replay_ = false;
				}
				const turn_info::PROCESS_DATA_RESULT result = turn_data.process_network_data(cfg, from, data_backlog_, skip_replay_);
				if (result == turn_info::PROCESS_RESTART_TURN) {
					player_type_changed_ = true;
					return;
				} else if (result == turn_info::PROCESS_END_TURN) {
					break;
				}
			}
		}

		play_slice();
		check_end_level();

		if (!network_processing_stopped_){
			turn_data.send_data();
		}

		gui_->draw();
	}

	turn_data.host_transfer().detach_handler(this);
	LOG_NG << "finished networked...\n";
	return;
}
Пример #13
0
possible_end_play_signal playsingle_controller::play_human_turn() {
    show_turn_dialog();
    HANDLE_END_PLAY_SIGNAL( execute_gotos() );

    end_turn_enable(true);
    while(!end_turn_) {
        HANDLE_END_PLAY_SIGNAL( play_slice() );
        HANDLE_END_PLAY_SIGNAL( check_end_level() );
        gui_->draw();
    }

    return boost::none;
}
Пример #14
0
void play_controller::play_slice_catch()
{
    if(should_return_to_play_side()) {
        return;
    }
    try
    {
        play_slice();
    }
    catch(const return_to_play_side_exception&)
    {
        assert(should_return_to_play_side());
    }
}
EXIT_STATUS editor_controller::main_loop()
{
	try {
		while (!do_quit_) {
			play_slice();
		}
	} catch (editor_exception& e) {
		gui2::show_transient_message(gui().video(), _("Fatal error"), e.what());
		return EXIT_ERROR;
	} catch (twml_exception& e) {
		e.show(gui());
	}
	return quit_mode_;
}
Пример #16
0
void playsingle_controller::linger()
{
    LOG_NG << "beginning end-of-scenario linger\n";
    browse_ = true;
    linger_ = true;

    // If we need to set the status depending on the completion state
    // the key to it is here.
    gui_->set_game_mode(game_display::LINGER_SP);

    // this is actually for after linger mode is over -- we don't
    // want to stay stuck in linger state when the *next* scenario
    // is over.
    set_completion setter(saved_game_,"running");

    // change the end-turn button text to its alternate label
    gui_->get_theme().refresh_title2("button-endturn", "title2");
    gui_->invalidate_theme();
    gui_->redraw_everything();

    // End all unit moves
    gamestate_.board_.set_all_units_user_end_turn();
    try {
        // Same logic as single-player human turn, but
        // *not* the same as multiplayer human turn.
        end_turn_enable(true);
        end_turn_ = false;
        while(!end_turn_) {
            // Reset the team number to make sure we're the right team.
            player_number_ = first_player_;
            play_slice();
            gui_->draw();
        }
    } 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;
    }

    // revert the end-turn button text to its normal label
    gui_->get_theme().refresh_title2("button-endturn", "title");
    gui_->invalidate_theme();
    gui_->redraw_everything();
    gui_->set_game_mode(game_display::RUNNING);

    LOG_NG << "ending end-of-scenario linger\n";
}
void replay_controller::play_turn(){

	LOG_REPLAY << "turn: " << current_turn_ << "\n";

	gui_->new_turn();
	gui_->invalidate_game_status();
	events::raise_draw_event();

	bool last_team = false;

	while ( (!last_team) && (!recorder.at_end()) && is_playing_ ){
		last_team = static_cast<size_t>(player_number_) == teams_.size();
		play_side(player_number_ - 1, false);
		play_slice();
	}
}
Пример #18
0
void playmp_controller::play_linger_turn()
{
	if (is_host()) {
		end_turn_enable(true);
	}

	while(end_turn_ == END_TURN_NONE) {
		config cfg;
		if(network_reader_.read(cfg)) {
			if(turn_data_.process_network_data(cfg) == turn_info::PROCESS_END_LINGER)
			{
				end_turn();
			}
		}
		play_slice();
	}
}
//make all sides move, then stop
possible_end_play_signal replay_controller::play_turn(){

	LOG_REPLAY << "turn: " << current_turn_ << "\n";

	gui_->new_turn();
	gui_->invalidate_game_status();
	events::raise_draw_event();

	bool last_team = false;

	while ( (!last_team) && (!recorder.at_end()) && is_playing_ ){
		last_team = static_cast<size_t>(player_number_) == gamestate_.board_.teams().size();
		PROPOGATE_END_PLAY_SIGNAL( play_side() );
		HANDLE_END_PLAY_SIGNAL( play_slice() );
	}
	return boost::none;
}
Пример #20
0
void playsingle_controller::linger()
{
	LOG_NG << "beginning end-of-scenario linger\n";
	linger_ = true;

	// If we need to set the status depending on the completion state
	// the key to it is here.
	gui_->set_game_mode(game_display::LINGER);

	// change the end-turn button text to its alternate label
	gui_->get_theme().refresh_title2("button-endturn", "title2");
	gui_->invalidate_theme();
	gui_->redraw_everything();

	// End all unit moves
	gamestate().board_.set_all_units_user_end_turn();
	try {
		// Same logic as single-player human turn, but
		// *not* the same as multiplayer human turn.
		end_turn_enable(true);
		end_turn_ = END_TURN_NONE;
		while(end_turn_ == END_TURN_NONE) {
			play_slice();
			gui_->draw();
		}
	} 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;
	}

	// revert the end-turn button text to its normal label
	gui_->get_theme().refresh_title2("button-endturn", "title");
	gui_->invalidate_theme();
	gui_->redraw_everything();
	gui_->set_game_mode(game_display::RUNNING);

	LOG_NG << "ending end-of-scenario linger\n";
}
Пример #21
0
void playsingle_controller::play_human_turn() 
{
	show_turn_dialog();
	execute_gotos();

	bool auto_end_turn = can_auto_end_turn(true);
	if (!auto_end_turn) {
		if (!unit::actor->is_city() && unit::actor->task() == unit::TASK_NONE) {
			gui_->scroll_to_tile(unit::actor->get_location(), game_display::ONSCREEN, true, true);
		}
	} else {
		return;
	}

	while (!end_turn_ && pause_when_human_ && !auto_end_turn) {
		play_slice();
		check_end_level();
		gui_->draw();

		auto_end_turn = can_auto_end_turn(false);
	}
}
Пример #22
0
void playmp_controller::play_human_turn()
{
	command_disabled_resetter reset_commands;
	int cur_ticks = SDL_GetTicks();
	show_turn_dialog();
	execute_gotos();

	bool auto_end_turn = can_auto_end_turn(true);
	if (!auto_end_turn) {
		if (!unit::actor->is_city() && unit::actor->task() == unit::TASK_NONE) {
			gui_->scroll_to_tile(unit::actor->get_location(), game_display::ONSCREEN, true, true);
		}
	} else {
		return;
	}

	if ((!linger_) || (is_host_)) {
		gui_->set_theme_object_active("endturn", true);
	}

	while (!end_turn_ && !auto_end_turn) {
		try {
			play_slice();
			check_end_level();

			std::deque<config> backlog;
			std::vector<config> cfgs = received_data_cfg_;
			received_data_cfg_.clear();
			for (std::vector<config>::const_iterator it = cfgs.begin(); it != cfgs.end(); ++ it) {
				const config& cfg = *it;
				if (turn_data_->process_network_data(cfg, lobby->transit.conn(), backlog, skip_replay_) == turn_info::PROCESS_RESTART_TURN) {
					// Clean undo stack if turn has to be restarted (losing control)
					if (!undo_stack_.empty()) {
						font::floating_label flabel(_("Undoing moves not yet transmitted to the server."));

						SDL_Color color = {255,255,255,255};
						flabel.set_color(color);
						SDL_Rect rect = gui_->map_area();
						flabel.set_position(rect.w/2, rect.h/2);
						flabel.set_lifetime(150);
						flabel.set_clip_rect(rect);

						font::add_floating_label(flabel);
					}

					while(!undo_stack_.empty()) {
						menu_handler_.undo(gui_->get_playing_team() + 1);
					}
					throw end_turn_exception(gui_->get_playing_team() + 1);
				}
			}

		} catch (end_level_exception& e) {
			turn_data_->send_data();
			throw e;
		}

		if (!linger_ && (current_team().countdown_time() > 0) && gamestate_.mp_settings().mp_countdown) {
			SDL_Delay(1);
			const int ticks = SDL_GetTicks();
			int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks));
			if (new_time > 0 ){
				current_team().set_countdown_time(new_time);
				cur_ticks = ticks;
				if(current_team().is_human() && !beep_warning_time_) {
					beep_warning_time_ = new_time - WARNTIME + ticks;
				}
				if(counting_down()) {
					think_about_countdown(ticks);
				}
			} else {
				// Clock time ended
				// If no turn bonus or action bonus -> defeat
				const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus;
				if ( (gamestate_.mp_settings().mp_countdown_turn_bonus == 0 )
					&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
					// Not possible to end level in MP with throw end_level_exception(DEFEAT);
					// because remote players only notice network disconnection
					// Current solution end remaining turns automatically
					current_team().set_countdown_time(10);
				} else {
					const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time;
					int secs = gamestate_.mp_settings().mp_countdown_turn_bonus;
					secs += action_increment  * current_team().action_bonus_count();
					current_team().set_action_bonus_count(0);
					secs = (secs > maxtime) ? maxtime : secs;
					current_team().set_countdown_time(1000 * secs);
				}
				turn_data_->send_data();

				throw end_turn_exception();
			}
		}

		gui_->draw();

		turn_data_->send_data();

		auto_end_turn = can_auto_end_turn(false);
	}
	menu_handler_.clear_undo_stack(player_number_);
}
Пример #23
0
void playsingle_controller::play_idle_loop()
{
	play_slice();
	gui_->draw();
	SDL_Delay(10);
}
Пример #24
0
possible_end_play_signal playmp_controller::play_human_turn(){
	LOG_NG << "playmp::play_human_turn...\n";

	remove_blindfold();
	int cur_ticks = SDL_GetTicks();
	show_turn_dialog();

	if (!preferences::disable_auto_moves()) {
		HANDLE_END_PLAY_SIGNAL(execute_gotos());
	}

	if (!linger_ || is_host()) {
		end_turn_enable(true);
	}
	while(!end_turn_) {
		turn_info_send send_safe(turn_data_);
			config cfg;

			if(network_reader_.read(cfg)) {
				turn_info::PROCESS_DATA_RESULT res;
				HANDLE_END_PLAY_SIGNAL( res = turn_data_.process_network_data(cfg, skip_replay_) );
				//PROCESS_RESTART_TURN_TEMPORARY_LOCAL should be impossible because that's means the currently active side (that's us) left.
				if (res == turn_info::PROCESS_RESTART_TURN || res == turn_info::PROCESS_RESTART_TURN_TEMPORARY_LOCAL)
				{
					// Clean undo stack if turn has to be restarted (losing control)
					if ( undo_stack_->can_undo() )
					{
						font::floating_label flabel(_("Undoing moves not yet transmitted to the server."));

						SDL_Color color = {255,255,255,255};
						flabel.set_color(color);
						SDL_Rect rect = gui_->map_area();
						flabel.set_position(rect.w/2, rect.h/2);
						flabel.set_lifetime(150);
						flabel.set_clip_rect(rect);

						font::add_floating_label(flabel);
					}

					while( undo_stack_->can_undo() )
						undo_stack_->undo();

					end_turn_struct ets = {static_cast<unsigned>(gui_->playing_side())};
					return possible_end_play_signal(ets);
					//throw end_turn_exception(gui_->playing_side());
				}
				else if(res == turn_info::PROCESS_END_LINGER)
				{
					if(!linger_)
						replay::process_error("Received unexpected next_scenario durign the game");
					else
					{
						//we end the turn immidiately to prevent receiving data of the next scenario while we are not playing it.
						end_turn();
					}
				}
			}

			HANDLE_END_PLAY_SIGNAL( play_slice() );
			HANDLE_END_PLAY_SIGNAL( check_end_level() );

		if (!linger_ && (current_team().countdown_time() > 0) && saved_game_.mp_settings().mp_countdown) {
			SDL_Delay(1);
			const int ticks = SDL_GetTicks();
			int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks));
			if (new_time > 0 ){
				current_team().set_countdown_time(new_time);
				cur_ticks = ticks;
				if(current_team().is_human() && !beep_warning_time_) {
					beep_warning_time_ = new_time - WARNTIME + ticks;
				}
				if(counting_down()) {
					think_about_countdown(ticks);
				}
			} else {
				// Clock time ended
				// If no turn bonus or action bonus -> defeat
				const int action_increment = saved_game_.mp_settings().mp_countdown_action_bonus;
				if ( (saved_game_.mp_settings().mp_countdown_turn_bonus == 0 )
					&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
					// Not possible to end level in MP with throw end_level_exception(DEFEAT);
					// because remote players only notice network disconnection
					// Current solution end remaining turns automatically
					current_team().set_countdown_time(10);
				}

				return possible_end_play_signal(end_turn_exception().to_struct());
				//throw end_turn_exception();
			}
		}

		gui_->draw();
	}
	return boost::none;
}
Пример #25
0
void playsingle_controller::handle_generic_event(const std::string& name){
	if (name == "ai_user_interact"){
		play_slice(false);
	}
}
Пример #26
0
void playmp_controller::play_human_turn(){
	LOG_NG << "playmp::play_human_turn...\n";
	command_disabled_resetter reset_commands;
	int cur_ticks = SDL_GetTicks();
	show_turn_dialog();
	execute_gotos();

	if (!linger_ || is_host_) {
		end_turn_enable(true);
	}
	while(!end_turn_) {

		try {
			config cfg;
			const network::connection res = network::receive_data(cfg);
			std::deque<config> backlog;

			if(res != network::null_connection) {
				if (turn_data_->process_network_data(cfg, res, backlog, skip_replay_) == turn_info::PROCESS_RESTART_TURN)
				{
					// Clean undo stack if turn has to be restarted (losing control)
					if ( undo_stack_->can_undo() )
					{
						font::floating_label flabel(_("Undoing moves not yet transmitted to the server."));

						SDL_Color color = {255,255,255,255};
						flabel.set_color(color);
						SDL_Rect rect = gui_->map_area();
						flabel.set_position(rect.w/2, rect.h/2);
						flabel.set_lifetime(150);
						flabel.set_clip_rect(rect);

						font::add_floating_label(flabel);
					}

					while( undo_stack_->can_undo() )
						undo_stack_->undo();
					throw end_turn_exception(gui_->playing_side());
				}
			}

			play_slice();
			check_end_level();
			// give a chance to the whiteboard to continue an execute_all_actions
			resources::whiteboard->continue_execute_all();
		} catch(const end_level_exception&) {
			turn_data_->send_data();
			throw;
		}

		if (!linger_ && (current_team().countdown_time() > 0) && gamestate_.mp_settings().mp_countdown) {
			SDL_Delay(1);
			const int ticks = SDL_GetTicks();
			int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks));
			if (new_time > 0 ){
				current_team().set_countdown_time(new_time);
				cur_ticks = ticks;
				if(current_team().is_human() && !beep_warning_time_) {
					beep_warning_time_ = new_time - WARNTIME + ticks;
				}
				if(counting_down()) {
					think_about_countdown(ticks);
				}
			} else {
				// Clock time ended
				// If no turn bonus or action bonus -> defeat
				const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus;
				if ( (gamestate_.mp_settings().mp_countdown_turn_bonus == 0 )
					&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
					// Not possible to end level in MP with throw end_level_exception(DEFEAT);
					// because remote players only notice network disconnection
					// Current solution end remaining turns automatically
					current_team().set_countdown_time(10);
				} else {
					const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time;
					int secs = gamestate_.mp_settings().mp_countdown_turn_bonus;
					secs += action_increment  * current_team().action_bonus_count();
					current_team().set_action_bonus_count(0);
					secs = (secs > maxtime) ? maxtime : secs;
					current_team().set_countdown_time(1000 * secs);
				}
				turn_data_->send_data();

				if (!rand_rng::has_new_seed_callback()) {
					throw end_turn_exception();
				}
			}
		}

		gui_->draw();

		turn_data_->send_data();
	}
}
Пример #27
0
void playmp_controller::play_human_turn(){
	LOG_NG << "playmp::play_human_turn...\n";
	command_disabled_resetter reset_commands;
	int cur_ticks = SDL_GetTicks();
	show_turn_dialog();
	execute_gotos();

	if ((!linger_) || (is_host_))
		gui_->enable_menu("endturn", true);
	while(!end_turn_) {

		try {
			config cfg;
			const network::connection res = network::receive_data(cfg);
			std::deque<config> backlog;

			if(res != network::null_connection) {
				if (turn_data_->process_network_data(cfg, res, backlog, skip_replay_) == turn_info::PROCESS_RESTART_TURN)
				{
					// Clean undo stack if turn has to be restarted (losing control)
					if (!undo_stack_.empty())
					{
						const std::string msg =_("Undoing moves not yet transmitted to the server.");
						const int size = 20;
						const int lifetime = 150;
						SDL_Color colour = {255,255,255,255};

						SDL_Rect rect = gui_->map_area();
						font::add_floating_label(msg,size, colour,
								rect.w/2,rect.h/2,0.0,0.0,lifetime,rect,font::CENTER_ALIGN);
					}

					while(!undo_stack_.empty())
						menu_handler_.undo(gui_->get_playing_team() + 1);
					throw end_turn_exception(gui_->get_playing_team() + 1);
				}
			}

			play_slice();
			check_end_level();
		} catch(end_level_exception& e) {
			turn_data_->send_data();
			throw e;
		}

		if (!linger_ && (current_team().countdown_time() > 0) && gamestate_.mp_settings().mp_countdown) {
			SDL_Delay(1);
			const int ticks = SDL_GetTicks();
			int new_time = current_team().countdown_time()-std::max<int>(1,(ticks - cur_ticks));
			if (new_time > 0 ){
				current_team().set_countdown_time(new_time);
				cur_ticks = ticks;
				if(current_team().is_human() && !beep_warning_time_) {
					beep_warning_time_ = new_time - WARNTIME + ticks;
				}
				if(counting_down()) {
					think_about_countdown(ticks);
				}
			} else {
				// Clock time ended
				// If no turn bonus or action bonus -> defeat
				const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus;
				if ( (gamestate_.mp_settings().mp_countdown_turn_bonus == 0 )
					&& (action_increment == 0 || current_team().action_bonus_count() == 0)) {
					// Not possible to end level in MP with throw end_level_exception(DEFEAT);
					// because remote players only notice network disconnection
					// Current solution end remaining turns automatically
					current_team().set_countdown_time(10);
				} else {
					const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time;
					int secs = gamestate_.mp_settings().mp_countdown_turn_bonus;
					secs += action_increment  * current_team().action_bonus_count();
					current_team().set_action_bonus_count(0);
					secs = (secs > maxtime) ? maxtime : secs;
					current_team().set_countdown_time(1000 * secs);
				}
				turn_data_->send_data();

				throw end_turn_exception();
			}
		}

		gui_->draw();

		turn_data_->send_data();
	}
	menu_handler_.clear_undo_stack(player_number_);
}