Backport (minimal version without cleanups) EdB's current_player work:

fixes bugs #7298, #7293, #7457.

This is the core of the following trunk changesets:

2006-10-27T10:23:18Z!edb@sigluy.net
2006-10-28T20:44:28Z!edb@sigluy.net
2006-10-30T21:37:34Z!edb@sigluy.net
2006-11-01T09:48:11Z!edb@sigluy.net

Basically, "current_player" is the current controller, "side_id" is
who started it.  The difference becomes important when a player is
dropped out and replaced.
This commit is contained in:
Rusty Russell 2006-11-01 12:38:03 +00:00
parent 2d30f44979
commit 45b677347b
8 changed files with 59 additions and 13 deletions

View File

@ -134,7 +134,7 @@ namespace gui{
if(teams[n].is_empty()) {
continue;
}
const std::string& name = teams[n].save_id();
const std::string& name = teams[n].current_player();
if( name.size() >= semiword.size() &&
std::equal(semiword.begin(),semiword.end(),name.begin(),chars_equal_insensitive)) {
if(matches.empty()) {

View File

@ -462,6 +462,7 @@ config connect::side::get_config() const
}
res["controller"] = controller_names[controller_];
res["description"] = id_;
res["current_player"] = id_;
if (id_.empty()) {
char const *description;

View File

@ -196,7 +196,7 @@ void wait::join_game(bool observe)
int side_choice = 0;
for(config::child_list::const_iterator s = sides_list.begin(); s != sides_list.end(); ++s) {
if((**s)["controller"] == "network" && (**s)["description"].empty()) {
if((**s)["save_id"] == preferences::login()) {
if((**s)["save_id"] == preferences::login() || (**s)["current_player"] == preferences::login()) {
side_choice = s - sides_list.begin();
}
}

View File

@ -170,7 +170,7 @@ LEVEL_RESULT play_game(display& disp, game_state& state, const config& game_conf
const config::child_list& sides_list = scenario->get_children("side");
for(config::child_list::const_iterator side = sides_list.begin();
side != sides_list.end(); ++side) {
std::string id = (**side)["save_id"];
std::string id = (**side)["current_player"];
if(id.empty())
continue;
controllers[id] = player_controller((**side)["controller"],
@ -190,7 +190,7 @@ LEVEL_RESULT play_game(display& disp, game_state& state, const config& game_conf
for(config::child_list::const_iterator side = sides_list.begin();
side != sides_list.end(); ++side) {
if((**side)["controller"] == "network" &&
(**side)["description"] == preferences::login()) {
(**side)["current_player"] == preferences::login()) {
(**side)["controller"] = preferences::client_type();
} else if((**side)["controller"] != "null") {
(**side)["controller"] = "network";
@ -368,7 +368,7 @@ LEVEL_RESULT play_game(display& disp, game_state& state, const config& game_conf
for(config::child_list::const_iterator side = sides_list.begin();
side != sides_list.end(); ++side) {
std::string id = (**side)["save_id"];
std::string id = (**side)["current_player"];
if(id.empty()) {
continue;
}

View File

@ -299,7 +299,7 @@ LEVEL_RESULT playsingle_controller::play_scenario(const std::vector<config*>& st
report << "\n";
}
report << font::BOLD_TEXT << i->save_id() << "\n";
report << font::BOLD_TEXT << i->current_player() << "\n";
}
report << _("Remaining gold: ")

View File

@ -144,6 +144,10 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
if(index < teams_.size()) {
teams_[index].set_current_player(player);
const unit_map::iterator leader = find_leader(units_, side);
if(leader != units_.end())
leader->second.rename(player);
if ( (controller == "human") && (!teams_[index].is_human()) ) {
teams_[index].make_human();
gui_.set_team(index);
@ -167,12 +171,18 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
throw network::error("");
}
const unit_map::iterator leader = find_leader(units_,side+1);
if (controller == "ai"){
teams_[side].make_ai();
config cfg;
cfg.values["side"] = lexical_cast<std::string>(side+1);
cfg.values["controller"] = "ai";
cfg.values["name"] = "ai"+cfg.values["side"];
teams_[side].set_current_player(cfg.values["name"]);
if (leader != units_.end())
leader->second.rename(cfg.values["name"]);
network::send_data(cfg);
return PROCESS_RESTART_TURN;
}
@ -186,7 +196,6 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
//see if the side still has a leader alive. If they have
//no leader, we assume they just want to be replaced by
//the AI.
const unit_map::const_iterator leader = find_leader(units_,side+1);
if(leader != units_.end()) {
options.push_back(_("Replace with AI"));
options.push_back(_("Replace with local player"));
@ -204,12 +213,12 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
//if this is an ally of the dropping side and it is not us (choose local player
//if you want that) and not ai or empty and if it is not the dropping side itself,
//get this team in as well
options.push_back(_("Replace with ") + team->save_id());
options.push_back(_("Replace with ") + team->current_player());
allies.push_back(&(*team));
}
}
const std::string msg = leader->second.description() + " " + _("has left the game. What do you want to do?");
const std::string msg = teams_[side].current_player() + " " + _("has left the game. What do you want to do?");
action = gui::show_dialog2(gui_,NULL,"",msg,gui::OK_ONLY,&options);
}
@ -223,6 +232,10 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
config cfg;
cfg.values["side"] = lexical_cast<std::string>(side+1);
cfg.values["controller"] = "ai";
cfg.values["name"] = "ai"+cfg.values["side"];
teams_[side].set_current_player(cfg.values["name"]);
if (leader != units_.end())
leader->second.rename(cfg.values["name"]);
network::send_data(cfg);
}
return PROCESS_RESTART_TURN;
@ -232,6 +245,10 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
config cfg;
cfg.values["side"] = lexical_cast<std::string>(side+1);
cfg.values["controller"] = "human";
cfg.values["name"] = "human"+cfg.values["side"];
teams_[side].set_current_player(cfg.values["name"]);
if (leader != units_.end())
leader->second.rename(cfg.values["name"]);
network::send_data(cfg);
}
return PROCESS_RESTART_TURN;
@ -247,6 +264,14 @@ turn_info::PROCESS_DATA_RESULT turn_info::process_network_data(const config& cfg
change_side_controller(cfg["side_drop"], allies[i]->save_id(), false /*not our own side*/);
} else {
teams_[side].make_ai();
config cfg;
cfg.values["side"] = lexical_cast<std::string>(side+1);
cfg.values["controller"] = "ai";
cfg.values["name"] = "ai"+cfg.values["side"];
teams_[side].set_current_player(cfg.values["name"]);
if (leader != units_.end())
leader->second.rename(cfg.values["name"]);
network::send_data(cfg);
}
return PROCESS_RESTART_TURN;
}

View File

@ -451,8 +451,7 @@ Units cannot be killed by poison alone. The poison will not reduce it below 1 HP
const std::vector<std::string> items = utils::split(flag);
const std::vector<std::string> sub_items = utils::split(items[0], ':');
image::locator flag_image(sub_items[0], new_rgb, old_rgb);
u = find_leader(units,playing_side);
return report("",flag_image,u != units.end() ? u->second.description() : "");
return report("",flag_image,teams[playing_side-1].current_player());
}
case OBSERVERS: {

View File

@ -203,9 +203,24 @@ bool game::take_side(network::connection player, const config& cfg)
return false;
}
// else take the current side
if (player == owner_ && started_ && !cfg["controller"].empty())
if (player == owner_ && started_ && !cfg["controller"].empty()) {
//if the owner have transfer side to an ai or an human in game
//fake a "change_controller" command so other player update controller name
//and set controller to the type owner have set
config fake;
config& change = fake.add_child("change_controller");
change["side"] = side;
change["player"] = cfg["name"];
change["controller"] = "network";
send_data(fake, owner_); //send change to all except owner
//update level so observer who join display the good player name
config::child_itors it = level_.child_range("side");
it.first += side_index;
wassert(it.first != it.second);
(**it.first)["current_player"] = cfg["name"];
side_controllers_[side_index] = cfg["controller"];
else
} else
side_controllers_[side_index] = "network";
sides_.insert(std::pair<network::connection, size_t>(player, side_index));
sides_taken_[side_index] = true;
@ -447,6 +462,12 @@ const std::string& game::transfer_side_control(const config& cfg)
change["controller"] = "human";
network::queue_data(response, sock_entering);
//update level so observer who join display the good player name
config::child_itors it = level_.child_range("side");
it.first += side_index;
wassert(it.first != it.second);
(**it.first)["current_player"] = player;
//if the host left and there are ai sides, transfer them to the new host
if (host_leave) {
for (unsigned int i = 0; i < side_controllers_.size(); i++){