]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/command/cmd.qc
Merge branch 'terencehill/spectate_player' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / command / cmd.qc
index 7c15a64e2f319241c35a7e7428cfc3b17497b8b3..ad9cab8e72301cbc7735ebea4a5e9b19c8bc4070 100644 (file)
@@ -254,22 +254,25 @@ void ClientCommand_wpeditor(entity caller, int request, int argc)
                        sprint(caller, "\nUsage:^3 cmd wpeditor action\n");
                        sprint(caller, "  Where 'action' can be:\n");
                        sprint(caller, "   ^5spawn^7: spawns a waypoint at player's position\n");
-                       sprint(caller, "   ^5remove^7: remove player's nearest waypoint\n");
-                       sprint(caller, "   ^5unreachable^7: useful to reveal waypoints and items unreachable from the current position and spawnpoints without a nearest waypoint\n");
+                       sprint(caller, "   ^5remove^7: removes player's nearest waypoint\n");
+                       sprint(caller, "   ^5unreachable^7: reveals waypoints and items unreachable from the current position and spawnpoints without a nearest waypoint\n");
                        sprint(caller, "   ^5saveall^7: saves all waypoints and links to file\n");
-                       sprint(caller, "   ^5relinkall^7: relink all waypoints as if they were respawned\n");
-                       sprint(caller, "   ^5spawn crosshair^7: spawns a waypoint at crosshair's position (in general useful to create special and hardwired links with ease from existing waypoints, in particular it's the only way to create custom jumppad waypoints (spawn another waypoint to create destination))\n");
-                       sprint(caller, "   ^5spawn jump^7: spawns a jump waypoint (spawn another waypoint to create destination)\n");
-                       sprint(caller, "   ^5spawn crouch^7: spawns a crouch waypoint\n");
-                       sprint(caller, "   ^5spawn support^7: spawns a support waypoint (spawn another waypoint to create destination from which all incoming links are removed), useful to replace links to preblematic jumppad/teleport waypoints\n");
+                       sprint(caller, "   ^5relinkall^7: relinks all waypoints as if they were respawned\n");
+                       sprint(caller, "   ^5spawn crosshair^7: spawns a waypoint at crosshair's position\n");
+                       sprint(caller, "   ^7 in general useful to create special and hardwired links with ease from existing waypoints\n");
+                       sprint(caller, "   ^7 in particular it's the only way to create custom jumppad waypoints (spawn another waypoint to create destination))\n");
+                       sprint(caller, "   ^5spawn jump^7: spawns a jump waypoint (place it at least 60 qu before jump start, spawn another waypoint to create destination)\n");
+                       sprint(caller, "   ^5spawn crouch^7: spawns a crouch waypoint (it links only to very close waypoints)\n");
+                       sprint(caller, "   ^5spawn support^7: spawns a support waypoint (spawn another waypoint to create destination from which all incoming links are removed)\n");
+                       sprint(caller, "   ^7 useful to replace links to problematic jumppad/teleport waypoints\n");
                        sprint(caller, "   ^5hardwire^7: marks the nearest waypoint as origin of a new hardwired link (spawn another waypoint over an existing one to create destination)\n");
                        sprint(caller, "   ^5hardwire crosshair^7: marks the waypoint at crosshair instead of the nearest waypoint\n");
                        sprint(caller, "   ^5lock^7: locks link display of the aimed waypoint (unlocks if no waypoint is found at crosshair's position)\n");
                        sprint(caller, "   ^5symorigin get|set\n");
                        sprint(caller, "   ^5symorigin get|set p1 p2 ... pX\n");
                        sprint(caller, "   ^5symaxis get|set p1 p2\n");
-                       sprint(caller, "   ^7 where p1 p2 ... pX are positions (\"x y z\", z can be omitted) that you know are perfectly symmetrical");
-                       sprint(caller, "   ^7 so you can determine origin/axis of symmetry of maps without ctf flags or where flags aren't perfectly symmetrical\n");
+                       sprint(caller, "   ^7 where p1 p2 ... pX are positions (\"x y z\", z can be omitted) that you know are perfectly symmetrical"
+                                                               " so you can determine origin/axis of symmetry of maps without ctf flags or where flags aren't perfectly symmetrical\n");
                        sprint(caller, "  See 'wpeditor_menu' for a selectable list of various commands and useful settings to edit waypoints.\n");
                        return;
                }
@@ -352,7 +355,7 @@ void ClientCommand_physics(entity caller, int request, int argc)
 
                        if (Physics_Valid(command) || command == "default")
                        {
-                               stuffcmd(caller, strcat("\nseta cl_physics ", command, "\nsendcvar cl_physics\n"));
+                               stuffcmd(caller, strcat("\nseta cl_physics ", command, "\n"));
                                sprint(caller, strcat("^2Physics set successfully changed to ^3", command, "\n"));
                                return;
                        }
@@ -632,15 +635,22 @@ void ClientCommand_spectate(entity caller, int request)
                {
                        if (!intermission_running && IS_CLIENT(caller))
                        {
-                               if((IS_SPEC(caller) || IS_OBSERVER(caller)) && argv(1) != "")
+                               if(argv(1) != "")
                                {
-                                       entity client = GetFilteredEntity(argv(1));
-                                       int spec_accepted = VerifyClientEntity(client, false, false);
-                                       if(spec_accepted > 0 && IS_PLAYER(client))
+                                       if(IS_SPEC(caller) || IS_OBSERVER(caller))
                                        {
-                                               if(Spectate(caller, client))
-                                                       return; // fall back to regular handling
+                                               entity client = GetFilteredEntity(argv(1));
+                                               int spec_accepted = VerifyClientEntity(client, false, false);
+                                               if(spec_accepted > 0 && IS_PLAYER(client))
+                                               {
+                                                       Spectate(caller, client);
+                                               }
+                                               else
+                                                       sprint(caller, "can't spectate ", argv(1), "^7\n");
                                        }
+                                       else
+                                               sprint(caller, "cmd spectate client only works when you are spectator/observer\n");
+                                       return;
                                }
 
                                int mutator_returnvalue = MUTATOR_CALLHOOK(ClientCommand_Spectate, caller);
@@ -657,7 +667,7 @@ void ClientCommand_spectate(entity caller, int request)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       sprint(caller, "\nUsage:^3 cmd spectate <client>\n");
+                       sprint(caller, "\nUsage:^3 cmd spectate [client]\n");
                        sprint(caller, "  Where 'client' can be the player to spectate.\n");
                        return;
                }
@@ -759,6 +769,18 @@ void ClientCommand_voice(entity caller, int request, int argc, string command)
                                        sprint(caller, sprintf("Invalid voice. Use one of: %s\n", allvoicesamples));
                                        return;
                                }
+                               if (IS_DEAD(caller))
+                               {
+                                       // don't warn the caller when trying to taunt while dead, just don't play any sounds!
+                                       // we still allow them to see warnings if it's invalid, so a dead player can find out the sounds in peace
+                                       return;
+                               }
+                               if (IS_SPEC(caller) || IS_OBSERVER(caller))
+                               {
+                                       // observers/spectators have no player model of their own to play taunts from
+                                       // again, allow them to see warnings
+                                       return;
+                               }
                                string msg = "";
                                if (argc >= 3)
                                        msg = substring(command, argv_start_index(2), argv_end_index(-1) - argv_start_index(2));
@@ -907,6 +929,7 @@ void SV_ParseClientCommand(entity this, string command)
                case "prespawn": break;                            // handled by engine in host_cmd.c
                case "sentcvar": break;                            // handled by server in this file
                case "spawn": break;                               // handled by engine in host_cmd.c
+               case "color": case "topcolor": case "bottomcolor": if(teamplay) return; else break; // handled by engine in host_cmd.c
                case "c2s": Net_ClientCommand(this, command); return; // handled by net.qh
 
                default: