]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/command/cmd.qc
Merge remote-tracking branch 'origin/terencehill/bot_waypoints'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / command / cmd.qc
index 1ec7233ca40e47d96f2718734fd0a95c36818e39..e39d5039dd8f4debe754d6487671416e401f5853 100644 (file)
@@ -8,15 +8,20 @@
 #include "common.qh"
 #include "vote.qh"
 
+#include "../bot/api.qh"
+
 #include "../campaign.qh"
 #include "../cheats.qh"
+#include "../client.qh"
+#include "../clientkill.qh"
 #include "../player.qh"
 #include "../ipban.qh"
 #include "../mapvoting.qh"
 #include "../scores.qh"
 #include "../teamplay.qh"
 
-#include "../mutators/_mod.qh"
+#include <server/mutators/_mod.qh>
+#include <common/gamemodes/_mod.qh>
 
 #ifdef SVQC
        #include <common/vehicles/all.qh>
@@ -30,7 +35,7 @@
 #include <common/physics/player.qh>
 #include <common/teams.qh>
 #include <common/util.qh>
-#include <common/triggers/triggers.qh>
+#include <common/mapobjects/triggers.qh>
 
 #include <common/minigames/sv_minigames.qh>
 
@@ -40,8 +45,6 @@
 
 #include <lib/warpzone/common.qh>
 
-void ClientKill_TeamChange(entity this, float targetteam);  // 0 = don't change, -1 = auto, -2 = spec
-
 // =========================================================
 //  Server side networked commands code, reworked by Samual
 //  Last updated: December 28th, 2011
@@ -72,7 +75,7 @@ bool SV_ParseClientCommand_floodcheck(entity this)
 //  Command Sub-Functions
 // =======================
 
-void ClientCommand_autoswitch(entity caller, float request, float argc)
+void ClientCommand_autoswitch(entity caller, int request, int argc)
 {
        switch (request)
        {
@@ -97,7 +100,7 @@ void ClientCommand_autoswitch(entity caller, float request, float argc)
        }
 }
 
-void ClientCommand_clientversion(entity caller, float request, float argc)  // internal command, used only by code
+void ClientCommand_clientversion(entity caller, int request, int argc)  // internal command, used only by code
 {
        switch (request)
        {
@@ -118,7 +121,7 @@ void ClientCommand_clientversion(entity caller, float request, float argc)  // i
                                        {
                                                // JoinBestTeam(caller, false, true);
                                        }
-                                       else if (teamplay && !autocvar_sv_spectate && !(caller.team_forced > 0))
+                                       else if (teamplay && !autocvar_sv_spectate && !(Player_GetForcedTeamIndex(caller) > 0))
                                        {
                                                TRANSMUTE(Observer, caller);  // really?
                                                stuffcmd(caller, "menu_showteamselect\n");
@@ -140,7 +143,7 @@ void ClientCommand_clientversion(entity caller, float request, float argc)  // i
        }
 }
 
-void ClientCommand_mv_getpicture(entity caller, float request, float argc)  // internal command, used only by code
+void ClientCommand_mv_getpicture(entity caller, int request, int argc)  // internal command, used only by code
 {
        switch (request)
        {
@@ -165,9 +168,91 @@ void ClientCommand_mv_getpicture(entity caller, float request, float argc)  // i
        }
 }
 
-bool joinAllowed(entity this);
-void Join(entity this);
-void ClientCommand_join(entity caller, float request)
+void ClientCommand_wpeditor(entity caller, int request, int argc)
+{
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if (!autocvar_g_waypointeditor)
+                       {
+                               sprint(caller, "ERROR: this command works only if the waypoint editor is on\n");
+                               return;
+                       }
+
+                       if (argv(1) != "")
+                       {
+                               if (argv(1) == "spawn")
+                               {
+                                       if (!IS_PLAYER(caller))
+                                               sprint(caller, "ERROR: this command works only if you are player\n");
+                                       else
+                                               waypoint_spawn_fromeditor(caller);
+                                       return;
+                               }
+                               else if (argv(1) == "remove")
+                               {
+                                       if (!IS_PLAYER(caller))
+                                               sprint(caller, "ERROR: this command works only if you are player\n");
+                                       else
+                                               waypoint_remove_fromeditor(caller);
+                                       return;
+                               }
+                               else if (argv(1) == "unreachable")
+                               {
+                                       if (!IS_PLAYER(caller))
+                                               sprint(caller, "ERROR: this command works only if you are player\n");
+                                       else
+                                               waypoint_unreachable(caller);
+                                       return;
+                               }
+                               else if (argv(1) == "saveall")
+                               {
+                                       waypoint_saveall();
+                                       return;
+                               }
+                               else if (argv(1) == "relinkall")
+                               {
+                                       waypoint_schedulerelinkall();
+                                       return;
+                               }
+                               else if (argv(1) == "symaxis")
+                               {
+                                       if (argv(2) == "set" || argv(2) == "get")
+                                       {
+                                               waypoint_getSymmetricalAxis_cmd(caller, (argv(2) == "set"), 3);
+                                               return;
+                                       }
+                               }
+                               else if (argv(1) == "symorigin")
+                               {
+                                       if (argv(2) == "set" || argv(2) == "get")
+                                       {
+                                               waypoint_getSymmetricalOrigin_cmd(caller, (argv(2) == "set"), 3);
+                                               return;
+                                       }
+                               }
+                       }
+               }
+
+               default:
+                       sprint(caller, "Incorrect parameters for ^2wpeditor^7\n");
+               case CMD_REQUEST_USAGE:
+               {
+                       sprint(caller, "\nUsage:^3 cmd wpeditor action\n");
+                       sprint(caller, "  Where 'action' can be: spawn, remove, unreachable, saveall, relinkall,\n");
+                       sprint(caller, "   symorigin get|set\n");
+                       sprint(caller, "   symorigin get|set p1 p2 ... pX\n");
+                       sprint(caller, "   symaxis get|set p1 p2\n");
+                       sprint(caller, "    where p1 p2 ... pX are positions \"x y z\" (z can be omitted)\n");
+                       sprint(caller, " symorigin and symaxis commands are useful to determine origin/axis of symmetry"
+                                                       " on maps without ctf flags or where flags aren't perfectly symmetrical\n");
+                       return;
+               }
+       }
+}
+
+void ClientCommand_join(entity caller, int request)
 {
        switch (request)
        {
@@ -191,7 +276,37 @@ void ClientCommand_join(entity caller, float request)
        }
 }
 
-void ClientCommand_physics(entity caller, float request, float argc)
+void ClientCommand_kill(entity caller, int request)
+{
+       switch (request)
+       {
+               case CMD_REQUEST_COMMAND:
+               {
+                       if(IS_SPEC(caller) || IS_OBSERVER(caller))
+                               return; // no point warning about this, command does nothing
+
+                       if(GetResourceAmount(caller, RESOURCE_HEALTH) <= 0)
+                       {
+                               sprint(caller, "Can't die - you are already dead!\n");
+                               return;
+                       }
+
+                       ClientKill(caller);
+
+                       return;  // never fall through to usage
+               }
+
+               default:
+               case CMD_REQUEST_USAGE:
+               {
+                       sprint(caller, "\nUsage:^3 cmd kill\n");
+                       sprint(caller, "  No arguments required.\n");
+                       return;
+               }
+       }
+}
+
+void ClientCommand_physics(entity caller, int request, int argc)
 {
        switch (request)
        {
@@ -231,7 +346,7 @@ void ClientCommand_physics(entity caller, float request, float argc)
        }
 }
 
-void ClientCommand_ready(entity caller, float request)  // todo: anti-spam for toggling readyness
+void ClientCommand_ready(entity caller, int request)  // todo: anti-spam for toggling readyness
 {
        switch (request)
        {
@@ -280,7 +395,7 @@ void ClientCommand_ready(entity caller, float request)  // todo: anti-spam for t
        }
 }
 
-void ClientCommand_say(entity caller, float request, float argc, string command)
+void ClientCommand_say(entity caller, int request, int argc, string command)
 {
        switch (request)
        {
@@ -300,13 +415,14 @@ void ClientCommand_say(entity caller, float request, float argc, string command)
        }
 }
 
-void ClientCommand_say_team(entity caller, float request, float argc, string command)
+void ClientCommand_say_team(entity caller, int request, int argc, string command)
 {
        switch (request)
        {
                case CMD_REQUEST_COMMAND:
                {
-                       if (argc >= 2)   Say(caller, true, NULL, substring(command, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), 1);
+                       if (argc >= 2)
+                               Say(caller, true, NULL, substring(command, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)), 1);
                        return;  // never fall through to usage
                }
 
@@ -321,7 +437,7 @@ void ClientCommand_say_team(entity caller, float request, float argc, string com
 }
 
 .bool team_selected;
-void ClientCommand_selectteam(entity caller, float request, float argc)
+void ClientCommand_selectteam(entity caller, int request, int argc)
 {
        switch (request)
        {
@@ -340,7 +456,7 @@ void ClientCommand_selectteam(entity caller, float request, float argc)
                                sprint(caller, "^7selectteam can only be used in teamgames\n");
                                return;
                        }
-                       if (caller.team_forced > 0)
+                       if (Player_GetForcedTeamIndex(caller) > 0)
                        {
                                sprint(caller, "^7selectteam can not be used as your team is forced\n");
                                return;
@@ -426,7 +542,7 @@ void ClientCommand_selectteam(entity caller, float request, float argc)
        }
 }
 
-void ClientCommand_selfstuff(entity caller, float request, string command)
+void ClientCommand_selfstuff(entity caller, int request, string command)
 {
        switch (request)
        {
@@ -450,7 +566,7 @@ void ClientCommand_selfstuff(entity caller, float request, string command)
        }
 }
 
-void ClientCommand_sentcvar(entity caller, float request, float argc, string command)
+void ClientCommand_sentcvar(entity caller, int request, int argc, string command)
 {
        switch (request)
        {
@@ -484,7 +600,7 @@ void ClientCommand_sentcvar(entity caller, float request, float argc, string com
        }
 }
 
-void ClientCommand_spectate(entity caller, float request)
+void ClientCommand_spectate(entity caller, int request)
 {
        switch (request)
        {
@@ -524,7 +640,7 @@ void ClientCommand_spectate(entity caller, float request)
        }
 }
 
-void ClientCommand_suggestmap(entity caller, float request, float argc)
+void ClientCommand_suggestmap(entity caller, int request, int argc)
 {
        switch (request)
        {
@@ -548,7 +664,7 @@ void ClientCommand_suggestmap(entity caller, float request, float argc)
        }
 }
 
-void ClientCommand_tell(entity caller, float request, float argc, string command)
+void ClientCommand_tell(entity caller, int request, int argc, string command)
 {
        switch (request)
        {
@@ -605,7 +721,7 @@ void ClientCommand_tell(entity caller, float request, float argc, string command
        }
 }
 
-void ClientCommand_voice(entity caller, float request, float argc, string command)
+void ClientCommand_voice(entity caller, int request, int argc, string command)
 {
        switch (request)
        {
@@ -642,7 +758,7 @@ void ClientCommand_voice(entity caller, float request, float argc, string comman
 
 /* use this when creating a new command, making sure to place it in alphabetical order... also,
 ** ADD ALL NEW COMMANDS TO commands.cfg WITH PROPER ALIASES IN THE SAME FASHION!
-void ClientCommand_(entity caller, float request)
+void ClientCommand_(entity caller, int request)
 {
     switch(request)
     {
@@ -672,8 +788,10 @@ void ClientCommand_(entity caller, float request)
 #define CLIENT_COMMANDS(ent, request, arguments, command) \
        CLIENT_COMMAND("autoswitch", ClientCommand_autoswitch(ent, request, arguments), "Whether or not to switch automatically when getting a better weapon") \
        CLIENT_COMMAND("clientversion", ClientCommand_clientversion(ent, request, arguments), "Release version of the game") \
-       CLIENT_COMMAND("mv_getpicture", ClientCommand_mv_getpicture(ent, request, arguments), "Retrieve mapshot picture from the server") \
        CLIENT_COMMAND("join", ClientCommand_join(ent, request), "Become a player in the game") \
+       CLIENT_COMMAND("kill", ClientCommand_kill(ent, request), "Become a member of the dead") \
+       CLIENT_COMMAND("minigame", ClientCommand_minigame(ent, request, arguments, command), "Start a minigame") \
+       CLIENT_COMMAND("mv_getpicture", ClientCommand_mv_getpicture(ent, request, arguments), "Retrieve mapshot picture from the server") \
        CLIENT_COMMAND("physics", ClientCommand_physics(ent, request, arguments), "Change physics set") \
        CLIENT_COMMAND("ready", ClientCommand_ready(ent, request), "Qualify as ready to end warmup stage (or restart server if allowed)") \
        CLIENT_COMMAND("say", ClientCommand_say(ent, request, arguments, command), "Print a message to chat to all players") \
@@ -685,7 +803,7 @@ void ClientCommand_(entity caller, float request)
        CLIENT_COMMAND("suggestmap", ClientCommand_suggestmap(ent, request, arguments), "Suggest a map to the mapvote at match end") \
        CLIENT_COMMAND("tell", ClientCommand_tell(ent, request, arguments, command), "Send a message directly to a player") \
        CLIENT_COMMAND("voice", ClientCommand_voice(ent, request, arguments, command), "Send voice message via sound") \
-       CLIENT_COMMAND("minigame", ClientCommand_minigame(ent, request, arguments, command), "Start a minigame") \
+       CLIENT_COMMAND("wpeditor", ClientCommand_wpeditor(ent, request, arguments), "Waypoint editor commands") \
        /* nothing */
 
 void ClientCommand_macro_help(entity caller)
@@ -697,7 +815,7 @@ void ClientCommand_macro_help(entity caller)
 #undef CLIENT_COMMAND
 }
 
-float ClientCommand_macro_command(float argc, entity caller, string command)
+float ClientCommand_macro_command(int argc, entity caller, string command)
 {
        #define CLIENT_COMMAND(name, function, description) \
                { if (name == strtolower(argv(0))) { function; return true; } }
@@ -708,7 +826,7 @@ float ClientCommand_macro_command(float argc, entity caller, string command)
        return false;
 }
 
-float ClientCommand_macro_usage(float argc, entity caller)
+float ClientCommand_macro_usage(int argc, entity caller)
 {
        #define CLIENT_COMMAND(name, function, description) \
                { if (name == strtolower(argv(1))) { function; return true; } }
@@ -746,7 +864,7 @@ void SV_ParseClientCommand(entity this, string command)
        // if we're banned, don't even parse the command
        if (Ban_MaybeEnforceBanOnce(this)) return;
 
-       float argc = tokenize_console(command);
+       int argc = tokenize_console(command);
 
        // Guide for working with argc arguments by example:
        // argc:   1    - 2      - 3     - 4
@@ -760,6 +878,7 @@ void SV_ParseClientCommand(entity this, string command)
                case "begin": break;                               // handled by engine in host_cmd.c
                case "download": break;                            // handled by engine in cl_parse.c
                case "mv_getpicture": break;                       // handled by server in this file
+               case "wpeditor": break;                            // handled by server in this file
                case "pause": break;                               // handled by engine in host_cmd.c
                case "prespawn": break;                            // handled by engine in host_cmd.c
                case "sentcvar": break;                            // handled by server in this file