Skip to content

Commit

Permalink
refactor playcampaign
Browse files Browse the repository at this point in the history
playcampaign's functions were moved to a new class (campaign_controller).
This removes the need to carry a lot of parameters around in playcampaign's
functions. Specially it removes those confusing boolean parameters to
play_game(). Some mp related parameters were also merged to a
mp_campaign_info struct.
  • Loading branch information
gfgtdf committed Sep 30, 2015
1 parent 9ebfec9 commit 7fc9a97
Show file tree
Hide file tree
Showing 20 changed files with 242 additions and 200 deletions.
49 changes: 33 additions & 16 deletions src/game_initialization/connect_engine.cpp
Expand Up @@ -23,6 +23,7 @@
#include "multiplayer_ui.hpp"
#include "mp_game_utils.hpp"
#include "mt_rng.hpp"
#include "playcampaign.hpp"
#include "tod_manager.hpp"
#include "multiplayer_ui.hpp" // For get_color_string
#include <boost/foreach.hpp>
Expand Down Expand Up @@ -76,20 +77,19 @@ const std::string attributes_to_trim[] = {
namespace ng {

connect_engine::connect_engine(saved_game& state,
const bool local_players_only, const bool first_scenario, const std::set<std::string>& players) :
const bool first_scenario, mp_campaign_info* campaign_info) :
level_(),
state_(state),
params_(state.mp_settings()),
default_controller_(local_players_only ? CNTR_LOCAL: CNTR_NETWORK),
local_players_only_(local_players_only),
default_controller_(campaign_info ? CNTR_NETWORK : CNTR_LOCAL),
campaign_info_(campaign_info),
first_scenario_(first_scenario),
force_lock_settings_(),
side_engines_(),
era_factions_(),
team_names_(),
user_team_names_(),
player_teams_(),
connected_users_(players)
player_teams_()
{
// Initial level config from the mp_game_settings.
level_ = mp::initial_level_config(state_);
Expand Down Expand Up @@ -227,8 +227,9 @@ void connect_engine::import_user(const config& data, const bool observer,
{
const std::string& username = data["name"];
assert(!username.empty());

connected_users_.insert(username);
if(campaign_info_) {
connected_users_rw().insert(username);
}
update_side_controller_options();

if (observer) {
Expand Down Expand Up @@ -607,7 +608,7 @@ std::pair<bool, bool> connect_engine::process_network_data(const config& data,
side_engine_ptr side_to_drop = side_engines_[side_drop];

// Remove user, whose side was dropped.
connected_users_.erase(side_to_drop->player_id());
connected_users_rw().erase(side_to_drop->player_id());
update_side_controller_options();

side_to_drop->reset();
Expand All @@ -634,7 +635,7 @@ std::pair<bool, bool> connect_engine::process_network_data(const config& data,
return result;
}

if (connected_users_.find(name) != connected_users_.end()) {
if (connected_users().find(name) != connected_users().end()) {
// TODO: Seems like a needless limitation
// to only allow one side per player.
if (find_user_side_index_by_id(name) != -1) {
Expand All @@ -646,7 +647,7 @@ std::pair<bool, bool> connect_engine::process_network_data(const config& data,

return result;
} else {
connected_users_.erase(name);
connected_users_rw().erase(name);
update_side_controller_options();
config observer_quit;
observer_quit.add_child("observer_quit")["name"] = name;
Expand Down Expand Up @@ -727,11 +728,10 @@ std::pair<bool, bool> connect_engine::process_network_data(const config& data,
if (const config& observer = data.child("observer_quit")) {
const t_string& observer_name = observer["name"];
if (!observer_name.empty()) {
if ((connected_users_.find(observer_name) !=
connected_users_.end()) &&
if ((connected_users().find(observer_name) != connected_users().end()) &&
(find_user_side_index_by_id(observer_name) != -1)) {

connected_users_.erase(observer_name);
connected_users_rw().erase(observer_name);
update_side_controller_options();
update_and_send_diff();
}
Expand Down Expand Up @@ -823,7 +823,7 @@ void connect_engine::load_previous_sides_users()
//Do this in an extra loop to make sure we import each user only once.
BOOST_FOREACH(const std::string& name, names)
{
if (connected_users_.find(name) != connected_users_.end()) {
if (connected_users().find(name) != connected_users().end() || !campaign_info_) {
import_user(name, false);
}
}
Expand All @@ -836,6 +836,23 @@ void connect_engine::update_side_controller_options()
}
}


const std::set<std::string>& connect_engine::connected_users() const
{
if(campaign_info_) {
return campaign_info_->connected_players;
}
else {
static std::set<std::string> empty;
return empty;
}
}
std::set<std::string>& connect_engine::connected_users_rw()
{
assert(campaign_info_);
return campaign_info_->connected_players;
}

side_engine::side_engine(const config& cfg, connect_engine& parent_engine,
const int index) :
cfg_(cfg),
Expand Down Expand Up @@ -1238,7 +1255,7 @@ void side_engine::update_controller_options()
controller_options_.clear();

// Default options.
if (!parent_.local_players_only_) {
if (parent_.campaign_info_) {
add_controller_option(CNTR_NETWORK, _("Network Player"), "human");
}
add_controller_option(CNTR_LOCAL, _("Local Player"), "human");
Expand All @@ -1251,7 +1268,7 @@ void side_engine::update_controller_options()

// Connected users.
add_controller_option(CNTR_LAST, _("--give--"), "human");
BOOST_FOREACH(const std::string& user, parent_.connected_users_) {
BOOST_FOREACH(const std::string& user, parent_.connected_users()) {
add_controller_option(parent_.default_controller_, user, "human");
}

Expand Down
13 changes: 6 additions & 7 deletions src/game_initialization/connect_engine.hpp
Expand Up @@ -24,6 +24,7 @@
#include <set>

namespace rand_rng { class mt_rng; }
struct mp_campaign_info;

namespace ng {

Expand All @@ -49,9 +50,7 @@ class connect_engine
/// @param players the player which are already connected to the current game.
/// This is always empty unless we advance form a previous scenario.
connect_engine(saved_game& state,
const bool local_players_only,
const bool first_scenario,
const std::set<std::string>& players = std::set<std::string>());
const bool first_scenario, mp_campaign_info* campaign_info);
~connect_engine();

config* current_config();
Expand Down Expand Up @@ -96,8 +95,7 @@ class connect_engine
else
throw "No scenariodata found";
}
const std::set<std::string>& connected_users() const
{ return connected_users_; }
const std::set<std::string>& connected_users() const;
const std::vector<std::string>& user_team_names()
{ return user_team_names_; }
std::vector<side_engine_ptr>& side_engines() { return side_engines_; }
Expand All @@ -124,7 +122,7 @@ class connect_engine
const mp_game_settings& params_;

const ng::controller default_controller_;
const bool local_players_only_;
mp_campaign_info* campaign_info_;
const bool first_scenario_;

bool force_lock_settings_;
Expand All @@ -134,7 +132,8 @@ class connect_engine
std::vector<std::string> team_names_;
std::vector<std::string> user_team_names_;
std::vector<std::string> player_teams_;
std::set<std::string> connected_users_;

std::set<std::string>& connected_users_rw();
};

class side_engine
Expand Down
61 changes: 33 additions & 28 deletions src/game_initialization/multiplayer.cpp
Expand Up @@ -40,7 +40,6 @@
#include "multiplayer_wait.hpp"
#include "multiplayer_lobby.hpp"
#include "playcampaign.hpp"
#include "playmp_controller.hpp"
#include "settings.hpp"
#include "scripting/plugins/context.hpp"
#include "sound.hpp"
Expand Down Expand Up @@ -443,7 +442,7 @@ static server_type open_connection(game_display& disp, const std::string& origin
// of those screen functions.

static void enter_wait_mode(game_display& disp, const config& game_config,
saved_game& state, bool observe)
saved_game& state, bool observe, int current_turn = 0)
{
DBG_MP << "entering wait mode" << std::endl;

Expand All @@ -452,6 +451,12 @@ static void enter_wait_mode(game_display& disp, const config& game_config,

gamelist.clear();
statistics::fresh_stats();
mp_campaign_info campaign_info;
campaign_info.is_host = false;
if(preferences::skip_mp_replay() || preferences::blindfold_replay()) {
campaign_info.skip_replay_until_turn = current_turn;
campaign_info.skip_replay_blindfolded = preferences::blindfold_replay();
}

{
mp::wait ui(disp, game_config, state, gamechat, gamelist);
Expand All @@ -460,6 +465,7 @@ static void enter_wait_mode(game_display& disp, const config& game_config,

run_lobby_loop(disp, ui);
res = ui.get_result();
campaign_info.connected_players.insert(ui.user_list().begin(), ui.user_list().end());

if (res == mp::ui::PLAY) {
ui.start_game();
Expand All @@ -474,10 +480,12 @@ static void enter_wait_mode(game_display& disp, const config& game_config,
}

switch (res) {
case mp::ui::PLAY:
play_game(disp, state, game_config, game_config_manager::get()->terrain_types(), IO_CLIENT,
preferences::skip_mp_replay() && observe, true, preferences::blindfold_replay() && observe);
case mp::ui::PLAY: {
campaign_controller controller(disp, state, game_config, game_config_manager::get()->terrain_types());
controller.set_mp_info(&campaign_info);
controller.play_game();
break;
}
case mp::ui::QUIT:
default:
break;
Expand All @@ -499,9 +507,15 @@ static bool enter_connect_mode(game_display& disp, const config& game_config,

gamelist.clear();
statistics::fresh_stats();
boost::optional<mp_campaign_info> campaign_info;
if(!local_players_only) {
campaign_info = mp_campaign_info();
campaign_info->connected_players.insert(preferences::login());
campaign_info->is_host = true;
}

{
ng::connect_engine_ptr connect_engine(new ng::connect_engine(state, local_players_only, true));
ng::connect_engine_ptr connect_engine(new ng::connect_engine(state, true, campaign_info.get_ptr()));
mp::connect ui(disp, state.mp_settings().name, game_config, gamechat, gamelist,
*connect_engine);
run_lobby_loop(disp, ui);
Expand All @@ -516,10 +530,12 @@ static bool enter_connect_mode(game_display& disp, const config& game_config,
} // end connect_engine_ptr scope

switch (res) {
case mp::ui::PLAY:
play_game(disp, state, game_config, game_config_manager::get()->terrain_types(), IO_SERVER, false,
!local_players_only);
case mp::ui::PLAY: {
campaign_controller controller(disp, state, game_config, game_config_manager::get()->terrain_types());
controller.set_mp_info(campaign_info.get_ptr());
controller.play_game();
break;
}
case mp::ui::CREATE:
enter_create_mode(disp, game_config, state, local_players_only);
break;
Expand Down Expand Up @@ -652,7 +668,7 @@ static void enter_lobby_mode(game_display& disp, const config& game_config,
DBG_MP << "entering lobby mode" << std::endl;

mp::ui::result res;

int current_turn = 0;
while (true) {
const config &cfg = game_config.child("lobby_music");
if (cfg) {
Expand Down Expand Up @@ -699,12 +715,14 @@ static void enter_lobby_mode(game_display& disp, const config& game_config,
mp::lobby ui(disp, game_config, gamechat, gamelist, installed_addons);
run_lobby_loop(disp, ui);
res = ui.get_result();
current_turn = ui.current_turn;
}

switch (res) {
case mp::ui::JOIN:
case mp::ui::OBSERVE:
try {
enter_wait_mode(disp, game_config, state, false);
enter_wait_mode(disp, game_config, state, res == mp::ui::OBSERVE, current_turn);
} catch(config::error& error) {
if(!error.message.empty()) {
gui2::show_error_message(disp.video(), error.message);
Expand All @@ -713,18 +731,6 @@ static void enter_lobby_mode(game_display& disp, const config& game_config,
network::send_data(config("refresh_lobby"), 0);
}
break;
case mp::ui::OBSERVE:
try {
enter_wait_mode(disp, game_config, state, true);
} catch(config::error& error) {
if(!error.message.empty()) {
gui2::show_error_message(disp.video(), error.message);
}
}
// update lobby content unconditionally because we might have left only after the
// game ended in which case we ignored the gamelist and need to request it again
network::send_data(config("refresh_lobby"), 0);
break;
case mp::ui::CREATE:
try {
enter_create_mode(disp, game_config, state, false);
Expand Down Expand Up @@ -758,7 +764,6 @@ void start_local_game(game_display& disp, const config& game_config,
DBG_MP << "starting local game" << std::endl;
gamechat.clear_history();
gamelist.clear();
playmp_controller::set_replay_last_turn(0);
preferences::set_message_private(false);
enter_create_mode(disp, game_config, state, true);
}
Expand All @@ -773,7 +778,6 @@ void start_local_game_commandline(game_display& disp, const config& game_config,
// needed in commandline mode, but they are required by the functions called.
gamechat.clear_history();
gamelist.clear();
playmp_controller::set_replay_last_turn(0);
preferences::set_message_private(false);

DBG_MP << "entering create mode" << std::endl;
Expand Down Expand Up @@ -882,7 +886,7 @@ void start_local_game_commandline(game_display& disp, const config& game_config,
statistics::fresh_stats();

{
ng::connect_engine_ptr connect_engine(new ng::connect_engine(state, true, true));
ng::connect_engine_ptr connect_engine(new ng::connect_engine(state, true, NULL));
mp::connect ui(disp, parameters.name, game_config, gamechat, gamelist,
*connect_engine);

Expand All @@ -898,7 +902,9 @@ void start_local_game_commandline(game_display& disp, const config& game_config,
unsigned int repeat = (cmdline_opts.multiplayer_repeat) ? *cmdline_opts.multiplayer_repeat : 1;
for(unsigned int i = 0; i < repeat; i++){
saved_game state_copy(state);
play_game(disp, state_copy, game_config, game_config_manager::get()->terrain_types(), IO_SERVER, false, false);
campaign_controller controller(disp, state_copy, game_config, game_config_manager::get()->terrain_types());
controller.play_game();
break;
}
}

Expand Down Expand Up @@ -942,7 +948,6 @@ void start_client(game_display& disp, const config& game_config,
} while (re_enter);
break;
case SIMPLE_SERVER:
playmp_controller::set_replay_last_turn(0);
preferences::set_message_private(false);
enter_wait_mode(disp, *game_config_ptr, state, false);
break;
Expand Down

0 comments on commit 7fc9a97

Please sign in to comment.