2000-05-10 20:33:16 +00:00
|
|
|
/*
|
2001-01-16 03:15:23 +00:00
|
|
|
sv_pr_cmds.c
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
(description)
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
Copyright (C) 1996-1997 Id Software, Inc.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
This program is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU General Public License
|
|
|
|
as published by the Free Software Foundation; either version 2
|
|
|
|
of the License, or (at your option) any later version.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
2000-05-10 20:33:16 +00:00
|
|
|
|
2000-05-11 16:03:29 +00:00
|
|
|
See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to:
|
|
|
|
|
|
|
|
Free Software Foundation, Inc.
|
|
|
|
59 Temple Place - Suite 330
|
|
|
|
Boston, MA 02111-1307, USA
|
|
|
|
|
|
|
|
$Id$
|
2000-05-10 20:33:16 +00:00
|
|
|
*/
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-05-17 10:03:19 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2000-12-08 06:51:37 +00:00
|
|
|
# include "config.h"
|
2000-05-17 10:03:19 +00:00
|
|
|
#endif
|
2001-02-07 05:45:59 +00:00
|
|
|
#ifdef HAVE_STRING_H
|
|
|
|
# include <string.h>
|
|
|
|
#endif
|
2000-05-21 08:24:45 +00:00
|
|
|
|
2000-12-28 05:18:38 +00:00
|
|
|
#include "cmd.h"
|
|
|
|
#include "msg.h"
|
|
|
|
#include "server.h"
|
2001-01-04 05:44:53 +00:00
|
|
|
#include "sv_pr_cmds.h"
|
2000-12-28 05:18:38 +00:00
|
|
|
#include "world.h"
|
|
|
|
#include "va.h"
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-01-02 03:22:46 +00:00
|
|
|
#define RETURN_EDICT(p, e) (((int *)(p)->pr_globals)[OFS_RETURN] = EDICT_TO_PROG(p, e))
|
2000-12-31 07:43:09 +00:00
|
|
|
#define RETURN_STRING(p, s) (((int *)(p)->pr_globals)[OFS_RETURN] = PR_SetString((p), s))
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
BUILT-IN FUNCTIONS
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
char *
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_VarString (progs_t *pr, int first)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i;
|
2000-05-10 11:29:38 +00:00
|
|
|
static char out[256];
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
out[0] = 0;
|
2000-12-31 07:43:09 +00:00
|
|
|
for (i = first; i < pr->pr_argc; i++) {
|
|
|
|
strncat (out, G_STRING (pr, (OFS_PARM0 + i * 3)),
|
2000-12-08 06:51:37 +00:00
|
|
|
sizeof (out) - strlen (out));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_errror
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
This is a TERMINAL error, which will kill off the entire server.
|
|
|
|
Dumps self.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
error(value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_error (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
edict_t *ed;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = PF_VarString (pr, 0);
|
2000-12-08 06:51:37 +00:00
|
|
|
Con_Printf ("======SERVER ERROR in %s:\n%s\n",
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
2001-01-02 03:22:46 +00:00
|
|
|
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2000-12-31 07:43:09 +00:00
|
|
|
ED_Print (pr, ed);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
SV_Error ("Program error");
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_objerror
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Dumps out self, then an error message. The program is aborted and self is
|
|
|
|
removed, but the level can continue.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
objerror(value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_objerror (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
edict_t *ed;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = PF_VarString (pr, 0);
|
2000-12-08 06:51:37 +00:00
|
|
|
Con_Printf ("======OBJECT ERROR in %s:\n%s\n",
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_GetString (pr, pr->pr_xfunction->s_name), s);
|
2001-01-02 03:22:46 +00:00
|
|
|
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2000-12-31 07:43:09 +00:00
|
|
|
ED_Print (pr, ed);
|
|
|
|
ED_Free (pr, ed);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_Error ("Program error");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_makevectors
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Writes new values for v_forward, v_up, and v_right based on angles
|
|
|
|
makevectors(vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_makevectors (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
AngleVectors (G_VECTOR (pr, OFS_PARM0), pr->pr_global_struct->v_forward,
|
|
|
|
pr->pr_global_struct->v_right, pr->pr_global_struct->v_up);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setorigin
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
This is the only valid way to move an object without using the physics of the world (setting velocity and waiting). Directly changing origin will not set internal links correctly, so clipping would be messed up. This should be called when an object is spawned, and then only if it is teleported.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
setorigin (entity, origin)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setorigin (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *e;
|
|
|
|
float *org;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e = G_EDICT (pr, OFS_PARM0);
|
|
|
|
org = G_VECTOR (pr, OFS_PARM1);
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (org, e->v.v.origin);
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_LinkEdict (e, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setsize
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
the size box is rotated by the current angle
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
setsize (entity, minvector, maxvector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setsize (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
edict_t *e;
|
|
|
|
float *min, *max;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e = G_EDICT (pr, OFS_PARM0);
|
|
|
|
min = G_VECTOR (pr, OFS_PARM1);
|
|
|
|
max = G_VECTOR (pr, OFS_PARM2);
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (min, e->v.v.mins);
|
|
|
|
VectorCopy (max, e->v.v.maxs);
|
|
|
|
VectorSubtract (max, min, e->v.v.size);
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_LinkEdict (e, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setmodel
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
setmodel(entity, model)
|
|
|
|
Also sets size, mins, and maxs for inline bmodels
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setmodel (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *e;
|
|
|
|
char *m, **check;
|
|
|
|
int i;
|
|
|
|
model_t *mod;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e = G_EDICT (pr, OFS_PARM0);
|
|
|
|
m = G_STRING (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// check to see if model was properly precached
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0, check = sv.model_precache; *check; i++, check++)
|
|
|
|
if (!strcmp (*check, m))
|
2000-05-10 11:29:38 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
if (!*check)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "no precache: %s\n", m);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
e->v.v.model = PR_SetString (pr, m);
|
|
|
|
e->v.v.modelindex = i;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// if it is an inline model, get the size information for it
|
2000-12-08 06:51:37 +00:00
|
|
|
if (m[0] == '*') {
|
2000-05-10 11:29:38 +00:00
|
|
|
mod = Mod_ForName (m, true);
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (mod->mins, e->v.v.mins);
|
|
|
|
VectorCopy (mod->maxs, e->v.v.maxs);
|
|
|
|
VectorSubtract (mod->maxs, mod->mins, e->v.v.size);
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_LinkEdict (e, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_bprint
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
broadcast print to everyone on server
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
bprint(value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_bprint (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *s;
|
|
|
|
int level;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
level = G_FLOAT (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = PF_VarString (pr, 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_BroadcastPrintf (level, "%s", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_sprint
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
single print to a specific client
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
sprint(clientent, value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_sprint (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
client_t *client;
|
|
|
|
int entnum;
|
|
|
|
int level;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
entnum = G_EDICTNUM (pr, OFS_PARM0);
|
|
|
|
level = G_FLOAT (pr, OFS_PARM1);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = PF_VarString (pr, 2);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
if (entnum < 1 || entnum > MAX_CLIENTS) {
|
2000-05-10 11:29:38 +00:00
|
|
|
Con_Printf ("tried to sprint to a non-client\n");
|
|
|
|
return;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
client = &svs.clients[entnum - 1];
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_ClientPrintf (client, level, "%s", s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_centerprint
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
single print to a specific client
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
centerprint(clientent, value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_centerprint (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
int entnum;
|
|
|
|
client_t *cl;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
entnum = G_EDICTNUM (pr, OFS_PARM0);
|
|
|
|
s = PF_VarString (pr, 1);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
if (entnum < 1 || entnum > MAX_CLIENTS) {
|
2000-05-10 11:29:38 +00:00
|
|
|
Con_Printf ("tried to sprint to a non-client\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
cl = &svs.clients[entnum - 1];
|
|
|
|
|
|
|
|
ClientReliableWrite_Begin (cl, svc_centerprint, 2 + strlen (s));
|
2000-05-10 11:29:38 +00:00
|
|
|
ClientReliableWrite_String (cl, s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_normalize
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
vector normalize(vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_normalize (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *value1;
|
|
|
|
vec3_t newvalue;
|
|
|
|
float new;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
value1 = G_VECTOR (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2];
|
|
|
|
new = sqrt (new);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (new == 0)
|
|
|
|
newvalue[0] = newvalue[1] = newvalue[2] = 0;
|
2000-12-08 06:51:37 +00:00
|
|
|
else {
|
|
|
|
new = 1 / new;
|
2000-05-10 11:29:38 +00:00
|
|
|
newvalue[0] = value1[0] * new;
|
|
|
|
newvalue[1] = value1[1] * new;
|
|
|
|
newvalue[2] = value1[2] * new;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (newvalue, G_VECTOR (pr, OFS_RETURN));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vlen
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
scalar vlen(vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vlen (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *value1;
|
|
|
|
float new;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
value1 = G_VECTOR (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2];
|
|
|
|
new = sqrt (new);
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = new;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vectoyaw
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
float vectoyaw(vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vectoyaw (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *value1;
|
|
|
|
float yaw;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
value1 = G_VECTOR (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (value1[1] == 0 && value1[0] == 0)
|
|
|
|
yaw = 0;
|
2000-12-08 06:51:37 +00:00
|
|
|
else {
|
|
|
|
yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (yaw < 0)
|
|
|
|
yaw += 360;
|
|
|
|
}
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = yaw;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vectoangles
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
vector vectoangles(vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vectoangles (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *value1;
|
|
|
|
float forward;
|
|
|
|
float yaw, pitch;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
value1 = G_VECTOR (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
if (value1[1] == 0 && value1[0] == 0) {
|
2000-05-10 11:29:38 +00:00
|
|
|
yaw = 0;
|
|
|
|
if (value1[2] > 0)
|
|
|
|
pitch = 90;
|
|
|
|
else
|
|
|
|
pitch = 270;
|
2000-12-08 06:51:37 +00:00
|
|
|
} else {
|
|
|
|
yaw = (int) (atan2 (value1[1], value1[0]) * 180 / M_PI);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (yaw < 0)
|
|
|
|
yaw += 360;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
forward = sqrt (value1[0] * value1[0] + value1[1] * value1[1]);
|
|
|
|
pitch = (int) (atan2 (value1[2], forward) * 180 / M_PI);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (pitch < 0)
|
|
|
|
pitch += 360;
|
|
|
|
}
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN + 0) = pitch;
|
|
|
|
G_FLOAT (pr, OFS_RETURN + 1) = yaw;
|
|
|
|
G_FLOAT (pr, OFS_RETURN + 2) = 0;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_Random
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Returns a number from 0<= num < 1
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
random()
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_random (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float num;
|
|
|
|
|
|
|
|
num = (rand () & 0x7fff) / ((float) 0x7fff);
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = num;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_ambientsound
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_ambientsound (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char **check;
|
|
|
|
char *samp;
|
|
|
|
float *pos;
|
|
|
|
float vol, attenuation;
|
|
|
|
int i, soundnum;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
pos = G_VECTOR (pr, OFS_PARM0);
|
|
|
|
samp = G_STRING (pr, OFS_PARM1);
|
|
|
|
vol = G_FLOAT (pr, OFS_PARM2);
|
|
|
|
attenuation = G_FLOAT (pr, OFS_PARM3);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
// check to see if samp was properly precached
|
2000-12-08 06:51:37 +00:00
|
|
|
for (soundnum = 0, check = sv.sound_precache; *check; check++, soundnum++)
|
|
|
|
if (!strcmp (*check, samp))
|
2000-05-10 11:29:38 +00:00
|
|
|
break;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
if (!*check) {
|
2000-05-10 11:29:38 +00:00
|
|
|
Con_Printf ("no precache: %s\n", samp);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// add an svc_spawnambient command to the level signon packet
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
MSG_WriteByte (&sv.signon, svc_spawnstaticsound);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
|
|
MSG_WriteCoord (&sv.signon, pos[i]);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
MSG_WriteByte (&sv.signon, soundnum);
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
MSG_WriteByte (&sv.signon, vol * 255);
|
|
|
|
MSG_WriteByte (&sv.signon, attenuation * 64);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_sound
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Each entity can have eight independant sound sources, like voice,
|
|
|
|
weapon, feet, etc.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Channel 0 is an auto-allocate channel, the others override anything
|
|
|
|
allready running on that entity/channel pair.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
An attenuation of 0 will play full volume everywhere in the level.
|
|
|
|
Larger attenuations will drop off.
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_sound (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *sample;
|
|
|
|
int channel;
|
|
|
|
edict_t *entity;
|
|
|
|
int volume;
|
|
|
|
float attenuation;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
entity = G_EDICT (pr, OFS_PARM0);
|
|
|
|
channel = G_FLOAT (pr, OFS_PARM1);
|
|
|
|
sample = G_STRING (pr, OFS_PARM2);
|
|
|
|
volume = G_FLOAT (pr, OFS_PARM3) * 255;
|
|
|
|
attenuation = G_FLOAT (pr, OFS_PARM4);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_StartSound (entity, channel, sample, volume, attenuation);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_break
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
break()
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_break (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
Con_Printf ("break statement\n");
|
|
|
|
*(int *) -4 = 0; // dump to debugger
|
2000-12-31 07:43:09 +00:00
|
|
|
// PR_RunError (pr, "break statement");
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_traceline
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Used for use tracing and shot targeting
|
|
|
|
Traces are blocked by bbox and exact bsp entityes, and also slide box entities
|
|
|
|
if the tryents flag is set.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
traceline (vector1, vector2, tryents)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_traceline (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *v1, *v2;
|
|
|
|
trace_t trace;
|
|
|
|
int nomonsters;
|
|
|
|
edict_t *ent;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
v1 = G_VECTOR (pr, OFS_PARM0);
|
|
|
|
v2 = G_VECTOR (pr, OFS_PARM1);
|
|
|
|
nomonsters = G_FLOAT (pr, OFS_PARM2);
|
|
|
|
ent = G_EDICT (pr, OFS_PARM3);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
pr->pr_global_struct->trace_allsolid = trace.allsolid;
|
|
|
|
pr->pr_global_struct->trace_startsolid = trace.startsolid;
|
|
|
|
pr->pr_global_struct->trace_fraction = trace.fraction;
|
|
|
|
pr->pr_global_struct->trace_inwater = trace.inwater;
|
|
|
|
pr->pr_global_struct->trace_inopen = trace.inopen;
|
|
|
|
VectorCopy (trace.endpos, pr->pr_global_struct->trace_endpos);
|
|
|
|
VectorCopy (trace.plane.normal, pr->pr_global_struct->trace_plane_normal);
|
|
|
|
pr->pr_global_struct->trace_plane_dist = trace.plane.dist;
|
2000-05-10 11:29:38 +00:00
|
|
|
if (trace.ent)
|
2001-01-02 03:22:46 +00:00
|
|
|
pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, trace.ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
else
|
2001-01-02 03:22:46 +00:00
|
|
|
pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, sv.edicts);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkpos
|
|
|
|
|
|
|
|
Returns true if the given entity can move to the given position from it's
|
|
|
|
current position by walking or rolling.
|
|
|
|
FIXME: make work...
|
|
|
|
scalar checkpos (entity, vector)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkpos (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
byte checkpvs[MAX_MAP_LEAFS / 8];
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
int
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_newcheckclient (progs_t *pr, int check)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i;
|
|
|
|
byte *pvs;
|
|
|
|
edict_t *ent;
|
|
|
|
mleaf_t *leaf;
|
|
|
|
vec3_t org;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// cycle to the next one
|
|
|
|
|
|
|
|
if (check < 1)
|
|
|
|
check = 1;
|
|
|
|
if (check > MAX_CLIENTS)
|
|
|
|
check = MAX_CLIENTS;
|
|
|
|
|
|
|
|
if (check == MAX_CLIENTS)
|
|
|
|
i = 1;
|
|
|
|
else
|
|
|
|
i = check + 1;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (;; i++) {
|
|
|
|
if (i == MAX_CLIENTS + 1)
|
2000-05-10 11:29:38 +00:00
|
|
|
i = 1;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = EDICT_NUM (pr, i);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (i == check)
|
2000-12-08 06:51:37 +00:00
|
|
|
break; // didn't find anything else
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (ent->free)
|
|
|
|
continue;
|
2001-02-02 21:22:35 +00:00
|
|
|
if (ent->v.v.health <= 0)
|
2000-05-10 11:29:38 +00:00
|
|
|
continue;
|
2001-02-02 21:22:35 +00:00
|
|
|
if ((int) ent->v.v.flags & FL_NOTARGET)
|
2000-05-10 11:29:38 +00:00
|
|
|
continue;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
// anything that is a client, or has a client as an enemy
|
2000-05-10 11:29:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the PVS for the entity
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorAdd (ent->v.v.origin, ent->v.v.view_ofs, org);
|
2000-05-10 11:29:38 +00:00
|
|
|
leaf = Mod_PointInLeaf (org, sv.worldmodel);
|
|
|
|
pvs = Mod_LeafPVS (leaf, sv.worldmodel);
|
2000-12-08 06:51:37 +00:00
|
|
|
memcpy (checkpvs, pvs, (sv.worldmodel->numleafs + 7) >> 3);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkclient
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Returns a client (or object that has a client enemy) that would be a
|
|
|
|
valid target.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
If there are more than one valid options, they are cycled each frame
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
If (self.origin + self.viewofs) is not in the PVS of the current target,
|
|
|
|
it is not returned at all.
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
name checkclient ()
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
|
|
|
#define MAX_CHECK 16
|
2000-12-08 06:51:37 +00:00
|
|
|
int c_invis, c_notvis;
|
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkclient (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
edict_t *ent, *self;
|
|
|
|
mleaf_t *leaf;
|
|
|
|
int l;
|
|
|
|
vec3_t view;
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
// find a new check if on a new frame
|
2000-12-08 06:51:37 +00:00
|
|
|
if (sv.time - sv.lastchecktime >= 0.1) {
|
2000-12-31 07:43:09 +00:00
|
|
|
sv.lastcheck = PF_newcheckclient (pr, sv.lastcheck);
|
2000-05-10 11:29:38 +00:00
|
|
|
sv.lastchecktime = sv.time;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
// return check if it might be visible
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = EDICT_NUM (pr, sv.lastcheck);
|
2001-02-02 21:22:35 +00:00
|
|
|
if (ent->free || ent->v.v.health <= 0) {
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, sv.edicts);
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// if current entity can't possibly see the check entity, return 0
|
2001-01-02 03:22:46 +00:00
|
|
|
self = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorAdd (self->v.v.origin, self->v.v.view_ofs, view);
|
2000-05-10 11:29:38 +00:00
|
|
|
leaf = Mod_PointInLeaf (view, sv.worldmodel);
|
|
|
|
l = (leaf - sv.worldmodel->leafs) - 1;
|
2000-12-08 06:51:37 +00:00
|
|
|
if ((l < 0) || !(checkpvs[l >> 3] & (1 << (l & 7)))) {
|
|
|
|
c_notvis++;
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, sv.edicts);
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
// might be able to see it
|
2000-12-08 06:51:37 +00:00
|
|
|
c_invis++;
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_stuffcmd
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Sends text over to the client's execution buffer
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
stuffcmd (clientent, value)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_stuffcmd (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
int entnum;
|
|
|
|
char *str;
|
|
|
|
client_t *cl;
|
|
|
|
char *buf;
|
2001-01-07 12:15:38 +00:00
|
|
|
char *p;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
entnum = G_EDICTNUM (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (entnum < 1 || entnum > MAX_CLIENTS)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "Parm 0 not a client");
|
|
|
|
str = G_STRING (pr, OFS_PARM1);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
cl = &svs.clients[entnum - 1];
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-06-18 14:24:19 +00:00
|
|
|
buf = cl->stufftext_buf;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (strlen (buf) + strlen (str) >= MAX_STUFFTEXT)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "stufftext buffer overflow");
|
2001-01-07 12:15:38 +00:00
|
|
|
strcat (buf, str);
|
|
|
|
|
|
|
|
if (!strcmp (buf, "disconnect\n")) {
|
|
|
|
// so long and thanks for all the fish
|
|
|
|
cl->drop = true;
|
|
|
|
buf[0] = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = strrchr (buf, '\n');
|
|
|
|
if (p) {
|
|
|
|
char t = p[1];
|
|
|
|
p[1] = 0;
|
|
|
|
ClientReliableWrite_Begin (cl, svc_stufftext, 2 + p - buf);
|
|
|
|
ClientReliableWrite_String (cl, buf);
|
|
|
|
p[1] = t;
|
|
|
|
strcpy (buf, p + 1); // safe because this is a downward, in
|
|
|
|
// buffer move
|
2000-06-18 14:24:19 +00:00
|
|
|
}
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_localcmd
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Sends text over to the client's execution buffer
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
localcmd (string)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_localcmd (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *str;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
str = G_STRING (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
Cbuf_AddText (str);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_cvar
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
float cvar (string)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_cvar (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *str;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
str = G_STRING (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = Cvar_VariableValue (str);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_cvar_set
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
float cvar (string)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_cvar_set (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
char *var_name, *val;
|
|
|
|
cvar_t *var;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
var_name = G_STRING (pr, OFS_PARM0);
|
|
|
|
val = G_STRING (pr, OFS_PARM1);
|
2000-12-08 06:51:37 +00:00
|
|
|
var = Cvar_FindVar (var_name);
|
2000-05-19 07:48:06 +00:00
|
|
|
if (!var)
|
2000-12-08 06:51:37 +00:00
|
|
|
var = Cvar_FindAlias (var_name);
|
|
|
|
if (!var) {
|
2000-05-19 07:48:06 +00:00
|
|
|
// FIXME: make Con_DPrint?
|
|
|
|
Con_Printf ("PF_cvar_set: variable %s not found\n", var_name);
|
|
|
|
return;
|
|
|
|
}
|
2000-05-17 23:16:23 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
Cvar_Set (var, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_findradius
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Returns a chain of entities that have origins within a spherical area
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
findradius (origin, radius)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_findradius (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent, *chain;
|
|
|
|
float rad;
|
|
|
|
float *org;
|
|
|
|
vec3_t eorg;
|
|
|
|
int i, j;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
chain = (edict_t *) sv.edicts;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
org = G_VECTOR (pr, OFS_PARM0);
|
|
|
|
rad = G_FLOAT (pr, OFS_PARM1);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = NEXT_EDICT (pr, sv.edicts);
|
|
|
|
for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (pr, ent)) {
|
2000-05-10 11:29:38 +00:00
|
|
|
if (ent->free)
|
|
|
|
continue;
|
2001-02-02 21:22:35 +00:00
|
|
|
if (ent->v.v.solid == SOLID_NOT)
|
2000-05-10 11:29:38 +00:00
|
|
|
continue;
|
2000-12-08 06:51:37 +00:00
|
|
|
for (j = 0; j < 3; j++)
|
|
|
|
eorg[j] =
|
2001-02-02 21:22:35 +00:00
|
|
|
org[j] - (ent->v.v.origin[j] +
|
|
|
|
(ent->v.v.mins[j] + ent->v.v.maxs[j]) * 0.5);
|
2000-12-08 06:51:37 +00:00
|
|
|
if (Length (eorg) > rad)
|
2000-05-10 11:29:38 +00:00
|
|
|
continue;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
ent->v.v.chain = EDICT_TO_PROG (pr, chain);
|
2000-05-10 11:29:38 +00:00
|
|
|
chain = ent;
|
|
|
|
}
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, chain);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_dprint
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_dprint (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
Con_Printf ("%s", PF_VarString (pr, 0));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
char pr_string_temp[128];
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_ftos (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float v;
|
|
|
|
int i; // 1999-07-25 FTOS fix by Maddes
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
v = G_FLOAT (pr, OFS_PARM0);
|
2000-08-16 21:43:24 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
if (v == (int) v)
|
|
|
|
snprintf (pr_string_temp, sizeof (pr_string_temp), "%d", (int) v);
|
2000-05-10 11:29:38 +00:00
|
|
|
else
|
2000-08-16 21:43:24 +00:00
|
|
|
// 1999-07-25 FTOS fix by Maddes start
|
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
snprintf (pr_string_temp, sizeof (pr_string_temp), "%1f", v);
|
|
|
|
for (i = strlen (pr_string_temp) - 1;
|
|
|
|
i > 0 && pr_string_temp[i] == '0' && pr_string_temp[i - 1] != '.';
|
|
|
|
i--) {
|
2000-08-16 21:43:24 +00:00
|
|
|
pr_string_temp[i] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 1999-07-25 FTOS fix by Maddes end
|
2000-12-31 07:43:09 +00:00
|
|
|
G_INT (pr, OFS_RETURN) = PR_SetString (pr, pr_string_temp);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_fabs (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float v;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
v = G_FLOAT (pr, OFS_PARM0);
|
|
|
|
G_FLOAT (pr, OFS_RETURN) = fabs (v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_vtos (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
snprintf (pr_string_temp, sizeof (pr_string_temp), "'%5.1f %5.1f %5.1f'",
|
2000-12-31 07:43:09 +00:00
|
|
|
G_VECTOR (pr, OFS_PARM0)[0], G_VECTOR (pr, OFS_PARM0)[1],
|
|
|
|
G_VECTOR (pr, OFS_PARM0)[2]);
|
|
|
|
G_INT (pr, OFS_RETURN) = PR_SetString (pr, pr_string_temp);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_Spawn (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ed;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ed = ED_Alloc (pr);
|
|
|
|
RETURN_EDICT (pr, ed);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_Remove (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ed;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ed = G_EDICT (pr, OFS_PARM0);
|
|
|
|
ED_Free (pr, ed);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// entity (entity start, .string field, string match) find = #5;
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_Find (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
int e;
|
|
|
|
int f;
|
|
|
|
char *s, *t;
|
|
|
|
edict_t *ed;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e = G_EDICTNUM (pr, OFS_PARM0);
|
|
|
|
f = G_INT (pr, OFS_PARM1);
|
|
|
|
s = G_STRING (pr, OFS_PARM2);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (!s)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "PF_Find: bad search string");
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
for (e++; e < sv.num_edicts; e++) {
|
2000-12-31 07:43:09 +00:00
|
|
|
ed = EDICT_NUM (pr, e);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (ed->free)
|
|
|
|
continue;
|
2001-02-01 08:38:25 +00:00
|
|
|
t = E_STRING (pr, ed, f);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (!t)
|
|
|
|
continue;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!strcmp (t, s)) {
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, ed);
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, sv.edicts);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_CheckEmptyString (progs_t *pr, char *s)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
|
|
|
if (s[0] <= ' ')
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "Bad string");
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_precache_file (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{ // precache_file is only used to copy
|
|
|
|
// files with qcc, it does nothing
|
2000-12-31 07:43:09 +00:00
|
|
|
G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_precache_sound (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *s;
|
|
|
|
int i;
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
if (sv.state != ss_loading)
|
2000-12-08 06:51:37 +00:00
|
|
|
PR_RunError
|
2000-12-31 07:43:09 +00:00
|
|
|
(pr, "PF_Precache_*: Precache can only be done in spawn functions");
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = G_STRING (pr, OFS_PARM0);
|
|
|
|
G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0);
|
|
|
|
PR_CheckEmptyString (pr, s);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
for (i = 0; i < MAX_SOUNDS; i++) {
|
|
|
|
if (!sv.sound_precache[i]) {
|
2000-05-10 11:29:38 +00:00
|
|
|
sv.sound_precache[i] = s;
|
|
|
|
return;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!strcmp (sv.sound_precache[i], s))
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "PF_precache_sound: overflow");
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_precache_model (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *s;
|
|
|
|
int i;
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
if (sv.state != ss_loading)
|
2000-12-08 06:51:37 +00:00
|
|
|
PR_RunError
|
2000-12-31 07:43:09 +00:00
|
|
|
(pr, "PF_Precache_*: Precache can only be done in spawn functions");
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = G_STRING (pr, OFS_PARM0);
|
|
|
|
G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0);
|
|
|
|
PR_CheckEmptyString (pr, s);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < MAX_MODELS; i++) {
|
|
|
|
if (!sv.model_precache[i]) {
|
2000-05-10 11:29:38 +00:00
|
|
|
sv.model_precache[i] = s;
|
|
|
|
return;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!strcmp (sv.model_precache[i], s))
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "PF_precache_model: overflow");
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_coredump (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
ED_PrintEdicts (pr);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_traceon (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
pr->pr_trace = true;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_traceoff (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
pr->pr_trace = false;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_eprint (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
ED_PrintNum (pr, G_EDICTNUM (pr, OFS_PARM0));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_walkmove
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
float(float yaw, float dist) walkmove
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_walkmove (progs_t *pr)
|
2000-12-08 06:51:37 +00:00
|
|
|
{
|
|
|
|
edict_t *ent;
|
|
|
|
float yaw, dist;
|
|
|
|
vec3_t move;
|
|
|
|
dfunction_t *oldf;
|
|
|
|
int oldself;
|
|
|
|
|
2001-01-02 03:22:46 +00:00
|
|
|
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2000-12-31 07:43:09 +00:00
|
|
|
yaw = G_FLOAT (pr, OFS_PARM0);
|
|
|
|
dist = G_FLOAT (pr, OFS_PARM1);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = 0;
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
yaw = yaw * M_PI * 2 / 360;
|
|
|
|
|
|
|
|
move[0] = cos (yaw) * dist;
|
|
|
|
move[1] = sin (yaw) * dist;
|
2000-05-10 11:29:38 +00:00
|
|
|
move[2] = 0;
|
|
|
|
|
|
|
|
// save program state, because SV_movestep may call other progs
|
2000-12-31 07:43:09 +00:00
|
|
|
oldf = pr->pr_xfunction;
|
|
|
|
oldself = pr->pr_global_struct->self;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = SV_movestep (ent, move, true);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
// restore program state
|
2000-12-31 07:43:09 +00:00
|
|
|
pr->pr_xfunction = oldf;
|
|
|
|
pr->pr_global_struct->self = oldself;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_droptofloor
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
void() droptofloor
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_droptofloor (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent;
|
|
|
|
vec3_t end;
|
|
|
|
trace_t trace;
|
|
|
|
|
2001-01-02 03:22:46 +00:00
|
|
|
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (ent->v.v.origin, end);
|
2000-05-10 11:29:38 +00:00
|
|
|
end[2] -= 256;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
trace = SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, false, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (trace.fraction == 1 || trace.allsolid)
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = 0;
|
2000-12-08 06:51:37 +00:00
|
|
|
else {
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (trace.endpos, ent->v.v.origin);
|
2000-05-10 11:29:38 +00:00
|
|
|
SV_LinkEdict (ent, false);
|
2001-02-02 21:22:35 +00:00
|
|
|
ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND;
|
|
|
|
ent->v.v.groundentity = EDICT_TO_PROG (pr, trace.ent);
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = 1;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_lightstyle
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
void(float style, string value) lightstyle
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_lightstyle (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int style;
|
|
|
|
char *val;
|
|
|
|
client_t *client;
|
|
|
|
int j;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
style = G_FLOAT (pr, OFS_PARM0);
|
|
|
|
val = G_STRING (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// change the string in sv
|
|
|
|
sv.lightstyles[style] = val;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
// send message to all clients on this server
|
|
|
|
if (sv.state != ss_active)
|
|
|
|
return;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++)
|
|
|
|
if (client->state == cs_spawned) {
|
|
|
|
ClientReliableWrite_Begin (client, svc_lightstyle,
|
|
|
|
strlen (val) + 3);
|
2000-05-10 11:29:38 +00:00
|
|
|
ClientReliableWrite_Char (client, style);
|
|
|
|
ClientReliableWrite_String (client, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_rint (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float f;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
f = G_FLOAT (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (f > 0)
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = (int) (f + 0.5);
|
2000-05-10 11:29:38 +00:00
|
|
|
else
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = (int) (f - 0.5);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_floor (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = floor (G_FLOAT (pr, OFS_PARM0));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_ceil (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = ceil (G_FLOAT (pr, OFS_PARM0));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkbottom
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_checkbottom (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = G_EDICT (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = SV_CheckBottom (ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_pointcontents
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_pointcontents (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *v;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
v = G_VECTOR (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = SV_PointContents (v);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_nextent
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
entity nextent(entity)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_nextent (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int i;
|
|
|
|
edict_t *ent;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
i = G_EDICTNUM (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
while (1) {
|
2000-05-10 11:29:38 +00:00
|
|
|
i++;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (i == sv.num_edicts) {
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, sv.edicts);
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = EDICT_NUM (pr, i);
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!ent->free) {
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_EDICT (pr, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_aim
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
Pick a vector for the player to shoot along
|
|
|
|
vector aim(entity, missilespeed)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
cvar_t *sv_aim;
|
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_aim (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent, *check, *bestent;
|
|
|
|
vec3_t start, dir, end, bestdir;
|
|
|
|
int i, j;
|
|
|
|
trace_t tr;
|
|
|
|
float dist, bestdist;
|
|
|
|
float speed;
|
|
|
|
char *noaim;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = G_EDICT (pr, OFS_PARM0);
|
|
|
|
speed = G_FLOAT (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorCopy (ent->v.v.origin, start);
|
2000-05-10 11:29:38 +00:00
|
|
|
start[2] += 20;
|
|
|
|
|
|
|
|
// noaim option
|
2000-12-31 07:43:09 +00:00
|
|
|
i = NUM_FOR_EDICT (pr, ent);
|
2000-12-08 06:51:37 +00:00
|
|
|
if (i > 0 && i < MAX_CLIENTS) {
|
|
|
|
noaim = Info_ValueForKey (svs.clients[i - 1].userinfo, "noaim");
|
|
|
|
if (atoi (noaim) > 0) {
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (pr->pr_global_struct->v_forward, G_VECTOR (pr, OFS_RETURN));
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// try sending a trace straight
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (pr->pr_global_struct->v_forward, dir);
|
2000-05-10 11:29:38 +00:00
|
|
|
VectorMA (start, 2048, dir, end);
|
|
|
|
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
|
2001-02-02 21:22:35 +00:00
|
|
|
if (tr.ent && tr.ent->v.v.takedamage == DAMAGE_AIM
|
|
|
|
&& (!teamplay->int_val || ent->v.v.team <= 0
|
|
|
|
|| ent->v.v.team != tr.ent->v.v.team)) {
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (pr->pr_global_struct->v_forward, G_VECTOR (pr, OFS_RETURN));
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// try all possible entities
|
|
|
|
VectorCopy (dir, bestdir);
|
2000-05-16 04:47:41 +00:00
|
|
|
bestdist = sv_aim->value;
|
2000-05-10 11:29:38 +00:00
|
|
|
bestent = NULL;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
check = NEXT_EDICT (pr, sv.edicts);
|
|
|
|
for (i = 1; i < sv.num_edicts; i++, check = NEXT_EDICT (pr, check)) {
|
2001-02-02 21:22:35 +00:00
|
|
|
if (check->v.v.takedamage != DAMAGE_AIM)
|
2000-05-10 11:29:38 +00:00
|
|
|
continue;
|
|
|
|
if (check == ent)
|
|
|
|
continue;
|
2001-02-02 21:22:35 +00:00
|
|
|
if (teamplay->int_val && ent->v.v.team > 0
|
|
|
|
&& ent->v.v.team == check->v.v.team) continue; // don't aim at
|
2000-12-08 06:51:37 +00:00
|
|
|
// teammate
|
|
|
|
for (j = 0; j < 3; j++)
|
2001-02-02 21:22:35 +00:00
|
|
|
end[j] = check->v.v.origin[j]
|
|
|
|
+ 0.5 * (check->v.v.mins[j] + check->v.v.maxs[j]);
|
2000-05-10 11:29:38 +00:00
|
|
|
VectorSubtract (end, start, dir);
|
|
|
|
VectorNormalize (dir);
|
2000-12-31 07:43:09 +00:00
|
|
|
dist = DotProduct (dir, pr->pr_global_struct->v_forward);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (dist < bestdist)
|
2000-12-08 06:51:37 +00:00
|
|
|
continue; // to far to turn
|
2000-05-10 11:29:38 +00:00
|
|
|
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
|
2000-12-08 06:51:37 +00:00
|
|
|
if (tr.ent == check) { // can shoot at this one
|
2000-05-10 11:29:38 +00:00
|
|
|
bestdist = dist;
|
|
|
|
bestent = check;
|
|
|
|
}
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
if (bestent) {
|
2001-02-02 21:22:35 +00:00
|
|
|
VectorSubtract (bestent->v.v.origin, ent->v.v.origin, dir);
|
2000-12-31 07:43:09 +00:00
|
|
|
dist = DotProduct (dir, pr->pr_global_struct->v_forward);
|
|
|
|
VectorScale (pr->pr_global_struct->v_forward, dist, end);
|
2000-05-10 11:29:38 +00:00
|
|
|
end[2] = dir[2];
|
|
|
|
VectorNormalize (end);
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (end, G_VECTOR (pr, OFS_RETURN));
|
2000-12-08 06:51:37 +00:00
|
|
|
} else {
|
2000-12-31 07:43:09 +00:00
|
|
|
VectorCopy (bestdir, G_VECTOR (pr, OFS_RETURN));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_changeyaw
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
This was a major timewaster in progs, so it was converted to C
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_changeyaw (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent;
|
|
|
|
float ideal, current, move, speed;
|
|
|
|
|
2001-01-02 03:22:46 +00:00
|
|
|
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
|
2001-02-02 21:22:35 +00:00
|
|
|
current = anglemod (ent->v.v.angles[1]);
|
|
|
|
ideal = ent->v.v.ideal_yaw;
|
|
|
|
speed = ent->v.v.yaw_speed;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
if (current == ideal)
|
|
|
|
return;
|
|
|
|
move = ideal - current;
|
2000-12-08 06:51:37 +00:00
|
|
|
if (ideal > current) {
|
2000-05-10 11:29:38 +00:00
|
|
|
if (move >= 180)
|
|
|
|
move = move - 360;
|
2000-12-08 06:51:37 +00:00
|
|
|
} else {
|
2000-05-10 11:29:38 +00:00
|
|
|
if (move <= -180)
|
|
|
|
move = move + 360;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
if (move > 0) {
|
2000-05-10 11:29:38 +00:00
|
|
|
if (move > speed)
|
|
|
|
move = speed;
|
2000-12-08 06:51:37 +00:00
|
|
|
} else {
|
2000-05-10 11:29:38 +00:00
|
|
|
if (move < -speed)
|
|
|
|
move = -speed;
|
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
ent->v.v.angles[1] = anglemod (current + move);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
===============================================================================
|
|
|
|
|
|
|
|
MESSAGE WRITING
|
|
|
|
|
|
|
|
===============================================================================
|
|
|
|
*/
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
#define MSG_BROADCAST 0 // unreliable to all
|
|
|
|
#define MSG_ONE 1 // reliable to one (msg_entity)
|
|
|
|
#define MSG_ALL 2 // reliable to all
|
|
|
|
#define MSG_INIT 3 // write to the init string
|
|
|
|
#define MSG_MULTICAST 4 // for multicast()
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
sizebuf_t *
|
2000-12-31 07:43:09 +00:00
|
|
|
WriteDest (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int dest;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
dest = G_FLOAT (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
switch (dest) {
|
|
|
|
case MSG_BROADCAST:
|
|
|
|
return &sv.datagram;
|
|
|
|
|
|
|
|
case MSG_ONE:
|
|
|
|
SV_Error ("Shouldn't be at MSG_ONE");
|
2000-05-10 11:29:38 +00:00
|
|
|
#if 0
|
2001-01-02 03:22:46 +00:00
|
|
|
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->msg_entity);
|
2000-12-31 07:43:09 +00:00
|
|
|
entnum = NUM_FOR_EDICT (pr, ent);
|
2000-12-08 06:51:37 +00:00
|
|
|
if (entnum < 1 || entnum > MAX_CLIENTS)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "WriteDest: not a client");
|
2000-12-08 06:51:37 +00:00
|
|
|
return &svs.clients[entnum - 1].netchan.message;
|
2000-05-10 11:29:38 +00:00
|
|
|
#endif
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
case MSG_ALL:
|
|
|
|
return &sv.reliable_datagram;
|
|
|
|
|
|
|
|
case MSG_INIT:
|
|
|
|
if (sv.state != ss_loading)
|
|
|
|
PR_RunError
|
2000-12-31 07:43:09 +00:00
|
|
|
(pr, "PF_Write_*: MSG_INIT can only be written in spawn functions");
|
2000-12-08 06:51:37 +00:00
|
|
|
return &sv.signon;
|
|
|
|
|
|
|
|
case MSG_MULTICAST:
|
|
|
|
return &sv.multicast;
|
|
|
|
|
|
|
|
default:
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "WriteDest: bad destination");
|
2000-12-08 06:51:37 +00:00
|
|
|
break;
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-05-10 11:29:38 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
static client_t *
|
2000-12-31 07:43:09 +00:00
|
|
|
Write_GetClient (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
int entnum;
|
|
|
|
edict_t *ent;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-01-02 03:22:46 +00:00
|
|
|
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->msg_entity);
|
2000-12-31 07:43:09 +00:00
|
|
|
entnum = NUM_FOR_EDICT (pr, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (entnum < 1 || entnum > MAX_CLIENTS)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "Write_GetClient: not a client");
|
2000-12-08 06:51:37 +00:00
|
|
|
return &svs.clients[entnum - 1];
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteByte (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 1);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Byte (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteByte (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteChar (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 1);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Char (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteChar (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteShort (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 2);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Short (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteShort (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteLong (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 4);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Long (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteLong (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteAngle (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 1);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Angle (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteAngle (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteCoord (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 2);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Coord (cl, G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteCoord (WriteDest (pr), G_FLOAT (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteString (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableCheckBlock (cl, 1 + strlen (G_STRING (pr, OFS_PARM1)));
|
|
|
|
ClientReliableWrite_String (cl, G_STRING (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteString (WriteDest (pr), G_STRING (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_WriteEntity (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
if (G_FLOAT (pr, OFS_PARM0) == MSG_ONE) {
|
|
|
|
client_t *cl = Write_GetClient (pr);
|
2000-12-08 06:51:37 +00:00
|
|
|
|
|
|
|
ClientReliableCheckBlock (cl, 2);
|
2000-12-31 07:43:09 +00:00
|
|
|
ClientReliableWrite_Short (cl, G_EDICTNUM (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
2000-12-31 07:43:09 +00:00
|
|
|
MSG_WriteShort (WriteDest (pr), G_EDICTNUM (pr, OFS_PARM1));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
int SV_ModelIndex (char *name);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_makestatic (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent;
|
|
|
|
int i;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = G_EDICT (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
MSG_WriteByte (&sv.signon, svc_spawnstatic);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
MSG_WriteByte (&sv.signon, SV_ModelIndex (PR_GetString (pr, ent->v.v.model)));
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2001-02-02 21:22:35 +00:00
|
|
|
MSG_WriteByte (&sv.signon, ent->v.v.frame);
|
|
|
|
MSG_WriteByte (&sv.signon, ent->v.v.colormap);
|
|
|
|
MSG_WriteByte (&sv.signon, ent->v.v.skin);
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < 3; i++) {
|
2001-02-02 21:22:35 +00:00
|
|
|
MSG_WriteCoord (&sv.signon, ent->v.v.origin[i]);
|
|
|
|
MSG_WriteAngle (&sv.signon, ent->v.v.angles[i]);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// throw the entity away now
|
2000-12-31 07:43:09 +00:00
|
|
|
ED_Free (pr, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setspawnparms
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_setspawnparms (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent;
|
|
|
|
int i;
|
|
|
|
client_t *client;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent = G_EDICT (pr, OFS_PARM0);
|
|
|
|
i = NUM_FOR_EDICT (pr, ent);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (i < 1 || i > MAX_CLIENTS)
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "Entity is not a client");
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// copy spawn parms out of the client_t
|
2000-12-08 06:51:37 +00:00
|
|
|
client = svs.clients + (i - 1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
for (i = 0; i < NUM_SPAWN_PARMS; i++)
|
2000-12-31 07:43:09 +00:00
|
|
|
(&pr->pr_global_struct->parm1)[i] = client->spawn_parms[i];
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_changelevel
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_changelevel (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *s;
|
|
|
|
static int last_spawncount;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
// make sure we don't issue two changelevels
|
|
|
|
if (svs.spawncount == last_spawncount)
|
|
|
|
return;
|
|
|
|
last_spawncount = svs.spawncount;
|
2000-12-08 06:51:37 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = G_STRING (pr, OFS_PARM0);
|
2000-12-08 06:51:37 +00:00
|
|
|
Cbuf_AddText (va ("map %s\n", s));
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_logfrag
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
logfrag (killer, killee)
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_logfrag (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *ent1, *ent2;
|
|
|
|
int e1, e2;
|
|
|
|
char *s;
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
ent1 = G_EDICT (pr, OFS_PARM0);
|
|
|
|
ent2 = G_EDICT (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e1 = NUM_FOR_EDICT (pr, ent1);
|
|
|
|
e2 = NUM_FOR_EDICT (pr, ent2);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
if (e1 < 1 || e1 > MAX_CLIENTS || e2 < 1 || e2 > MAX_CLIENTS)
|
2000-05-10 11:29:38 +00:00
|
|
|
return;
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
s = va ("\\%s\\%s\\\n", svs.clients[e1 - 1].name, svs.clients[e2 - 1].name);
|
|
|
|
|
|
|
|
SZ_Print (&svs.log[svs.logsequence & 1], s);
|
2000-05-10 11:29:38 +00:00
|
|
|
if (sv_fraglogfile) {
|
2000-09-27 19:44:26 +00:00
|
|
|
Qprintf (sv_fraglogfile, s);
|
|
|
|
Qflush (sv_fraglogfile);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_infokey
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
string(entity e, string key) infokey
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_infokey (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
edict_t *e;
|
|
|
|
int e1;
|
|
|
|
char *value;
|
|
|
|
char *key;
|
|
|
|
static char ov[256];
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
e = G_EDICT (pr, OFS_PARM0);
|
|
|
|
e1 = NUM_FOR_EDICT (pr, e);
|
|
|
|
key = G_STRING (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
if (e1 == 0) {
|
2000-12-08 06:51:37 +00:00
|
|
|
if ((value = Info_ValueForKey (svs.info, key)) == NULL || !*value)
|
|
|
|
value = Info_ValueForKey (localinfo, key);
|
2000-05-10 11:29:38 +00:00
|
|
|
} else if (e1 <= MAX_CLIENTS) {
|
2000-12-08 06:51:37 +00:00
|
|
|
if (!strcmp (key, "ip"))
|
|
|
|
value =
|
|
|
|
strcpy (ov,
|
|
|
|
NET_BaseAdrToString (svs.clients[e1 - 1].netchan.
|
|
|
|
remote_address));
|
|
|
|
else if (!strcmp (key, "ping")) {
|
|
|
|
int ping = SV_CalcPing (&svs.clients[e1 - 1]);
|
|
|
|
|
|
|
|
snprintf (ov, sizeof (ov), "%d", ping);
|
2000-05-10 11:29:38 +00:00
|
|
|
value = ov;
|
|
|
|
} else
|
2000-12-08 06:51:37 +00:00
|
|
|
value = Info_ValueForKey (svs.clients[e1 - 1].userinfo, key);
|
2000-05-10 11:29:38 +00:00
|
|
|
} else
|
|
|
|
value = "";
|
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
RETURN_STRING (pr, value);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_stof
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
float(string s) stof
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_stof (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
char *s;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
s = G_STRING (pr, OFS_PARM0);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
G_FLOAT (pr, OFS_RETURN) = atof (s);
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_multicast
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
void(vector where, float set) multicast
|
2000-05-10 11:29:38 +00:00
|
|
|
*/
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_multicast (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-08 06:51:37 +00:00
|
|
|
float *o;
|
|
|
|
int to;
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-31 07:43:09 +00:00
|
|
|
o = G_VECTOR (pr, OFS_PARM0);
|
|
|
|
to = G_FLOAT (pr, OFS_PARM1);
|
2000-05-10 11:29:38 +00:00
|
|
|
|
|
|
|
SV_Multicast (o, to);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
void
|
2000-12-31 07:43:09 +00:00
|
|
|
PF_Fixme (progs_t *pr)
|
2000-05-10 11:29:38 +00:00
|
|
|
{
|
2000-12-31 07:43:09 +00:00
|
|
|
PR_RunError (pr, "unimplemented bulitin");
|
2000-05-10 11:29:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
builtin_t pr_builtin[] = {
|
2000-05-10 11:29:38 +00:00
|
|
|
PF_Fixme,
|
2000-12-08 06:51:37 +00:00
|
|
|
PF_makevectors, // void(entity e) makevectors
|
|
|
|
// = #1;
|
|
|
|
PF_setorigin, // void(entity e, vector o) setorigin
|
|
|
|
// = #2;
|
|
|
|
PF_setmodel, // void(entity e, string m) setmodel
|
|
|
|
// = #3;
|
|
|
|
PF_setsize, // void(entity e, vector min, vector
|
|
|
|
// max) setsize = #4;
|
|
|
|
PF_Fixme, // void(entity e, vector min, vector
|
|
|
|
// max) setabssize = #5;
|
|
|
|
PF_break, // void() break =
|
|
|
|
// #6;
|
|
|
|
PF_random, // float() random
|
|
|
|
// = #7;
|
|
|
|
PF_sound, // void(entity e, float chan, string
|
|
|
|
// samp) sound = #8;
|
|
|
|
PF_normalize, // vector(vector v) normalize
|
|
|
|
// = #9;
|
|
|
|
PF_error, // void(string e) error =
|
|
|
|
// #10;
|
|
|
|
PF_objerror, // void(string e) objerror
|
|
|
|
// = #11;
|
|
|
|
PF_vlen, // float(vector v) vlen =
|
|
|
|
// #12;
|
|
|
|
PF_vectoyaw, // float(vector v) vectoyaw =
|
|
|
|
// #13;
|
|
|
|
PF_Spawn, // entity() spawn
|
|
|
|
// = #14;
|
|
|
|
PF_Remove, // void(entity e) remove
|
|
|
|
// = #15;
|
|
|
|
PF_traceline, // float(vector v1, vector v2, float
|
|
|
|
// tryents) traceline = #16;
|
|
|
|
PF_checkclient, // entity() clientlist
|
|
|
|
// = #17;
|
|
|
|
PF_Find, // entity(entity start, .string fld,
|
|
|
|
// string match) find = #18;
|
|
|
|
PF_precache_sound, // void(string s) precache_sound
|
|
|
|
// = #19;
|
|
|
|
PF_precache_model, // void(string s) precache_model
|
|
|
|
// = #20;
|
|
|
|
PF_stuffcmd, // void(entity client, string
|
|
|
|
// s)stuffcmd = #21;
|
|
|
|
PF_findradius, // entity(vector org, float rad)
|
|
|
|
// findradius = #22;
|
|
|
|
PF_bprint, // void(string s) bprint
|
|
|
|
// = #23;
|
|
|
|
PF_sprint, // void(entity client, string s)
|
|
|
|
// sprint = #24;
|
|
|
|
PF_dprint, // void(string s) dprint
|
|
|
|
// = #25;
|
|
|
|
PF_ftos, // void(string s) ftos =
|
|
|
|
// #26;
|
|
|
|
PF_vtos, // void(string s) vtos =
|
|
|
|
// #27;
|
|
|
|
PF_coredump,
|
|
|
|
PF_traceon,
|
|
|
|
PF_traceoff,
|
|
|
|
PF_eprint, // void(entity e) debug print an
|
|
|
|
// entire entity
|
|
|
|
PF_walkmove, // float(float yaw, float dist)
|
|
|
|
// walkmove
|
|
|
|
PF_Fixme, // float(float yaw, float dist)
|
|
|
|
// walkmove
|
|
|
|
PF_droptofloor,
|
|
|
|
PF_lightstyle,
|
|
|
|
PF_rint,
|
|
|
|
PF_floor,
|
|
|
|
PF_ceil,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_checkbottom,
|
|
|
|
PF_pointcontents,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_fabs,
|
|
|
|
PF_aim,
|
|
|
|
PF_cvar,
|
|
|
|
PF_localcmd,
|
|
|
|
PF_nextent,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_changeyaw,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_vectoangles,
|
|
|
|
|
|
|
|
PF_WriteByte,
|
|
|
|
PF_WriteChar,
|
|
|
|
PF_WriteShort,
|
|
|
|
PF_WriteLong,
|
|
|
|
PF_WriteCoord,
|
|
|
|
PF_WriteAngle,
|
|
|
|
PF_WriteString,
|
|
|
|
PF_WriteEntity,
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
PF_Fixme,
|
|
|
|
|
|
|
|
SV_MoveToGoal,
|
|
|
|
PF_precache_file,
|
|
|
|
PF_makestatic,
|
|
|
|
|
|
|
|
PF_changelevel,
|
|
|
|
PF_Fixme,
|
|
|
|
|
|
|
|
PF_cvar_set,
|
|
|
|
PF_centerprint,
|
|
|
|
|
|
|
|
PF_ambientsound,
|
|
|
|
|
|
|
|
PF_precache_model,
|
|
|
|
PF_precache_sound, // precache_sound2 is different only
|
|
|
|
// for qcc
|
|
|
|
PF_precache_file,
|
|
|
|
|
|
|
|
PF_setspawnparms,
|
|
|
|
|
|
|
|
PF_logfrag,
|
|
|
|
|
|
|
|
PF_infokey,
|
|
|
|
PF_stof,
|
|
|
|
PF_multicast
|
|
|
|
};
|
2000-05-10 11:29:38 +00:00
|
|
|
|
2000-12-08 06:51:37 +00:00
|
|
|
builtin_t *pr_builtins = pr_builtin;
|
|
|
|
int pr_numbuiltins = sizeof (pr_builtin) / sizeof (pr_builtin[0]);
|