Пример #1
0
void playmp_controller::after_human_turn(){
	if ( gamestate_.mp_settings().mp_countdown ){
		const int action_increment = gamestate_.mp_settings().mp_countdown_action_bonus;
		const int maxtime = gamestate_.mp_settings().mp_countdown_reservoir_time;
		int secs = (current_team().countdown_time() / 1000) + 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);
		recorder.add_countdown_update(current_team().countdown_time(),player_number_);
	}
	LOG_NG << "playmp::after_human_turn...\n";
	end_turn_record();

	//ensure that turn_data_ is constructed before it is used.
	if (turn_data_ == NULL) init_turn_data();

	//send one more time to make sure network is up-to-date.
	playsingle_controller::after_human_turn();
	turn_data_->send_data();
	if (turn_data_ != NULL){
		turn_data_->host_transfer().detach_handler(this);
		delete turn_data_;
		turn_data_ = NULL;
	}

}
Пример #2
0
void playmp_controller::wait_for_upload()
{
	// If the host is here we'll never leave since we wait for the host to
	// upload the next scenario.
	assert(!is_host_);

	const bool set_turn_data = (turn_data_ == 0);
	if(set_turn_data) {
		init_turn_data();
	}

	while(true) {
		try {
			config cfg;
			const network::connection res = dialogs::network_receive_dialog(*gui_, _("Waiting for next scenario..."), cfg);

			std::deque<config> backlog;
			if(res != network::null_connection) {
				if (turn_data_->process_network_data(cfg, res, backlog, skip_replay_)
						== turn_info::PROCESS_END_LINGER) {
					break;
				}
			}

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

	if(set_turn_data) {
		release_turn_data();
	}
}
Пример #3
0
void playmp_controller::before_human_turn(bool save){
	LOG_NG << "playmp::before_human_turn...\n";
	playsingle_controller::before_human_turn(save);

	init_turn_data();
}
Пример #4
0
void playmp_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
	// we're needed here.
	gui_->set_game_mode(game_display::LINGER_MP);

	// 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.
	gamestate_.classification().completion = "running";
	// End all unit moves
	for (unit_map::iterator u = units_.begin(); u != units_.end(); ++ u) {
		u->set_user_end_turn(true);
	}
	//current_team().set_countdown_time(0);
	//halt and cancel the countdown timer
	reset_countdown();

	set_end_scenario_button();

	if ( get_end_level_data().reveal_map ) {
		// switch to observer viewpoint
		gui_->set_team(0,true);
		gui_->recalculate_minimap();
		gui_->invalidate_all();
		gui_->draw(true,true);
	}
	bool quit;
	do {
		quit = true;
		try {
			// reimplement parts of play_side()
			player_number_ = first_player_;
			init_turn_data();

			play_human_turn();
			turn_over_ = true;  // We don't want to linger mode to add end_turn to replay
			after_human_turn();
			LOG_NG << "finished human turn" << std::endl;
		} catch (game::load_game_exception&) {
			LOG_NG << "caught load-game-exception" << std::endl;
			// this should not happen, the option to load a game is disabled
			throw;
		} catch (end_level_exception&) {
			// thrown if the host ends the scenario and let us advance
			// to the next level
			LOG_NG << "caught end-level-exception" << std::endl;
			reset_end_scenario_button();
			throw;
		} catch (end_turn_exception&) {
			// thrown if the host leaves the game (sends [leave_game]), we need
			// to stay in this loop to stay in linger mode, otherwise the game
			// gets aborted
			LOG_NG << "caught end-turn-exception" << std::endl;
			quit = false;
		} catch (network::error&) {
			LOG_NG << "caught network-error-exception" << std::endl;
			quit = false;
		}
	} while (!quit);

	reset_end_scenario_button();

	LOG_NG << "ending end-of-scenario linger\n";
}
Пример #5
0
void playmp_controller::before_human_turn(bool save)
{
	playsingle_controller::before_human_turn(save);

	init_turn_data();
}
Пример #6
0
void playmp_controller::play_side()
{
	utils::string_map player;
	player["name"] = current_team().current_player();
	std::string turn_notification_msg = _("$name has taken control");
	turn_notification_msg = utils::interpolate_variables_into_string(turn_notification_msg, &player);
	gui_->send_notification(_("Turn changed"), turn_notification_msg);

	int end_ticks = calculate_end_ticks();

	player_type_changed_ = false;
	while (unit_map::main_ticks < end_ticks && !player_type_changed_) {
		VALIDATE(!unit::actor, "playmp_controller::play_side, unit::actor isn't NULL!");

		if (!skip_next_turn_) {
			end_turn_ = false;
		}

		unit* u = &units_.current_unit();
		if (!tent::turn_based) {
			int past_ticks = u->backward_ticks(u->ticks());
			if (unit_map::main_ticks + past_ticks >= end_ticks) {
				units_.do_escape_ticks_uh(teams_, *gui_, end_ticks - unit_map::main_ticks, false);
				autosave_ticks_ = -1;
				continue;
			}
			units_.do_escape_ticks_uh(teams_, *gui_, past_ticks, true);
		} else {
			if (u->side() < player_number_) {
				unit_map::main_ticks = end_ticks;
				player_number_ = 1;
				continue;
			}
		}
		// if exist spirit feature/technology, second maybe goto first. need reget
		u = &units_.current_unit();

		player_number_ = u->side(); // init_turn_data need player_number_ be valid.
		team& t = teams_[player_number_ - 1];

		bool local = t.is_local();
		bool new_side = false;
		if (local || loading_game_) {
			if (local) {
				init_turn_data();
			}
			new_side = do_prefix_unit(end_ticks, loading_game_, false);
		}

		if (t.is_network()) {
			play_network_turn();

		} else if (actor_can_continue_action(units_, player_number_)) {
			// we can't call playsingle_controller::play_side because
			// we need to catch exception here
			if (t.is_human()) {
				try {
					if (!loading_game_ && unit::actor->human_team_can_ai()) {
						play_ai_turn(turn_data_);
					}
					before_human_turn(new_side);
					play_human_turn();
					after_human_turn();
				} catch (end_turn_exception& end_turn) {
					if (end_turn.redo == player_number_ - 1) {
						player_type_changed_ = true;
						// if new controller is not human,
						// reset gui to prev human one
						if (!teams_[player_number_ - 2].is_human()) {
							browse_ = true;
							int t = find_human_team_before(player_number_ - 1);

							if (t <= 0)
								t = gui_->get_playing_team() + 1;

							gui_->set_team(t-1);
							gui_->recalculate_minimap();
							gui_->invalidate_all();
							gui_->draw(true,true);
						}
					} else {
						after_human_turn();
					}
				}

			} else if (t.is_ai()) {
				play_ai_turn(turn_data_);

			}
		}

		if (local) {
			do_post_unit(false);
			release_turn_data();
		}

		loading_game_ = false;
	}
	//keep looping if the type of a team (human/ai/networked) has changed mid-turn

	skip_next_turn_ = false;
}