mail[Wesnoth-commits] r13538 - in /trunk/src: playturn.cpp server/game.cpp


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by joerg . hinrichs on September 12, 2006 - 22:00:
Author: jhinrichs
Date: Tue Sep 12 22:00:08 2006
New Revision: 13538

URL: http://svn.gna.org/viewcvs/wesnoth?rev=13538&view=rev
Log:
Fixes bug #6747 (Transfer of control: After host left, AI sides get stuck). 
This one transfers AI sides, too.

Modified:
    trunk/src/playturn.cpp
    trunk/src/server/game.cpp

Modified: trunk/src/playturn.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/playturn.cpp?rev=13538&r1=13537&r2=13538&view=diff
==============================================================================
--- trunk/src/playturn.cpp (original)
+++ trunk/src/playturn.cpp Tue Sep 12 22:00:08 2006
@@ -159,9 +159,16 @@
        //if a side has dropped out of the game.
        if(cfg["side_drop"] != "") {
                const size_t side = atoi(cfg["side_drop"].c_str())-1;
+               const std::string controller = cfg["controller"];
+
                if(side >= teams_.size()) {
                        LOG_STREAM(err, network) << "unknown side " << side 
<< " is dropping game\n";
                        throw network::error("");
+               }
+
+               if (controller == "ai"){
+                       teams_[side].make_ai();
+                       return PROCESS_RESTART_TURN;
                }
 
                int action = 0;
@@ -187,10 +194,11 @@
 
                        //get all allies in as options to transfer control
                        for (std::vector<team>::iterator team = 
teams_.begin(); team != teams_.end(); team++){
-                               if ( (!team->is_enemy(side + 1)) && 
(!team->is_human())
-                                       && (team->current_player() != 
teams_[side].current_player()) ){
-                                       //if this is an ally of the dropping 
side and it is not us (choose local player
-                                       //if you want that) and if it is not 
the dropping side itself, get this team in as well
+                               if ( (!team->is_enemy(side + 1)) && 
(!team->is_human()) && (!team->is_ai()) && (!team->is_empty())
+                                       && (team->current_player() != 
teams_[side].current_player()) ){
+                                       //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());
                                        allies.push_back(&(*team));
                                }

Modified: trunk/src/server/game.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/server/game.cpp?rev=13538&r1=13537&r2=13538&view=diff
==============================================================================
--- trunk/src/server/game.cpp (original)
+++ trunk/src/server/game.cpp Tue Sep 12 22:00:08 2006
@@ -357,22 +357,24 @@
                return already;
        }
 
+       //get the socket of the player that issued the command
+       bool host = false; //we need to save this information before the 
player is erased 
+       network::connection sock;
+       bool foundCommandPlayer = false;
+       std::multimap<network::connection, size_t>::iterator oldside;
+       for (std::multimap<network::connection, size_t>::iterator s = 
sides_.begin(); s != sides_.end(); s++){
+               if (s->second == side_index){
+                       sock = s->first;
+                       foundCommandPlayer = true;
+                       oldside = s;
+                       host = is_needed(sock);
+                       break;
+               }
+       }
+
        //The player owns this side
        if(cfg["own_side"] == "yes") {
-               //get the socket of the player that issued the command
-               network::connection sock;
-               bool found = false;
-               std::multimap<network::connection, size_t>::iterator oldside;
-               for (std::multimap<network::connection, size_t>::iterator s = 
sides_.begin(); s != sides_.end(); s++){
-                       if (s->second == side_index){
-                               sock = s->first;
-                               found = true;
-                               oldside = s;
-                               break;
-                       }
-               }
-
-               if (!found){
+               if (!foundCommandPlayer){
                        static const std::string player_not_found = "This 
side is not listed for the game";
                        return player_not_found;
                }
@@ -386,9 +388,6 @@
 
                //if a player gives up their last side, make them an observer
                if (sides_.count(sock) == 1){
-                       //we need to save this information before the player 
is erased
-                       bool host = is_needed(sock);
-
                        observers_.push_back(*p);
                        players_.erase(p);
 
@@ -432,6 +431,19 @@
 
        change["controller"] = "human";
        network::queue_data(response, sock_entering);
+
+       //if the host left and there are ai sides, transfer them to the new 
host
+       if (host){
+               for (unsigned int i = 0; i < side_controllers_.size(); i++){
+                       if (side_controllers_[i] == "ai"){
+                               change["side"] = lexical_cast<std::string, 
unsigned int>(i + 1);
+                               change["controller"] = "ai";
+                               network::queue_data(response, sock_entering);
+                               sides_.insert(std::pair<const 
network::connection,size_t>(sock_entering, i));
+                       }
+               }
+               sides_.erase(sock);
+       }
 
        if(sides_.count(sock_entering) < 2) {
                //send everyone a message saying that the observer who is 
taking the side has quit
@@ -650,6 +662,12 @@
 void game::remove_player(network::connection player, bool notify_creator)
 {
        LOG_SERVER << "removing player...\n";
+
+       bool host = false;
+       if (players_.size() > 0){
+               host = player == players_.front();
+       }
+
        {
                const user_vector::iterator itor = 
std::find(players_.begin(),players_.end(),player);
 
@@ -666,18 +684,37 @@
 
        LOG_SERVER << debug_player_info();
        bool observer = true;
-       std::pair<std::multimap<network::connection,size_t>::const_iterator,
-                 std::multimap<network::connection,size_t>::const_iterator> 
sides = sides_.equal_range(player);
-       while(sides.first != sides.second) {
+
+       //check for ai sides first and drop them, too, if the host left
+       if (host){
+               //can't do this with an iterator, because it doesn't know the 
side_index
+               for (size_t side = 0; side < side_controllers_.size(); 
side++){
+                       //send the host a notification of removal of this side
+                       if(notify_creator && players_.empty() == false && 
side_controllers_[side] == "ai") {
+                               std::string msg = "AI side " + 
lexical_cast<std::string, size_t>(side + 1) + " is transferred to new host";
+                               send_data(construct_server_message(msg));
+                               config drop;
+                               drop["side_drop"] = lexical_cast<std::string, 
size_t>(side + 1);
+                               drop["controller"] = "ai";
+                               network::queue_data(drop, players_.front());
+                               sides_taken_[side] = false;
+                               observer = false;
+                       }
+               }
+       }
+
+       //look for all sides the player controlled and drop them
+       std::multimap<network::connection, size_t>::const_iterator side;
+       for (side = sides_.find(player); side != sides_.end(); side++){
                //send the host a notification of removal of this side
-               if(notify_creator && players_.empty() == false) {
+               if(notify_creator && players_.empty() == false && side->first 
== player) {
                        config drop;
-                       drop["side_drop"] = lexical_cast<std::string, 
size_t>(sides.first->second + 1);
+                       drop["side_drop"] = lexical_cast<std::string, 
size_t>(side->second + 1);
+                       drop["controller"] = side_controllers_[player];
                        network::queue_data(drop, players_.front());
                }
-               sides_taken_[sides.first->second] = false;
+               sides_taken_[side->second] = false;
                observer = false;
-               ++sides.first;
        }
        if(!observer)
                sides_.erase(player);




Related Messages


Powered by MHonArc, Updated Tue Sep 12 23:20:08 2006