Always use mp::connect_engine to set up an MP scenario.

The engine was slightly modified to have an option to force import
players when starting a game, so that previous players would be carried
over and correctly assigned to their corresponding sides.

As a side effect, the play_game() loop received a slight clean up,
because some code there became unnecessary.
This commit is contained in:
Andrius Silinskas 2013-08-27 15:32:37 +01:00
parent f9c21bf925
commit 279065a036
3 changed files with 56 additions and 75 deletions

View file

@ -183,19 +183,7 @@ connect_engine::connect_engine(game_display& disp, game_state& state,
}
// Load reserved players information into the sides.
if (!first_scenario_) {
std::map<std::string, std::string> side_users =
utils::map_split(level_.child("multiplayer")["side_users"]);
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
const std::string& save_id = side->save_id();
if (side_users.find(save_id) != side_users.end()) {
side->set_current_player(side_users[save_id]);
side->update_controller_options();
side->set_controller(CNTR_RESERVED);
}
}
}
load_previous_sides_users(RESERVE_USERS);
// Add host to the connected users list.
import_user(preferences::login(), false);
@ -286,7 +274,6 @@ void connect_engine::import_user(const config& data, const bool observer,
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
if (side->available_for_user(username) ||
side->controller() == CNTR_LOCAL) {
side->place_user(data);
side_assigned = true;
@ -367,7 +354,7 @@ bool connect_engine::can_start_game() const
return false;
}
void connect_engine::start_game()
void connect_engine::start_game(LOAD_USERS load_users)
{
DBG_MP << "starting a new game" << std::endl;
@ -414,6 +401,9 @@ void connect_engine::start_game()
// Make other clients not show the results of resolve_random().
config lock("stop_updates");
network::send_data(lock, 0);
load_previous_sides_users(load_users);
update_and_send_diff(true);
save_reserved_sides_information();
@ -750,6 +740,29 @@ void connect_engine::save_reserved_sides_information()
level_.child("multiplayer")["side_users"] = utils::join_map(side_users);
}
void connect_engine::load_previous_sides_users(LOAD_USERS load_users)
{
if (load_users == NO_LOAD || first_scenario_) {
return;
}
std::map<std::string, std::string> side_users =
utils::map_split(level_.child("multiplayer")["side_users"]);
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
const std::string& save_id = side->save_id();
if (side_users.find(save_id) != side_users.end()) {
side->set_current_player(side_users[save_id]);
if (load_users == RESERVE_USERS) {
side->update_controller_options();
side->set_controller(CNTR_RESERVED);
} else if (load_users == FORCE_IMPORT_USERS) {
import_user(side_users[save_id], false);
}
}
}
}
void connect_engine::update_side_controller_options()
{
BOOST_FOREACH(side_engine_ptr side, side_engines_) {

View file

@ -48,6 +48,8 @@ public:
const bool first_scenario);
~connect_engine();
enum LOAD_USERS { NO_LOAD, RESERVE_USERS, FORCE_IMPORT_USERS };
config* current_config();
void import_user(const std::string& name, const bool observer,
@ -64,7 +66,7 @@ public:
void update_and_send_diff(bool update_time_of_day = false);
bool can_start_game() const;
void start_game();
void start_game(LOAD_USERS load_users = NO_LOAD);
void start_game_commandline(const commandline_options& cmdline_opts);
// Return pair first element specifies whether to leave the game
@ -97,6 +99,7 @@ private:
void send_level_data(const network::connection sock) const;
void save_reserved_sides_information();
void load_previous_sides_users(LOAD_USERS load_users);
void update_side_controller_options();

View file

@ -399,17 +399,6 @@ LEVEL_RESULT play_game(game_display& disp, game_state& gamestate,
gamestate.carryover_sides_start = sides.to_config();
std::map<std::string, std::string> controllers;
if(io_type == IO_SERVER) {
BOOST_FOREACH(config &side, const_cast<config *>(scenario)->child_range("side"))
{
std::string id = side["save_id"];
if(id.empty())
continue;
}
}
while(scenario != NULL) {
// If we are a multiplayer client, tweak the controllers
if(io_type == IO_CLIENT) {
@ -608,56 +597,40 @@ LEVEL_RESULT play_game(game_display& disp, game_state& gamestate,
}
if(io_type == IO_SERVER && scenario != NULL) {
mp_game_settings& params = gamestate.mp_settings();
params.scenario_data = *scenario;
params.saved_game = false;
params.use_map_settings =
(*scenario)["force_use_map_settings"].to_bool(true);
team_init(params.scenario_data, gamestate);
mp::connect_engine_ptr
connect_engine(new mp::connect_engine(disp, gamestate,
params, !network_game, false));
if (game_config::campaign_screens) {
mp_game_settings& params = gamestate.mp_settings();
params.scenario_data = *scenario;
params.saved_game = false;
params.use_map_settings =
(*scenario)["force_use_map_settings"].to_bool(true);
team_init(params.scenario_data, gamestate);
mp::connect_engine_ptr
connect_engine(new mp::connect_engine(disp, gamestate,
params, !network_game, false));
// Opens mp::connect dialog to get a new gamestate.
mp::ui::result connect_res = mp::goto_mp_connect(disp,
*connect_engine, game_config, params.name);
if (connect_res == mp::ui::QUIT) {
return QUIT;
}
starting_pos = gamestate.replay_start();
scenario = &starting_pos;
} else {
// Start the next scenario immediately.
connect_engine->
start_game(mp::connect_engine::FORCE_IMPORT_USERS);
}
// Tweaks sides to adapt controllers and descriptions.
BOOST_FOREACH(config &side, starting_pos.child_range("side"))
{
std::string id = side["save_id"];
if(id.empty()) {
id = side["id"].str();
}
if(!id.empty()) {
// Update side info to match current_player info
// to allow it taking the side in next scenario
// and to be set in the players list on side server.
std::map<std::string, std::string>::const_iterator ctr =
controllers.find(id);
if(ctr != controllers.end()) {
if (const config& c = gamestate.snapshot.find_child("side", "save_id", id)) {
side["current_player"] = c["current_player"];
}
side["controller"] = ctr->second;
}
}
if (side["controller"].empty())
side["controller"] = "ai";
}
starting_pos = gamestate.replay_start();
scenario = &starting_pos;
// TODO: move this code to mp::connect_engine
// in order to send generated data to the network
// before starting the game.
//
// If the entire scenario should be randomly generated
if((*scenario)["scenario_generation"] != "") {
/*if((*scenario)["scenario_generation"] != "") {
generate_scenario(scenario);
}
@ -669,15 +642,7 @@ LEVEL_RESULT play_game(game_display& disp, game_state& gamestate,
// If the map should be randomly generated
if(map_data.empty() && (*scenario)["map_generation"] != "") {
generate_map(scenario);
}
// Move the player information into the hosts gamestate.
write_players(gamestate, starting_pos, true, true);
// Send next scenario data.
network::send_data(mp::next_level_config(*scenario, gamestate),
0);
network::send_data(config("start_game"), 0);
}*/
}
}