Refactor users related code (mp::connect).
This commit is contained in:
parent
055caebcf2
commit
3c75c21583
5 changed files with 410 additions and 381 deletions
|
@ -35,6 +35,17 @@ static lg::log_domain log_mp_connect("mp/connect");
|
|||
|
||||
namespace mp {
|
||||
|
||||
std::vector<std::string> controller_options_names(
|
||||
const std::vector<controller_option>& controller_options)
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
BOOST_FOREACH(const controller_option& option, controller_options) {
|
||||
names.push_back(option.second);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
connect::side::side(connect& parent, side_engine_ptr engine) :
|
||||
parent_(&parent),
|
||||
engine_(engine),
|
||||
|
@ -50,8 +61,8 @@ connect::side::side(connect& parent, side_engine_ptr engine) :
|
|||
label_gold_(parent.video(), "100", font::SIZE_SMALL, font::LOBBY_COLOR),
|
||||
label_income_(parent.video(), _("Normal"), font::SIZE_SMALL,
|
||||
font::LOBBY_COLOR),
|
||||
combo_controller_(new gui::combo_drag(parent.disp(), parent.player_types_,
|
||||
parent.combo_control_group_)),
|
||||
combo_controller_(new gui::combo_drag(parent.disp(),
|
||||
std::vector<std::string>(), parent.combo_control_group_)),
|
||||
combo_ai_algorithm_(parent.disp(), std::vector<std::string>()),
|
||||
combo_faction_(parent.disp(), std::vector<std::string>()),
|
||||
combo_leader_(parent.disp(), std::vector<std::string>()),
|
||||
|
@ -85,7 +96,8 @@ connect::side::side(connect& parent, side_engine_ptr engine) :
|
|||
label_gold_.hide(parent_->params_.saved_game);
|
||||
label_income_.hide(parent_->params_.saved_game);
|
||||
|
||||
init_ai_algorithm_combo();
|
||||
update_controller_combo_list();
|
||||
update_ai_algorithm_combo();
|
||||
|
||||
if (parent_->params_.use_map_settings) {
|
||||
// Gold, income, team, and color are only suggestions.
|
||||
|
@ -155,47 +167,19 @@ void connect::side::process_event()
|
|||
changed_ = true;
|
||||
parent_->sides_[drop_target].changed_ = true;
|
||||
|
||||
init_ai_algorithm_combo();
|
||||
parent_->sides_[drop_target].init_ai_algorithm_combo();
|
||||
update_ai_algorithm_combo();
|
||||
parent_->sides_[drop_target].update_ai_algorithm_combo();
|
||||
|
||||
update_ui();
|
||||
parent_->sides_[drop_target].update_ui();
|
||||
} else if (combo_controller_->changed() &&
|
||||
combo_controller_->selected() >= 0) {
|
||||
|
||||
const int cntr_last =
|
||||
(engine_->save_id().empty() ? CNTR_LAST-1 : CNTR_LAST) -
|
||||
(parent_->engine_.local_players_only() ? 1 : 0);
|
||||
if (combo_controller_->selected() == cntr_last) {
|
||||
update_controller_ui();
|
||||
} else if (combo_controller_->selected() < cntr_last) {
|
||||
// Correct entry number if CNTR_NETWORK
|
||||
// is not allowed for combo_controller_.
|
||||
engine_->
|
||||
set_mp_controller(mp::controller(combo_controller_->selected() +
|
||||
(parent_->engine_.local_players_only() ? 1 : 0)));
|
||||
engine_->set_player_id("");
|
||||
engine_->set_ready_for_start(false);
|
||||
changed_ = true;
|
||||
} else {
|
||||
// Give user a second side.
|
||||
size_t user = combo_controller_->selected() - cntr_last - 1;
|
||||
|
||||
const std::string new_id = parent_->engine_.users()[user].name;
|
||||
if (new_id != engine_->player_id()) {
|
||||
engine_->set_player_id(new_id);
|
||||
engine_->set_mp_controller(
|
||||
parent_->engine_.users()[user].controller);
|
||||
engine_->set_ready_for_start(true);
|
||||
changed_ = true;
|
||||
}
|
||||
}
|
||||
hide_ai_algorithm_combo(parent_->hidden());
|
||||
} else if (combo_controller_->changed()) {
|
||||
changed_ = engine_->controller_changed(combo_controller_->selected());
|
||||
update_controller_combo();
|
||||
}
|
||||
|
||||
if (combo_controller_->hidden()) {
|
||||
combo_controller_->hide(false);
|
||||
}
|
||||
|
||||
if (parent_->params_.saved_game) {
|
||||
return;
|
||||
}
|
||||
|
@ -240,7 +224,6 @@ void connect::side::process_event()
|
|||
changed_ = true;
|
||||
}
|
||||
if (slider_income_.value() != engine_->income()) {
|
||||
|
||||
engine_->set_income(slider_income_.value());
|
||||
std::stringstream buf;
|
||||
if (engine_->income() < 0) {
|
||||
|
@ -265,11 +248,13 @@ bool connect::side::changed()
|
|||
return false;
|
||||
}
|
||||
|
||||
void connect::side::update_user_list(
|
||||
const std::vector<std::string>& name_list) {
|
||||
void connect::side::update_controller_combo_list()
|
||||
{
|
||||
engine_->update_controller_options();
|
||||
combo_controller_->set_items(controller_options_names(
|
||||
engine_->controller_options()));
|
||||
|
||||
combo_controller_->set_items(name_list);
|
||||
update_controller_ui();
|
||||
update_controller_combo();
|
||||
}
|
||||
|
||||
void connect::side::update_ui()
|
||||
|
@ -278,7 +263,7 @@ void connect::side::update_ui()
|
|||
update_leader_combo();
|
||||
update_gender_combo();
|
||||
|
||||
update_controller_ui();
|
||||
update_controller_combo();
|
||||
|
||||
combo_team_.set_selected(engine_->team());
|
||||
combo_color_.set_selected(engine_->color());
|
||||
|
@ -296,13 +281,13 @@ void connect::side::update_ui()
|
|||
label_income_.set_text(buf.str());
|
||||
}
|
||||
|
||||
void connect::side::hide_ai_algorithm_combo(bool invisible)
|
||||
void connect::side::hide_ai_algorithm_combo(bool force)
|
||||
{
|
||||
if (!invisible) {
|
||||
if (engine_->mp_controller() == CNTR_COMPUTER) {
|
||||
if (!force) {
|
||||
if (engine_->controller() == CNTR_COMPUTER) {
|
||||
// Computer selected, show AI combo.
|
||||
label_original_controller_.hide(true);
|
||||
combo_ai_algorithm_.hide(false);
|
||||
label_original_controller_.hide(true);
|
||||
} else {
|
||||
// Computer de-selected, hide AI combo.
|
||||
combo_ai_algorithm_.hide(true);
|
||||
|
@ -333,28 +318,26 @@ void connect::side::add_widgets_to_scrollpane(gui::scrollpane& pane, int pos)
|
|||
pane.add_widget(&label_income_, 475 + slider_gold_.width(), 35 + pos);
|
||||
}
|
||||
|
||||
void connect::side::init_ai_algorithm_combo()
|
||||
void connect::side::update_ai_algorithm_combo()
|
||||
{
|
||||
assert(parent_->ai_algorithms_.empty() == false);
|
||||
assert(!parent_->ai_algorithms_.empty());
|
||||
|
||||
int sel = 0;
|
||||
std::vector<ai::description*> &ais_list = parent_->ai_algorithms_;
|
||||
std::vector<std::string> ais;
|
||||
int i = 0;
|
||||
BOOST_FOREACH(const ai::description *desc, ais_list){
|
||||
std::vector<std::string> ais;
|
||||
BOOST_FOREACH(const ai::description* desc, parent_->ai_algorithms_){
|
||||
ais.push_back(desc->text);
|
||||
if (desc->id == engine_->ai_algorithm()){
|
||||
if (desc->id == engine_->ai_algorithm()) {
|
||||
sel = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
combo_ai_algorithm_.set_items(ais);
|
||||
combo_ai_algorithm_.set_selected(sel);
|
||||
if (!ais_list.empty()) {
|
||||
// Ensures that the visually selected AI
|
||||
// is the one that will be loaded.
|
||||
engine_->set_ai_algorithm(ais_list[sel]->id);
|
||||
}
|
||||
|
||||
// Ensures that the visually selected AI
|
||||
// is the one that will be loaded.
|
||||
engine_->set_ai_algorithm(parent_->ai_algorithms_[sel]->id);
|
||||
}
|
||||
|
||||
void connect::side::update_faction_combo()
|
||||
|
@ -394,26 +377,9 @@ void connect::side::update_gender_combo()
|
|||
engine_->color(), parent_->params_.saved_game);
|
||||
}
|
||||
|
||||
void connect::side::update_controller_ui()
|
||||
void connect::side::update_controller_combo()
|
||||
{
|
||||
if (engine_->player_id().empty()) {
|
||||
combo_controller_->set_selected(
|
||||
engine_->mp_controller() - (parent_->engine_.local_players_only() ? 1 : 0));
|
||||
} else {
|
||||
connected_user_list::iterator player =
|
||||
parent_->engine_.find_player_by_id(engine_->player_id());
|
||||
|
||||
if (player != parent_->engine_.users().end()) {
|
||||
const int no_reserve = engine_->save_id().empty() ? - 1 : 0;
|
||||
combo_controller_->set_selected(
|
||||
CNTR_LAST + no_reserve + 1 +
|
||||
(player - parent_->engine_.users().begin()) -
|
||||
(parent_->engine_.local_players_only() ? 1 : 0));
|
||||
} else {
|
||||
assert(parent_->engine_.local_players_only() != true);
|
||||
combo_controller_->set_selected(CNTR_NETWORK);
|
||||
}
|
||||
}
|
||||
combo_controller_->set_selected(engine_->current_controller_index());
|
||||
|
||||
hide_ai_algorithm_combo(parent_->hidden());
|
||||
}
|
||||
|
@ -423,7 +389,6 @@ connect::connect(game_display& disp, const config& game_config,
|
|||
bool local_players_only, bool first_scenario) :
|
||||
mp::ui(disp, _("Game Lobby: ") + params.name, game_config, c, gamelist),
|
||||
params_(params),
|
||||
player_types_(),
|
||||
player_teams_(),
|
||||
player_colors_(),
|
||||
ai_algorithms_(),
|
||||
|
@ -468,6 +433,7 @@ connect::connect(game_display& disp, const config& game_config,
|
|||
throw config::error(
|
||||
_("The scenario is invalid because it has no sides."));
|
||||
}
|
||||
update_side_controller_combos();
|
||||
|
||||
if (first_scenario) {
|
||||
// Send Initial information
|
||||
|
@ -480,10 +446,6 @@ connect::connect(game_display& disp, const config& game_config,
|
|||
network::send_data(response, 0);
|
||||
}
|
||||
|
||||
update_user_combos();
|
||||
|
||||
engine_.assign_side_for_host();
|
||||
|
||||
append_to_title(" — " + engine_.level()["name"].t_str());
|
||||
gold_title_label_.hide(params_.saved_game);
|
||||
income_title_label_.hide(params_.saved_game);
|
||||
|
@ -532,7 +494,7 @@ void connect::process_event()
|
|||
engine_.users().push_back(connected_user(d.textbox_text(),
|
||||
CNTR_LOCAL, 0));
|
||||
update_playerlist_state();
|
||||
update_user_combos();
|
||||
update_side_controller_combos();
|
||||
}
|
||||
}
|
||||
} while (already_exists);
|
||||
|
@ -648,32 +610,28 @@ void connect::process_network_data(const config& data,
|
|||
const network::connection sock)
|
||||
{
|
||||
ui::process_network_data(data, sock);
|
||||
network_res_tuple result = engine_.process_network_data(data, sock);
|
||||
std::pair<bool, bool> result = engine_.process_network_data(data, sock);
|
||||
|
||||
if (result.get<0>()) {
|
||||
if (result.first) {
|
||||
set_result(QUIT);
|
||||
} else {
|
||||
if (result.get<1>()) {
|
||||
update_user_combos();
|
||||
update_playerlist_state(result.get<2>());
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(int side_index, result.get<3>()) {
|
||||
sides_[side_index].update_ui();
|
||||
}
|
||||
update_side_controller_combos();
|
||||
update_playerlist_state(result.second);
|
||||
BOOST_FOREACH(side& s, sides_) {
|
||||
s.update_ui();
|
||||
}
|
||||
}
|
||||
|
||||
void connect::process_network_error(network::error& error)
|
||||
{
|
||||
int res = engine_.process_network_error(error);
|
||||
bool res = engine_.process_network_error(error);
|
||||
|
||||
if (res > 0) {
|
||||
sides_[res - 1].update_ui();
|
||||
}
|
||||
|
||||
if (res != 1) {
|
||||
update_user_combos();
|
||||
if (res) {
|
||||
BOOST_FOREACH(side& s, sides_) {
|
||||
s.update_ui();
|
||||
}
|
||||
update_side_controller_combos();
|
||||
update_playerlist_state();
|
||||
}
|
||||
}
|
||||
|
@ -691,14 +649,6 @@ bool connect::accept_connections()
|
|||
|
||||
void connect::lists_init()
|
||||
{
|
||||
// Options.
|
||||
if (!engine_.local_players_only()) {
|
||||
player_types_.push_back(_("Network Player"));
|
||||
}
|
||||
player_types_.push_back(_("Local Player"));
|
||||
player_types_.push_back(_("Computer Player"));
|
||||
player_types_.push_back(_("Empty"));
|
||||
|
||||
// AI algorithms.
|
||||
const config &era = engine_.level().child("era");
|
||||
ai::configuration::add_era_ai_from_config(era);
|
||||
|
@ -795,6 +745,7 @@ void connect::lists_init()
|
|||
|
||||
index++;
|
||||
}
|
||||
engine_.init_after_side_engines_assigned();
|
||||
|
||||
// Add side widgets to scroll pane.
|
||||
int side_pos_y_offset = 0;
|
||||
|
@ -825,7 +776,7 @@ void connect::update_playerlist_state(bool silent)
|
|||
} else {
|
||||
// Updates the player list
|
||||
std::vector<std::string> playerlist;
|
||||
BOOST_FOREACH(const connected_user& user, engine_.users()) {
|
||||
BOOST_FOREACH(const connected_user& user, engine_.connected_users()) {
|
||||
playerlist.push_back(user.name);
|
||||
}
|
||||
set_user_list(playerlist, silent);
|
||||
|
@ -833,22 +784,10 @@ void connect::update_playerlist_state(bool silent)
|
|||
}
|
||||
}
|
||||
|
||||
void connect::update_user_combos()
|
||||
void connect::update_side_controller_combos()
|
||||
{
|
||||
BOOST_FOREACH(side& s, sides_) {
|
||||
typedef std::vector<std::string> name_list;
|
||||
|
||||
name_list list = player_types_;
|
||||
if (!s.engine()->save_id().empty()) {
|
||||
list.push_back(_("Reserved"));
|
||||
}
|
||||
list.push_back(_("--give--"));
|
||||
|
||||
BOOST_FOREACH(const connected_user& user, engine_.users()) {
|
||||
list.push_back(user.name);
|
||||
}
|
||||
|
||||
s.update_user_list(list);
|
||||
s.update_controller_combo_list();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ namespace ai {
|
|||
|
||||
namespace mp {
|
||||
|
||||
// Helper function to retrieve controller names.
|
||||
std::vector<std::string> controller_options_names(
|
||||
const std::vector<controller_option>& controller_options);
|
||||
|
||||
class connect : public mp::ui
|
||||
{
|
||||
public:
|
||||
|
@ -46,11 +50,10 @@ public:
|
|||
// Returns true if this side changed since last call to this method.
|
||||
bool changed();
|
||||
|
||||
// Adds an user to the user list combo.
|
||||
void update_user_list(const std::vector<std::string>& name_list);
|
||||
void update_controller_combo_list();
|
||||
|
||||
void update_ui();
|
||||
void hide_ai_algorithm_combo(bool invisible);
|
||||
void hide_ai_algorithm_combo(bool force);
|
||||
|
||||
void add_widgets_to_scrollpane(gui::scrollpane& pane, int pos);
|
||||
|
||||
|
@ -58,13 +61,12 @@ public:
|
|||
const side_engine_ptr engine() const { return engine_; }
|
||||
|
||||
private:
|
||||
void init_ai_algorithm_combo();
|
||||
|
||||
// Update UI methods and their helper(s).
|
||||
void update_ai_algorithm_combo();
|
||||
void update_faction_combo();
|
||||
void update_leader_combo();
|
||||
void update_gender_combo();
|
||||
void update_controller_ui();
|
||||
void update_controller_combo();
|
||||
|
||||
// The mp::connect widget owning this mp::connect::side.
|
||||
connect* parent_;
|
||||
|
@ -129,12 +131,11 @@ private:
|
|||
// Updates the state of the player list, the launch button and of the start
|
||||
// game label, to reflect the actual state.
|
||||
void update_playerlist_state(bool silent = true);
|
||||
void update_user_combos();
|
||||
void update_side_controller_combos();
|
||||
|
||||
const mp_game_settings params_;
|
||||
|
||||
// Lists used for combos.
|
||||
std::vector<std::string> player_types_;
|
||||
std::vector<std::string> player_teams_;
|
||||
std::vector<std::string> player_colors_;
|
||||
std::vector<ai::description*> ai_algorithms_;
|
||||
|
|
|
@ -69,13 +69,14 @@ connect_engine::connect_engine(game_display& disp,
|
|||
level_(),
|
||||
state_(),
|
||||
params_(params),
|
||||
local_players_only_(local_players_only),
|
||||
default_controller_(local_players_only ? CNTR_LOCAL: CNTR_NETWORK),
|
||||
first_scenario_(first_scenario),
|
||||
side_engines_(),
|
||||
era_factions_(),
|
||||
team_names_(),
|
||||
user_team_names_(),
|
||||
users_()
|
||||
connected_users_(),
|
||||
default_controller_options_()
|
||||
{
|
||||
level_ = initial_level_config(disp, params, state_);
|
||||
if (level_.empty()) {
|
||||
|
@ -88,8 +89,16 @@ connect_engine::connect_engine(game_display& disp,
|
|||
era_factions_.push_back(&era);
|
||||
}
|
||||
|
||||
// Adds the current user as default user.
|
||||
users_.push_back(connected_user(preferences::login(), CNTR_LOCAL, 0));
|
||||
if (!local_players_only) {
|
||||
default_controller_options_.push_back(
|
||||
std::make_pair(CNTR_NETWORK, _("Network Player")));
|
||||
}
|
||||
default_controller_options_.push_back(
|
||||
std::make_pair(CNTR_LOCAL, _("Local Player")));
|
||||
default_controller_options_.push_back(
|
||||
std::make_pair(CNTR_COMPUTER, _("Computer Player")));
|
||||
default_controller_options_.push_back(
|
||||
std::make_pair(CNTR_EMPTY, _("Empty")));
|
||||
}
|
||||
|
||||
connect_engine::~connect_engine()
|
||||
|
@ -123,30 +132,66 @@ void connect_engine::add_side_engine(side_engine_ptr engine)
|
|||
side_engines_.push_back(engine);
|
||||
}
|
||||
|
||||
void connect_engine::assign_side_for_host()
|
||||
void connect_engine::init_after_side_engines_assigned()
|
||||
{
|
||||
// Take the first available side or available side with id == login.
|
||||
int side_choice = -1;
|
||||
int counter = 0;
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
if (side->allow_player()) {
|
||||
if (side_choice == -1) {
|
||||
side_choice = counter;
|
||||
}
|
||||
if (side->current_player() == preferences::login()) {
|
||||
side_engines_[counter]->set_player_from_users_list(
|
||||
preferences::login());
|
||||
side_choice = gamemap::MAX_PLAYERS;
|
||||
}
|
||||
}
|
||||
// Add host to the connected users list.
|
||||
config user_data;
|
||||
user_data["name"] = preferences::login();
|
||||
import_user(HOST, user_data, 0);
|
||||
}
|
||||
|
||||
counter++;
|
||||
void connect_engine::import_user(USER_TYPE user_type, const config& data,
|
||||
int sock, int side_taken)
|
||||
{
|
||||
const std::string& username = data["name"];
|
||||
assert(!username.empty());
|
||||
|
||||
// Check if user with such name isn't already connected.
|
||||
bool already_connected = false;
|
||||
BOOST_FOREACH(const connected_user& user, connected_users_) {
|
||||
if (user.name == username) {
|
||||
already_connected = true;
|
||||
}
|
||||
}
|
||||
// Finally, add user to the connected user list.
|
||||
if (!already_connected) {
|
||||
connected_users_.push_back(connected_user(username, sock));
|
||||
update_side_controller_options();
|
||||
}
|
||||
|
||||
if (side_choice != -1 && side_choice != gamemap::MAX_PLAYERS) {
|
||||
if (side_engines_[side_choice]->player_id() == "") {
|
||||
side_engines_[side_choice]->set_player_from_users_list(
|
||||
preferences::login());
|
||||
if (user_type == OBSERVER) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool side_assigned = false;
|
||||
if (side_taken >= 0) {
|
||||
side_engines_[side_taken]->place_user(data);
|
||||
side_assigned = true;
|
||||
}
|
||||
|
||||
// Check if user has a side(s) reserved for him.
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
if (side->current_player() == username) {
|
||||
side->place_user(data);
|
||||
|
||||
side_assigned = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (side_taken < 0) {
|
||||
// If no sides were assigned for a user,
|
||||
// take a first available side.
|
||||
if (!side_assigned) {
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +199,7 @@ void connect_engine::assign_side_for_host()
|
|||
bool connect_engine::sides_available() const
|
||||
{
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
if (side->available()) {
|
||||
if (side->available_for_user()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -196,9 +241,9 @@ bool connect_engine::can_start_game() const
|
|||
// First check if all sides are ready to start the game.
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
if (!side->ready_for_start()) {
|
||||
const int side_num = side->index() + 1;
|
||||
DBG_MP << "not all sides are ready, side " <<
|
||||
side->new_config().get("side")->str() << " not ready" <<
|
||||
std::endl;
|
||||
side_num << " not ready\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -213,10 +258,8 @@ bool connect_engine::can_start_game() const
|
|||
* [1] http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=568029
|
||||
*/
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
if (side->mp_controller() != CNTR_EMPTY) {
|
||||
if (side->allow_player()) {
|
||||
return true;
|
||||
}
|
||||
if (side->controller() != CNTR_EMPTY && side->allow_player()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -319,7 +362,7 @@ void connect_engine::start_game_commandline(
|
|||
|
||||
// Set AI algorithm to RCA AI for all sides,
|
||||
// then override if commandline option was given.
|
||||
side->set_ai_algorithm_commandline("ai_default_rca");
|
||||
side->set_ai_algorithm("ai_default_rca");
|
||||
if (cmdline_opts.multiplayer_algorithm) {
|
||||
BOOST_FOREACH(const mp_option& option,
|
||||
*cmdline_opts.multiplayer_algorithm) {
|
||||
|
@ -328,7 +371,7 @@ void connect_engine::start_game_commandline(
|
|||
DBG_MP << "\tsetting side " << option.get<0>() <<
|
||||
"\tfaction: " << option.get<1>() << std::endl;
|
||||
|
||||
side->set_ai_algorithm_commandline(option.get<1>());
|
||||
side->set_ai_algorithm(option.get<1>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -394,38 +437,35 @@ void connect_engine::start_game_commandline(
|
|||
network::send_data(config("start_game"), 0);
|
||||
}
|
||||
|
||||
network_res_tuple connect_engine::process_network_data(const config& data,
|
||||
std::pair<bool, bool> connect_engine::process_network_data(const config& data,
|
||||
const network::connection sock)
|
||||
{
|
||||
network_res_tuple result;
|
||||
result.get<0>() = false;
|
||||
result.get<1>() = false;
|
||||
result.get<2>() = true;
|
||||
std::pair<bool, bool> result(std::make_pair(false, true));
|
||||
|
||||
if (data.child("leave_game")) {
|
||||
result.get<0>() = true;
|
||||
result.first = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
// A side has been dropped.
|
||||
if (!data["side_drop"].empty()) {
|
||||
unsigned side_drop = data["side_drop"].to_int() - 1;
|
||||
result.get<3>().push_back(side_drop);
|
||||
|
||||
if (side_drop < side_engines_.size()) {
|
||||
side_engine_ptr side_to_drop = side_engines_[side_drop];
|
||||
|
||||
connected_user_list::iterator player =
|
||||
find_player_by_id(side_to_drop->player_id());
|
||||
if (player != users_.end()) {
|
||||
users_.erase(player);
|
||||
// Remove user, whose side was dropped.
|
||||
const int user_index =
|
||||
find_user_index_by_id(side_to_drop->player_id());
|
||||
if (user_index != -1) {
|
||||
connected_users_.erase(connected_users_.begin() + user_index);
|
||||
update_side_controller_options();
|
||||
}
|
||||
|
||||
side_to_drop->reset(side_to_drop->mp_controller());
|
||||
side_to_drop->reset();
|
||||
|
||||
update_and_send_diff();
|
||||
|
||||
result.get<1>() = true;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -446,11 +486,11 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
return result;
|
||||
}
|
||||
|
||||
connected_user_list::iterator player = find_player_by_id(name);
|
||||
if (player != users().end()) {
|
||||
const int user_index = find_user_index_by_id(name);
|
||||
if (user_index != -1) {
|
||||
// TODO: Seems like a needless limitation
|
||||
// to only allow one side per player.
|
||||
if (find_player_side_index_by_id(name) != -1) {
|
||||
if (find_user_side_index_by_id(name) != -1) {
|
||||
config response;
|
||||
response["failed"] = true;
|
||||
response["message"] = "The nickname '" + name +
|
||||
|
@ -459,23 +499,22 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
|
||||
return result;
|
||||
} else {
|
||||
users_.erase(player);
|
||||
connected_users_.erase(connected_users_.begin() + user_index);
|
||||
update_side_controller_options();
|
||||
config observer_quit;
|
||||
observer_quit.add_child("observer_quit")["name"] = name;
|
||||
network::send_data(observer_quit, 0);
|
||||
|
||||
result.get<1>() = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Assigns this user to a side.
|
||||
if (side_taken < side_engines_.size()) {
|
||||
if (!side_engines_[side_taken]->available(name)) {
|
||||
if (!side_engines_[side_taken]->available_for_user(name)) {
|
||||
// This side is already taken.
|
||||
// Try to reassing the player to a different position.
|
||||
side_taken = 0;
|
||||
BOOST_FOREACH(side_engine_ptr s, side_engines_) {
|
||||
if (s->available()) {
|
||||
if (s->available_for_user()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -492,8 +531,6 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
kick["username"] = data["name"];
|
||||
network::send_data(res, 0);
|
||||
|
||||
result.get<1>() = true;
|
||||
|
||||
update_and_send_diff();
|
||||
|
||||
ERR_CF << "ERROR: Couldn't assign a side to '" <<
|
||||
|
@ -505,30 +542,12 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
|
||||
LOG_CF << "client has taken a valid position\n";
|
||||
|
||||
// Adds the name to the list.
|
||||
users_.push_back(connected_user(name, CNTR_NETWORK, sock));
|
||||
|
||||
result.get<3>().push_back(side_taken);
|
||||
side_engines_[side_taken]->import_network_user(data);
|
||||
|
||||
// Check if more sides are reserved for this player.
|
||||
int side_index = 0;
|
||||
BOOST_FOREACH(side_engine_ptr& s, side_engines_) {
|
||||
if (s->available(data["name"]) &&
|
||||
s->current_player() == data["name"]) {
|
||||
|
||||
result.get<3>().push_back(side_index);
|
||||
s->import_network_user(data);
|
||||
}
|
||||
|
||||
side_index++;
|
||||
}
|
||||
|
||||
result.get<1>() = true;
|
||||
result.get<2>() = false;
|
||||
import_user(PLAYER, data, sock, side_taken);
|
||||
|
||||
update_and_send_diff();
|
||||
|
||||
result.second = false;
|
||||
|
||||
LOG_NW << "sent player data\n";
|
||||
} else {
|
||||
ERR_CF << "tried to take illegal side: " << side_taken << "\n";
|
||||
|
@ -539,46 +558,30 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
}
|
||||
}
|
||||
|
||||
if (const config &change_faction = data.child("change_faction")) {
|
||||
int side_taken = find_player_side_index_by_id(change_faction["name"]);
|
||||
if (side_taken != -1) {
|
||||
result.get<3>().push_back(side_taken);
|
||||
side_engines_[side_taken]->import_network_user(change_faction);
|
||||
side_engines_[side_taken]->set_ready_for_start(true);
|
||||
|
||||
result.get<1>() = true;
|
||||
if (const config& change_faction = data.child("change_faction")) {
|
||||
int side_taken = find_user_side_index_by_id(change_faction["name"]);
|
||||
if (side_taken != -1) {
|
||||
import_user(PLAYER, change_faction, sock, side_taken);
|
||||
|
||||
update_and_send_diff();
|
||||
}
|
||||
}
|
||||
|
||||
if (const config &c = data.child("observer")) {
|
||||
const t_string &observer_name = c["name"];
|
||||
if (!observer_name.empty()) {
|
||||
connected_user_list::iterator player =
|
||||
find_player_by_id(observer_name);
|
||||
if (player == users_.end()) {
|
||||
users_.push_back(connected_user(observer_name, CNTR_NETWORK,
|
||||
sock));
|
||||
|
||||
result.get<1>() = true;
|
||||
|
||||
update_and_send_diff();
|
||||
}
|
||||
}
|
||||
if (const config& observer = data.child("observer")) {
|
||||
import_user(OBSERVER, observer, sock);
|
||||
update_and_send_diff();
|
||||
}
|
||||
|
||||
if (const config &c = data.child("observer_quit")) {
|
||||
const t_string &observer_name = c["name"];
|
||||
if (const config& observer = data.child("observer_quit")) {
|
||||
const t_string& observer_name = observer["name"];
|
||||
if (!observer_name.empty()) {
|
||||
connected_user_list::iterator player =
|
||||
find_player_by_id(observer_name);
|
||||
if (player != users_.end() &&
|
||||
find_player_side_index_by_id(observer_name) == -1) {
|
||||
const int user_index = find_user_index_by_id(observer_name);
|
||||
if (user_index != -1 &&
|
||||
find_user_side_index_by_id(observer_name) == -1) {
|
||||
|
||||
users_.erase(player);
|
||||
|
||||
result.get<1>() = true;
|
||||
connected_users_.erase(connected_users_.begin() + user_index);
|
||||
update_side_controller_options();
|
||||
|
||||
update_and_send_diff();
|
||||
}
|
||||
|
@ -588,7 +591,7 @@ network_res_tuple connect_engine::process_network_data(const config& data,
|
|||
return result;
|
||||
}
|
||||
|
||||
int connect_engine::process_network_error(network::error& error)
|
||||
bool connect_engine::process_network_error(network::error& error)
|
||||
{
|
||||
// If the problem isn't related to any specific connection,
|
||||
// it's a general error and we should just re-throw the error.
|
||||
|
@ -599,25 +602,26 @@ int connect_engine::process_network_error(network::error& error)
|
|||
throw network::error(error.message);
|
||||
}
|
||||
|
||||
int res = -1;
|
||||
bool res = false;
|
||||
|
||||
// A socket has disconnected. Remove it, and resets its side.
|
||||
connected_user_list::iterator user;
|
||||
for(user = users_.begin(); user != users_.end(); ++user) {
|
||||
if (user->connection == error.socket) {
|
||||
int side_index = find_player_side_index_by_id(user->name);
|
||||
int user_index = 0;
|
||||
BOOST_FOREACH(connected_user& user, connected_users_) {
|
||||
if (user.connection == error.socket) {
|
||||
int side_index = find_user_side_index_by_id(user.name);
|
||||
if (side_index != -1) {
|
||||
side_engines_[side_index]->
|
||||
reset((local_players_only_) ? CNTR_LOCAL : CNTR_NETWORK);
|
||||
res = side_index + 1;
|
||||
} else {
|
||||
res = 0;
|
||||
side_engines_[side_index]->reset();
|
||||
}
|
||||
|
||||
users_.erase(user);
|
||||
res = true;
|
||||
|
||||
connected_users_.erase(connected_users_.begin() + user_index);
|
||||
update_side_controller_options();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
user_index++;
|
||||
}
|
||||
|
||||
// Now disconnect the socket.
|
||||
|
@ -625,7 +629,7 @@ int connect_engine::process_network_error(network::error& error)
|
|||
|
||||
// If there have been changes to the positions taken,
|
||||
// then notify other players.
|
||||
if (res != -1) {
|
||||
if (res) {
|
||||
update_and_send_diff();
|
||||
}
|
||||
|
||||
|
@ -645,20 +649,25 @@ void connect_engine::process_network_connection(const network::connection sock)
|
|||
}
|
||||
}
|
||||
|
||||
connected_user_list::iterator
|
||||
connect_engine::find_player_by_id(const std::string& id)
|
||||
int connect_engine::find_user_index_by_id(const std::string& id)
|
||||
{
|
||||
connected_user_list::iterator itor;
|
||||
for (itor = users_.begin(); itor != users_.end(); ++itor) {
|
||||
if (itor->name == id) {
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(const connected_user& user, connected_users_) {
|
||||
if (user.name == id) {
|
||||
break;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return itor;
|
||||
if (i >= connected_users_.size()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int connect_engine::find_player_side_index_by_id(const std::string& id) const
|
||||
int connect_engine::find_user_side_index_by_id(const std::string& id) const
|
||||
{
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
|
@ -676,33 +685,43 @@ int connect_engine::find_player_side_index_by_id(const std::string& id) const
|
|||
return i;
|
||||
}
|
||||
|
||||
void connect_engine::update_side_controller_options()
|
||||
{
|
||||
BOOST_FOREACH(side_engine_ptr side, side_engines_) {
|
||||
side->update_controller_options();
|
||||
}
|
||||
}
|
||||
|
||||
side_engine::side_engine(const config& cfg, connect_engine& parent_engine,
|
||||
const int index) :
|
||||
cfg_(cfg),
|
||||
parent_(parent_engine),
|
||||
mp_controller_(CNTR_NETWORK),
|
||||
controller_(CNTR_NETWORK),
|
||||
current_controller_index_(0),
|
||||
available_factions_(),
|
||||
choosable_factions_(),
|
||||
choosable_leaders_(),
|
||||
choosable_genders_(),
|
||||
controller_options_(),
|
||||
current_faction_(NULL),
|
||||
current_leader_("null"),
|
||||
current_gender_("null"),
|
||||
ready_for_start_(false),
|
||||
allow_player_(cfg["controller"] == "ai" && cfg["allow_player"].empty() ?
|
||||
false : cfg["allow_player"].to_bool(true)),
|
||||
allow_changes_(cfg["allow_changes"].to_bool(true)),
|
||||
leader_id_(cfg["id"]),
|
||||
save_id_(cfg["save_id"]),
|
||||
current_player_(cfg["current_player"]),
|
||||
index_(index),
|
||||
team_(0),
|
||||
color_(index),
|
||||
gold_(cfg["gold"].to_int(100)),
|
||||
income_(cfg["income"]),
|
||||
id_(cfg["id"]),
|
||||
player_id_(cfg["player_id"]),
|
||||
save_id_(cfg["save_id"]),
|
||||
current_player_(cfg["current_player"]),
|
||||
ai_algorithm_()
|
||||
{
|
||||
update_controller_options();
|
||||
|
||||
// Tweak the controllers.
|
||||
if (cfg["controller"] == "human_ai" ||
|
||||
cfg["controller"] == "network_ai") {
|
||||
|
@ -710,16 +729,17 @@ side_engine::side_engine(const config& cfg, connect_engine& parent_engine,
|
|||
cfg_["controller"] = "ai";
|
||||
}
|
||||
if (allow_player_ && !parent_.params_.saved_game) {
|
||||
mp_controller_ = (parent_.local_players_only_) ? CNTR_LOCAL :
|
||||
CNTR_NETWORK;
|
||||
set_controller(parent_.default_controller_);
|
||||
} else if (!current_player_.empty()) {
|
||||
set_controller(CNTR_RESERVED);
|
||||
} else {
|
||||
size_t i = CNTR_NETWORK;
|
||||
if (!allow_player_) {
|
||||
if (cfg["controller"] == "null") {
|
||||
mp_controller_ = CNTR_EMPTY;
|
||||
set_controller(CNTR_EMPTY);
|
||||
} else {
|
||||
cfg_["controller"] = controller_names[CNTR_COMPUTER];
|
||||
mp_controller_ = CNTR_COMPUTER;
|
||||
set_controller(CNTR_COMPUTER);
|
||||
}
|
||||
} else {
|
||||
if (cfg["controller"] == "network" ||
|
||||
|
@ -730,7 +750,7 @@ side_engine::side_engine(const config& cfg, connect_engine& parent_engine,
|
|||
|
||||
for (; i != CNTR_LAST; ++i) {
|
||||
if (cfg["controller"] == controller_names[i]) {
|
||||
mp_controller_ = static_cast<mp::controller>(i);
|
||||
set_controller(static_cast<mp::controller>(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -801,13 +821,13 @@ config side_engine::new_config() const
|
|||
if (!cfg_.has_attribute("side") || cfg_["side"].to_int() != index_ + 1) {
|
||||
res["side"] = index_ + 1;
|
||||
}
|
||||
res["controller"] = controller_names[mp_controller_];
|
||||
res["controller"] = controller_names[controller_];
|
||||
res["current_player"] = player_id_.empty() ? current_player_ : player_id_;
|
||||
res["id"] = id_;
|
||||
res["id"] = leader_id_;
|
||||
|
||||
if (player_id_.empty()) {
|
||||
std::string description;
|
||||
switch(mp_controller_) {
|
||||
switch(controller_) {
|
||||
case CNTR_NETWORK:
|
||||
description = N_("(Vacant slot)");
|
||||
|
||||
|
@ -921,7 +941,7 @@ config side_engine::new_config() const
|
|||
trimmed.remove_attribute(attribute);
|
||||
}
|
||||
|
||||
if (mp_controller_ != CNTR_COMPUTER) {
|
||||
if (controller_ != CNTR_COMPUTER) {
|
||||
// Only override names for computer controlled players.
|
||||
trimmed.remove_attribute("user_description");
|
||||
}
|
||||
|
@ -934,66 +954,83 @@ config side_engine::new_config() const
|
|||
|
||||
bool side_engine::ready_for_start() const
|
||||
{
|
||||
// Sides without players are always ready.
|
||||
if (!allow_player_) {
|
||||
// Sides without players are always ready.
|
||||
return true;
|
||||
}
|
||||
|
||||
// The host and the AI are always ready.
|
||||
if ((mp_controller_ == mp::CNTR_COMPUTER) ||
|
||||
(mp_controller_ == mp::CNTR_EMPTY) ||
|
||||
(mp_controller_ == mp::CNTR_LOCAL)) {
|
||||
if ((controller_ == mp::CNTR_COMPUTER) ||
|
||||
(controller_ == mp::CNTR_EMPTY) ||
|
||||
(controller_ == mp::CNTR_LOCAL)) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return ready_for_start_;
|
||||
}
|
||||
|
||||
bool side_engine::available(const std::string& name) const
|
||||
{
|
||||
if (name.empty()) {
|
||||
return allow_player_ && ((mp_controller_ == CNTR_NETWORK &&
|
||||
player_id_.empty()) || mp_controller_ == CNTR_RESERVED);
|
||||
if (controller_ == CNTR_NETWORK && !player_id_.empty()) {
|
||||
// Side is assigned to a network player.
|
||||
return true;
|
||||
}
|
||||
|
||||
return allow_player_ &&
|
||||
((mp_controller_ == CNTR_NETWORK && player_id_.empty()) ||
|
||||
(mp_controller_ == CNTR_RESERVED && current_player_ == name));
|
||||
return false;
|
||||
}
|
||||
|
||||
void side_engine::set_player_from_users_list(const std::string& player_id)
|
||||
bool side_engine::available_for_user(const std::string& name) const
|
||||
{
|
||||
connected_user_list::iterator i = parent_.find_player_by_id(player_id);
|
||||
if (i != parent_.users_.end()) {
|
||||
player_id_ = player_id;
|
||||
mp_controller_ = i->controller;
|
||||
if (!allow_player_) {
|
||||
// Computer sides are never available for players.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (controller_ == CNTR_NETWORK && player_id_.empty()) {
|
||||
// Side is free and waiting for user.
|
||||
return true;
|
||||
}
|
||||
if (controller_ == CNTR_RESERVED && name.empty()) {
|
||||
// Side is still available to someone.
|
||||
return true;
|
||||
}
|
||||
if (controller_ == CNTR_RESERVED && current_player_ == name) {
|
||||
// Side is available only for the player with specific name.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void side_engine::swap_sides_on_drop_target(const int drop_target) {
|
||||
const std::string target_id =
|
||||
parent_.side_engines_[drop_target]->player_id_;
|
||||
const mp::controller target_controller =
|
||||
parent_.side_engines_[drop_target]->mp_controller_;
|
||||
parent_.side_engines_[drop_target]->controller_;
|
||||
const std::string target_ai =
|
||||
parent_.side_engines_[drop_target]->ai_algorithm_;
|
||||
|
||||
parent_.side_engines_[drop_target]->ai_algorithm_ = ai_algorithm_;
|
||||
if (player_id_.empty()) {
|
||||
parent_.side_engines_[drop_target]->mp_controller_ = mp_controller_;
|
||||
parent_.side_engines_[drop_target]->set_controller(controller_);
|
||||
} else {
|
||||
parent_.side_engines_[drop_target]->
|
||||
set_player_from_users_list(player_id_);
|
||||
const int user_index = parent_.find_user_index_by_id(player_id_);
|
||||
if (user_index != -1) {
|
||||
const connected_user& user = parent_.connected_users_[user_index];
|
||||
parent_.side_engines_[drop_target]->player_id_ = user.name;
|
||||
parent_.side_engines_[drop_target]->set_controller(
|
||||
parent_.default_controller_);
|
||||
}
|
||||
}
|
||||
|
||||
ai_algorithm_ = target_ai;
|
||||
if (target_id.empty())
|
||||
{
|
||||
mp_controller_ = target_controller;
|
||||
set_controller(target_controller);
|
||||
player_id_ = "";
|
||||
} else {
|
||||
set_player_from_users_list(target_id);
|
||||
const int user_index = parent_.find_user_index_by_id(target_id);
|
||||
if (user_index != -1) {
|
||||
const connected_user& user = parent_.connected_users_[user_index];
|
||||
parent_.side_engines_[drop_target]->player_id_ = user.name;
|
||||
parent_.side_engines_[drop_target]->set_controller(
|
||||
parent_.default_controller_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,16 +1141,10 @@ void side_engine::resolve_random()
|
|||
}
|
||||
}
|
||||
|
||||
void side_engine::reset(mp::controller controller)
|
||||
void side_engine::reset()
|
||||
{
|
||||
player_id_.clear();
|
||||
mp_controller_ = controller;
|
||||
|
||||
if (mp_controller_ == mp::CNTR_NETWORK ||
|
||||
mp_controller_ == mp::CNTR_RESERVED) {
|
||||
|
||||
ready_for_start_ = false;
|
||||
}
|
||||
set_controller(parent_.default_controller_);
|
||||
|
||||
if (!parent_.params_.saved_game) {
|
||||
set_current_faction(choosable_factions_[0]);
|
||||
|
@ -1122,22 +1153,58 @@ void side_engine::reset(mp::controller controller)
|
|||
}
|
||||
}
|
||||
|
||||
void side_engine::import_network_user(const config& data)
|
||||
void side_engine::place_user(const config& data)
|
||||
{
|
||||
if (mp_controller_ == CNTR_RESERVED || parent_.params_.saved_game) {
|
||||
ready_for_start_ = true;
|
||||
}
|
||||
|
||||
player_id_ = data["name"].str();
|
||||
mp_controller_ = CNTR_NETWORK;
|
||||
set_controller(parent_.default_controller_);
|
||||
|
||||
BOOST_FOREACH(const config* faction, choosable_factions_) {
|
||||
if ((*faction)["id"] == data["faction"]) {
|
||||
set_current_faction(faction);
|
||||
if (data.has_attribute("faction")) {
|
||||
// Network user's data carry information about chosen
|
||||
// faction, leader and genders.
|
||||
BOOST_FOREACH(const config* faction, choosable_factions_) {
|
||||
if ((*faction)["id"] == data["faction"]) {
|
||||
set_current_faction(faction);
|
||||
}
|
||||
}
|
||||
set_current_leader(data["leader"]);
|
||||
set_current_gender(data["gender"]);
|
||||
}
|
||||
set_current_leader(data["leader"]);
|
||||
set_current_gender(data["gender"]);
|
||||
}
|
||||
|
||||
void side_engine::update_controller_options()
|
||||
{
|
||||
controller_options_ = parent_.default_controller_options_;
|
||||
if (!save_id_.empty()) {
|
||||
controller_options_.push_back(
|
||||
std::make_pair(CNTR_RESERVED, _("Reserved")));
|
||||
}
|
||||
|
||||
controller_options_.push_back(std::make_pair(CNTR_LAST, _("--give--")));
|
||||
|
||||
BOOST_FOREACH(const connected_user& user, parent_.connected_users_) {
|
||||
controller_options_.push_back(std::make_pair(
|
||||
parent_.default_controller_, user.name));
|
||||
}
|
||||
}
|
||||
|
||||
bool side_engine::controller_changed(const int selection)
|
||||
{
|
||||
const mp::controller selected_cntr = controller_options_[selection].first;
|
||||
if (selected_cntr == CNTR_LAST) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if user was selected. If so assign a side to him/her.
|
||||
// If not, make sure that no user is assigned to this side.
|
||||
if (selected_cntr == parent_.default_controller_ && selection != 0) {
|
||||
player_id_ = controller_options_[selection].second;
|
||||
} else {
|
||||
player_id_.clear();
|
||||
}
|
||||
|
||||
set_controller(selected_cntr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void side_engine::set_current_faction(const config* current_faction)
|
||||
|
@ -1187,22 +1254,16 @@ void side_engine::set_faction_commandline(const std::string& faction_name)
|
|||
|
||||
void side_engine::set_controller_commandline(const std::string& controller_name)
|
||||
{
|
||||
mp_controller_ = CNTR_LOCAL;
|
||||
set_controller(CNTR_LOCAL);
|
||||
|
||||
if (controller_name == "ai") {
|
||||
mp_controller_ = CNTR_COMPUTER;
|
||||
set_controller(CNTR_COMPUTER);
|
||||
}
|
||||
if (controller_name == "null") {
|
||||
mp_controller_ = CNTR_EMPTY;
|
||||
set_controller(CNTR_EMPTY);
|
||||
}
|
||||
|
||||
player_id_ = "";
|
||||
}
|
||||
|
||||
void side_engine::set_ai_algorithm_commandline(
|
||||
const std::string& algorithm_name)
|
||||
{
|
||||
ai_algorithm_ = algorithm_name;
|
||||
player_id_.clear();
|
||||
}
|
||||
|
||||
void side_engine::update_choosable_leaders()
|
||||
|
@ -1220,4 +1281,27 @@ void side_engine::update_choosable_genders()
|
|||
parent_.params_.use_map_settings, parent_.params_.saved_game);
|
||||
}
|
||||
|
||||
void side_engine::set_controller(mp::controller controller)
|
||||
{
|
||||
controller_ = controller;
|
||||
|
||||
// Update current controller index.
|
||||
int i = 0;
|
||||
BOOST_FOREACH(const controller_option& option, controller_options_) {
|
||||
if (option.first == controller) {
|
||||
current_controller_index_ = i;
|
||||
|
||||
if (player_id_.empty() || player_id_ == option.second) {
|
||||
// Stop searching if no user is assigned to a side
|
||||
// or the selected user is found.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
assert(current_controller_index_ < controller_options_.size());
|
||||
}
|
||||
|
||||
} // end namespace mp
|
||||
|
|
|
@ -19,28 +19,31 @@
|
|||
#include "gamestatus.hpp"
|
||||
#include "multiplayer_ui.hpp"
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
namespace mp {
|
||||
|
||||
enum controller {
|
||||
CNTR_NETWORK = 0,
|
||||
CNTR_LOCAL,
|
||||
CNTR_COMPUTER,
|
||||
CNTR_EMPTY,
|
||||
CNTR_RESERVED,
|
||||
CNTR_LAST
|
||||
};
|
||||
|
||||
class side_engine;
|
||||
|
||||
struct connected_user
|
||||
{
|
||||
connected_user(const std::string& name, mp::controller controller,
|
||||
network::connection connection) :
|
||||
connected_user(const std::string& name, network::connection connection) :
|
||||
name(name),
|
||||
controller(controller),
|
||||
connection(connection)
|
||||
{};
|
||||
std::string name;
|
||||
mp::controller controller;
|
||||
network::connection connection;
|
||||
};
|
||||
|
||||
typedef boost::shared_ptr<side_engine> side_engine_ptr;
|
||||
typedef std::vector<connected_user> connected_user_list;
|
||||
typedef boost::tuple<bool, bool, bool, std::vector<int> > network_res_tuple;
|
||||
typedef std::pair<mp::controller, std::string> controller_option;
|
||||
|
||||
class connect_engine
|
||||
{
|
||||
|
@ -49,10 +52,17 @@ public:
|
|||
const bool local_players_only, const bool first_scenario);
|
||||
~connect_engine();
|
||||
|
||||
enum USER_TYPE { HOST, PLAYER, OBSERVER };
|
||||
|
||||
config* current_config();
|
||||
|
||||
void add_side_engine(side_engine_ptr engine);
|
||||
void assign_side_for_host();
|
||||
// Should be called after all calls to 'add_side_engine()'
|
||||
// have been made, so that everything could be initialized.
|
||||
void init_after_side_engines_assigned();
|
||||
|
||||
void import_user(USER_TYPE user_type, const config& data, int sock,
|
||||
int side_taken = -1);
|
||||
|
||||
// Returns true if there are still sides available for this game.
|
||||
bool sides_available() const;
|
||||
|
@ -66,29 +76,26 @@ public:
|
|||
void start_game();
|
||||
void start_game_commandline(const commandline_options& cmdline_opts);
|
||||
|
||||
// Acts according to the given data and returns tuple
|
||||
// holding information on what has changed.
|
||||
// 0th - quit?
|
||||
// 1st - update UI?
|
||||
// 2nd - silent UI update?
|
||||
// 3rd - side UIs to update.
|
||||
network_res_tuple process_network_data(const config& data,
|
||||
// Return pair first element specifies whether to leave the game
|
||||
// and second element whether to silently update UI.
|
||||
std::pair<bool, bool> process_network_data(const config& data,
|
||||
const network::connection sock);
|
||||
// Returns -1 if UI should not be updated at all,
|
||||
// 0 if UI should be updated or (side index + 1)
|
||||
// if some side's UI should be updated as well.
|
||||
int process_network_error(network::error& error);
|
||||
// Returns true, if UI should be updated.
|
||||
bool process_network_error(network::error& error);
|
||||
void process_network_connection(const network::connection sock);
|
||||
|
||||
connected_user_list::iterator find_player_by_id(const std::string& id);
|
||||
int find_user_index_by_id(const std::string& id);
|
||||
// Returns the side which is taken by a given user,
|
||||
// or -1 if none was found.
|
||||
int find_user_side_index_by_id(const std::string& id) const;
|
||||
|
||||
|
||||
/* Setters & Getters */
|
||||
|
||||
const config& level() const { return level_; }
|
||||
const game_state& state() const { return state_; }
|
||||
bool local_players_only() const { return local_players_only_; }
|
||||
connected_user_list& users() { return users_; }
|
||||
const std::vector<connected_user>& connected_users() const
|
||||
{ return connected_users_; }
|
||||
std::vector<std::string>& team_names() { return team_names_; }
|
||||
std::vector<std::string>& user_team_names() { return user_team_names_; }
|
||||
|
||||
|
@ -99,25 +106,24 @@ private:
|
|||
connect_engine(const connect_engine&);
|
||||
void operator=(const connect_engine&);
|
||||
|
||||
friend side_engine;
|
||||
void update_side_controller_options();
|
||||
|
||||
// Returns the side which is taken by a given player,
|
||||
// or -1 if none was found.
|
||||
int find_player_side_index_by_id(const std::string& id) const;
|
||||
friend side_engine;
|
||||
|
||||
config level_;
|
||||
game_state state_;
|
||||
|
||||
const mp_game_settings& params_;
|
||||
|
||||
const bool local_players_only_;
|
||||
const mp::controller default_controller_;
|
||||
const bool first_scenario_;
|
||||
|
||||
std::vector<side_engine_ptr> side_engines_;
|
||||
std::vector<const config*> era_factions_;
|
||||
std::vector<std::string> team_names_;
|
||||
std::vector<std::string> user_team_names_;
|
||||
connected_user_list users_;
|
||||
std::vector<connected_user> connected_users_;
|
||||
std::vector<controller_option> default_controller_options_;
|
||||
};
|
||||
|
||||
class side_engine
|
||||
|
@ -135,19 +141,20 @@ public:
|
|||
bool ready_for_start() const;
|
||||
// Returns true if this side is waiting for a network player and
|
||||
// players are allowed.
|
||||
bool available(const std::string& name = "") const;
|
||||
|
||||
void set_player_from_users_list(const std::string& player_id);
|
||||
bool available_for_user(const std::string& name = "") const;
|
||||
|
||||
void swap_sides_on_drop_target(const int drop_target);
|
||||
|
||||
void resolve_random();
|
||||
|
||||
// Resets this side to its default state.
|
||||
void reset(mp::controller controller);
|
||||
void reset();
|
||||
|
||||
// Imports data from the network into this side.
|
||||
void import_network_user(const config& data);
|
||||
// Place user into this side.
|
||||
void place_user(const config& data);
|
||||
|
||||
void update_controller_options();
|
||||
bool controller_changed(const int selection);
|
||||
|
||||
void set_current_faction(const config* current_faction);
|
||||
void set_current_leader(const std::string& current_leader);
|
||||
|
@ -158,8 +165,6 @@ public:
|
|||
// Game set up from command line helpers.
|
||||
void set_faction_commandline(const std::string& faction_name);
|
||||
void set_controller_commandline(const std::string& controller_name);
|
||||
void set_ai_algorithm_commandline(const std::string& algorithm_name);
|
||||
|
||||
|
||||
/* Setters & Getters */
|
||||
|
||||
|
@ -169,12 +174,14 @@ public:
|
|||
{ return choosable_leaders_; }
|
||||
const std::vector<std::string>& choosable_genders()
|
||||
{ return choosable_genders_; }
|
||||
const std::vector<controller_option>& controller_options()
|
||||
{ return controller_options_; }
|
||||
const config& cfg() const { return cfg_; }
|
||||
const std::string& current_leader() const { return current_leader_; }
|
||||
const std::string& current_gender() const { return current_gender_; }
|
||||
controller mp_controller() const { return mp_controller_; }
|
||||
void set_mp_controller(controller mp_controller)
|
||||
{ mp_controller_ = mp_controller; }
|
||||
mp::controller controller() const { return controller_; }
|
||||
unsigned current_controller_index() const
|
||||
{ return current_controller_index_; }
|
||||
int index() const { return index_; }
|
||||
void set_index(int index) { index_ = index; }
|
||||
int team() const { return team_; }
|
||||
|
@ -186,14 +193,11 @@ public:
|
|||
int income() const { return income_; }
|
||||
void set_income(int income) { income_ = income; }
|
||||
const std::string& player_id() const { return player_id_; }
|
||||
void set_player_id(const std::string& player_id) { player_id_ = player_id; }
|
||||
const std::string& save_id() const { return save_id_; }
|
||||
const std::string& current_player() const { return current_player_; }
|
||||
const std::string& ai_algorithm() const { return ai_algorithm_; }
|
||||
void set_ai_algorithm(const std::string& ai_algorithm)
|
||||
{ ai_algorithm_ = ai_algorithm; }
|
||||
void set_ready_for_start(const bool ready_for_start)
|
||||
{ ready_for_start_ = ready_for_start; }
|
||||
bool allow_player() const { return allow_player_; }
|
||||
|
||||
private:
|
||||
|
@ -203,10 +207,13 @@ private:
|
|||
void update_choosable_leaders();
|
||||
void update_choosable_genders();
|
||||
|
||||
void set_controller(mp::controller controller);
|
||||
|
||||
config cfg_;
|
||||
connect_engine& parent_;
|
||||
|
||||
controller mp_controller_;
|
||||
mp::controller controller_;
|
||||
unsigned current_controller_index_;
|
||||
|
||||
// All factions which could be played by a side (including Random).
|
||||
std::vector<const config*> available_factions_;
|
||||
|
@ -215,24 +222,24 @@ private:
|
|||
std::vector<std::string> choosable_leaders_;
|
||||
std::vector<std::string> choosable_genders_;
|
||||
|
||||
std::vector<controller_option> controller_options_;
|
||||
|
||||
const config* current_faction_;
|
||||
std::string current_leader_;
|
||||
std::string current_gender_;
|
||||
|
||||
bool ready_for_start_;
|
||||
bool allow_player_;
|
||||
bool allow_changes_;
|
||||
const bool allow_player_;
|
||||
const bool allow_changes_;
|
||||
const std::string leader_id_;
|
||||
const std::string save_id_;
|
||||
const std::string current_player_;
|
||||
|
||||
// Configurable variables.
|
||||
int index_;
|
||||
int team_;
|
||||
int color_;
|
||||
int gold_;
|
||||
int income_;
|
||||
std::string id_;
|
||||
std::string player_id_;
|
||||
std::string save_id_;
|
||||
std::string current_player_;
|
||||
std::string ai_algorithm_;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,8 +32,6 @@ class game_state;
|
|||
|
||||
namespace mp {
|
||||
|
||||
enum controller { CNTR_NETWORK = 0, CNTR_LOCAL, CNTR_COMPUTER, CNTR_EMPTY, CNTR_RESERVED, CNTR_LAST };
|
||||
|
||||
const std::string random_enemy_picture("units/random-dice.png");
|
||||
|
||||
void check_response(network::connection res, const config& data);
|
||||
|
|
Loading…
Add table
Reference in a new issue