}
}
-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");
// 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.");
}
return cliptrace;
}
-trace_t CL_TraceLine_FromViewOrigin(int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces)
-{
- vec3_t org, temp, dest;
-
- Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, org);
- VectorSet(temp, 65536, 0, 0);
- Matrix4x4_Transform(&r_refdef.view.matrix, temp, dest);
-
- return CL_TraceLine(org, dest, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, extend, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities, hitsurfaces);
-
-}
-
/*
==================
CL_Move
int CL_GenericHitSuperContentsMask(const prvm_edict_t *edict);
trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
-trace_t CL_TraceLine_FromViewOrigin(int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, float extend, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities, qboolean hitsurfaces);
trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask, qboolean hitnetworkbrushmodels, qboolean hitnetworkplayers, int *hitnetworkentity, qboolean hitcsqcentities);
trace_t CL_Cache_TraceLineSurfaces(const vec3_t start, const vec3_t end, int type, int hitsupercontentsmask, int skipsupercontentsmask, int skipmaterialflagsmask);
#define CL_PointSuperContents(point) (CL_TracePoint((point), sv_gameplayfix_swiminbmodels.integer ? MOVE_NOMONSTERS : MOVE_WORLDONLY, NULL, 0, 0, 0, true, false, NULL, false).startsupercontents)
vec3_t temp;
trace_t svtrace, cltrace;
int hitnetentity = -1;
- // TODO: Use CL_TraceLine_FromViewOrigin
+
Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, org);
VectorSet(temp, 65536, 0, 0);
Matrix4x4_Transform(&r_refdef.view.matrix, temp, dest);
static void SV_Ent_Create_f(cmd_state_t *cmd)
{
prvm_prog_t *prog = SVVM_prog;
+ prvm_edict_t *ed;
ddef_t *key;
int i;
- qboolean expectval = false, haveorigin = false;
+ qboolean haveorigin;
+
+ qboolean expectval = false;
void (*print)(const char *, ...) = (cmd->source == src_client ? SV_ClientPrintf : Con_Printf);
- prvm_edict_t *ed = PRVM_ED_Alloc(SVVM_prog);
+ if(!Cmd_Argc(cmd))
+ return;
+
+ ed = PRVM_ED_Alloc(SVVM_prog);
PRVM_ED_ParseEpair(prog, ed, PRVM_ED_FindField(prog, "classname"), Cmd_Argv(cmd, 1), false);
+ // Spawn where the player is aiming. We need a view matrix first.
+ if(cmd->source == src_client)
+ {
+ vec3_t org, temp, dest;
+ matrix4x4_t view;
+ trace_t trace;
+ char buf[128];
+
+ SV_GetEntityMatrix(prog, host_client->edict, &view, true);
+
+ Matrix4x4_OriginFromMatrix(&view, org);
+ VectorSet(temp, 65536, 0, 0);
+ Matrix4x4_Transform(&view, temp, dest);
+
+ trace = SV_TraceLine(org, dest, MOVE_NORMAL, NULL, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value);
+
+ dpsnprintf(buf, sizeof(buf), "%g %g %g", trace.endpos[0], trace.endpos[1], trace.endpos[2]);
+ PRVM_ED_ParseEpair(prog, ed, PRVM_ED_FindField(prog, "origin"), buf, false);
+
+ haveorigin = true;
+ }
+ // Or spawn at a specified origin.
+ else
+ {
+ print = Con_Printf;
+ haveorigin = false;
+ }
+
// Allow more than one key/value pair by cycling between expecting either one.
for(i = 2; i < Cmd_Argc(cmd); i++)
{
return;
}
- if(!strcmp(Cmd_Argv(cmd, i), "origin") && !haveorigin)
+ /*
+ * This is mostly for dedicated server console, but if the
+ * player gave a custom origin, we can ignore the traceline.
+ */
+ if(!strcmp(Cmd_Argv(cmd, i), "origin"))
haveorigin = true;
expectval = true;
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");
PRVM_ED_Free(prog, ed);
return;
}