]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Implement "ent_create" command. Creates an entity where you're aiming.
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 24 Jul 2020 16:00:54 +0000 (16:00 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 24 Jul 2020 16:00:54 +0000 (16:00 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12875 d7cf8633-e32d-0410-b094-e92efae38249

cl_cmd.c
sv_ccmds.c

index 64d2131e3199cc853291824a56786abf8e3d44f5..01ba68a78715d4fb923572ac6cdf637c25c55dec 100644 (file)
--- a/cl_cmd.c
+++ b/cl_cmd.c
@@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "image.h"
 #include <time.h>
 
+#include "cl_collision.h"
+
 cvar_t cl_name = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "name", "player", "change your player name"};
 cvar_t cl_rate = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate", "20000", "change your connection speed"};
 cvar_t cl_rate_burstsize = {CVAR_CLIENT | CVAR_SAVE | CVAR_USERINFO, "rate_burstsize", "1024", "internal storage cvar for current rate control burst size (changed by rate_burstsize command)"};
@@ -631,6 +633,29 @@ static void CL_PingPLReport_f(cmd_state_t *cmd)
        }
 }
 
+static void CL_Ent_Create_f(cmd_state_t *cmd)
+{
+       trace_t trace;
+       char vabuf[MAX_INPUTLINE];
+
+       if(Cmd_Argc(cmd) < 1)
+               return;
+
+       if(!strstr(Cmd_Args(cmd), "origin"))
+       {
+               // Get coordinates where the player is aiming.
+               trace = CL_TraceLine_FromViewOrigin(MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value, true, false, NULL, false, true);
+               dpsnprintf(vabuf, sizeof(vabuf), "ent_create %s origin \"%g %g %g\"", Cmd_Args(cmd), trace.endpos[0], trace.endpos[1], trace.endpos[2]);
+       }
+       else
+       {
+               // Unless we're setting origin manually.
+               dpsnprintf(vabuf, sizeof(vabuf), "ent_create %s", Cmd_Args(cmd));
+       }
+
+       CL_ForwardToServer(vabuf);
+}
+
 void CL_InitCommands(void)
 {
        dpsnprintf(cls.userinfo, sizeof(cls.userinfo), "\\name\\player\\team\\none\\topcolor\\0\\bottomcolor\\0\\rate\\10000\\msg\\1\\noaim\\1\\*ver\\dp");
@@ -668,4 +693,5 @@ void CL_InitCommands(void)
        // commands that are only sent by server to client for execution
        Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "pingplreport", CL_PingPLReport_f, "command sent by server containing client ping and packet loss values for scoreboard, triggered by pings command from client (not used by QW servers)");
        Cmd_AddCommand(CMD_CLIENT_FROM_SERVER, "fullserverinfo", CL_FullServerinfo_f, "internal use only, sent by server to client to update client's local copy of serverinfo string");
+       Cmd_AddCommand(CMD_CLIENT, "ent_create", CL_Ent_Create_f, "Creates an entity at the specified coordinate, of the specified classname. If executed from a server, origin has to be specified manually.");
 }
index c5a6fdf8514ff6ba42ed8dbd5b7cc30a3941cdeb..c4aad6fc2457312d06fb4963ccdaa6b6e377fc4a 100644 (file)
@@ -1507,6 +1507,68 @@ static void SV_SendCvar_f(cmd_state_t *cmd)
        host_client = old;
 }
 
+static void SV_Ent_Create_f(cmd_state_t *cmd)
+{
+       prvm_prog_t *prog = SVVM_prog;
+       ddef_t *key;
+       int i;
+       qboolean expectval = false, haveorigin = false;
+       void (*print)(const char *, ...) = (cmd->source == src_client ? SV_ClientPrintf : Con_Printf);
+
+       prvm_edict_t *ed = PRVM_ED_Alloc(SVVM_prog);
+
+       PRVM_ED_ParseEpair(prog, ed, PRVM_ED_FindField(prog, "classname"), Cmd_Argv(cmd, 1), false);
+
+       for(i = 2; i < Cmd_Argc(cmd); i++)
+       {
+               if(!expectval)
+               {
+                       if(!(key = PRVM_ED_FindField(prog, Cmd_Argv(cmd, i))))
+                       {
+                               Con_Printf("Key %s not found!\n", Cmd_Argv(cmd, i));
+                               return;
+                       }
+
+                       if(!strcmp(Cmd_Argv(cmd, i), "origin") && !haveorigin)
+                               haveorigin = true;
+
+                       expectval = true;
+               }
+               else
+               {
+                       PRVM_ED_ParseEpair(prog, ed, key, Cmd_Argv(cmd, i), false);
+                       expectval = false;
+               }
+       }
+       
+       if(!haveorigin)
+       {
+               print("Missing origin\n");
+               if(cmd->source == src_client)
+                       print("This should never happen if you're a player. Please report this to a developer.\n");
+               return;
+       }
+
+       // Spawn it
+       PRVM_ED_CallPrespawnFunction(prog, ed);
+       
+       if(!PRVM_ED_CallSpawnFunction(prog, ed, NULL, NULL))
+       {
+               print("Could not spawn a \"%s\". No such entity or it has no spawn function\n", Cmd_Argv(cmd, 1));
+               if(cmd->source == src_client)
+                       Con_Printf("%s tried to spawn a \"%s\"\n", host_client->name, Cmd_Argv(cmd, 1));
+               return;
+       }
+
+       PRVM_ED_CallPostspawnFunction(prog, ed);        
+
+       // Make it appear in the world
+       SV_LinkEdict(ed);
+
+       if(cmd->source == src_client)
+               Con_Printf("%s spawned a \"%s\"\n", host_client->name, Cmd_Argv(cmd, 1));
+}
+
 void SV_InitOperatorCommands(void)
 {
        Cvar_RegisterVariable(&sv_cheats);
@@ -1556,5 +1618,7 @@ void SV_InitOperatorCommands(void)
        Cmd_AddCommand(CMD_USERINFO, "rate_burstsize", SV_Rate_BurstSize_f, "change your network connection speed");
        Cmd_AddCommand(CMD_USERINFO, "pmodel", SV_PModel_f, "(Nehahra-only) change your player model choice");
        Cmd_AddCommand(CMD_USERINFO, "playermodel", SV_Playermodel_f, "change your player model");
-       Cmd_AddCommand(CMD_USERINFO, "playerskin", SV_Playerskin_f, "change your player skin number");  
+       Cmd_AddCommand(CMD_USERINFO, "playerskin", SV_Playerskin_f, "change your player skin number");
+
+       Cmd_AddCommand(CMD_CHEAT | CMD_SERVER_FROM_CLIENT, "ent_create", SV_Ent_Create_f, "Creates an entity at the specified coordinate, of the specified classname. If executed from a server, origin has to be specified manually.");
 }