]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/gamecommand.qc
Make GameCommand_playerdemo() use switches instead of many if/else statements
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / gamecommand.qc
index a302491627fb3419aaf4cba42086cbe927066c34..eb15e3df456c05f95842517e08630dc4473db733 100644 (file)
@@ -1,6 +1,6 @@
 // =====================================================
 //  Server side game commands code, reworked by Samual
-//  Last updated: November 6th, 2011
+//  Last updated: November 8th, 2011
 // =====================================================
 
 #define GC_REQUEST_COMMAND 1
@@ -12,6 +12,11 @@ string GotoMap(string m);
 
 void race_deleteTime(string map, float pos);
 
+#define SHUFFLETEAMS_MAX_PLAYERS 255
+#define SHUFFLETEAMS_MAX_TEAMS 4
+float shuffleteams_players[SHUFFLETEAMS_MAX_PLAYERS]; // maximum of 255 player slots
+float shuffleteams_teams[SHUFFLETEAMS_MAX_TEAMS]; // maximum of 4 teams
+
 
 // ============================
 //  Misc. Supporting Functions
@@ -214,7 +219,7 @@ void GameCommand_allspec(float request, float argc)
                {
                        print("\nUsage:^3 sv_cmd allspec [reason]\n");
                        print("  Where 'reason' is an optional argument for explanation of allspec command.\n");
-                       print("See also: ^2moveplayer^7\n");
+                       print("See also: ^2moveplayer, shuffleteams^7\n");
                        return;
                }
        }
@@ -1137,7 +1142,7 @@ void GameCommand_moveplayer(float request, float argc)
                        print("    2 (10) no centerprint, admin message; 3 (11) no centerprint, no admin message\n");
                        print("Examples: moveplayer 1,3,5 red 3\n");
                        print("          moveplayer 2 spec \n");
-                       print("See also: ^2allspec^7\n");
+                       print("See also: ^2allspec, shuffleteams^7\n");
                        return;
                }
        }
@@ -1194,7 +1199,7 @@ void GameCommand_onslaught_updatelinks(float request) // UNTESTED // should this
        }
 }
 
-void GameCommand_playerdemo(float request, float argc) // UNTESTED // TODO: change the if statements for sub arguments to switches
+void GameCommand_playerdemo(float request, float argc) // UNTESTED
 {      
        switch(request)
        {
@@ -1204,57 +1209,64 @@ void GameCommand_playerdemo(float request, float argc) // UNTESTED // TODO: chan
                        float i, n, entno;
                        string s;
                        
-                       if(argv(1) == "read")
+                       switch(argv(1))
                        {
-                               // TODO: Create a general command for looking this up, save a lot of space everywhere in this file
-                               entno = stof(argv(2));
-                               if((entno < 1) | (entno > maxclients)) {
-                                       print("Player ", argv(2), " doesn't exist\n");
+                               case "read":
+                               {
+                                       // TODO: Create a general command for looking this up, save a lot of space everywhere in this file
+                                       entno = stof(argv(2));
+                                       if((entno < 1) | (entno > maxclients)) {
+                                               print("Player ", argv(2), " doesn't exist\n");
+                                               return;
+                                       }
+                                       client = edict_num(entno);
+                                       if(clienttype(client) != CLIENTTYPE_BOT) {
+                                               print("Player ", client.netname, " is not a bot\n");
+                                               return;
+                                       }
+                                       self = client;
+                                       playerdemo_open_read(argv(3));
                                        return;
                                }
-                               client = edict_num(entno);
-                               if(clienttype(client) != CLIENTTYPE_BOT) {
-                                       print("Player ", client.netname, " is not a bot\n");
+                               
+                               case "write":
+                               {
+                                       entno = stof(argv(2));
+                                       if((entno < 1) | (entno > maxclients)) {
+                                               print("Player ", argv(2), " doesn't exist\n");
+                                               return;
+                                       }
+                                       client = edict_num(entno);
+                                       self = client;
+                                       playerdemo_open_write(argv(3));
                                        return;
                                }
-                               self = client;
-                               playerdemo_open_read(argv(3));
-                               return;
-                       }
-                       else if(argv(1) == "write")
-                       {
-                               entno = stof(argv(2));
-                               if((entno < 1) | (entno > maxclients)) {
-                                       print("Player ", argv(2), " doesn't exist\n");
+                               
+                               case "auto_read_and_write":
+                               {
+                                       s = argv(2);
+                                       n = stof(argv(3));
+                                       cvar_set("bot_number", ftos(n));
+                                       localcmd("wait; wait; wait\n");
+                                       for(i = 0; i < n; ++i)
+                                               localcmd("sv_cmd playerdemo read ", ftos(i+2), " ", s, ftos(i+1), "\n");
+                                       localcmd("sv_cmd playerdemo write 1 ", ftos(n+1), "\n");
                                        return;
                                }
-                               client = edict_num(entno);
-                               self = client;
-                               playerdemo_open_write(argv(3));
-                               return;
-                       }
-                       else if(argv(1) == "auto_read_and_write")
-                       {
-                               s = argv(2);
-                               n = stof(argv(3));
-                               cvar_set("bot_number", ftos(n));
-                               localcmd("wait; wait; wait\n");
-                               for(i = 0; i < n; ++i)
-                                       localcmd("sv_cmd playerdemo read ", ftos(i+2), " ", s, ftos(i+1), "\n");
-                               localcmd("sv_cmd playerdemo write 1 ", ftos(n+1), "\n");
-                               return;
-                       }
-                       else if(argv(1) == "auto_read")
-                       {
-                               s = argv(2);
-                               n = stof(argv(3));
-                               cvar_set("bot_number", ftos(n));
-                               localcmd("wait; wait; wait\n");
-                               for(i = 0; i < n; ++i)
-                                       localcmd("sv_cmd playerdemo read ", ftos(i+2), " ", s, ftos(i+1), "\n");
+                               
+                               case "auto_read":
+                               {
+                                       s = argv(2);
+                                       n = stof(argv(3));
+                                       cvar_set("bot_number", ftos(n));
+                                       localcmd("wait; wait; wait\n");
+                                       for(i = 0; i < n; ++i)
+                                               localcmd("sv_cmd playerdemo read ", ftos(i+2), " ", s, ftos(i+1), "\n");
+                                       return;
+                               }
+                               
                                return;
                        }
-                       return;
                }
                        
                default:
@@ -1404,6 +1416,105 @@ void GameCommand_setbots(float request, float argc)
        }
 }
 
+void GameCommand_shuffleteams(float request)
+{
+       switch(request)
+       {
+               case GC_REQUEST_COMMAND:
+               {
+                       if(teamplay)
+                       {
+                               entity tmp_player;
+                               float i, x, z, t_teams, t_players, random_number, team_color;
+
+                               // count the total amount of players and total amount of teams
+                               FOR_EACH_PLAYER(tmp_player)
+                               {
+                                       CheckAllowedTeams(tmp_player);
+                                       
+                                       if(c1 >= 0) t_teams = max(1, t_teams);
+                                       if(c2 >= 0) t_teams = max(2, t_teams);
+                                       if(c3 >= 0) t_teams = max(3, t_teams);
+                                       if(c4 >= 0) t_teams = max(4, t_teams);
+                                       
+                                       ++t_players;
+                               }
+                               
+                               // build a list of the players in a random order
+                               FOR_EACH_PLAYER(tmp_player)
+                               {
+                                       for(;;)
+                                       {
+                                               random_number = bound(1, floor(random() * maxclients) + 1, maxclients);
+                                               
+                                               if(shuffleteams_players[random_number])
+                                               {
+                                                       continue; // a player is already assigned to this slot
+                                               }
+                                               else
+                                               {
+                                                       shuffleteams_players[random_number] = num_for_edict(tmp_player);
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               // finally, from the list made earlier, re-join the players in different order. 
+                               for(i = 1; i <= t_teams; ++i)
+                               {
+                                       // find out how many players to assign to this team
+                                       x = (t_players / t_teams);
+                                       x = ((i == 1) ? ceil(x) : floor(x));
+                                       
+                                       team_color = NumberToTeamNumber(i);
+                                       
+                                       // sort through the random list of players made earlier 
+                                       for(z = 1; z <= maxclients; ++z)
+                                       {
+                                               if(shuffleteams_teams[i] >= x)
+                                                       break; // move on to next team
+                                               
+                                               if not(shuffleteams_players[z])
+                                                       continue; // not a player, move on to next random slot
+                                                       
+                                               self = edict_num(shuffleteams_players[z]); // TODO: add sanity checks for this entity to make sure it's okay and not some error.
+                                               if(self.team != team_color) 
+                                               {
+                                                       MoveToTeam(self, team_color, 6, 0);
+                                                       shuffleteams_players[z] = 0;
+                                                       shuffleteams_teams[i] = shuffleteams_teams[i] + 1;
+                                               }
+                                       }
+                               }
+                               
+                               print("Successfully shuffled the players around randomly.\n");
+                               
+                               // clear the buffers now
+                               for (i=0; i<SHUFFLETEAMS_MAX_PLAYERS; ++i)
+                                       shuffleteams_players[i] = 0;
+                               
+                               for (i=0; i<SHUFFLETEAMS_MAX_TEAMS; ++i)
+                                       shuffleteams_teams[i] = 0;
+                       }
+                       else
+                       {
+                               print("Can't shuffle teams when currently not playing a team game.\n");
+                       }
+                       
+                       return;
+               }
+                       
+               default:
+               case GC_REQUEST_USAGE:
+               {
+                       print("\nUsage:^3 sv_cmd shuffleteams\n");
+                       print("  No arguments required.\n");
+                       print("See also: ^2moveplayer, allspec^7\n");
+                       return;
+               }
+       }
+}
+
 void GameCommand_stuffto(float request, float argc)
 {
        // This... is a fairly dangerous and powerful command... - It allows any arguments to be sent to a client via rcon.
@@ -1702,7 +1813,6 @@ void GameCommand_warp(float request, float argc)
                {
                        if(autocvar_g_campaign)
                        {
-                               
                                if(argc >= 2)
                                {
                                        CampaignLevelWarp(stof(argv(1)));
@@ -1743,8 +1853,8 @@ void GameCommand_(float request)
                default:
                case GC_REQUEST_USAGE:
                {
-                       sprint(self, "\nUsage:^3 cmd \n");
-                       sprint(self, "  No arguments required.\n");
+                       print("\nUsage:^3 sv_cmd \n");
+                       print("  No arguments required.\n");
                        return;
                }
        }
@@ -1804,11 +1914,15 @@ void GameCommand_(float request)
 #define SERVER_COMMANDS_5(request,arguments) \
        SERVER_COMMAND("reducematchtime", GameCommand_reducematchtime(request), "Decrease the timelimit value incrementally") \
        SERVER_COMMAND("setbots", GameCommand_setbots(request, arguments), "Adjust how many bots are in the match") \
+       SERVER_COMMAND("shuffleteams", GameCommand_shuffleteams(request), "Randomly move players to different teams") \
        SERVER_COMMAND("stuffto", GameCommand_stuffto(request, arguments), "Send a command to be executed on a client") \
        SERVER_COMMAND("teamstatus", GameCommand_teamstatus(request), "Show information about player and team scores") \
        SERVER_COMMAND("time", GameCommand_time(request), "Print different formats/readouts of time") \
        SERVER_COMMAND("trace", GameCommand_trace(request, arguments), "Various debugging tools with tracing") \
        SERVER_COMMAND("unlockteams", GameCommand_unlockteams(request), "Enable the ability for players to switch or enter teams") \
+       /* nothing */
+       
+#define SERVER_COMMANDS_6(request,arguments) \
        SERVER_COMMAND("warp", GameCommand_warp(request, arguments), "Choose different level in campaign") \
        /* nothing */
 
@@ -1822,6 +1936,7 @@ void GameCommand_macro_help()
        SERVER_COMMANDS_3(0, 0)
        SERVER_COMMANDS_4(0, 0)
        SERVER_COMMANDS_5(0, 0)
+       SERVER_COMMANDS_6(0, 0)
        #undef SERVER_COMMAND
        
        return;
@@ -1837,6 +1952,7 @@ float GameCommand_macro_command(float argc)
        SERVER_COMMANDS_3(GC_REQUEST_COMMAND, argc)
        SERVER_COMMANDS_4(GC_REQUEST_COMMAND, argc)
        SERVER_COMMANDS_5(GC_REQUEST_COMMAND, argc)
+       SERVER_COMMANDS_6(GC_REQUEST_COMMAND, argc)
        #undef SERVER_COMMAND
        
        return FALSE;
@@ -1852,6 +1968,7 @@ float GameCommand_macro_usage(float argc)
        SERVER_COMMANDS_3(GC_REQUEST_USAGE, argc)
        SERVER_COMMANDS_4(GC_REQUEST_USAGE, argc)
        SERVER_COMMANDS_5(GC_REQUEST_USAGE, argc)
+       SERVER_COMMANDS_6(GC_REQUEST_USAGE, argc)
        #undef SERVER_COMMAND
        
        return FALSE;
@@ -1903,4 +2020,6 @@ void GameCommand(string command)
        
        // nothing above caught the command, must be invalid
        print("Invalid command. For a list of supported commands, try sv_cmd help.\n");
+       
+       return;
 }
\ No newline at end of file