0
0
Fork 0
mirror of https://git.code.sf.net/p/quake/quakeforge synced 2025-04-24 02:22:47 +00:00

merge in my progs work off the `taniwha' branch. This prigs us a few nice

thinks:
  o Full progs modularity
  o CSQC should now be just a matter of creating the builtin functions and
    loading the code.
  o total independence from progs globals, functions and entity field layouts
    on the conditoin that their definitions have not been stripped from the
    progs file.
  o optional (though currently forced on) type checking on access to progs
    entity fields from C
  o the progs engine is fully shared between nq and qw.
This commit is contained in:
Bill Currie 2001-03-04 06:30:30 +00:00
commit cf3629b3b3
49 changed files with 3607 additions and 4728 deletions

View file

@ -1380,6 +1380,7 @@ AC_OUTPUT(
include/Makefile
include/win32/version.h
libs/Makefile
libs/gamecode/Makefile
libs/util/Makefile
qw/include/Makefile
qw/source/Makefile

1
include/.gitignore vendored
View file

@ -1,3 +1,4 @@
.vimrc
Makefile.in
Makefile
config.h.in

View file

@ -33,7 +33,16 @@
#include "qtypes.h"
typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer} etype_t;
typedef enum {
ev_void,
ev_string,
ev_float,
ev_vector,
ev_entity,
ev_field,
ev_func,
ev_pointer
} etype_t;
#define OFS_NULL 0
#define OFS_RETURN 1

View file

@ -29,12 +29,9 @@
#ifndef _PROGS_H
#define _PROGS_H
#include "gcc_attr.h"
#include "protocol.h"
#include "pr_comp.h" // defs shared with qcc
#include "progdefs.h" // generated by program cdefs
#include "link.h"
#include "quakeio.h"
#include "pr_comp.h"
typedef union eval_s
{
@ -49,8 +46,10 @@ typedef union eval_s
typedef union pr_type_u {
float float_var;
int int_var;
string_t string_t_var;
func_t func_t_var;
string_t string_var;
func_t func_var;
int entity_var;
float vector_var[1]; // really 3, but this structure must be 32 bits
} pr_type_t;
#define MAX_ENT_LEAFS 16
@ -62,14 +61,9 @@ typedef struct edict_s
int num_leafs;
short leafnums[MAX_ENT_LEAFS];
entity_state_t baseline;
float freetime; // sv.time when the object was freed
union {
entvars_t v; // C exported fields from progs
pr_type_t vv[1];
} v;
// other fields from progs come immediately after
void *data; // external per-edict data
pr_type_t v[1]; // fields from progs
} edict_t;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
@ -104,6 +98,7 @@ void ED_ParseGlobals (progs_t *pr, char *data);
void ED_LoadFromFile (progs_t *pr, char *data);
ddef_t *ED_FindField (progs_t *pr, char *name);
int ED_GetFieldIndex (progs_t *pr, char *name);
dfunction_t *ED_FindFunction (progs_t *pr, char *name);
@ -128,16 +123,16 @@ int NUM_FOR_EDICT(progs_t *pr, edict_t *e);
#define G_INT(p,o) G_var (p, o, int)
#define G_EDICT(p,o) ((edict_t *)(PR_edicts (p) + G_INT (p, o)))
#define G_EDICTNUM(p,o) NUM_FOR_EDICT(p, G_EDICT(p, o))
#define G_VECTOR(p,o) (&G_FLOAT (p, o))
#define G_STRING(p,o) PR_GetString (p, G_var (p, o, string_t))
#define G_FUNCTION(p,o) G_var (p, o, func_t)
#define G_VECTOR(p,o) G_var (p, o, vector)
#define G_STRING(p,o) PR_GetString (p, G_var (p, o, string))
#define G_FUNCTION(p,o) G_var (p, o, func)
#define E_var(e,o,t) ((e)->v.vv[o].t##_var)
#define E_var(e,o,t) ((e)->v[o].t##_var)
#define E_FLOAT(e,o) E_var (e, o, float)
#define E_INT(e,o) E_var (e, o, int)
#define E_VECTOR(e,o) (&E_FLOAT (e, o))
#define E_STRING(p,e,o) (PR_GetString (p, E_var (e, o, string_t)))
#define E_VECTOR(e,o) E_var (e, o, vector)
#define E_STRING(p,e,o) (PR_GetString (p, E_var (e, o, string)))
extern int type_size[8];
@ -145,14 +140,10 @@ typedef void (*builtin_t) (progs_t *pr);
extern builtin_t *pr_builtins;
extern int pr_numbuiltins;
int FindFieldOffset (progs_t *pr, char *field);
extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC
extern func_t SpectatorConnect;
extern func_t SpectatorThink;
extern func_t SpectatorDisconnect;
ddef_t *PR_FindGlobal (progs_t *pr, const char *name);
eval_t *PR_GetGlobalPointer (progs_t *pr, const char *name);
void PR_Error (progs_t *pr, const char *error, ...) __attribute__((format(printf,2,3)));
void PR_RunError (progs_t *pr, char *error, ...) __attribute__((format(printf,2,3)));
void ED_PrintEdicts (progs_t *pr);
@ -176,8 +167,7 @@ int PR_SetString(progs_t *pr, char *s);
// externaly supplied functions
int ED_Parse_Extra_Fields (progs_t *pr, char *key, char *value);
void FindEdictFieldOffsets (progs_t *pr);
int ED_Prune_Edict (progs_t *pr, edict_t *ent);
//============================================================================
@ -193,14 +183,14 @@ struct progs_s {
dprograms_t *progs;
dfunction_t *pr_functions;
char *pr_strings;
int pr_stringsize;
ddef_t *pr_globaldefs;
ddef_t *pr_fielddefs;
dstatement_t *pr_statements;
globalvars_t *pr_global_struct;
pr_type_t *pr_globals; // same as pr_global_struct
int pr_edict_size; // in bytes
int pr_edictareasize; // LordHavoc: for bounds checking
int pr_edictareasize; // for bounds checking, starts at 0
int pr_argc;
@ -219,13 +209,26 @@ struct progs_s {
edict_t **edicts;
int *num_edicts;
int *reserved_edicts; //alloc will start at reserved_edicts+1
double *time;
int null_bad;
int crc;
unsigned short crc;
void (*unlink)(edict_t *ent);
void (*flush)(void);
// required globals
struct {
float *time;
int *self;
} globals;
// required fields (offsets into the edict)
struct {
int nextthink;
int frame;
int think;
} fields;
};
#endif // _PROGS_H

View file

@ -1,4 +1,4 @@
SUBDIRS= util
SUBDIRS= gamecode util
clean-local:
rm -f *.a

4
libs/gamecode/.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.deps
.vimrc
Makefile.in
Makefile

View file

@ -0,0 +1,8 @@
noinst_LIBRARIES = libqfgamecode.a
libqfgamecode_a_SOURCES = pr_edict.c pr_exec.c
all-local: ../libqfgamecode.a
../libqfgamecode.a: libqfgamecode.a
cp $(noinst_LIBRARIES) ..

View file

@ -44,24 +44,25 @@
#include "qdefs.h"
#include "qendian.h"
#include "quakefs.h"
#include "server.h"
#include "world.h"
#include "sys.h" //XXX
#include "zone.h"
#include "va.h"
cvar_t *pr_boundscheck;
cvar_t *pr_boundscheck;
int type_size[8] = {
int type_size[8] = {
1,
sizeof (void *) / 4,
sizeof (string_t) / 4,
1,
3,
1,
1,
sizeof (void *) / 4,
sizeof (func_t) / 4,
sizeof (void *) / 4
};
ddef_t *ED_FieldAtOfs (progs_t *pr, int ofs);
qboolean ED_ParseEpair (progs_t *pr, void *base, ddef_t *key, char *s);
ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs);
qboolean ED_ParseEpair (progs_t * pr, pr_type_t *base, ddef_t *key, char *s);
#define MAX_FIELD_LEN 64
#define GEFV_CACHESIZE 2
@ -79,8 +80,10 @@ static gefv_cache gefvCache[GEFV_CACHESIZE] = { {NULL, ""}, {NULL, ""} };
Sets everything to NULL
*/
void
ED_ClearEdict (progs_t *pr, edict_t *e)
ED_ClearEdict (progs_t * pr, edict_t *e)
{
if (NUM_FOR_EDICT(pr,e)<*pr->reserved_edicts)
printf("clearing reserved edict %d\n", NUM_FOR_EDICT(pr,e));
memset (&e->v, 0, pr->progs->entityfields * 4);
e->free = false;
}
@ -94,13 +97,15 @@ ED_ClearEdict (progs_t *pr, edict_t *e)
instead of being removed and recreated, which can cause interpolated
angles and bad trails.
*/
edict_t *
ED_Alloc (progs_t *pr)
edict_t *
ED_Alloc (progs_t * pr)
{
int i;
edict_t *e;
int start = pr->reserved_edicts ? *pr->reserved_edicts : 0;
int max_edicts = pr->pr_edictareasize / pr->pr_edict_size;
for (i = MAX_CLIENTS + 1; i < *(pr)->num_edicts; i++) {
for (i = start + 1; i < *(pr)->num_edicts; i++) {
e = EDICT_NUM (pr, i);
// the first couple seconds of server time can involve a lot of
// freeing and allocating, so relax the replacement policy
@ -110,7 +115,7 @@ ED_Alloc (progs_t *pr)
}
}
if (i == MAX_EDICTS) {
if (i == max_edicts) {
Con_Printf ("WARNING: ED_Alloc: no free edicts\n");
i--; // step on whatever is the last edict
e = EDICT_NUM (pr, i);
@ -131,23 +136,13 @@ ED_Alloc (progs_t *pr)
FIXME: walk all entities and NULL out references to this entity
*/
void
ED_Free (progs_t *pr, edict_t *ed)
ED_Free (progs_t * pr, edict_t *ed)
{
if (pr->unlink)
pr->unlink (ed); // unlink from world bsp
ED_ClearEdict (pr, ed);
ed->free = true;
ed->v.v.model = 0;
ed->v.v.takedamage = 0;
ed->v.v.modelindex = 0;
ed->v.v.colormap = 0;
ed->v.v.skin = 0;
ed->v.v.frame = 0;
VectorCopy (vec3_origin, ed->v.v.origin);
VectorCopy (vec3_origin, ed->v.v.angles);
ed->v.v.nextthink = -1;
ed->v.v.solid = 0;
ed->freetime = *(pr)->time;
}
@ -156,8 +151,8 @@ ED_Free (progs_t *pr, edict_t *ed)
/*
ED_GlobalAtOfs
*/
ddef_t *
ED_GlobalAtOfs (progs_t *pr, int ofs)
ddef_t *
ED_GlobalAtOfs (progs_t * pr, int ofs)
{
ddef_t *def;
int i;
@ -173,8 +168,8 @@ ED_GlobalAtOfs (progs_t *pr, int ofs)
/*
ED_FieldAtOfs
*/
ddef_t *
ED_FieldAtOfs (progs_t *pr, int ofs)
ddef_t *
ED_FieldAtOfs (progs_t * pr, int ofs)
{
ddef_t *def;
int i;
@ -190,8 +185,8 @@ ED_FieldAtOfs (progs_t *pr, int ofs)
/*
ED_FindField
*/
ddef_t *
ED_FindField (progs_t *pr, char *name)
ddef_t *
ED_FindField (progs_t * pr, char *name)
{
ddef_t *def;
int i;
@ -204,12 +199,22 @@ ED_FindField (progs_t *pr, char *name)
return NULL;
}
int
ED_GetFieldIndex (progs_t *pr, char *name)
{
ddef_t *def;
def = ED_FindField (pr, name);
if (def)
return def->ofs;
return -1;
}
/*
ED_FindGlobal
PR_FindGlobal
*/
ddef_t *
ED_FindGlobal (progs_t *pr, char *name)
ddef_t *
PR_FindGlobal (progs_t * pr, const char *name)
{
ddef_t *def;
int i;
@ -222,12 +227,23 @@ ED_FindGlobal (progs_t *pr, char *name)
return NULL;
}
eval_t *
PR_GetGlobalPointer (progs_t *pr, const char *name)
{
ddef_t *def;
def = PR_FindGlobal (pr, name);
if (def)
return (eval_t*)&pr->pr_globals[def->ofs];
return 0;
}
/*
ED_FindFunction
*/
dfunction_t *
ED_FindFunction (progs_t *pr, char *name)
ED_FindFunction (progs_t * pr, char *name)
{
dfunction_t *func;
int i;
@ -240,8 +256,8 @@ ED_FindFunction (progs_t *pr, char *name)
return NULL;
}
eval_t *
GetEdictFieldValue (progs_t *pr, edict_t *ed, char *field)
eval_t *
GetEdictFieldValue (progs_t * pr, edict_t *ed, char *field)
{
ddef_t *def = NULL;
int i;
@ -274,8 +290,8 @@ GetEdictFieldValue (progs_t *pr, edict_t *ed, char *field)
Returns a string describing *data in a type specific manner
*/
char *
PR_ValueString (progs_t *pr, etype_t type, eval_t *val)
char *
PR_ValueString (progs_t * pr, etype_t type, pr_type_t *val)
{
static char line[256];
ddef_t *def;
@ -285,29 +301,32 @@ PR_ValueString (progs_t *pr, etype_t type, eval_t *val)
switch (type) {
case ev_string:
snprintf (line, sizeof (line), "%s", PR_GetString (pr, val->string));
snprintf (line, sizeof (line), "%s",
PR_GetString (pr, val->string_var));
break;
case ev_entity:
snprintf (line, sizeof (line), "entity %i",
NUM_FOR_EDICT (pr, PROG_TO_EDICT (pr, val->edict)));
NUM_FOR_EDICT (pr, PROG_TO_EDICT (pr, val->entity_var)));
break;
case ev_function:
f = pr->pr_functions + val->function;
snprintf (line, sizeof (line), "%s()", PR_GetString (pr, f->s_name));
case ev_func:
f = pr->pr_functions + val->func_var;
snprintf (line, sizeof (line), "%s()",
PR_GetString (pr, f->s_name));
break;
case ev_field:
def = ED_FieldAtOfs (pr, val->_int);
snprintf (line, sizeof (line), ".%s", PR_GetString (pr, def->s_name));
def = ED_FieldAtOfs (pr, val->int_var);
snprintf (line, sizeof (line), ".%s",
PR_GetString (pr, def->s_name));
break;
case ev_void:
strcpy (line, "void");
break;
case ev_float:
snprintf (line, sizeof (line), "%5.1f", val->_float);
snprintf (line, sizeof (line), "%5.1f", val->float_var);
break;
case ev_vector:
snprintf (line, sizeof (line), "'%5.1f %5.1f %5.1f'",
val->vector[0], val->vector[1], val->vector[2]);
val->vector_var[0], val->vector_var[1], val->vector_var[2]);
break;
case ev_pointer:
strcpy (line, "pointer");
@ -326,8 +345,8 @@ PR_ValueString (progs_t *pr, etype_t type, eval_t *val)
Returns a string describing *data in a type specific manner
Easier to parse than PR_ValueString
*/
char *
PR_UglyValueString (progs_t *pr, etype_t type, eval_t *val)
char *
PR_UglyValueString (progs_t * pr, etype_t type, eval_t *val)
{
static char line[256];
ddef_t *def;
@ -337,19 +356,21 @@ PR_UglyValueString (progs_t *pr, etype_t type, eval_t *val)
switch (type) {
case ev_string:
snprintf (line, sizeof (line), "%s", PR_GetString (pr, val->string));
snprintf (line, sizeof (line), "%s",
PR_GetString (pr, val->string));
break;
case ev_entity:
snprintf (line, sizeof (line), "%i",
NUM_FOR_EDICT (pr, PROG_TO_EDICT (pr, val->edict)));
break;
case ev_function:
case ev_func:
f = pr->pr_functions + val->function;
snprintf (line, sizeof (line), "%s", PR_GetString (pr, f->s_name));
break;
case ev_field:
def = ED_FieldAtOfs (pr, val->_int);
snprintf (line, sizeof (line), "%s", PR_GetString (pr, def->s_name));
snprintf (line, sizeof (line), "%s",
PR_GetString (pr, def->s_name));
break;
case ev_void:
strcpy (line, "void");
@ -375,8 +396,8 @@ PR_UglyValueString (progs_t *pr, etype_t type, eval_t *val)
Returns a string with a description and the contents of a global,
padded to 20 field width
*/
char *
PR_GlobalString (progs_t *pr, int ofs)
char *
PR_GlobalString (progs_t * pr, int ofs)
{
char *s;
int i;
@ -402,8 +423,8 @@ PR_GlobalString (progs_t *pr, int ofs)
return line;
}
char *
PR_GlobalStringNoContents (progs_t *pr, int ofs)
char *
PR_GlobalStringNoContents (progs_t * pr, int ofs)
{
int i;
ddef_t *def;
@ -431,11 +452,11 @@ PR_GlobalStringNoContents (progs_t *pr, int ofs)
For debugging
*/
void
ED_Print (progs_t *pr, edict_t *ed)
ED_Print (progs_t * pr, edict_t *ed)
{
int l;
ddef_t *d;
int *v;
pr_type_t *v;
int i, j;
char *name;
int type;
@ -445,19 +466,20 @@ ED_Print (progs_t *pr, edict_t *ed)
return;
}
Con_Printf ("\nEDICT %i:\n", NUM_FOR_EDICT (pr, ed));
for (i = 1; i < pr->progs->numfielddefs; i++) {
d = &pr->pr_fielddefs[i];
name = PR_GetString (pr, d->s_name);
if (name[strlen (name) - 2] == '_')
continue; // skip _x, _y, _z vars
v = (int *) ((char *) &ed->v + d->ofs * 4);
v = ed->v + d->ofs;
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
for (j = 0; j < type_size[type]; j++)
if (v[j])
if (v[j].int_var)
break;
if (j == type_size[type])
continue;
@ -467,7 +489,7 @@ ED_Print (progs_t *pr, edict_t *ed)
while (l++ < 15)
Con_Printf (" ");
Con_Printf ("%s\n", PR_ValueString (pr, d->type, (eval_t *) v));
Con_Printf ("%s\n", PR_ValueString (pr, d->type, v));
}
}
@ -477,7 +499,7 @@ ED_Print (progs_t *pr, edict_t *ed)
For savegames
*/
void
ED_Write (progs_t *pr, QFile *f, edict_t *ed)
ED_Write (progs_t * pr, QFile *f, edict_t *ed)
{
ddef_t *d;
int *v;
@ -516,7 +538,7 @@ ED_Write (progs_t *pr, QFile *f, edict_t *ed)
}
void
ED_PrintNum (progs_t *pr, int ent)
ED_PrintNum (progs_t * pr, int ent)
{
ED_Print (pr, EDICT_NUM (pr, ent));
}
@ -527,7 +549,7 @@ ED_PrintNum (progs_t *pr, int ent)
For debugging, prints all the entities in the current server
*/
void
ED_PrintEdicts (progs_t *pr)
ED_PrintEdicts (progs_t * pr)
{
int i;
@ -544,31 +566,32 @@ ED_PrintEdicts (progs_t *pr)
For debugging
*/
void
ED_Count (progs_t *pr)
ED_Count (progs_t * pr)
{
int i;
edict_t *ent;
int active, models, solid, step;
ddef_t *solid_def;
ddef_t *model_def;
solid_def = ED_FindField (pr, "solid");
model_def = ED_FindField (pr, "model");
active = models = solid = step = 0;
for (i = 0; i < *(pr)->num_edicts; i++) {
ent = EDICT_NUM (pr, i);
if (ent->free)
continue;
active++;
if (ent->v.v.solid)
if (solid_def && ent->v[solid_def->ofs].float_var)
solid++;
if (ent->v.v.model)
if (model_def && ent->v[model_def->ofs].float_var)
models++;
if (ent->v.v.movetype == MOVETYPE_STEP)
step++;
}
Con_Printf ("num_edicts:%3i\n", *(pr)->num_edicts);
Con_Printf ("active :%3i\n", active);
Con_Printf ("view :%3i\n", models);
Con_Printf ("touch :%3i\n", solid);
Con_Printf ("step :%3i\n", step);
}
@ -582,7 +605,7 @@ ED_Count (progs_t *pr)
ED_WriteGlobals
*/
void
ED_WriteGlobals (progs_t *pr, QFile *f)
ED_WriteGlobals (progs_t * pr, QFile *f)
{
ddef_t *def;
int i;
@ -603,7 +626,8 @@ ED_WriteGlobals (progs_t *pr, QFile *f)
name = PR_GetString (pr, def->s_name);
Qprintf (f, "\"%s\" ", name);
Qprintf (f, "\"%s\"\n",
PR_UglyValueString (pr, type, (eval_t *) &pr->pr_globals[def->ofs]));
PR_UglyValueString (pr, type,
(eval_t *) &pr->pr_globals[def->ofs]));
}
Qprintf (f, "}\n");
}
@ -612,7 +636,7 @@ ED_WriteGlobals (progs_t *pr, QFile *f)
ED_ParseGlobals
*/
void
ED_ParseGlobals (progs_t *pr, char *data)
ED_ParseGlobals (progs_t * pr, char *data)
{
char keyname[64];
ddef_t *key;
@ -623,26 +647,26 @@ ED_ParseGlobals (progs_t *pr, char *data)
if (com_token[0] == '}')
break;
if (!data)
SV_Error ("ED_ParseEntity: EOF without closing brace");
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
strcpy (keyname, com_token);
// parse value
data = COM_Parse (data);
if (!data)
SV_Error ("ED_ParseEntity: EOF without closing brace");
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
SV_Error ("ED_ParseEntity: closing brace without data");
PR_Error (pr, "ED_ParseEntity: closing brace without data");
key = ED_FindGlobal (pr, keyname);
key = PR_FindGlobal (pr, keyname);
if (!key) {
Con_Printf ("%s is not a global\n", keyname);
Con_Printf ("'%s' is not a global\n", keyname);
continue;
}
if (!ED_ParseEpair (pr, (void *) pr->pr_globals, key, com_token))
SV_Error ("ED_ParseGlobals: parse error");
if (!ED_ParseEpair (pr, pr->pr_globals, key, com_token))
PR_Error (pr, "ED_ParseGlobals: parse error");
}
}
@ -652,8 +676,8 @@ ED_ParseGlobals (progs_t *pr, char *data)
/*
ED_NewString
*/
char *
ED_NewString (progs_t *pr, char *string)
char *
ED_NewString (progs_t * pr, char *string)
{
char *new, *new_p;
int i, l;
@ -684,24 +708,24 @@ ED_NewString (progs_t *pr, char *string)
returns false if error
*/
qboolean
ED_ParseEpair (progs_t *pr, void *base, ddef_t *key, char *s)
ED_ParseEpair (progs_t * pr, pr_type_t *base, ddef_t *key, char *s)
{
int i;
char string[128];
ddef_t *def;
char *v, *w;
void *d;
eval_t *d;
dfunction_t *func;
d = (void *) ((int *) base + key->ofs);
d = (eval_t*)&base[key->ofs];
switch (key->type & ~DEF_SAVEGLOBAL) {
case ev_string:
*(string_t *) d = PR_SetString (pr, ED_NewString (pr, s));
d->string = PR_SetString (pr, ED_NewString (pr, s));
break;
case ev_float:
*(float *) d = atof (s);
d->_float = atof (s);
break;
case ev_vector:
@ -712,13 +736,13 @@ ED_ParseEpair (progs_t *pr, void *base, ddef_t *key, char *s)
while (*v && *v != ' ')
v++;
*v = 0;
((float *) d)[i] = atof (w);
d->vector[i] = atof (w);
w = v = v + 1;
}
break;
case ev_entity:
*(int *) d = EDICT_TO_PROG (pr, EDICT_NUM (pr, atoi (s)));
d->edict = EDICT_TO_PROG (pr, EDICT_NUM (pr, atoi (s)));
break;
case ev_field:
@ -727,16 +751,16 @@ ED_ParseEpair (progs_t *pr, void *base, ddef_t *key, char *s)
Con_Printf ("Can't find field %s\n", s);
return false;
}
*(int *) d = G_INT (pr, def->ofs);
d->_int = G_INT (pr, def->ofs);
break;
case ev_function:
case ev_func:
func = ED_FindFunction (pr, s);
if (!func) {
Con_Printf ("Can't find function %s\n", s);
return false;
}
*(func_t *) d = func - pr->pr_functions;
d->function = func - pr->pr_functions;
break;
default:
@ -752,18 +776,19 @@ ED_ParseEpair (progs_t *pr, void *base, ddef_t *key, char *s)
ed should be a properly initialized empty edict.
Used for initial level load and for savegames.
*/
char *
ED_ParseEdict (progs_t *pr, char *data, edict_t *ent)
char *
ED_ParseEdict (progs_t * pr, char *data, edict_t *ent)
{
ddef_t *key;
qboolean anglehack;
qboolean init;
char keyname[256];
int n;
init = false;
// clear it
if (ent != *(pr)->edicts) // hack
if (ent != *(pr)->edicts) // hack
memset (&ent->v, 0, pr->progs->entityfields * 4);
// go through all the dictionary pairs
@ -773,7 +798,7 @@ ED_ParseEdict (progs_t *pr, char *data, edict_t *ent)
if (com_token[0] == '}')
break;
if (!data)
SV_Error ("ED_ParseEntity: EOF without closing brace");
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
// anglehack is to allow QuakeEd to write single scalar angles
// and allow them to be turned into vectors. (FIXME...)
@ -789,13 +814,20 @@ ED_ParseEdict (progs_t *pr, char *data, edict_t *ent)
strcpy (keyname, com_token);
// another hack to fix heynames with trailing spaces
n = strlen (keyname);
while (n && keyname[n - 1] == ' ') {
keyname[n - 1] = 0;
n--;
}
// parse value
data = COM_Parse (data);
if (!data)
SV_Error ("ED_ParseEntity: EOF without closing brace");
PR_Error (pr, "ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
SV_Error ("ED_ParseEntity: closing brace without data");
PR_Error (pr, "ED_ParseEntity: closing brace without data");
init = true;
@ -807,20 +839,19 @@ ED_ParseEdict (progs_t *pr, char *data, edict_t *ent)
key = ED_FindField (pr, keyname);
if (!key) {
if (!ED_Parse_Extra_Fields (pr, keyname, com_token)) {
Con_Printf ("%s is not a field\n", keyname);
Con_Printf ("'%s' is not a field\n", keyname);
continue;
}
} else {
int ret;
if (anglehack) {
char temp[32];
strncpy (temp, com_token, sizeof (temp));
temp[sizeof (temp) - 1] = 0;
snprintf (com_token, sizeof (com_token), "0 %s 0", temp);
ret = ED_ParseEpair (pr, ent->v, key, va ("0 %s 0", com_token));
} else {
ret = ED_ParseEpair (pr, ent->v, key, com_token);
}
if (!ED_ParseEpair (pr, (void *) &ent->v, key, com_token))
SV_Error ("ED_ParseEdict: parse error");
if (!ret)
PR_Error (pr, "ED_ParseEdict: parse error");
}
}
@ -845,24 +876,27 @@ ED_ParseEdict (progs_t *pr, char *data, edict_t *ent)
to call ED_CallSpawnFunctions () to let the objects initialize themselves.
*/
void
ED_LoadFromFile (progs_t *pr, char *data)
ED_LoadFromFile (progs_t * pr, char *data)
{
edict_t *ent;
int inhibit;
dfunction_t *func;
eval_t *classname;
ddef_t *def;
ent = NULL;
inhibit = 0;
pr->pr_global_struct->time = *(pr)->time;
// parse ents
*pr->globals.time = *(pr)->time;
// parse ents
while (1) {
// parse the opening brace
// parse the opening brace
data = COM_Parse (data);
if (!data)
break;
if (com_token[0] != '{')
SV_Error ("ED_LoadFromFile: found %s when expecting {", com_token);
PR_Error (pr, "ED_LoadFromFile: found %s when expecting {", com_token);
if (!ent)
ent = EDICT_NUM (pr, 0);
@ -870,23 +904,25 @@ ED_LoadFromFile (progs_t *pr, char *data)
ent = ED_Alloc (pr);
data = ED_ParseEdict (pr, data, ent);
// remove things from different skill levels or deathmatch
if (((int) ent->v.v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) {
// remove things from different skill levels or deathmatch
if (ED_Prune_Edict (pr, ent)) {
ED_Free (pr, ent);
inhibit++;
continue;
}
//
// immediately call spawn function
//
if (!ent->v.v.classname) {
//
// immediately call spawn function
//
def = ED_FindField (pr, "classname");
if (!def) {
Con_Printf ("No classname for:\n");
ED_Print (pr, ent);
ED_Free (pr, ent);
continue;
}
classname = (eval_t*)&ent->v[def->ofs];
// look for the spawn function
func = ED_FindFunction (pr, PR_GetString (pr, ent->v.v.classname));
func = ED_FindFunction (pr, PR_GetString (pr, classname->string));
if (!func) {
Con_Printf ("No spawn function for:\n");
@ -895,7 +931,7 @@ ED_LoadFromFile (progs_t *pr, char *data)
continue;
}
pr->pr_global_struct->self = EDICT_TO_PROG (pr, ent);
*pr->globals.self = EDICT_TO_PROG (pr, ent);
PR_ExecuteProgram (pr, func - pr->pr_functions);
if (pr->flush)
pr->flush ();
@ -908,7 +944,7 @@ ED_LoadFromFile (progs_t *pr, char *data)
PR_LoadProgs
*/
void
PR_LoadProgs (progs_t *pr, char *progsname)
PR_LoadProgs (progs_t * pr, char *progsname)
{
int i;
dstatement_t *st;
@ -923,35 +959,38 @@ PR_LoadProgs (progs_t *pr, char *progsname)
Con_DPrintf ("Programs occupy %iK.\n", com_filesize / 1024);
// store prog crc
// store prog crc
pr->crc = CRC_Block ((byte *) pr->progs, com_filesize);
// byte swap the header
// byte swap the header
for (i = 0; i < sizeof (*pr->progs) / 4; i++)
((int *) pr->progs)[i] = LittleLong (((int *) pr->progs)[i]);
if (pr->progs->version != PROG_VERSION)
SV_Error ("progs.dat has wrong version number (%i should be %i)",
pr->progs->version, PROG_VERSION);
if (pr->progs->crc != PROGHEADER_CRC)
SV_Error ("You must have the qwprogs.dat from QuakeWorld installed");
PR_Error (pr, "%s has wrong version number (%i should be %i)",
progsname, pr->progs->version, PROG_VERSION);
pr->pr_functions = (dfunction_t *) ((byte *) pr->progs + pr->progs->ofs_functions);
pr->pr_functions =
(dfunction_t *) ((byte *) pr->progs + pr->progs->ofs_functions);
pr->pr_strings = (char *) pr->progs + pr->progs->ofs_strings;
pr->pr_globaldefs = (ddef_t *) ((byte *) pr->progs + pr->progs->ofs_globaldefs);
pr->pr_fielddefs = (ddef_t *) ((byte *) pr->progs + pr->progs->ofs_fielddefs);
pr->pr_statements = (dstatement_t *) ((byte *) pr->progs + pr->progs->ofs_statements);
pr->pr_stringsize = LittleLong (pr->progs->numstrings);
pr->pr_globaldefs =
(ddef_t *) ((byte *) pr->progs + pr->progs->ofs_globaldefs);
pr->pr_fielddefs =
(ddef_t *) ((byte *) pr->progs + pr->progs->ofs_fielddefs);
pr->pr_statements =
(dstatement_t *) ((byte *) pr->progs + pr->progs->ofs_statements);
pr->num_prstr = 0;
pr->pr_global_struct = (globalvars_t *) ((byte *) pr->progs + pr->progs->ofs_globals);
pr->pr_globals = (pr_type_t *) pr->pr_global_struct;
pr->pr_globals =
(pr_type_t *) ((byte *) pr->progs + pr->progs->ofs_globals);
pr->pr_edict_size =
pr->progs->entityfields * 4 + sizeof (edict_t) - sizeof (entvars_t);
pr->progs->entityfields * 4 + sizeof (edict_t) - sizeof (pr_type_t);
pr->pr_edictareasize = pr->pr_edict_size * MAX_EDICTS;
pr->pr_edictareasize = 0;
// byte swap the lumps
for (i = 0; i < pr->progs->numstatements; i++) {
@ -964,10 +1003,12 @@ PR_LoadProgs (progs_t *pr, char *progsname)
for (i = 0; i < pr->progs->numfunctions; i++) {
pr->pr_functions[i].first_statement =
LittleLong (pr->pr_functions[i].first_statement);
pr->pr_functions[i].parm_start = LittleLong (pr->pr_functions[i].parm_start);
pr->pr_functions[i].parm_start =
LittleLong (pr->pr_functions[i].parm_start);
pr->pr_functions[i].s_name = LittleLong (pr->pr_functions[i].s_name);
pr->pr_functions[i].s_file = LittleLong (pr->pr_functions[i].s_file);
pr->pr_functions[i].numparms = LittleLong (pr->pr_functions[i].numparms);
pr->pr_functions[i].numparms =
LittleLong (pr->pr_functions[i].numparms);
pr->pr_functions[i].locals = LittleLong (pr->pr_functions[i].locals);
}
@ -980,7 +1021,7 @@ PR_LoadProgs (progs_t *pr, char *progsname)
for (i = 0; i < pr->progs->numfielddefs; i++) {
pr->pr_fielddefs[i].type = LittleShort (pr->pr_fielddefs[i].type);
if (pr->pr_fielddefs[i].type & DEF_SAVEGLOBAL)
SV_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
PR_Error (pr, "PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL");
pr->pr_fielddefs[i].ofs = LittleShort (pr->pr_fielddefs[i].ofs);
pr->pr_fielddefs[i].s_name = LittleLong (pr->pr_fielddefs[i].s_name);
}
@ -988,24 +1029,32 @@ PR_LoadProgs (progs_t *pr, char *progsname)
for (i = 0; i < pr->progs->numglobals; i++)
((int *) pr->pr_globals)[i] = LittleLong (((int *) pr->pr_globals)[i]);
// LordHavoc: Ender added this
FindEdictFieldOffsets (pr);
if (!(pr->globals.time = (float*)PR_GetGlobalPointer (pr, "time")))
PR_Error (pr, "%s: undefined symbol: time", progsname);
if (!(pr->globals.self = (int*)PR_GetGlobalPointer (pr, "self")))
PR_Error (pr, "%s: undefined symbol: self", progsname);
if ((pr->fields.nextthink = ED_GetFieldIndex (pr, "nextthink")) == -1)
PR_Error (pr, "%s: undefined field: nextthink", progsname);
if ((pr->fields.frame = ED_GetFieldIndex (pr, "frame")) == -1)
PR_Error (pr, "%s: undefined field: frame", progsname);
if ((pr->fields.think = ED_GetFieldIndex (pr, "think")) == -1)
PR_Error (pr, "%s: undefined field: think", progsname);
// LordHavoc: bounds check anything static
for (i = 0, st = pr->pr_statements; i < pr->progs->numstatements; i++, st++) {
switch (st->op) {
case OP_IF:
case OP_IFNOT:
if ((unsigned short) st->a >= pr->progs->numglobals || st->b + i < 0
|| st->b + i >= pr->progs->numstatements)
SV_Error
("PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n",
if ((unsigned short) st->a >= pr->progs->numglobals
|| st->b + i < 0 || st->b + i >= pr->progs->numstatements)
PR_Error
(pr, "PR_LoadProgs: out of bounds IF/IFNOT (statement %d)\n",
i);
break;
case OP_GOTO:
if (st->a + i < 0 || st->a + i >= pr->progs->numstatements)
SV_Error
("PR_LoadProgs: out of bounds GOTO (statement %d)\n",
PR_Error
(pr, "PR_LoadProgs: out of bounds GOTO (statement %d)\n",
i);
break;
// global global global
@ -1046,8 +1095,8 @@ PR_LoadProgs (progs_t *pr, char *progsname)
if ((unsigned short) st->a >= pr->progs->numglobals
|| (unsigned short) st->b >= pr->progs->numglobals
|| (unsigned short) st->c >= pr->progs->numglobals)
SV_Error
("PR_LoadProgs: out of bounds global index (statement %d)\n",
PR_Error
(pr, "PR_LoadProgs: out of bounds global index (statement %d)\n",
i);
break;
// global none global
@ -1058,8 +1107,8 @@ PR_LoadProgs (progs_t *pr, char *progsname)
case OP_NOT_ENT:
if ((unsigned short) st->a >= pr->progs->numglobals
|| (unsigned short) st->c >= pr->progs->numglobals)
SV_Error
("PR_LoadProgs: out of bounds global index (statement %d)\n",
PR_Error
(pr, "PR_LoadProgs: out of bounds global index (statement %d)\n",
i);
break;
// 2 globals
@ -1078,8 +1127,8 @@ PR_LoadProgs (progs_t *pr, char *progsname)
case OP_STORE_V:
if ((unsigned short) st->a >= pr->progs->numglobals
|| (unsigned short) st->b >= pr->progs->numglobals)
SV_Error
("PR_LoadProgs: out of bounds global index (statement %d)\n",
PR_Error
(pr, "PR_LoadProgs: out of bounds global index (statement %d)\n",
i);
break;
// 1 global
@ -1095,19 +1144,16 @@ PR_LoadProgs (progs_t *pr, char *progsname)
case OP_DONE:
case OP_RETURN:
if ((unsigned short) st->a >= pr->progs->numglobals)
SV_Error
("PR_LoadProgs: out of bounds global index (statement %d)\n",
PR_Error
(pr, "PR_LoadProgs: out of bounds global index (statement %d)\n",
i);
break;
default:
SV_Error ("PR_LoadProgs: unknown opcode %d at statement %d\n",
PR_Error (pr, "PR_LoadProgs: unknown opcode %d at statement %d\n",
st->op, i);
break;
}
}
FindEdictFieldOffsets (pr); // LordHavoc: update field offset
// list
}
void
@ -1123,23 +1169,37 @@ PR_Init (void)
{
}
edict_t *
EDICT_NUM (progs_t *pr, int n)
edict_t *
EDICT_NUM (progs_t * pr, int n)
{
if (n < 0 || n >= MAX_EDICTS)
SV_Error ("EDICT_NUM: bad number %i", n);
return (edict_t *) ((byte *) *(pr)->edicts + (n) * pr->pr_edict_size);
int offs = n * pr->pr_edict_size;
if (offs < 0 || n >= pr->pr_edictareasize)
PR_Error (pr, "EDICT_NUM: bad number %i", n);
return PROG_TO_EDICT (pr, offs);
}
int
NUM_FOR_EDICT (progs_t *pr, edict_t *e)
NUM_FOR_EDICT (progs_t * pr, edict_t *e)
{
int b;
b = (byte *) e - (byte *) *(pr)->edicts;
b = (byte *) e - (byte *) * (pr)->edicts;
b = b / pr->pr_edict_size;
if (b < 0 || b >= *(pr)->num_edicts)
SV_Error ("NUM_FOR_EDICT: bad pointer");
PR_Error (pr, "NUM_FOR_EDICT: bad pointer");
return b;
}
void
PR_Error (progs_t *pr, const char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, error);
vsnprintf (string, sizeof (string), error, argptr);
va_end (argptr);
Sys_Error ("%s", string);
}

View file

@ -41,7 +41,6 @@
#include "console.h"
#include "cvar.h"
#include "progs.h"
#include "server.h"
#include "sys.h"
char *pr_opnames[] = {
@ -138,7 +137,7 @@ char *pr_opnames[] = {
PR_PrintStatement
*/
void
PR_PrintStatement (progs_t *pr, dstatement_t *s)
PR_PrintStatement (progs_t * pr, dstatement_t *s)
{
int i;
@ -156,7 +155,8 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s)
Con_Printf ("branch %i", s->a);
} else if ((unsigned int) (s->op - OP_STORE_F) < 6) {
Con_Printf ("%s", PR_GlobalString (pr, (unsigned short) s->a));
Con_Printf ("%s", PR_GlobalStringNoContents (pr, (unsigned short) s->b));
Con_Printf ("%s",
PR_GlobalStringNoContents (pr, (unsigned short) s->b));
} else {
if (s->a)
Con_Printf ("%s", PR_GlobalString (pr, (unsigned short) s->a));
@ -173,7 +173,7 @@ PR_PrintStatement (progs_t *pr, dstatement_t *s)
PR_StackTrace
*/
void
PR_StackTrace (progs_t *pr)
PR_StackTrace (progs_t * pr)
{
dfunction_t *f;
int i;
@ -200,7 +200,7 @@ PR_StackTrace (progs_t *pr)
PR_Profile
*/
void
PR_Profile (progs_t *pr)
PR_Profile (progs_t * pr)
{
dfunction_t *f, *best;
int max;
@ -234,7 +234,7 @@ PR_Profile (progs_t *pr)
Aborts the currently executing function
*/
void
PR_RunError (progs_t *pr, char *error, ...)
PR_RunError (progs_t * pr, char *error, ...)
{
va_list argptr;
char string[1024];
@ -247,10 +247,10 @@ PR_RunError (progs_t *pr, char *error, ...)
PR_StackTrace (pr);
Con_Printf ("%s\n", string);
pr->pr_depth = 0; // dump the stack so SV_Error can
// shutdown functions
pr->pr_depth = 0; // dump the stack so PR_Error can
// shutdown functions
SV_Error ("Program error");
PR_Error (pr, "Program error");
}
/*
@ -265,10 +265,11 @@ PR_RunError (progs_t *pr, char *error, ...)
Returns the new program statement counter
*/
int
PR_EnterFunction (progs_t *pr, dfunction_t *f)
PR_EnterFunction (progs_t * pr, dfunction_t *f)
{
int i, j, c, o;
//printf("%s:\n", PR_GetString(pr,f->s_name));
pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement;
pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction;
pr->pr_depth++;
@ -289,7 +290,9 @@ PR_EnterFunction (progs_t *pr, dfunction_t *f)
o = f->parm_start;
for (i = 0; i < f->numparms; i++) {
for (j = 0; j < f->parm_size[i]; j++) {
((int *) pr->pr_globals)[o] = ((int *) pr->pr_globals)[OFS_PARM0 + i * 3 + j];
((int *) pr->pr_globals)[o] =
((int *) pr->pr_globals)[OFS_PARM0 + i * 3 + j];
o++;
}
}
@ -302,12 +305,12 @@ PR_EnterFunction (progs_t *pr, dfunction_t *f)
PR_LeaveFunction
*/
int
PR_LeaveFunction (progs_t *pr)
PR_LeaveFunction (progs_t * pr)
{
int i, c;
if (pr->pr_depth <= 0)
SV_Error ("prog stack underflow");
PR_Error (pr, "prog stack underflow");
// restore locals from the stack
c = pr->pr_xfunction->locals;
@ -330,15 +333,17 @@ PR_LeaveFunction (progs_t *pr)
/*
PR_ExecuteProgram
*/
// LordHavoc: optimized
#define OPA ((eval_t *)&pr->pr_globals[(unsigned short) st->a])
#define OPB ((eval_t *)&pr->pr_globals[(unsigned short) st->b])
#define OPC ((eval_t *)&pr->pr_globals[(unsigned short) st->c])
#define OPA (pr->pr_globals[(unsigned short) st->a])
#define OPB (pr->pr_globals[(unsigned short) st->b])
#define OPC (pr->pr_globals[(unsigned short) st->c])
#define E_OPA ((eval_t *)&OPA)
#define E_OPB ((eval_t *)&OPB)
#define E_OPC ((eval_t *)&OPC)
extern cvar_t *pr_boundscheck;
void
PR_ExecuteProgram (progs_t *pr, func_t fnum)
PR_ExecuteProgram (progs_t * pr, func_t fnum)
{
dstatement_t *st;
dfunction_t *f, *newf;
@ -348,12 +353,13 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
int profile, startprofile;
if (!fnum || fnum >= pr->progs->numfunctions) {
if (pr->pr_global_struct->self)
ED_Print (pr, PROG_TO_EDICT (pr, pr->pr_global_struct->self));
SV_Error ("PR_ExecuteProgram: NULL function");
if (*pr->globals.self)
ED_Print (pr, PROG_TO_EDICT (pr, *pr->globals.self));
PR_Error (pr, "PR_ExecuteProgram: NULL function");
}
f = &pr->pr_functions[fnum];
//printf("%s:\n", PR_GetString(pr,f->s_name));
pr->pr_trace = false;
@ -377,134 +383,134 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
switch (st->op) {
case OP_ADD_F:
OPC->_float = OPA->_float + OPB->_float;
E_OPC->_float = E_OPA->_float + E_OPB->_float;
break;
case OP_ADD_V:
OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
E_OPC->vector[0] = E_OPA->vector[0] + E_OPB->vector[0];
E_OPC->vector[1] = E_OPA->vector[1] + E_OPB->vector[1];
E_OPC->vector[2] = E_OPA->vector[2] + E_OPB->vector[2];
break;
case OP_SUB_F:
OPC->_float = OPA->_float - OPB->_float;
E_OPC->_float = E_OPA->_float - E_OPB->_float;
break;
case OP_SUB_V:
OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
E_OPC->vector[0] = E_OPA->vector[0] - E_OPB->vector[0];
E_OPC->vector[1] = E_OPA->vector[1] - E_OPB->vector[1];
E_OPC->vector[2] = E_OPA->vector[2] - E_OPB->vector[2];
break;
case OP_MUL_F:
OPC->_float = OPA->_float * OPB->_float;
E_OPC->_float = E_OPA->_float * E_OPB->_float;
break;
case OP_MUL_V:
OPC->_float =
OPA->vector[0] * OPB->vector[0] +
OPA->vector[1] * OPB->vector[1] +
OPA->vector[2] * OPB->vector[2];
E_OPC->_float =
E_OPA->vector[0] * E_OPB->vector[0] +
E_OPA->vector[1] * E_OPB->vector[1] +
E_OPA->vector[2] * E_OPB->vector[2];
break;
case OP_MUL_FV:
OPC->vector[0] = OPA->_float * OPB->vector[0];
OPC->vector[1] = OPA->_float * OPB->vector[1];
OPC->vector[2] = OPA->_float * OPB->vector[2];
E_OPC->vector[0] = E_OPA->_float * E_OPB->vector[0];
E_OPC->vector[1] = E_OPA->_float * E_OPB->vector[1];
E_OPC->vector[2] = E_OPA->_float * E_OPB->vector[2];
break;
case OP_MUL_VF:
OPC->vector[0] = OPB->_float * OPA->vector[0];
OPC->vector[1] = OPB->_float * OPA->vector[1];
OPC->vector[2] = OPB->_float * OPA->vector[2];
E_OPC->vector[0] = E_OPB->_float * E_OPA->vector[0];
E_OPC->vector[1] = E_OPB->_float * E_OPA->vector[1];
E_OPC->vector[2] = E_OPB->_float * E_OPA->vector[2];
break;
case OP_DIV_F:
OPC->_float = OPA->_float / OPB->_float;
E_OPC->_float = E_OPA->_float / E_OPB->_float;
break;
case OP_BITAND:
OPC->_float = (int) OPA->_float & (int) OPB->_float;
E_OPC->_float = (int) E_OPA->_float & (int) E_OPB->_float;
break;
case OP_BITOR:
OPC->_float = (int) OPA->_float | (int) OPB->_float;
E_OPC->_float = (int) E_OPA->_float | (int) E_OPB->_float;
break;
case OP_GE:
OPC->_float = OPA->_float >= OPB->_float;
E_OPC->_float = E_OPA->_float >= E_OPB->_float;
break;
case OP_LE:
OPC->_float = OPA->_float <= OPB->_float;
E_OPC->_float = E_OPA->_float <= E_OPB->_float;
break;
case OP_GT:
OPC->_float = OPA->_float > OPB->_float;
E_OPC->_float = E_OPA->_float > E_OPB->_float;
break;
case OP_LT:
OPC->_float = OPA->_float < OPB->_float;
E_OPC->_float = E_OPA->_float < E_OPB->_float;
break;
case OP_AND:
OPC->_float = OPA->_float && OPB->_float;
E_OPC->_float = E_OPA->_float && E_OPB->_float;
break;
case OP_OR:
OPC->_float = OPA->_float || OPB->_float;
E_OPC->_float = E_OPA->_float || E_OPB->_float;
break;
case OP_NOT_F:
OPC->_float = !OPA->_float;
E_OPC->_float = !E_OPA->_float;
break;
case OP_NOT_V:
OPC->_float = !OPA->vector[0] && !OPA->vector[1]
&& !OPA->vector[2];
E_OPC->_float = !E_OPA->vector[0] && !E_OPA->vector[1]
&& !E_OPA->vector[2];
break;
case OP_NOT_S:
OPC->_float = !OPA->string || !*PR_GetString (pr, OPA->string);
E_OPC->_float = !E_OPA->string || !*PR_GetString (pr, E_OPA->string);
break;
case OP_NOT_FNC:
OPC->_float = !OPA->function;
E_OPC->_float = !E_OPA->function;
break;
case OP_NOT_ENT:
OPC->_float = (PROG_TO_EDICT (pr, OPA->edict) == *pr->edicts);
E_OPC->_float = (PROG_TO_EDICT (pr, E_OPA->edict) == *pr->edicts);
break;
case OP_EQ_F:
OPC->_float = OPA->_float == OPB->_float;
E_OPC->_float = E_OPA->_float == E_OPB->_float;
break;
case OP_EQ_V:
OPC->_float = (OPA->vector[0] == OPB->vector[0])
&& (OPA->vector[1] == OPB->vector[1])
&& (OPA->vector[2] == OPB->vector[2]);
E_OPC->_float = (E_OPA->vector[0] == E_OPB->vector[0])
&& (E_OPA->vector[1] == E_OPB->vector[1])
&& (E_OPA->vector[2] == E_OPB->vector[2]);
break;
case OP_EQ_S:
OPC->_float =
!strcmp (PR_GetString (pr, OPA->string),
PR_GetString (pr, OPB->string));
E_OPC->_float =
!strcmp (PR_GetString (pr, E_OPA->string),
PR_GetString (pr, E_OPB->string));
break;
case OP_EQ_E:
OPC->_float = OPA->_int == OPB->_int;
E_OPC->_float = E_OPA->_int == E_OPB->_int;
break;
case OP_EQ_FNC:
OPC->_float = OPA->function == OPB->function;
E_OPC->_float = E_OPA->function == E_OPB->function;
break;
case OP_NE_F:
OPC->_float = OPA->_float != OPB->_float;
E_OPC->_float = E_OPA->_float != E_OPB->_float;
break;
case OP_NE_V:
OPC->_float = (OPA->vector[0] != OPB->vector[0])
|| (OPA->vector[1] != OPB->vector[1])
|| (OPA->vector[2] != OPB->vector[2]);
E_OPC->_float = (E_OPA->vector[0] != E_OPB->vector[0])
|| (E_OPA->vector[1] != E_OPB->vector[1])
|| (E_OPA->vector[2] != E_OPB->vector[2]);
break;
case OP_NE_S:
OPC->_float =
strcmp (PR_GetString (pr, OPA->string),
PR_GetString (pr, OPB->string));
E_OPC->_float =
strcmp (PR_GetString (pr, E_OPA->string),
PR_GetString (pr, E_OPB->string));
break;
case OP_NE_E:
OPC->_float = OPA->_int != OPB->_int;
E_OPC->_float = E_OPA->_int != E_OPB->_int;
break;
case OP_NE_FNC:
OPC->_float = OPA->function != OPB->function;
E_OPC->_float = E_OPA->function != E_OPB->function;
break;
// ==================
// ==================
case OP_STORE_F:
case OP_STORE_ENT:
case OP_STORE_FLD: // integers
case OP_STORE_S:
case OP_STORE_FNC: // pointers
OPB->_int = OPA->_int;
E_OPB->_int = E_OPA->_int;
break;
case OP_STORE_V:
OPB->vector[0] = OPA->vector[0];
OPB->vector[1] = OPA->vector[1];
OPB->vector[2] = OPA->vector[2];
E_OPB->vector[0] = E_OPA->vector[0];
E_OPB->vector[1] = E_OPA->vector[1];
E_OPB->vector[2] = E_OPA->vector[2];
break;
case OP_STOREP_F:
@ -513,60 +519,64 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
case OP_STOREP_S:
case OP_STOREP_FNC: // pointers
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 4 > pr->pr_edictareasize)) {
&& (E_OPB->_int < 0 || E_OPB->_int + 4 > pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an out of bounds edict\n");
(pr,
"Progs attempted to write to an out of bounds edict\n");
return;
}
if (pr_boundscheck->int_val && (OPB->_int % pr->pr_edict_size <
if (pr_boundscheck->int_val && (E_OPB->_int % pr->pr_edict_size <
((byte *) & (*pr->edicts)->v -
(byte *) *pr->edicts))) {
(byte *) * pr->edicts))) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an engine edict field\n");
return;
}
ptr = (eval_t *) ((byte *) *pr->edicts + OPB->_int);
ptr->_int = OPA->_int;
ptr = (eval_t *) ((byte *) * pr->edicts + E_OPB->_int);
ptr->_int = E_OPA->_int;
break;
case OP_STOREP_V:
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 12 > pr->pr_edictareasize)) {
&& (E_OPB->_int < 0 || E_OPB->_int + 12 > pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an out of bounds edict\n");
(pr,
"Progs attempted to write to an out of bounds edict\n");
return;
}
ptr = (eval_t *) ((byte *) *pr->edicts + OPB->_int);
ptr->vector[0] = OPA->vector[0];
ptr->vector[1] = OPA->vector[1];
ptr->vector[2] = OPA->vector[2];
ptr = (eval_t *) ((byte *) * pr->edicts + E_OPB->_int);
ptr->vector[0] = E_OPA->vector[0];
ptr->vector[1] = E_OPA->vector[1];
ptr->vector[2] = E_OPA->vector[2];
break;
case OP_ADDRESS:
if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
&& (E_OPA->edict < 0 || E_OPA->edict >= pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to address an out of bounds edict\n");
return;
}
if (pr_boundscheck->int_val
&& (OPA->edict == 0 && pr->null_bad)) {
&& (E_OPA->edict == 0 && pr->null_bad)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError (pr, "assignment to world entity");
return;
}
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
&& (E_OPB->_int < 0 || E_OPB->_int >= pr->progs->entityfields)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to address an invalid field in an edict\n");
(pr,
"Progs attempted to address an invalid field in an edict\n");
return;
}
ed = PROG_TO_EDICT (pr, OPA->edict);
OPC->_int =
(byte *) ((int *) &ed->v + OPB->_int) - (byte *) *pr->edicts;
ed = PROG_TO_EDICT (pr, E_OPA->edict);
E_OPC->_int =
(byte *) ((int *) &ed->v + E_OPB->_int)
- (byte *) * pr->edicts;
break;
case OP_LOAD_F:
case OP_LOAD_FLD:
@ -574,56 +584,61 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
case OP_LOAD_S:
case OP_LOAD_FNC:
if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
&& (E_OPA->edict < 0 || E_OPA->edict >= pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an out of bounds edict number\n");
(pr,
"Progs attempted to read an out of bounds edict number\n");
return;
}
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
&& (E_OPB->_int < 0 || E_OPB->_int >= pr->progs->entityfields)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an invalid field in an edict\n");
(pr,
"Progs attempted to read an invalid field in an edict\n");
return;
}
ed = PROG_TO_EDICT (pr, OPA->edict);
OPC->_int = ((eval_t *) ((int *) &ed->v + OPB->_int))->_int;
ed = PROG_TO_EDICT (pr, E_OPA->edict);
E_OPC->_int = ((eval_t *) ((int *) &ed->v + E_OPB->_int))->_int;
break;
case OP_LOAD_V:
if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
&& (E_OPA->edict < 0 || E_OPA->edict >= pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an out of bounds edict number\n");
(pr,
"Progs attempted to read an out of bounds edict number\n");
return;
}
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 2 >= pr->progs->entityfields)) {
&& (E_OPB->_int < 0
|| E_OPB->_int + 2 >= pr->progs->entityfields)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an invalid field in an edict\n");
(pr,
"Progs attempted to read an invalid field in an edict\n");
return;
}
ed = PROG_TO_EDICT (pr, OPA->edict);
OPC->vector[0] =
((eval_t *) ((int *) &ed->v + OPB->_int))->vector[0];
OPC->vector[1] =
((eval_t *) ((int *) &ed->v + OPB->_int))->vector[1];
OPC->vector[2] =
((eval_t *) ((int *) &ed->v + OPB->_int))->vector[2];
ed = PROG_TO_EDICT (pr, E_OPA->edict);
E_OPC->vector[0] =
((eval_t *) ((int *) &ed->v + E_OPB->_int))->vector[0];
E_OPC->vector[1] =
((eval_t *) ((int *) &ed->v + E_OPB->_int))->vector[1];
E_OPC->vector[2] =
((eval_t *) ((int *) &ed->v + E_OPB->_int))->vector[2];
break;
// ==================
// ==================
case OP_IFNOT:
if (!OPA->_int)
st += st->b - 1; // offset the s++
if (!E_OPA->_int)
st += st->b - 1; // offset the s++
break;
case OP_IF:
if (OPA->_int)
st += st->b - 1; // offset the s++
if (E_OPA->_int)
st += st->b - 1; // offset the s++
break;
case OP_GOTO:
st += st->a - 1; // offset the s++
st += st->a - 1; // offset the s++
break;
case OP_CALL0:
case OP_CALL1:
@ -638,9 +653,9 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
startprofile = profile;
pr->pr_xstatement = st - pr->pr_statements;
pr->pr_argc = st->op - OP_CALL0;
if (!OPA->function)
if (!E_OPA->function)
PR_RunError (pr, "NULL function");
newf = &pr->pr_functions[OPA->function];
newf = &pr->pr_functions[E_OPA->function];
if (newf->first_statement < 0) { // negative
// statements are
// built in functions
@ -656,211 +671,207 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
break;
case OP_DONE:
case OP_RETURN:
pr->pr_globals[OFS_RETURN] = pr->pr_globals[(unsigned short) st->a];
pr->pr_globals[OFS_RETURN + 1] =
pr->pr_globals[(unsigned short) st->a + 1];
pr->pr_globals[OFS_RETURN + 2] =
pr->pr_globals[(unsigned short) st->a + 2];
memcpy (&pr->pr_globals[OFS_RETURN], &OPA, 3 * sizeof (OPA));
st = &pr->pr_statements[PR_LeaveFunction (pr)];
if (pr->pr_depth == exitdepth)
return; // all done
return; // all done
break;
case OP_STATE:
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
ed->v.v.nextthink = pr->pr_global_struct->time + 0.1;
ed->v.v.frame = OPA->_float;
ed->v.v.think = OPB->function;
ed = PROG_TO_EDICT (pr, *pr->globals.self);
ed->v[pr->fields.nextthink].float_var = *pr->globals.time + 0.1;
ed->v[pr->fields.frame].float_var = E_OPA->_float;
ed->v[pr->fields.think].func_var = E_OPB->function;
break;
// LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
/*
case OP_ADD_I:
OPC->_int = OPA->_int + OPB->_int;
E_OPC->_int = E_OPA->_int + E_OPB->_int;
break;
case OP_ADD_IF:
OPC->_int = OPA->_int + (int) OPB->_float;
E_OPC->_int = E_OPA->_int + (int) E_OPB->_float;
break;
case OP_ADD_FI:
OPC->_float = OPA->_float + (float) OPB->_int;
E_OPC->_float = E_OPA->_float + (float) E_OPB->_int;
break;
case OP_SUB_I:
OPC->_int = OPA->_int - OPB->_int;
E_OPC->_int = E_OPA->_int - E_OPB->_int;
break;
case OP_SUB_IF:
OPC->_int = OPA->_int - (int) OPB->_float;
E_OPC->_int = E_OPA->_int - (int) E_OPB->_float;
break;
case OP_SUB_FI:
OPC->_float = OPA->_float - (float) OPB->_int;
E_OPC->_float = E_OPA->_float - (float) E_OPB->_int;
break;
case OP_MUL_I:
OPC->_int = OPA->_int * OPB->_int;
E_OPC->_int = E_OPA->_int * E_OPB->_int;
break;
case OP_MUL_IF:
OPC->_int = OPA->_int * (int) OPB->_float;
E_OPC->_int = E_OPA->_int * (int) E_OPB->_float;
break;
case OP_MUL_FI:
OPC->_float = OPA->_float * (float) OPB->_int;
E_OPC->_float = E_OPA->_float * (float) E_OPB->_int;
break;
case OP_MUL_VI:
OPC->vector[0] = (float) OPB->_int * OPA->vector[0];
OPC->vector[1] = (float) OPB->_int * OPA->vector[1];
OPC->vector[2] = (float) OPB->_int * OPA->vector[2];
E_OPC->vector[0] = (float) E_OPB->_int * E_OPA->vector[0];
E_OPC->vector[1] = (float) E_OPB->_int * E_OPA->vector[1];
E_OPC->vector[2] = (float) E_OPB->_int * E_OPA->vector[2];
break;
case OP_DIV_VF:
{
float temp = 1.0f / OPB->_float;
float temp = 1.0f / E_OPB->_float;
OPC->vector[0] = temp * OPA->vector[0];
OPC->vector[1] = temp * OPA->vector[1];
OPC->vector[2] = temp * OPA->vector[2];
E_OPC->vector[0] = temp * E_OPA->vector[0];
E_OPC->vector[1] = temp * E_OPA->vector[1];
E_OPC->vector[2] = temp * E_OPA->vector[2];
}
break;
case OP_DIV_I:
OPC->_int = OPA->_int / OPB->_int;
E_OPC->_int = E_OPA->_int / E_OPB->_int;
break;
case OP_DIV_IF:
OPC->_int = OPA->_int / (int) OPB->_float;
E_OPC->_int = E_OPA->_int / (int) E_OPB->_float;
break;
case OP_DIV_FI:
OPC->_float = OPA->_float / (float) OPB->_int;
E_OPC->_float = E_OPA->_float / (float) E_OPB->_int;
break;
case OP_CONV_IF:
OPC->_float = OPA->_int;
E_OPC->_float = E_OPA->_int;
break;
case OP_CONV_FI:
OPC->_int = OPA->_float;
E_OPC->_int = E_OPA->_float;
break;
case OP_BITAND_I:
OPC->_int = OPA->_int & OPB->_int;
E_OPC->_int = E_OPA->_int & E_OPB->_int;
break;
case OP_BITOR_I:
OPC->_int = OPA->_int | OPB->_int;
E_OPC->_int = E_OPA->_int | E_OPB->_int;
break;
case OP_BITAND_IF:
OPC->_int = OPA->_int & (int) OPB->_float;
E_OPC->_int = E_OPA->_int & (int) E_OPB->_float;
break;
case OP_BITOR_IF:
OPC->_int = OPA->_int | (int) OPB->_float;
E_OPC->_int = E_OPA->_int | (int) E_OPB->_float;
break;
case OP_BITAND_FI:
OPC->_float = (int) OPA->_float & OPB->_int;
E_OPC->_float = (int) E_OPA->_float & E_OPB->_int;
break;
case OP_BITOR_FI:
OPC->_float = (int) OPA->_float | OPB->_int;
E_OPC->_float = (int) E_OPA->_float | E_OPB->_int;
break;
case OP_GE_I:
OPC->_float = OPA->_int >= OPB->_int;
E_OPC->_float = E_OPA->_int >= E_OPB->_int;
break;
case OP_LE_I:
OPC->_float = OPA->_int <= OPB->_int;
E_OPC->_float = E_OPA->_int <= E_OPB->_int;
break;
case OP_GT_I:
OPC->_float = OPA->_int > OPB->_int;
E_OPC->_float = E_OPA->_int > E_OPB->_int;
break;
case OP_LT_I:
OPC->_float = OPA->_int < OPB->_int;
E_OPC->_float = E_OPA->_int < E_OPB->_int;
break;
case OP_AND_I:
OPC->_float = OPA->_int && OPB->_int;
E_OPC->_float = E_OPA->_int && E_OPB->_int;
break;
case OP_OR_I:
OPC->_float = OPA->_int || OPB->_int;
E_OPC->_float = E_OPA->_int || E_OPB->_int;
break;
case OP_GE_IF:
OPC->_float = (float) OPA->_int >= OPB->_float;
E_OPC->_float = (float) E_OPA->_int >= E_OPB->_float;
break;
case OP_LE_IF:
OPC->_float = (float) OPA->_int <= OPB->_float;
E_OPC->_float = (float) E_OPA->_int <= E_OPB->_float;
break;
case OP_GT_IF:
OPC->_float = (float) OPA->_int > OPB->_float;
E_OPC->_float = (float) E_OPA->_int > E_OPB->_float;
break;
case OP_LT_IF:
OPC->_float = (float) OPA->_int < OPB->_float;
E_OPC->_float = (float) E_OPA->_int < E_OPB->_float;
break;
case OP_AND_IF:
OPC->_float = (float) OPA->_int && OPB->_float;
E_OPC->_float = (float) E_OPA->_int && E_OPB->_float;
break;
case OP_OR_IF:
OPC->_float = (float) OPA->_int || OPB->_float;
E_OPC->_float = (float) E_OPA->_int || E_OPB->_float;
break;
case OP_GE_FI:
OPC->_float = OPA->_float >= (float) OPB->_int;
E_OPC->_float = E_OPA->_float >= (float) E_OPB->_int;
break;
case OP_LE_FI:
OPC->_float = OPA->_float <= (float) OPB->_int;
E_OPC->_float = E_OPA->_float <= (float) E_OPB->_int;
break;
case OP_GT_FI:
OPC->_float = OPA->_float > (float) OPB->_int;
E_OPC->_float = E_OPA->_float > (float) E_OPB->_int;
break;
case OP_LT_FI:
OPC->_float = OPA->_float < (float) OPB->_int;
E_OPC->_float = E_OPA->_float < (float) E_OPB->_int;
break;
case OP_AND_FI:
OPC->_float = OPA->_float && (float) OPB->_int;
E_OPC->_float = E_OPA->_float && (float) E_OPB->_int;
break;
case OP_OR_FI:
OPC->_float = OPA->_float || (float) OPB->_int;
E_OPC->_float = E_OPA->_float || (float) E_OPB->_int;
break;
case OP_NOT_I:
OPC->_float = !OPA->_int;
E_OPC->_float = !E_OPA->_int;
break;
case OP_EQ_I:
OPC->_float = OPA->_int == OPB->_int;
E_OPC->_float = E_OPA->_int == E_OPB->_int;
break;
case OP_EQ_IF:
OPC->_float = (float) OPA->_int == OPB->_float;
E_OPC->_float = (float) E_OPA->_int == E_OPB->_float;
break;
case OP_EQ_FI:
OPC->_float = OPA->_float == (float) OPB->_int;
E_OPC->_float = E_OPA->_float == (float) E_OPB->_int;
break;
case OP_NE_I:
OPC->_float = OPA->_int != OPB->_int;
E_OPC->_float = E_OPA->_int != E_OPB->_int;
break;
case OP_NE_IF:
OPC->_float = (float) OPA->_int != OPB->_float;
E_OPC->_float = (float) E_OPA->_int != E_OPB->_float;
break;
case OP_NE_FI:
OPC->_float = OPA->_float != (float) OPB->_int;
E_OPC->_float = E_OPA->_float != (float) E_OPB->_int;
break;
case OP_STORE_I:
OPB->_int = OPA->_int;
E_OPB->_int = E_OPA->_int;
break;
case OP_STOREP_I:
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 4 > pr->pr_edictareasize)) {
&& (E_OPB->_int < 0 || E_OPB->_int + 4 > pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an out of bounds edict\n");
return;
}
if (pr_boundscheck->int_val
&& (OPB->_int % pr->pr_edict_size <
&& (E_OPB->_int % pr->pr_edict_size <
((byte *) & (*pr->edicts)->v - (byte *) *pr->edicts))) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an engine edict field\n");
return;
}
ptr = (eval_t *) ((byte *) *pr->edicts + OPB->_int);
ptr->_int = OPA->_int;
ptr = (eval_t *) ((byte *) *pr->edicts + E_OPB->_int);
ptr->_int = E_OPA->_int;
break;
case OP_LOAD_I:
if (pr_boundscheck->int_val
&& (OPA->edict < 0 || OPA->edict >= pr->pr_edictareasize)) {
&& (E_OPA->edict < 0 || E_OPA->edict >= pr->pr_edictareasize)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an out of bounds edict number\n");
return;
}
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= pr->progs->entityfields)) {
&& (E_OPB->_int < 0 || E_OPB->_int >= pr->progs->entityfields)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an invalid field in an edict\n");
return;
}
ed = PROG_TO_EDICT (pr, OPA->edict);
OPC->_int = ((eval_t *) ((int *) &ed->v + OPB->_int))->_int;
ed = PROG_TO_EDICT (pr, E_OPA->edict);
E_OPC->_int = ((eval_t *) ((int *) &ed->v + E_OPB->_int))->_int;
break;
case OP_GSTOREP_I:
@ -870,29 +881,29 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
case OP_GSTOREP_S:
case OP_GSTOREP_FNC: // pointers
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int >= pr->pr_globaldefs)) {
&& (E_OPB->_int < 0 || E_OPB->_int >= pr->pr_globaldefs)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an invalid indexed global\n");
return;
}
pr->pr_globals[OPB->_int] = OPA->_float;
pr->pr_globals[E_OPB->_int] = E_OPA->_float;
break;
case OP_GSTOREP_V:
if (pr_boundscheck->int_val
&& (OPB->_int < 0 || OPB->_int + 2 >= pr->pr_globaldefs)) {
&& (E_OPB->_int < 0 || E_OPB->_int + 2 >= pr->pr_globaldefs)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to write to an invalid indexed global\n");
return;
}
pr->pr_globals[OPB->_int] = OPA->vector[0];
pr->pr_globals[OPB->_int + 1] = OPA->vector[1];
pr->pr_globals[OPB->_int + 2] = OPA->vector[2];
pr->pr_globals[E_OPB->_int] = E_OPA->vector[0];
pr->pr_globals[E_OPB->_int + 1] = E_OPA->vector[1];
pr->pr_globals[E_OPB->_int + 2] = E_OPA->vector[2];
break;
case OP_GADDRESS:
i = OPA->_int + (int) OPB->_float;
i = E_OPA->_int + (int) E_OPB->_float;
if (pr_boundscheck->int_val
&& (i < 0 || i >= pr->pr_globaldefs)) {
pr->pr_xstatement = st - pr->pr_statements;
@ -900,7 +911,7 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
(pr, "Progs attempted to address an out of bounds global\n");
return;
}
OPC->_float = pr->pr_globals[i];
E_OPC->_float = pr->pr_globals[i];
break;
case OP_GLOAD_I:
@ -910,30 +921,30 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
case OP_GLOAD_S:
case OP_GLOAD_FNC:
if (pr_boundscheck->int_val
&& (OPA->_int < 0 || OPA->_int >= pr->pr_globaldefs)) {
&& (E_OPA->_int < 0 || E_OPA->_int >= pr->pr_globaldefs)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an invalid indexed global\n");
return;
}
OPC->_float = pr->pr_globals[OPA->_int];
E_OPC->_float = pr->pr_globals[E_OPA->_int];
break;
case OP_GLOAD_V:
if (pr_boundscheck->int_val
&& (OPA->_int < 0 || OPA->_int + 2 >= pr->pr_globaldefs)) {
&& (E_OPA->_int < 0 || E_OPA->_int + 2 >= pr->pr_globaldefs)) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs attempted to read an invalid indexed global\n");
return;
}
OPC->vector[0] = pr->pr_globals[OPA->_int];
OPC->vector[1] = pr->pr_globals[OPA->_int + 1];
OPC->vector[2] = pr->pr_globals[OPA->_int + 2];
E_OPC->vector[0] = pr->pr_globals[E_OPA->_int];
E_OPC->vector[1] = pr->pr_globals[E_OPA->_int + 1];
E_OPC->vector[2] = pr->pr_globals[E_OPA->_int + 2];
break;
case OP_BOUNDCHECK:
if (OPA->_int < 0 || OPA->_int >= st->b) {
if (E_OPA->_int < 0 || E_OPA->_int >= st->b) {
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError
(pr, "Progs boundcheck failed at line number %d, value is < 0 or >= %d\n",
@ -944,14 +955,14 @@ PR_ExecuteProgram (progs_t *pr, func_t fnum)
*/
default:
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError (pr, "Bad opcode %i", st->op);
pr->pr_xstatement = st - pr->pr_statements;
PR_RunError (pr, "Bad opcode %i", st->op);
}
}
}
char *
PR_GetString (progs_t *pr, int num)
PR_GetString (progs_t * pr, int num)
{
if (num < 0) {
// Con_DPrintf("GET:%d == %s\n", num, pr->pr_strtbl[-num]);
@ -961,11 +972,11 @@ PR_GetString (progs_t *pr, int num)
}
int
PR_SetString (progs_t *pr, char *s)
PR_SetString (progs_t * pr, char *s)
{
int i;
int i = s - pr->pr_strings;
if (s - pr->pr_strings < 0) {
if (i < 0 || i > pr->pr_stringsize) {
for (i = 0; i <= pr->num_prstr; i++)
if (pr->pr_strtbl[i] == s)
break;

View file

@ -43,10 +43,10 @@ extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
// up / down
#define PITCH 0

View file

@ -1,186 +0,0 @@
/*
pr_comp.h
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
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$
*/
// this file is shared by quake and qcc
typedef enum {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_field, ev_function, ev_pointer} etype_t;
#define OFS_NULL 0
#define OFS_RETURN 1
#define OFS_PARM0 4 // leave 3 ofs for each parm to hold vectors
#define OFS_PARM1 7
#define OFS_PARM2 10
#define OFS_PARM3 13
#define OFS_PARM4 16
#define OFS_PARM5 19
#define OFS_PARM6 22
#define OFS_PARM7 25
#define RESERVED_OFS 28
enum {
OP_DONE,
OP_MUL_F,
OP_MUL_V,
OP_MUL_FV,
OP_MUL_VF,
OP_DIV_F,
OP_ADD_F,
OP_ADD_V,
OP_SUB_F,
OP_SUB_V,
OP_EQ_F,
OP_EQ_V,
OP_EQ_S,
OP_EQ_E,
OP_EQ_FNC,
OP_NE_F,
OP_NE_V,
OP_NE_S,
OP_NE_E,
OP_NE_FNC,
OP_LE,
OP_GE,
OP_LT,
OP_GT,
OP_LOAD_F,
OP_LOAD_V,
OP_LOAD_S,
OP_LOAD_ENT,
OP_LOAD_FLD,
OP_LOAD_FNC,
OP_ADDRESS,
OP_STORE_F,
OP_STORE_V,
OP_STORE_S,
OP_STORE_ENT,
OP_STORE_FLD,
OP_STORE_FNC,
OP_STOREP_F,
OP_STOREP_V,
OP_STOREP_S,
OP_STOREP_ENT,
OP_STOREP_FLD,
OP_STOREP_FNC,
OP_RETURN,
OP_NOT_F,
OP_NOT_V,
OP_NOT_S,
OP_NOT_ENT,
OP_NOT_FNC,
OP_IF,
OP_IFNOT,
OP_CALL0,
OP_CALL1,
OP_CALL2,
OP_CALL3,
OP_CALL4,
OP_CALL5,
OP_CALL6,
OP_CALL7,
OP_CALL8,
OP_STATE,
OP_GOTO,
OP_AND,
OP_OR,
OP_BITAND,
OP_BITOR
};
typedef struct statement_s
{
unsigned short op;
short a,b,c;
} dstatement_t;
typedef struct
{
unsigned short type; // if DEF_SAVEGLOBGAL bit is set
// the variable needs to be saved in savegames
unsigned short ofs;
int s_name;
} ddef_t;
#define DEF_SAVEGLOBAL (1<<15)
#define MAX_PARMS 8
typedef struct
{
int first_statement; // negative numbers are builtins
int parm_start;
int locals; // total ints of parms + locals
int profile; // runtime
int s_name;
int s_file; // source file defined in
int numparms;
byte parm_size[MAX_PARMS];
} dfunction_t;
#define PROG_VERSION 6
typedef struct
{
int version;
int crc; // check of header file
int ofs_statements;
int numstatements; // statement 0 is an error
int ofs_globaldefs;
int numglobaldefs;
int ofs_fielddefs;
int numfielddefs;
int ofs_functions;
int numfunctions; // function 0 is an empty
int ofs_strings;
int numstrings; // first string is a null string
int ofs_globals;
int numglobals;
int entityfields;
} dprograms_t;

View file

@ -1,151 +0,0 @@
/*
progs.h
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
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$
*/
#ifndef __progs_h
#define __progs_h
#include "gcc_attr.h"
#include "protocol.h"
#include "pr_comp.h" // defs shared with qcc
#include "progdefs.h" // generated by program cdefs
#include "link.h"
#include "quakeio.h"
typedef union eval_s
{
string_t string;
float _float;
float vector[3];
func_t function;
int _int;
int edict;
} eval_t;
#define MAX_ENT_LEAFS 16
typedef struct edict_s
{
qboolean free;
link_t area; // linked to a division node or leaf
int num_leafs;
short leafnums[MAX_ENT_LEAFS];
entity_state_t baseline;
float freetime; // sv.time when the object was freed
entvars_t v; // C exported fields from progs
// other fields from progs come immediately after
} edict_t;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
//============================================================================
extern dprograms_t *progs;
extern dfunction_t *pr_functions;
extern char *pr_strings;
extern ddef_t *pr_globaldefs;
extern ddef_t *pr_fielddefs;
extern dstatement_t *pr_statements;
extern globalvars_t *pr_global_struct;
extern float *pr_globals; // same as pr_global_struct
extern int pr_edict_size; // in bytes
//============================================================================
void PR_Init (void);
void PR_ExecuteProgram (func_t fnum);
void PR_LoadProgs (void);
void PR_Profile_f (void);
edict_t *ED_Alloc (void);
void ED_Free (edict_t *ed);
char *ED_NewString (char *string);
// returns a copy of the string allocated from the server's string heap
void ED_Print (edict_t *ed);
void ED_Write (QFile *f, edict_t *ed);
char *ED_ParseEdict (char *data, edict_t *ent);
void ED_WriteGlobals (QFile *f);
void ED_ParseGlobals (char *data);
void ED_LoadFromFile (char *data);
//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size))
//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size)
edict_t *EDICT_NUM(int n);
int NUM_FOR_EDICT(edict_t *e);
#define NEXT_EDICT(e) ((edict_t *)( (byte *)e + pr_edict_size))
#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts)
#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e))
//============================================================================
#define G_FLOAT(o) (pr_globals[o])
#define G_INT(o) (*(int *)&pr_globals[o])
#define G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o]))
#define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
#define G_VECTOR(o) (&pr_globals[o])
#define G_STRING(o) (pr_strings + *(string_t *)&pr_globals[o])
#define G_FUNCTION(o) (*(func_t *)&pr_globals[o])
#define E_FLOAT(e,o) (((float*)&e->v)[o])
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o])
#define E_VECTOR(e,o) (&((float*)&e->v)[o])
#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)&e->v)[o])
extern int type_size[8];
typedef void (*builtin_t) (void);
extern builtin_t *pr_builtins;
extern int pr_numbuiltins;
extern int pr_argc;
extern qboolean pr_trace;
extern dfunction_t *pr_xfunction;
extern int pr_xstatement;
extern unsigned short pr_crc;
void PR_RunError (char *error, ...);
void ED_PrintEdicts (void);
void ED_PrintNum (int ent);
eval_t *GetEdictFieldValue(edict_t *ed, char *field);
#endif // __progs_h

View file

@ -36,12 +36,14 @@
#include "cvar.h"
#include "protocol.h"
#include "model.h"
#include "progs.h"
#include "sv_progs.h"
#include "sizebuf.h"
#include "info.h"
#include "quakeio.h"
#include "client.h"
extern progs_t sv_pr_state;
typedef struct
{
int maxclients;
@ -282,7 +284,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink);
void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg);
void SV_MoveToGoal (void);
void SV_MoveToGoal (progs_t *pr);
void SV_CheckForNewClients (void);
void SV_RunClients (void);
@ -293,4 +295,8 @@ void SV_SpawnServer (char *server, char *startspot);
void SV_SpawnServer (char *server);
#endif
void SV_LoadProgs (void);
void SV_Progs_Init (void);
void SV_Progs_Init_Cvars (void);
#endif // __server_h

108
nq/include/sv_pr_cmds.h Normal file
View file

@ -0,0 +1,108 @@
/*
sv_pr_cmds.h
server progs builtin prototypes
Copyright (C) 2000 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
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.
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.
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$
*/
#ifndef __sv_pr_cmds_h
#define __sv_pr_cmds_h
char * PF_VarString (progs_t * pr, int first);
void PF_error (progs_t * pr);
void PF_objerror (progs_t * pr);
void PF_makevectors (progs_t * pr);
void PF_setorigin (progs_t * pr);
void PF_setsize (progs_t * pr);
void PF_setmodel (progs_t * pr);
void PF_bprint (progs_t * pr);
void PF_sprint (progs_t * pr);
void PF_centerprint (progs_t * pr);
void PF_normalize (progs_t * pr);
void PF_vlen (progs_t * pr);
void PF_vectoyaw (progs_t * pr);
void PF_vectoangles (progs_t * pr);
void PF_random (progs_t * pr);
void PF_particle (progs_t * pr);
void PF_ambientsound (progs_t * pr);
void PF_sound (progs_t * pr);
void PF_break (progs_t * pr);
void PF_traceline (progs_t * pr);
void PF_TraceToss (progs_t * pr);
void PF_checkpos (progs_t * pr);
int PF_newcheckclient (progs_t * pr, int check);
void PF_checkclient (progs_t * pr);
void PF_stuffcmd (progs_t * pr);
void PF_localcmd (progs_t * pr);
void PF_cvar (progs_t * pr);
void PF_cvar_set (progs_t * pr);
void PF_findradius (progs_t * pr);
void PF_dprint (progs_t * pr);
void PF_ftos (progs_t * pr);
void PF_fabs (progs_t * pr);
void PF_vtos (progs_t * pr);
void PF_etos (progs_t * pr);
void PF_Spawn (progs_t * pr);
void PF_Remove (progs_t * pr);
void PF_Find (progs_t * pr);
void PF_precache_file (progs_t * pr);
void PF_precache_sound (progs_t * pr);
void PF_precache_model (progs_t * pr);
void PF_coredump (progs_t * pr);
void PF_traceon (progs_t * pr);
void PF_traceoff (progs_t * pr);
void PF_eprint (progs_t * pr);
void PF_walkmove (progs_t * pr);
void PF_droptofloor (progs_t * pr);
void PF_lightstyle (progs_t * pr);
void PF_rint (progs_t * pr);
void PF_floor (progs_t * pr);
void PF_ceil (progs_t * pr);
void PF_checkbottom (progs_t * pr);
void PF_pointcontents (progs_t * pr);
void PF_nextent (progs_t * pr);
void PF_aim (progs_t * pr);
void PF_changeyaw (progs_t * pr);
void PF_changepitch (progs_t * pr);
void PF_WriteByte (progs_t * pr);
void PF_WriteChar (progs_t * pr);
void PF_WriteShort (progs_t * pr);
void PF_WriteLong (progs_t * pr);
void PF_WriteAngle (progs_t * pr);
void PF_WriteCoord (progs_t * pr);
void PF_WriteString (progs_t * pr);
void PF_WriteEntity (progs_t * pr);
void PF_makestatic (progs_t * pr);
void PF_setspawnparms (progs_t * pr);
void PF_changelevel (progs_t * pr);
void PF_WaterMove (progs_t * pr);
void PF_sin (progs_t * pr);
void PF_cos (progs_t * pr);
void PF_sqrt (progs_t * pr);
void PF_Fixme (progs_t * pr);
#endif // __sv_pr_cmds_h

197
nq/include/sv_progs.h Normal file
View file

@ -0,0 +1,197 @@
/*
sv_progs.h
server specific progs definitions
Copyright (C) 2000 Bill Currie
Author: Bill Currie
Date: 28 Feb 2001
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.
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.
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$
*/
#ifndef __sv_progs_h
#define __sv_progs_h
#include "progs.h"
#include "sv_pr_cmds.h"
typedef struct {
int *self;
int *other;
int *world;
float *time;
float *frametime;
float *force_retouch;
string_t *mapname;
string_t *startspot;
float *deathmatch;
float *coop;
float *teamplay;
float *serverflags;
float *total_secrets;
float *total_monsters;
float *found_secrets;
float *killed_monsters;
float *parms;
vec3_t *v_forward;
vec3_t *v_up;
vec3_t *v_right;
float *trace_allsolid;
float *trace_startsolid;
float *trace_fraction;
vec3_t *trace_endpos;
vec3_t *trace_plane_normal;
float *trace_plane_dist;
int *trace_ent;
float *trace_inopen;
float *trace_inwater;
int *msg_entity;
string_t *null;
} sv_globals_t;
extern sv_globals_t sv_globals;
typedef struct {
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
} sv_funcs_t;
extern sv_funcs_t sv_funcs;
typedef struct
{
int modelindex; //float
int absmin; //vec3_t
int absmax; //vec3_t
int ltime; //float
int movetype; //float
int solid; //float
int origin; //vec3_t
int oldorigin; //vec3_t
int velocity; //vec3_t
int angles; //vec3_t
int avelocity; //vec3_t
int basevelocity; //vec3_t
int punchangle; //vec3_t
int classname; //string_t
int model; //string_t
int frame; //float
int skin; //float
int effects; //float
int drawPercent; //float
int gravity; //float
int mass; //float
int light_level; //float
int mins; //vec3_t
int maxs; //vec3_t
int size; //vec3_t
int touch; //func_t
int use; //func_t
int think; //func_t
int blocked; //func_t
int nextthink; //float
int groundentity; //int
int health; //float
int frags; //float
int weapon; //float
int weaponmodel; //string_t
int weaponframe; //float
int currentammo; //float
int ammo_shells; //float
int ammo_nails; //float
int ammo_rockets; //float
int ammo_cells; //float
int items; //float
int items2; //float
int takedamage; //float
int chain; //int
int deadflag; //float
int view_ofs; //vec3_t
int button0; //float
int button1; //float
int button2; //float
int impulse; //float
int fixangle; //float
int v_angle; //vec3_t
int idealpitch; //float
int pitch_speed; //float
int netname; //string_t
int enemy; //int
int flags; //float
int colormap; //float
int team; //float
int max_health; //float
int teleport_time; //float
int armortype; //float
int armorvalue; //float
int waterlevel; //float
int watertype; //float
int ideal_yaw; //float
int yaw_speed; //float
int aiment; //int
int goalentity; //int
int spawnflags; //float
int target; //string_t
int targetname; //string_t
int dmg_take; //float
int dmg_save; //float
int dmg_inflictor; //int
int owner; //int
int movedir; //vec3_t
int message; //string_t
int sounds; //float
int noise; //string_t
int noise1; //string_t
int noise2; //string_t
int noise3; //string_t
int dmg; //float
int dmgtime; //float
int air_finished; //float
int pain_finished; //float
int radsuit_finished; //float
int speed; //Float
} sv_fields_t;
extern sv_fields_t sv_fields;
#if 1
#define SVFIELD(e,f,t) \
((ED_FindField (&sv_pr_state, #f)->type == ev_##t) \
? E_var (e, sv_fields.f, t) \
: PR_Error (&sv_pr_state, \
"bad type access to %s as %s at %s:%d", \
#f, #t, __FILE__, __LINE__), \
E_var (e, sv_fields.f, t))
#else
#define SVFIELD(e,f,t) E_var (e, sv_fields.f, t)
#endif
#endif // __sv_progs_h

View file

@ -30,7 +30,7 @@
#define __world_h
#include "qtypes.h"
#include "progs.h"
#include "sv_progs.h"
typedef struct
{

View file

@ -128,8 +128,8 @@ libqfnet_a_SOURCES= net_bsd.c net_dgrm.c net_loop.c \
EXTRA_libqfcd_a_SOURCES=net_dos.c net_bw.c net_ipx.c net_mp.c net_ser.c \
net_win.c net_wins.c net_wipx.c
client_LIBS= -L. -L../../libs -lqfsys -lqfsnd -lqfcd -lqfjs -lqfnet -lqfutil $(SOUND_LIBS) $(NET_LIBS) $(Z_LIBS)
client_LIB_DEPS= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a ../../libs/libqfutil.a
client_LIBS= -L. -L../../libs -lqfsys -lqfsnd -lqfcd -lqfjs -lqfnet -lqfgamecode -lqfutil $(SOUND_LIBS) $(NET_LIBS) $(Z_LIBS)
client_LIB_DEPS= libqfsys.a libqfsnd.a libqfcd.a libqfjs.a libqfnet.a ../../libs/libqfgamecode.a ../../libs/libqfutil.a
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
cl_tent.c console.c keys.c menu.c sbar.c r_part.c r_view.c \
@ -137,8 +137,8 @@ client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
gib_interpret.c gib_modules.c gib_parse.c gib_stack.c vid.c
server_SOURCES= host.c host_cmd.c \
pr_cmds.c pr_edict.c pr_exec.c \
sv_cvar.c sv_main.c sv_move.c sv_phys.c sv_user.c
pr_cmds.c \
sv_cvar.c sv_main.c sv_move.c sv_phys.c sv_progs.c sv_user.c
combined_SOURCES= $(common_SOURCES) $(client_SOURCES) $(server_SOURCES)

View file

@ -51,6 +51,7 @@
#include "sys.h"
#include "screen.h"
#include "gib.h"
#include "sv_progs.h"
/*
@ -394,10 +395,12 @@ SV_DropClient (qboolean crash)
if (host_client->edict && host_client->spawned) {
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
saveSelf = pr_global_struct->self;
pr_global_struct->self = EDICT_TO_PROG (host_client->edict);
PR_ExecuteProgram (pr_global_struct->ClientDisconnect);
pr_global_struct->self = saveSelf;
saveSelf = *sv_globals.self;
*sv_globals.self =
EDICT_TO_PROG (&sv_pr_state, host_client->edict);
PR_ExecuteProgram (&sv_pr_state,
sv_funcs.ClientDisconnect);
*sv_globals.self = saveSelf;
}
Sys_Printf ("Client %s removed\n", host_client->name);
@ -590,7 +593,7 @@ void
_Host_ServerFrame (void)
{
// run the world state
pr_global_struct->frametime = host_frametime;
*sv_globals.frametime = host_frametime;
// read client messages
SV_RunClients ();
@ -608,7 +611,7 @@ Host_ServerFrame (void)
float temp_host_frametime;
// run the world state
pr_global_struct->frametime = host_frametime;
*sv_globals.frametime = host_frametime;
// set the time and clear the general datagram
SV_ClearDatagram ();
@ -637,7 +640,7 @@ void
Host_ServerFrame (void)
{
// run the world state
pr_global_struct->frametime = host_frametime;
*sv_globals.frametime = host_frametime;
// set the time and clear the general datagram
SV_ClearDatagram ();
@ -943,7 +946,10 @@ Host_Init (quakeparms_t *parms)
Key_Init ();
Con_Init ();
M_Init ();
PR_Init_Cvars ();
PR_Init ();
SV_Progs_Init_Cvars ();
SV_Progs_Init ();
Mod_Init ();
NET_Init ();
SV_Init ();

View file

@ -40,9 +40,9 @@
#include "msg.h"
#include "model.h"
#include "console.h"
#include "progs.h"
#include "keys.h"
#include "sys.h"
#include "sv_progs.h"
int current_skill;
@ -116,7 +116,7 @@ Host_Status_f (void)
} else
hours = 0;
print ("#%-2u %-16.16s %3i %2i:%02i:%02i\n", j + 1, client->name,
(int) client->edict->v.frags, hours, minutes, seconds);
(int) SVFIELD (client->edict, frags, float), hours, minutes, seconds);
print (" %s\n", client->netconnection->address);
}
}
@ -137,11 +137,11 @@ Host_God_f (void)
return;
}
if (pr_global_struct->deathmatch && !host_client->privileged)
if (*sv_globals.deathmatch && !host_client->privileged)
return;
sv_player->v.flags = (int) sv_player->v.flags ^ FL_GODMODE;
if (!((int) sv_player->v.flags & FL_GODMODE))
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) ^ FL_GODMODE;
if (!((int) SVFIELD (sv_player, flags, float) & FL_GODMODE))
SV_ClientPrintf ("godmode OFF\n");
else
SV_ClientPrintf ("godmode ON\n");
@ -155,11 +155,11 @@ Host_Notarget_f (void)
return;
}
if (pr_global_struct->deathmatch && !host_client->privileged)
if (*sv_globals.deathmatch && !host_client->privileged)
return;
sv_player->v.flags = (int) sv_player->v.flags ^ FL_NOTARGET;
if (!((int) sv_player->v.flags & FL_NOTARGET))
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) ^ FL_NOTARGET;
if (!((int) SVFIELD (sv_player, flags, float) & FL_NOTARGET))
SV_ClientPrintf ("notarget OFF\n");
else
SV_ClientPrintf ("notarget ON\n");
@ -175,16 +175,16 @@ Host_Noclip_f (void)
return;
}
if (pr_global_struct->deathmatch && !host_client->privileged)
if (*sv_globals.deathmatch && !host_client->privileged)
return;
if (sv_player->v.movetype != MOVETYPE_NOCLIP) {
if (SVFIELD (sv_player, movetype, float) != MOVETYPE_NOCLIP) {
noclip_anglehack = true;
sv_player->v.movetype = MOVETYPE_NOCLIP;
SVFIELD (sv_player, movetype, float) = MOVETYPE_NOCLIP;
SV_ClientPrintf ("noclip ON\n");
} else {
noclip_anglehack = false;
sv_player->v.movetype = MOVETYPE_WALK;
SVFIELD (sv_player, movetype, float) = MOVETYPE_WALK;
SV_ClientPrintf ("noclip OFF\n");
}
}
@ -204,14 +204,14 @@ Host_Fly_f (void)
return;
}
if (pr_global_struct->deathmatch && !host_client->privileged)
if (*sv_globals.deathmatch && !host_client->privileged)
return;
if (sv_player->v.movetype != MOVETYPE_FLY) {
sv_player->v.movetype = MOVETYPE_FLY;
if (SVFIELD (sv_player, movetype, float) != MOVETYPE_FLY) {
SVFIELD (sv_player, movetype, float) = MOVETYPE_FLY;
SV_ClientPrintf ("flymode ON\n");
} else {
sv_player->v.movetype = MOVETYPE_WALK;
SVFIELD (sv_player, movetype, float) = MOVETYPE_WALK;
SV_ClientPrintf ("flymode OFF\n");
}
}
@ -511,7 +511,7 @@ Host_Savegame_f (void)
}
for (i = 0; i < svs.maxclients; i++) {
if (svs.clients[i].active && (svs.clients[i].edict->v.health <= 0)) {
if (svs.clients[i].active && (SVFIELD (svs.clients[i].edict, health, float) <= 0)) {
Con_Printf ("Can't savegame with a dead player\n");
return;
}
@ -546,9 +546,9 @@ Host_Savegame_f (void)
}
ED_WriteGlobals (f);
ED_WriteGlobals (&sv_pr_state, f);
for (i = 0; i < sv.num_edicts; i++) {
ED_Write (f, EDICT_NUM (i));
ED_Write (&sv_pr_state, f, EDICT_NUM (&sv_pr_state, i));
Qflush (f);
}
Qclose (f);
@ -678,13 +678,13 @@ Host_Loadgame_f (void)
Sys_Error ("First token isn't a brace");
if (entnum == -1) { // parse the global vars
ED_ParseGlobals (start);
ED_ParseGlobals (&sv_pr_state, start);
} else { // parse an edict
ent = EDICT_NUM (entnum);
memset (&ent->v, 0, progs->entityfields * 4);
ent = EDICT_NUM (&sv_pr_state, entnum);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
ent->free = false;
ED_ParseEdict (start, ent);
ED_ParseEdict (&sv_pr_state, start, ent);
// link it into the bsp tree
if (!ent->free)
@ -748,7 +748,7 @@ SaveGamestate ()
for (i = svs.maxclients + 1; i < sv.num_edicts; i++) {
ent = EDICT_NUM (i);
if ((int) ent->v.flags & FL_ARCHIVE_OVERRIDE)
if ((int) SVFIELD (ent, flags, float) & FL_ARCHIVE_OVERRIDE)
continue;
Qprintf (f, "%i\n", i);
ED_Write (f, ent);
@ -936,7 +936,8 @@ Host_Name_f (void)
if (strcmp (host_client->name, newName) != 0)
Con_Printf ("%s renamed to %s\n", host_client->name, newName);
strcpy (host_client->name, newName);
host_client->edict->v.netname = host_client->name - pr_strings;
SVFIELD (host_client->edict, netname, string) =
PR_SetString (&sv_pr_state, host_client->name);
// send notification to all clients
@ -1001,7 +1002,7 @@ Host_Say (qboolean teamonly)
if (!client || !client->active || !client->spawned)
continue;
if (teamplay->int_val && teamonly
&& client->edict->v.team != save->edict->v.team) continue;
&& SVFIELD (client->edict, team, float) != SVFIELD (save->edict, team, float)) continue;
host_client = client;
SV_ClientPrintf ("%s", text);
}
@ -1116,7 +1117,7 @@ Host_Color_f (void)
}
host_client->colors = playercolor;
host_client->edict->v.team = bottom + 1;
SVFIELD (host_client->edict, team, float) = bottom + 1;
// send notification to all clients
MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
@ -1137,14 +1138,15 @@ Host_Kill_f (void)
return;
}
if (sv_player->v.health <= 0) {
if (SVFIELD (sv_player, health, float) <= 0) {
SV_ClientPrintf ("Can't suicide -- already dead!\n");
return;
}
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->ClientKill);
*sv_globals.time = sv.time;
*sv_globals.self =
EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientKill);
}
@ -1168,10 +1170,10 @@ Host_Pause_f (void)
if (sv.paused) {
SV_BroadcastPrintf ("%s paused the game\n",
pr_strings + sv_player->v.netname);
PR_GetString (&sv_pr_state, SVFIELD (sv_player, netname, string)));
} else {
SV_BroadcastPrintf ("%s unpaused the game\n",
pr_strings + sv_player->v.netname);
PR_GetString (&sv_pr_state, SVFIELD (sv_player, netname, string)));
}
// send notification to all clients
@ -1237,26 +1239,29 @@ Host_Spawn_f (void)
// set up the edict
ent = host_client->edict;
memset (&ent->v, 0, progs->entityfields * 4);
ent->v.colormap = NUM_FOR_EDICT (ent);
ent->v.team = (host_client->colors & 15) + 1;
ent->v.netname = host_client->name - pr_strings;
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
SVFIELD (ent, colormap, float) = NUM_FOR_EDICT (&sv_pr_state, ent);
SVFIELD (ent, team, float) = (host_client->colors & 15) + 1;
SVFIELD (ent, netname, string) = PR_SetString (&sv_pr_state, host_client->name);
// copy spawn parms out of the client_t
for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
sv_globals.parms[i] = host_client->spawn_parms[i];
// call the spawn function
pr_global_struct->time = sv.time;
pr_global_struct->self = EDICT_TO_PROG (sv_player);
PR_ExecuteProgram (pr_global_struct->ClientConnect);
*sv_globals.time = sv.time;
*sv_globals.self =
EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state,
sv_funcs.ClientConnect);
if ((Sys_DoubleTime () - host_client->netconnection->connecttime) <=
sv.time) Sys_Printf ("%s entered the game\n", host_client->name);
PR_ExecuteProgram (pr_global_struct->PutClientInServer);
PR_ExecuteProgram (&sv_pr_state,
sv_funcs.PutClientInServer);
}
@ -1291,19 +1296,23 @@ Host_Spawn_f (void)
//
MSG_WriteByte (&host_client->message, svc_updatestat);
MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS);
MSG_WriteLong (&host_client->message, pr_global_struct->total_secrets);
MSG_WriteLong (&host_client->message,
*sv_globals.total_secrets);
MSG_WriteByte (&host_client->message, svc_updatestat);
MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS);
MSG_WriteLong (&host_client->message, pr_global_struct->total_monsters);
MSG_WriteLong (&host_client->message,
*sv_globals.total_monsters);
MSG_WriteByte (&host_client->message, svc_updatestat);
MSG_WriteByte (&host_client->message, STAT_SECRETS);
MSG_WriteLong (&host_client->message, pr_global_struct->found_secrets);
MSG_WriteLong (&host_client->message,
*sv_globals.found_secrets);
MSG_WriteByte (&host_client->message, svc_updatestat);
MSG_WriteByte (&host_client->message, STAT_MONSTERS);
MSG_WriteLong (&host_client->message, pr_global_struct->killed_monsters);
MSG_WriteLong (&host_client->message,
*sv_globals.killed_monsters);
//
@ -1312,10 +1321,10 @@ Host_Spawn_f (void)
// in a state where it is expecting the client to correct the angle
// and it won't happen if the game was just loaded, so you wind up
// with a permanent head tilt
ent = EDICT_NUM (1 + (host_client - svs.clients));
ent = EDICT_NUM (&sv_pr_state, 1 + (host_client - svs.clients));
MSG_WriteByte (&host_client->message, svc_setangle);
for (i = 0; i < 2; i++)
MSG_WriteAngle (&host_client->message, ent->v.angles[i]);
MSG_WriteAngle (&host_client->message, SVFIELD (ent, angles, vector)[i]);
MSG_WriteAngle (&host_client->message, 0);
SV_WriteClientdataToMessage (sv_player, &host_client->message);
@ -1365,8 +1374,9 @@ Host_Kick_f (void)
Cmd_ForwardToServer ();
return;
}
} else if (pr_global_struct->deathmatch && !host_client->privileged)
return;
}
else if (*sv_globals.deathmatch
&& !host_client->privileged) return;
save = host_client;
@ -1447,7 +1457,7 @@ Host_Give_f (void)
return;
}
if (pr_global_struct->deathmatch && !host_client->privileged)
if (*sv_globals.deathmatch && !host_client->privileged)
return;
t = Cmd_Argv (1);
@ -1468,101 +1478,104 @@ Host_Give_f (void)
if (hipnotic) {
if (t[0] == '6') {
if (t[1] == 'a')
sv_player->v.items =
(int) sv_player->v.items | HIT_PROXIMITY_GUN;
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | HIT_PROXIMITY_GUN;
else
sv_player->v.items =
(int) sv_player->v.items | IT_GRENADE_LAUNCHER;
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | IT_GRENADE_LAUNCHER;
} else if (t[0] == '9')
sv_player->v.items =
(int) sv_player->v.items | HIT_LASER_CANNON;
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | HIT_LASER_CANNON;
else if (t[0] == '0')
sv_player->v.items = (int) sv_player->v.items | HIT_MJOLNIR;
SVFIELD (sv_player, items, float) = (int) SVFIELD (sv_player, items, float) | HIT_MJOLNIR;
else if (t[0] >= '2')
sv_player->v.items =
(int) sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | (IT_SHOTGUN << (t[0] - '2'));
} else {
if (t[0] >= '2')
sv_player->v.items =
(int) sv_player->v.items | (IT_SHOTGUN << (t[0] - '2'));
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | (IT_SHOTGUN << (t[0] - '2'));
}
break;
case 's':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_shells1");
val = GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_shells1");
if (val)
val->_float = v;
}
sv_player->v.ammo_shells = v;
SVFIELD (sv_player, ammo_shells, float) = v;
break;
case 'n':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_nails1");
val = GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_nails1");
if (val) {
val->_float = v;
if (sv_player->v.weapon <= IT_LIGHTNING)
sv_player->v.ammo_nails = v;
if (SVFIELD (sv_player, weapon, float) <= IT_LIGHTNING)
SVFIELD (sv_player, ammo_nails, float) = v;
}
} else {
sv_player->v.ammo_nails = v;
SVFIELD (sv_player, ammo_nails, float) = v;
}
break;
case 'l':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_lava_nails");
val =
GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_lava_nails");
if (val) {
val->_float = v;
if (sv_player->v.weapon > IT_LIGHTNING)
sv_player->v.ammo_nails = v;
if (SVFIELD (sv_player, weapon, float) > IT_LIGHTNING)
SVFIELD (sv_player, ammo_nails, float) = v;
}
}
break;
case 'r':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_rockets1");
val = GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_rockets1");
if (val) {
val->_float = v;
if (sv_player->v.weapon <= IT_LIGHTNING)
sv_player->v.ammo_rockets = v;
if (SVFIELD (sv_player, weapon, float) <= IT_LIGHTNING)
SVFIELD (sv_player, ammo_rockets, float) = v;
}
} else {
sv_player->v.ammo_rockets = v;
SVFIELD (sv_player, ammo_rockets, float) = v;
}
break;
case 'm':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_multi_rockets");
val =
GetEdictFieldValue (&sv_pr_state, sv_player,
"ammo_multi_rockets");
if (val) {
val->_float = v;
if (sv_player->v.weapon > IT_LIGHTNING)
sv_player->v.ammo_rockets = v;
if (SVFIELD (sv_player, weapon, float) > IT_LIGHTNING)
SVFIELD (sv_player, ammo_rockets, float) = v;
}
}
break;
case 'h':
sv_player->v.health = v;
SVFIELD (sv_player, health, float) = v;
break;
case 'c':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_cells1");
val = GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_cells1");
if (val) {
val->_float = v;
if (sv_player->v.weapon <= IT_LIGHTNING)
sv_player->v.ammo_cells = v;
if (SVFIELD (sv_player, weapon, float) <= IT_LIGHTNING)
SVFIELD (sv_player, ammo_cells, float) = v;
}
} else {
sv_player->v.ammo_cells = v;
SVFIELD (sv_player, ammo_cells, float) = v;
}
break;
case 'p':
if (rogue) {
val = GetEdictFieldValue (sv_player, "ammo_plasma");
val = GetEdictFieldValue (&sv_pr_state, sv_player, "ammo_plasma");
if (val) {
val->_float = v;
if (sv_player->v.weapon > IT_LIGHTNING)
sv_player->v.ammo_cells = v;
if (SVFIELD (sv_player, weapon, float) > IT_LIGHTNING)
SVFIELD (sv_player, ammo_cells, float) = v;
}
}
break;
@ -1576,8 +1589,8 @@ FindViewthing (void)
edict_t *e;
for (i = 0; i < sv.num_edicts; i++) {
e = EDICT_NUM (i);
if (!strcmp (pr_strings + e->v.classname, "viewthing"))
e = EDICT_NUM (&sv_pr_state, i);
if (!strcmp (PR_GetString (&sv_pr_state, SVFIELD (e, classname, string)), "viewthing"))
return e;
}
Con_Printf ("No viewthing on map\n");
@ -1605,8 +1618,8 @@ Host_Viewmodel_f (void)
return;
}
e->v.frame = 0;
cl.model_precache[(int) e->v.modelindex] = m;
SVFIELD (e, frame, float) = 0;
cl.model_precache[(int) SVFIELD (e, modelindex, float)] = m;
}
/*
@ -1624,13 +1637,13 @@ Host_Viewframe_f (void)
e = FindViewthing ();
if (!e)
return;
m = cl.model_precache[(int) e->v.modelindex];
m = cl.model_precache[(int) SVFIELD (e, modelindex, float)];
f = atoi (Cmd_Argv (1));
if (f >= m->numframes)
f = m->numframes - 1;
e->v.frame = f;
SVFIELD (e, frame, float) = f;
}
@ -1662,13 +1675,13 @@ Host_Viewnext_f (void)
e = FindViewthing ();
if (!e)
return;
m = cl.model_precache[(int) e->v.modelindex];
m = cl.model_precache[(int) SVFIELD (e, modelindex, float)];
e->v.frame = e->v.frame + 1;
if (e->v.frame >= m->numframes)
e->v.frame = m->numframes - 1;
SVFIELD (e, frame, float) = SVFIELD (e, frame, float) + 1;
if (SVFIELD (e, frame, float) >= m->numframes)
SVFIELD (e, frame, float) = m->numframes - 1;
PrintFrameName (m, e->v.frame);
PrintFrameName (m, SVFIELD (e, frame, float));
}
/*
@ -1686,13 +1699,13 @@ Host_Viewprev_f (void)
if (!e)
return;
m = cl.model_precache[(int) e->v.modelindex];
m = cl.model_precache[(int) SVFIELD (e, modelindex, float)];
e->v.frame = e->v.frame - 1;
if (e->v.frame < 0)
e->v.frame = 0;
SVFIELD (e, frame, float) = SVFIELD (e, frame, float) - 1;
if (SVFIELD (e, frame, float) < 0)
SVFIELD (e, frame, float) = 0;
PrintFrameName (m, e->v.frame);
PrintFrameName (m, SVFIELD (e, frame, float));
}
/*

View file

@ -45,6 +45,7 @@
#include "console.h"
#include "net.h"
#include "game.h"
#include "sv_progs.h"
// This is enables a simple IP banning mechanism
#define BAN_TEST
@ -145,8 +146,8 @@ NET_Ban_f (void)
}
print = Con_Printf;
} else {
if (pr_global_struct->deathmatch && !host_client->privileged)
return;
if (*sv_globals.deathmatch
&& !host_client->privileged) return;
print = SV_ClientPrintf;
}
@ -945,7 +946,7 @@ _Datagram_CheckNewConnections (void)
MSG_WriteByte (net_message->message, playerNumber);
MSG_WriteString (net_message->message, client->name);
MSG_WriteLong (net_message->message, client->colors);
MSG_WriteLong (net_message->message, (int) client->edict->v.frags);
MSG_WriteLong (net_message->message, SVFIELD (client->edict, frags, float));
MSG_WriteLong (net_message->message,
(int) (net_time - client->netconnection->connecttime));
MSG_WriteString (net_message->message, client->netconnection->address);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,680 +0,0 @@
/*
pr_exec.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdarg.h>
#include "progs.h"
#include "server.h"
#include "host.h"
#include "sys.h"
#include "console.h"
/*
*/
typedef struct {
int s;
dfunction_t *f;
} prstack_t;
#define MAX_STACK_DEPTH 32
prstack_t pr_stack[MAX_STACK_DEPTH];
int pr_depth;
#define LOCALSTACK_SIZE 2048
int localstack[LOCALSTACK_SIZE];
int localstack_used;
qboolean pr_trace;
dfunction_t *pr_xfunction;
int pr_xstatement;
int pr_argc;
char *pr_opnames[] = {
"DONE",
"MUL_F",
"MUL_V",
"MUL_FV",
"MUL_VF",
"DIV",
"ADD_F",
"ADD_V",
"SUB_F",
"SUB_V",
"EQ_F",
"EQ_V",
"EQ_S",
"EQ_E",
"EQ_FNC",
"NE_F",
"NE_V",
"NE_S",
"NE_E",
"NE_FNC",
"LE",
"GE",
"LT",
"GT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"ADDRESS",
"STORE_F",
"STORE_V",
"STORE_S",
"STORE_ENT",
"STORE_FLD",
"STORE_FNC",
"STOREP_F",
"STOREP_V",
"STOREP_S",
"STOREP_ENT",
"STOREP_FLD",
"STOREP_FNC",
"RETURN",
"NOT_F",
"NOT_V",
"NOT_S",
"NOT_ENT",
"NOT_FNC",
"IF",
"IFNOT",
"CALL0",
"CALL1",
"CALL2",
"CALL3",
"CALL4",
"CALL5",
"CALL6",
"CALL7",
"CALL8",
"STATE",
"GOTO",
"AND",
"OR",
"BITAND",
"BITOR"
};
char *PR_GlobalString (int ofs);
char *PR_GlobalStringNoContents (int ofs);
//=============================================================================
/*
=================
PR_PrintStatement
=================
*/
void
PR_PrintStatement (dstatement_t *s)
{
int i;
if ((unsigned) s->op < sizeof (pr_opnames) / sizeof (pr_opnames[0])) {
Con_Printf ("%s ", pr_opnames[s->op]);
i = strlen (pr_opnames[s->op]);
for (; i < 10; i++)
Con_Printf (" ");
}
if (s->op == OP_IF || s->op == OP_IFNOT)
Con_Printf ("%sbranch %i", PR_GlobalString (s->a), s->b);
else if (s->op == OP_GOTO) {
Con_Printf ("branch %i", s->a);
} else if ((unsigned) (s->op - OP_STORE_F) < 6) {
Con_Printf ("%s", PR_GlobalString (s->a));
Con_Printf ("%s", PR_GlobalStringNoContents (s->b));
} else {
if (s->a)
Con_Printf ("%s", PR_GlobalString (s->a));
if (s->b)
Con_Printf ("%s", PR_GlobalString (s->b));
if (s->c)
Con_Printf ("%s", PR_GlobalStringNoContents (s->c));
}
Con_Printf ("\n");
}
/*
============
PR_StackTrace
============
*/
void
PR_StackTrace (void)
{
dfunction_t *f;
int i;
if (pr_depth == 0) {
Con_Printf ("<NO STACK>\n");
return;
}
pr_stack[pr_depth].f = pr_xfunction;
for (i = pr_depth; i >= 0; i--) {
f = pr_stack[i].f;
if (!f) {
Con_Printf ("<NO FUNCTION>\n");
} else
Con_Printf ("%12s : %s\n", pr_strings + f->s_file,
pr_strings + f->s_name);
}
}
/*
============
PR_Profile_f
============
*/
void
PR_Profile_f (void)
{
dfunction_t *f, *best;
int max;
int num;
int i;
num = 0;
do {
max = 0;
best = NULL;
for (i = 0; i < progs->numfunctions; i++) {
f = &pr_functions[i];
if (f->profile > max) {
max = f->profile;
best = f;
}
}
if (best) {
if (num < 10)
Con_Printf ("%7i %s\n", best->profile,
pr_strings + best->s_name);
num++;
best->profile = 0;
}
} while (best);
}
/*
============
PR_RunError
Aborts the currently executing function
============
*/
void
PR_RunError (char *error, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, error);
vsnprintf (string, sizeof (string), error, argptr);
va_end (argptr);
PR_PrintStatement (pr_statements + pr_xstatement);
PR_StackTrace ();
Con_Printf ("%s\n", string);
pr_depth = 0; // dump the stack so host_error can
// shutdown functions
Host_Error ("Program error");
}
/*
============================================================================
PR_ExecuteProgram
The interpretation main loop
============================================================================
*/
/*
====================
PR_EnterFunction
Returns the new program statement counter
====================
*/
int
PR_EnterFunction (dfunction_t *f)
{
int i, j, c, o;
pr_stack[pr_depth].s = pr_xstatement;
pr_stack[pr_depth].f = pr_xfunction;
pr_depth++;
if (pr_depth >= MAX_STACK_DEPTH)
PR_RunError ("stack overflow");
// save off any locals that the new function steps on
c = f->locals;
if (localstack_used + c > LOCALSTACK_SIZE)
PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
for (i = 0; i < c; i++)
localstack[localstack_used + i] =
((int *) pr_globals)[f->parm_start + i];
localstack_used += c;
// copy parameters
o = f->parm_start;
for (i = 0; i < f->numparms; i++) {
for (j = 0; j < f->parm_size[i]; j++) {
((int *) pr_globals)[o] = ((int *) pr_globals)[OFS_PARM0 + i * 3 + j];
o++;
}
}
pr_xfunction = f;
return f->first_statement - 1; // offset the s++
}
/*
====================
PR_LeaveFunction
====================
*/
int
PR_LeaveFunction (void)
{
int i, c;
if (pr_depth <= 0)
Sys_Error ("prog stack underflow");
// restore locals from the stack
c = pr_xfunction->locals;
localstack_used -= c;
if (localstack_used < 0)
PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
for (i = 0; i < c; i++)
((int *) pr_globals)[pr_xfunction->parm_start + i] =
localstack[localstack_used + i];
// up stack
pr_depth--;
pr_xfunction = pr_stack[pr_depth].f;
return pr_stack[pr_depth].s;
}
/*
====================
PR_ExecuteProgram
====================
*/
void
PR_ExecuteProgram (func_t fnum)
{
eval_t *a, *b, *c;
int s;
dstatement_t *st;
dfunction_t *f, *newf;
int runaway;
int i;
edict_t *ed;
int exitdepth;
eval_t *ptr;
a = b = c = 0;
st = 0;
if (!fnum || fnum >= progs->numfunctions) {
if (pr_global_struct->self)
ED_Print (PROG_TO_EDICT (pr_global_struct->self));
Host_Error ("PR_ExecuteProgram: NULL function");
}
f = &pr_functions[fnum];
runaway = 100000;
pr_trace = false;
// make a stack frame
exitdepth = pr_depth;
s = PR_EnterFunction (f);
while (1) {
s++; // next statement
st = &pr_statements[s];
a = (eval_t *) &pr_globals[st->a];
b = (eval_t *) &pr_globals[st->b];
c = (eval_t *) &pr_globals[st->c];
if (!--runaway)
PR_RunError ("runaway loop error");
pr_xfunction->profile++;
pr_xstatement = s;
if (pr_trace)
PR_PrintStatement (st);
switch (st->op) {
case OP_ADD_F:
c->_float = a->_float + b->_float;
break;
case OP_ADD_V:
c->vector[0] = a->vector[0] + b->vector[0];
c->vector[1] = a->vector[1] + b->vector[1];
c->vector[2] = a->vector[2] + b->vector[2];
break;
case OP_SUB_F:
c->_float = a->_float - b->_float;
break;
case OP_SUB_V:
c->vector[0] = a->vector[0] - b->vector[0];
c->vector[1] = a->vector[1] - b->vector[1];
c->vector[2] = a->vector[2] - b->vector[2];
break;
case OP_MUL_F:
c->_float = a->_float * b->_float;
break;
case OP_MUL_V:
c->_float = a->vector[0] * b->vector[0]
+ a->vector[1] * b->vector[1]
+ a->vector[2] * b->vector[2];
break;
case OP_MUL_FV:
c->vector[0] = a->_float * b->vector[0];
c->vector[1] = a->_float * b->vector[1];
c->vector[2] = a->_float * b->vector[2];
break;
case OP_MUL_VF:
c->vector[0] = b->_float * a->vector[0];
c->vector[1] = b->_float * a->vector[1];
c->vector[2] = b->_float * a->vector[2];
break;
case OP_DIV_F:
c->_float = a->_float / b->_float;
break;
case OP_BITAND:
c->_float = (int) a->_float & (int) b->_float;
break;
case OP_BITOR:
c->_float = (int) a->_float | (int) b->_float;
break;
case OP_GE:
c->_float = a->_float >= b->_float;
break;
case OP_LE:
c->_float = a->_float <= b->_float;
break;
case OP_GT:
c->_float = a->_float > b->_float;
break;
case OP_LT:
c->_float = a->_float < b->_float;
break;
case OP_AND:
c->_float = a->_float && b->_float;
break;
case OP_OR:
c->_float = a->_float || b->_float;
break;
case OP_NOT_F:
c->_float = !a->_float;
break;
case OP_NOT_V:
c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
break;
case OP_NOT_S:
c->_float = !a->string || !pr_strings[a->string];
break;
case OP_NOT_FNC:
c->_float = !a->function;
break;
case OP_NOT_ENT:
c->_float = (PROG_TO_EDICT (a->edict) == sv.edicts);
break;
case OP_EQ_F:
c->_float = a->_float == b->_float;
break;
case OP_EQ_V:
c->_float = (a->vector[0] == b->vector[0]) &&
(a->vector[1] == b->vector[1]) &&
(a->vector[2] == b->vector[2]);
break;
case OP_EQ_S:
c->_float =
!strcmp (pr_strings + a->string, pr_strings + b->string);
break;
case OP_EQ_E:
c->_float = a->_int == b->_int;
break;
case OP_EQ_FNC:
c->_float = a->function == b->function;
break;
case OP_NE_F:
c->_float = a->_float != b->_float;
break;
case OP_NE_V:
c->_float = (a->vector[0] != b->vector[0]) ||
(a->vector[1] != b->vector[1]) ||
(a->vector[2] != b->vector[2]);
break;
case OP_NE_S:
c->_float = strcmp (pr_strings + a->string, pr_strings + b->string);
break;
case OP_NE_E:
c->_float = a->_int != b->_int;
break;
case OP_NE_FNC:
c->_float = a->function != b->function;
break;
//==================
case OP_STORE_F:
case OP_STORE_ENT:
case OP_STORE_FLD: // integers
case OP_STORE_S:
case OP_STORE_FNC: // pointers
b->_int = a->_int;
break;
case OP_STORE_V:
b->vector[0] = a->vector[0];
b->vector[1] = a->vector[1];
b->vector[2] = a->vector[2];
break;
case OP_STOREP_F:
case OP_STOREP_ENT:
case OP_STOREP_FLD: // integers
case OP_STOREP_S:
case OP_STOREP_FNC: // pointers
ptr = (eval_t *) ((byte *) sv.edicts + b->_int);
ptr->_int = a->_int;
break;
case OP_STOREP_V:
ptr = (eval_t *) ((byte *) sv.edicts + b->_int);
ptr->vector[0] = a->vector[0];
ptr->vector[1] = a->vector[1];
ptr->vector[2] = a->vector[2];
break;
case OP_ADDRESS:
ed = PROG_TO_EDICT (a->edict);
#ifdef PARANOID
NUM_FOR_EDICT (ed); // make sure it's in range
#endif
if (ed == (edict_t *) sv.edicts && sv.state == ss_active)
PR_RunError ("assignment to world entity");
c->_int = (byte *) ((int *) &ed->v + b->_int) - (byte *) sv.edicts;
break;
case OP_LOAD_F:
case OP_LOAD_FLD:
case OP_LOAD_ENT:
case OP_LOAD_S:
case OP_LOAD_FNC:
ed = PROG_TO_EDICT (a->edict);
#ifdef PARANOID
NUM_FOR_EDICT (ed); // make sure it's in range
#endif
a = (eval_t *) ((int *) &ed->v + b->_int);
c->_int = a->_int;
break;
case OP_LOAD_V:
ed = PROG_TO_EDICT (a->edict);
#ifdef PARANOID
NUM_FOR_EDICT (ed); // make sure it's in range
#endif
a = (eval_t *) ((int *) &ed->v + b->_int);
c->vector[0] = a->vector[0];
c->vector[1] = a->vector[1];
c->vector[2] = a->vector[2];
break;
//==================
case OP_IFNOT:
if (!a->_int)
s += st->b - 1; // offset the s++
break;
case OP_IF:
if (a->_int)
s += st->b - 1; // offset the s++
break;
case OP_GOTO:
s += st->a - 1; // offset the s++
break;
case OP_CALL0:
case OP_CALL1:
case OP_CALL2:
case OP_CALL3:
case OP_CALL4:
case OP_CALL5:
case OP_CALL6:
case OP_CALL7:
case OP_CALL8:
pr_argc = st->op - OP_CALL0;
if (!a->function)
PR_RunError ("NULL function");
newf = &pr_functions[a->function];
if (newf->first_statement < 0) { // negative statements are
// built in functions
i = -newf->first_statement;
if (i >= pr_numbuiltins)
PR_RunError ("Bad builtin call number");
pr_builtins[i] ();
break;
}
s = PR_EnterFunction (newf);
break;
case OP_DONE:
case OP_RETURN:
pr_globals[OFS_RETURN] = pr_globals[st->a];
pr_globals[OFS_RETURN + 1] = pr_globals[st->a + 1];
pr_globals[OFS_RETURN + 2] = pr_globals[st->a + 2];
s = PR_LeaveFunction ();
if (pr_depth == exitdepth)
return; // all done
break;
case OP_STATE:
ed = PROG_TO_EDICT (pr_global_struct->self);
#ifdef FPS_20
ed->v.nextthink = pr_global_struct->time + 0.05;
#else
ed->v.nextthink = pr_global_struct->time + 0.1;
#endif
if (a->_float != ed->v.frame) {
ed->v.frame = a->_float;
}
ed->v.think = b->function;
break;
default:
PR_RunError ("Bad opcode %i", st->op);
}
}
}

View file

@ -38,12 +38,15 @@
#include "cmd.h"
#include "host.h"
#include "world.h"
#include "sv_progs.h"
server_t sv;
server_static_t svs;
char localmodels[MAX_MODELS][5]; // inline model names for precache
entity_state_t baselines[MAX_EDICTS];
//============================================================================
/*
@ -157,7 +160,7 @@ SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
return;
}
ent = NUM_FOR_EDICT (entity);
ent = NUM_FOR_EDICT (&sv_pr_state, entity);
channel = (ent << 3) | channel;
@ -178,8 +181,8 @@ SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
MSG_WriteByte (&sv.datagram, sound_num);
for (i = 0; i < 3; i++)
MSG_WriteCoord (&sv.datagram,
entity->v.origin[i] + 0.5 * (entity->v.mins[i] +
entity->v.maxs[i]));
SVFIELD (entity, origin, vector)[i] + 0.5 * (SVFIELD (entity, mins, vector)[i] +
SVFIELD (entity, maxs, vector)[i]));
}
/*
@ -206,7 +209,7 @@ SV_SendServerinfo (client_t *client)
MSG_WriteByte (&client->message, svc_print);
snprintf (message, sizeof (message), "%c\nVersion %s server (%i CRC)", 2,
NQ_VERSION, pr_crc);
NQ_VERSION, sv_pr_state.crc);
MSG_WriteString (&client->message, message);
MSG_WriteByte (&client->message, svc_serverinfo);
@ -218,7 +221,8 @@ SV_SendServerinfo (client_t *client)
else
MSG_WriteByte (&client->message, GAME_COOP);
snprintf (message, sizeof (message), pr_strings + sv.edicts->v.message);
snprintf (message, sizeof (message),
PR_GetString (&sv_pr_state, SVFIELD (sv.edicts, message, string)));
MSG_WriteString (&client->message, message);
@ -232,12 +236,13 @@ SV_SendServerinfo (client_t *client)
// send music
MSG_WriteByte (&client->message, svc_cdtrack);
MSG_WriteByte (&client->message, sv.edicts->v.sounds);
MSG_WriteByte (&client->message, sv.edicts->v.sounds);
MSG_WriteByte (&client->message, SVFIELD (sv.edicts, sounds, float));
MSG_WriteByte (&client->message, SVFIELD (sv.edicts, sounds, float));
// set view
MSG_WriteByte (&client->message, svc_setview);
MSG_WriteShort (&client->message, NUM_FOR_EDICT (client->edict));
MSG_WriteShort (&client->message,
NUM_FOR_EDICT (&sv_pr_state, client->edict));
MSG_WriteByte (&client->message, svc_signonnum);
MSG_WriteByte (&client->message, 1);
@ -270,7 +275,7 @@ SV_ConnectClient (int clientnum)
edictnum = clientnum + 1;
ent = EDICT_NUM (edictnum);
ent = EDICT_NUM (&sv_pr_state, edictnum);
// set up the client_t
netconnection = client->netconnection;
@ -294,9 +299,10 @@ SV_ConnectClient (int clientnum)
memcpy (client->spawn_parms, spawn_parms, sizeof (spawn_parms));
else {
// call the progs to get default spawn parms for the new client
PR_ExecuteProgram (pr_global_struct->SetNewParms);
PR_ExecuteProgram (&sv_pr_state,
sv_funcs.SetNewParms);
for (i = 0; i < NUM_SPAWN_PARMS; i++)
client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
client->spawn_parms[i] = sv_globals.parms[i];
}
SV_SendServerinfo (client);
@ -444,15 +450,15 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
edict_t *ent;
// find the client's PVS
VectorAdd (clent->v.origin, clent->v.view_ofs, org);
VectorAdd (SVFIELD (clent, origin, vector), SVFIELD (clent, view_ofs, vector), org);
pvs = SV_FatPVS (org);
// send over all entities (excpet the client) that touch the pvs
ent = NEXT_EDICT (sv.edicts);
for (e = 1; e < sv.num_edicts; e++, ent = NEXT_EDICT (ent)) {
ent = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, ent = NEXT_EDICT (&sv_pr_state, ent)) {
#ifdef QUAKE2
// don't send if flagged for NODRAW and there are no lighting effects
if (ent->v.effects == EF_NODRAW)
if (SVFIELD (ent, effects, float) == EF_NODRAW)
continue;
#endif
@ -460,7 +466,7 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
if (ent != clent) // clent is ALLWAYS sent
{
// ignore ents without visible models
if (!ent->v.modelindex || !pr_strings[ent->v.model])
if (!SVFIELD (ent, modelindex, float) || !*PR_GetString (&sv_pr_state, SVFIELD (ent, model, string)))
continue;
for (i = 0; i < ent->num_leafs; i++)
@ -479,36 +485,36 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
bits = 0;
for (i = 0; i < 3; i++) {
miss = ent->v.origin[i] - ent->baseline.origin[i];
miss = SVFIELD (ent, origin, vector)[i] - ((entity_state_t*)ent->data)->origin[i];
if (miss < -0.1 || miss > 0.1)
bits |= U_ORIGIN1 << i;
}
if (ent->v.angles[0] != ent->baseline.angles[0])
if (SVFIELD (ent, angles, vector)[0] != ((entity_state_t*)ent->data)->angles[0])
bits |= U_ANGLE1;
if (ent->v.angles[1] != ent->baseline.angles[1])
if (SVFIELD (ent, angles, vector)[1] != ((entity_state_t*)ent->data)->angles[1])
bits |= U_ANGLE2;
if (ent->v.angles[2] != ent->baseline.angles[2])
if (SVFIELD (ent, angles, vector)[2] != ((entity_state_t*)ent->data)->angles[2])
bits |= U_ANGLE3;
if (ent->v.movetype == MOVETYPE_STEP)
if (SVFIELD (ent, movetype, float) == MOVETYPE_STEP)
bits |= U_NOLERP; // don't mess up the step animation
if (ent->baseline.colormap != ent->v.colormap)
if (((entity_state_t*)ent->data)->colormap != SVFIELD (ent, colormap, float))
bits |= U_COLORMAP;
if (ent->baseline.skin != ent->v.skin)
if (((entity_state_t*)ent->data)->skin != SVFIELD (ent, skin, float))
bits |= U_SKIN;
if (ent->baseline.frame != ent->v.frame)
if (((entity_state_t*)ent->data)->frame != SVFIELD (ent, frame, float))
bits |= U_FRAME;
if (ent->baseline.effects != ent->v.effects)
if (((entity_state_t*)ent->data)->effects != SVFIELD (ent, effects, float))
bits |= U_EFFECTS;
if (ent->baseline.modelindex != ent->v.modelindex)
if (((entity_state_t*)ent->data)->modelindex != SVFIELD (ent, modelindex, float))
bits |= U_MODEL;
if (e >= 256)
@ -530,27 +536,27 @@ SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg)
MSG_WriteByte (msg, e);
if (bits & U_MODEL)
MSG_WriteByte (msg, ent->v.modelindex);
MSG_WriteByte (msg, SVFIELD (ent, modelindex, float));
if (bits & U_FRAME)
MSG_WriteByte (msg, ent->v.frame);
MSG_WriteByte (msg, SVFIELD (ent, frame, float));
if (bits & U_COLORMAP)
MSG_WriteByte (msg, ent->v.colormap);
MSG_WriteByte (msg, SVFIELD (ent, colormap, float));
if (bits & U_SKIN)
MSG_WriteByte (msg, ent->v.skin);
MSG_WriteByte (msg, SVFIELD (ent, skin, float));
if (bits & U_EFFECTS)
MSG_WriteByte (msg, ent->v.effects);
MSG_WriteByte (msg, SVFIELD (ent, effects, float));
if (bits & U_ORIGIN1)
MSG_WriteCoord (msg, ent->v.origin[0]);
MSG_WriteCoord (msg, SVFIELD (ent, origin, vector)[0]);
if (bits & U_ANGLE1)
MSG_WriteAngle (msg, ent->v.angles[0]);
MSG_WriteAngle (msg, SVFIELD (ent, angles, vector)[0]);
if (bits & U_ORIGIN2)
MSG_WriteCoord (msg, ent->v.origin[1]);
MSG_WriteCoord (msg, SVFIELD (ent, origin, vector)[1]);
if (bits & U_ANGLE2)
MSG_WriteAngle (msg, ent->v.angles[1]);
MSG_WriteAngle (msg, SVFIELD (ent, angles, vector)[1]);
if (bits & U_ORIGIN3)
MSG_WriteCoord (msg, ent->v.origin[2]);
MSG_WriteCoord (msg, SVFIELD (ent, origin, vector)[2]);
if (bits & U_ANGLE3)
MSG_WriteAngle (msg, ent->v.angles[2]);
MSG_WriteAngle (msg, SVFIELD (ent, angles, vector)[2]);
}
}
@ -566,9 +572,9 @@ SV_CleanupEnts (void)
int e;
edict_t *ent;
ent = NEXT_EDICT (sv.edicts);
for (e = 1; e < sv.num_edicts; e++, ent = NEXT_EDICT (ent)) {
ent->v.effects = (int) ent->v.effects & ~EF_MUZZLEFLASH;
ent = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, ent = NEXT_EDICT (&sv_pr_state, ent)) {
SVFIELD (ent, effects, float) = (int) SVFIELD (ent, effects, float) & ~EF_MUZZLEFLASH;
}
}
@ -594,18 +600,18 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
//
// send a damage message
//
if (ent->v.dmg_take || ent->v.dmg_save) {
other = PROG_TO_EDICT (ent->v.dmg_inflictor);
if (SVFIELD (ent, dmg_take, float) || SVFIELD (ent, dmg_save, float)) {
other = PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, dmg_inflictor, entity));
MSG_WriteByte (msg, svc_damage);
MSG_WriteByte (msg, ent->v.dmg_save);
MSG_WriteByte (msg, ent->v.dmg_take);
MSG_WriteByte (msg, SVFIELD (ent, dmg_save, float));
MSG_WriteByte (msg, SVFIELD (ent, dmg_take, float));
for (i = 0; i < 3; i++)
MSG_WriteCoord (msg,
other->v.origin[i] + 0.5 * (other->v.mins[i] +
other->v.maxs[i]));
SVFIELD (other, origin, vector)[i] + 0.5 * (SVFIELD (other, mins, vector)[i] +
SVFIELD (other, maxs, vector)[i]));
ent->v.dmg_take = 0;
ent->v.dmg_save = 0;
SVFIELD (ent, dmg_take, float) = 0;
SVFIELD (ent, dmg_save, float) = 0;
}
//
// send the current viewpos offset from the view entity
@ -613,57 +619,57 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
SV_SetIdealPitch (); // how much to look up / down ideally
// a fixangle might get lost in a dropped packet. Oh well.
if (ent->v.fixangle) {
if (SVFIELD (ent, fixangle, float)) {
MSG_WriteByte (msg, svc_setangle);
for (i = 0; i < 3; i++)
MSG_WriteAngle (msg, ent->v.angles[i]);
ent->v.fixangle = 0;
MSG_WriteAngle (msg, SVFIELD (ent, angles, vector)[i]);
SVFIELD (ent, fixangle, float) = 0;
}
bits = 0;
if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT)
if (SVFIELD (ent, view_ofs, vector)[2] != DEFAULT_VIEWHEIGHT)
bits |= SU_VIEWHEIGHT;
if (ent->v.idealpitch)
if (SVFIELD (ent, idealpitch, float))
bits |= SU_IDEALPITCH;
// stuff the sigil bits into the high bits of items for sbar, or else
// mix in items2
#ifdef QUAKE2
items = (int) ent->v.items | ((int) ent->v.items2 << 23);
items = (int) SVFIELD (ent, items, float) | ((int) SVFIELD (ent, items2, float) << 23);
#else
val = GetEdictFieldValue (ent, "items2");
val = GetEdictFieldValue (&sv_pr_state, ent, "items2");
if (val)
items = (int) ent->v.items | ((int) val->_float << 23);
items = (int) SVFIELD (ent, items, float) | ((int) val->_float << 23);
else
items =
(int) ent->v.items | ((int) pr_global_struct->serverflags << 28);
(int) SVFIELD (ent, items, float) | ((int) sv_globals.serverflags << 28);
#endif
bits |= SU_ITEMS;
if ((int) ent->v.flags & FL_ONGROUND)
if ((int) SVFIELD (ent, flags, float) & FL_ONGROUND)
bits |= SU_ONGROUND;
if (ent->v.waterlevel >= 2)
if (SVFIELD (ent, waterlevel, float) >= 2)
bits |= SU_INWATER;
for (i = 0; i < 3; i++) {
if (ent->v.punchangle[i])
if (SVFIELD (ent, punchangle, vector)[i])
bits |= (SU_PUNCH1 << i);
if (ent->v.velocity[i])
if (SVFIELD (ent, velocity, vector)[i])
bits |= (SU_VELOCITY1 << i);
}
if (ent->v.weaponframe)
if (SVFIELD (ent, weaponframe, float))
bits |= SU_WEAPONFRAME;
if (ent->v.armorvalue)
if (SVFIELD (ent, armorvalue, float))
bits |= SU_ARMOR;
// if (ent->v.weapon)
// if (SVFIELD (ent, weapon, float))
bits |= SU_WEAPON;
// send the data
@ -672,40 +678,42 @@ SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
MSG_WriteShort (msg, bits);
if (bits & SU_VIEWHEIGHT)
MSG_WriteChar (msg, ent->v.view_ofs[2]);
MSG_WriteChar (msg, SVFIELD (ent, view_ofs, vector)[2]);
if (bits & SU_IDEALPITCH)
MSG_WriteChar (msg, ent->v.idealpitch);
MSG_WriteChar (msg, SVFIELD (ent, idealpitch, float));
for (i = 0; i < 3; i++) {
if (bits & (SU_PUNCH1 << i))
MSG_WriteChar (msg, ent->v.punchangle[i]);
MSG_WriteChar (msg, SVFIELD (ent, punchangle, vector)[i]);
if (bits & (SU_VELOCITY1 << i))
MSG_WriteChar (msg, ent->v.velocity[i] / 16);
MSG_WriteChar (msg, SVFIELD (ent, velocity, vector)[i] / 16);
}
// [always sent] if (bits & SU_ITEMS)
MSG_WriteLong (msg, items);
if (bits & SU_WEAPONFRAME)
MSG_WriteByte (msg, ent->v.weaponframe);
MSG_WriteByte (msg, SVFIELD (ent, weaponframe, float));
if (bits & SU_ARMOR)
MSG_WriteByte (msg, ent->v.armorvalue);
MSG_WriteByte (msg, SVFIELD (ent, armorvalue, float));
if (bits & SU_WEAPON)
MSG_WriteByte (msg, SV_ModelIndex (pr_strings + ent->v.weaponmodel));
MSG_WriteByte (msg,
SV_ModelIndex (PR_GetString (&sv_pr_state,
SVFIELD (ent, weaponmodel, string))));
MSG_WriteShort (msg, ent->v.health);
MSG_WriteByte (msg, ent->v.currentammo);
MSG_WriteByte (msg, ent->v.ammo_shells);
MSG_WriteByte (msg, ent->v.ammo_nails);
MSG_WriteByte (msg, ent->v.ammo_rockets);
MSG_WriteByte (msg, ent->v.ammo_cells);
MSG_WriteShort (msg, SVFIELD (ent, health, float));
MSG_WriteByte (msg, SVFIELD (ent, currentammo, float));
MSG_WriteByte (msg, SVFIELD (ent, ammo_shells, float));
MSG_WriteByte (msg, SVFIELD (ent, ammo_nails, float));
MSG_WriteByte (msg, SVFIELD (ent, ammo_rockets, float));
MSG_WriteByte (msg, SVFIELD (ent, ammo_cells, float));
if (standard_quake) {
MSG_WriteByte (msg, ent->v.weapon);
MSG_WriteByte (msg, SVFIELD (ent, weapon, float));
} else {
for (i = 0; i < 32; i++) {
if (((int) ent->v.weapon) & (1 << i)) {
if (((int) SVFIELD (ent, weapon, float)) & (1 << i)) {
MSG_WriteByte (msg, i);
break;
}
@ -765,16 +773,17 @@ SV_UpdateToReliableMessages (void)
// check for changes to be sent over the reliable streams
for (i = 0, host_client = svs.clients; i < svs.maxclients;
i++, host_client++) {
if (host_client->old_frags != host_client->edict->v.frags) {
if (host_client->old_frags != SVFIELD (host_client->edict, frags, float)) {
for (j = 0, client = svs.clients; j < svs.maxclients; j++, client++) {
if (!client->active)
continue;
MSG_WriteByte (&client->message, svc_updatefrags);
MSG_WriteByte (&client->message, i);
MSG_WriteShort (&client->message, host_client->edict->v.frags);
MSG_WriteShort (&client->message,
SVFIELD (host_client->edict, frags, float));
}
host_client->old_frags = host_client->edict->v.frags;
host_client->old_frags = SVFIELD (host_client->edict, frags, float);
}
}
@ -932,26 +941,26 @@ SV_CreateBaseline (void)
for (entnum = 0; entnum < sv.num_edicts; entnum++) {
// get the current server version
svent = EDICT_NUM (entnum);
svent = EDICT_NUM (&sv_pr_state, entnum);
if (svent->free)
continue;
if (entnum > svs.maxclients && !svent->v.modelindex)
if (entnum > svs.maxclients && !SVFIELD (svent, modelindex, float))
continue;
//
// create entity baseline
//
VectorCopy (svent->v.origin, svent->baseline.origin);
VectorCopy (svent->v.angles, svent->baseline.angles);
svent->baseline.frame = svent->v.frame;
svent->baseline.skin = svent->v.skin;
VectorCopy (SVFIELD (svent, origin, vector), ((entity_state_t*)svent->data)->origin);
VectorCopy (SVFIELD (svent, angles, vector), ((entity_state_t*)svent->data)->angles);
((entity_state_t*)svent->data)->frame = SVFIELD (svent, frame, float);
((entity_state_t*)svent->data)->skin = SVFIELD (svent, skin, float);
if (entnum > 0 && entnum <= svs.maxclients) {
svent->baseline.colormap = entnum;
svent->baseline.modelindex = SV_ModelIndex ("progs/player.mdl");
((entity_state_t*)svent->data)->colormap = entnum;
((entity_state_t*)svent->data)->modelindex = SV_ModelIndex ("progs/player.mdl");
} else {
svent->baseline.colormap = 0;
svent->baseline.modelindex =
SV_ModelIndex (pr_strings + svent->v.model);
((entity_state_t*)svent->data)->colormap = 0;
((entity_state_t*)svent->data)->modelindex =
SV_ModelIndex (PR_GetString (&sv_pr_state,SVFIELD (svent, model, string)));
}
//
@ -960,13 +969,13 @@ SV_CreateBaseline (void)
MSG_WriteByte (&sv.signon, svc_spawnbaseline);
MSG_WriteShort (&sv.signon, entnum);
MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
MSG_WriteByte (&sv.signon, svent->baseline.frame);
MSG_WriteByte (&sv.signon, svent->baseline.colormap);
MSG_WriteByte (&sv.signon, svent->baseline.skin);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->modelindex);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->frame);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->colormap);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->skin);
for (i = 0; i < 3; i++) {
MSG_WriteCoord (&sv.signon, svent->baseline.origin[i]);
MSG_WriteAngle (&sv.signon, svent->baseline.angles[i]);
MSG_WriteCoord (&sv.signon, ((entity_state_t*)svent->data)->origin[i]);
MSG_WriteAngle (&sv.signon, ((entity_state_t*)svent->data)->angles[i]);
}
}
}
@ -1015,7 +1024,7 @@ SV_SaveSpawnparms (void)
{
int i, j;
svs.serverflags = pr_global_struct->serverflags;
svs.serverflags = *sv_globals.serverflags;
for (i = 0, host_client = svs.clients; i < svs.maxclients;
i++, host_client++) {
@ -1023,10 +1032,13 @@ SV_SaveSpawnparms (void)
continue;
// call the progs to get default spawn parms for the new client
pr_global_struct->self = EDICT_TO_PROG (host_client->edict);
PR_ExecuteProgram (pr_global_struct->SetChangeParms);
*sv_globals.self =
EDICT_TO_PROG (&sv_pr_state, host_client->edict);
PR_ExecuteProgram (&sv_pr_state,
sv_funcs.SetChangeParms);
for (j = 0; j < NUM_SPAWN_PARMS; j++)
host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
host_client->spawn_parms[j] =
sv_globals.parms[j];
}
}
@ -1092,12 +1104,18 @@ SV_SpawnServer (char *server)
#endif
// load progs to get entity field count
PR_LoadProgs ();
SV_LoadProgs ();
// allocate server memory
sv.max_edicts = MAX_EDICTS;
sv_pr_state.pr_edictareasize = sv_pr_state.pr_edict_size * MAX_EDICTS;
sv.edicts = Hunk_AllocName (sv_pr_state.pr_edictareasize, "edicts");
sv.edicts = Hunk_AllocName (sv.max_edicts * pr_edict_size, "edicts");
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
ent = EDICT_NUM (&sv_pr_state, i);
ent->data = &baselines[i];
}
sv.datagram.maxsize = sizeof (sv.datagram_buf);
sv.datagram.cursize = 0;
@ -1114,7 +1132,7 @@ SV_SpawnServer (char *server)
// leave slots at start for clients only
sv.num_edicts = svs.maxclients + 1;
for (i = 0; i < svs.maxclients; i++) {
ent = EDICT_NUM (i + 1);
ent = EDICT_NUM (&sv_pr_state, i + 1);
svs.clients[i].edict = ent;
}
@ -1138,9 +1156,9 @@ SV_SpawnServer (char *server)
//
SV_ClearWorld ();
sv.sound_precache[0] = pr_strings;
sv.sound_precache[0] = sv_pr_state.pr_strings;
sv.model_precache[0] = pr_strings;
sv.model_precache[0] = sv_pr_state.pr_strings;
sv.model_precache[1] = sv.modelname;
for (i = 1; i < sv.worldmodel->numsubmodels; i++) {
sv.model_precache[1 + i] = localmodels[i];
@ -1150,28 +1168,29 @@ SV_SpawnServer (char *server)
//
// load the rest of the entities
//
ent = EDICT_NUM (0);
memset (&ent->v, 0, progs->entityfields * 4);
ent = EDICT_NUM (&sv_pr_state, 0);
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
ent->free = false;
ent->v.model = sv.worldmodel->name - pr_strings;
ent->v.modelindex = 1; // world model
ent->v.solid = SOLID_BSP;
ent->v.movetype = MOVETYPE_PUSH;
SVFIELD (ent, model, string) = PR_SetString (&sv_pr_state, sv.worldmodel->name);
SVFIELD (ent, modelindex, float) = 1; // world model
SVFIELD (ent, solid, float) = SOLID_BSP;
SVFIELD (ent, movetype, float) = MOVETYPE_PUSH;
if (coop->int_val)
pr_global_struct->coop = coop->int_val;
*sv_globals.coop = coop->int_val;
else
pr_global_struct->deathmatch = deathmatch->int_val;
*sv_globals.deathmatch = deathmatch->int_val;
pr_global_struct->mapname = sv.name - pr_strings;
*sv_globals.mapname = PR_SetString (&sv_pr_state, sv.name);
#ifdef QUAKE2
pr_global_struct->startspot = sv.startspot - pr_strings;
*sv_globals.startspot =
PR_SetString (&sv_pr_state, sv.startspot);
#endif
// serverflags are for cross level information (sigils)
pr_global_struct->serverflags = svs.serverflags;
*sv_globals.serverflags = svs.serverflags;
ED_LoadFromFile (sv.worldmodel->entities);
ED_LoadFromFile (&sv_pr_state, sv.worldmodel->entities);
sv.active = true;

View file

@ -31,6 +31,7 @@
#endif
#include "server.h"
#include "sv_progs.h"
#include "world.h"
#define STEPSIZE 18
@ -54,8 +55,8 @@ SV_CheckBottom (edict_t *ent)
int x, y;
float mid, bottom;
VectorAdd (ent->v.origin, ent->v.mins, mins);
VectorAdd (ent->v.origin, ent->v.maxs, maxs);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), mins);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), maxs);
// if all of the points under the corners are solid world, don't bother
// with the tougher checks
@ -128,34 +129,33 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
edict_t *enemy;
// try the move
VectorCopy (ent->v.origin, oldorg);
VectorAdd (ent->v.origin, move, neworg);
VectorCopy (SVFIELD (ent, origin, vector), oldorg);
VectorAdd (SVFIELD (ent, origin, vector), move, neworg);
// flying monsters don't step up
if ((int) ent->v.flags & (FL_SWIM | FL_FLY)) {
if ((int) SVFIELD (ent, flags, float) & (FL_SWIM | FL_FLY)) {
// try one move with vertical motion, then one without
for (i = 0; i < 2; i++) {
VectorAdd (ent->v.origin, move, neworg);
enemy = PROG_TO_EDICT (ent->v.enemy);
VectorAdd (SVFIELD (ent, origin, vector), move, neworg);
enemy = PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, enemy, entity));
if (i == 0 && enemy != sv.edicts) {
dz =
ent->v.origin[2] -
PROG_TO_EDICT (ent->v.enemy)->v.origin[2];
SVFIELD (ent, origin, vector)[2] - SVFIELD (enemy, origin, vector)[2];
if (dz > 40)
neworg[2] -= 8;
if (dz < 30)
neworg[2] += 8;
}
trace =
SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, false,
ent);
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), neworg,
false, ent);
if (trace.fraction == 1) {
if (((int) ent->v.flags & FL_SWIM)
if (((int) SVFIELD (ent, flags, float) & FL_SWIM)
&& SV_PointContents (trace.endpos) == CONTENTS_EMPTY)
return false; // swim monster left water
VectorCopy (trace.endpos, ent->v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
if (relink)
SV_LinkEdict (ent, true);
return true;
@ -172,24 +172,24 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
VectorCopy (neworg, end);
end[2] -= STEPSIZE * 2;
trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent);
trace = SV_Move (neworg, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.allsolid)
return false;
if (trace.startsolid) {
neworg[2] -= STEPSIZE;
trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent);
trace = SV_Move (neworg, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.allsolid || trace.startsolid)
return false;
}
if (trace.fraction == 1) {
// if monster had the ground pulled out, go ahead and fall
if ((int) ent->v.flags & FL_PARTIALGROUND) {
VectorAdd (ent->v.origin, move, ent->v.origin);
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) {
VectorAdd (SVFIELD (ent, origin, vector), move, SVFIELD (ent, origin, vector));
if (relink)
SV_LinkEdict (ent, true);
ent->v.flags = (int) ent->v.flags & ~FL_ONGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) & ~FL_ONGROUND;
// Con_Printf ("fall down\n");
return true;
}
@ -197,10 +197,10 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
return false; // walked off an edge
}
// check point traces down for dangling corners
VectorCopy (trace.endpos, ent->v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
if (!SV_CheckBottom (ent)) {
if ((int) ent->v.flags & FL_PARTIALGROUND) { // entity had floor
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) { // entity had floor
// mostly pulled out
// from underneath it
// and is trying to correct
@ -208,15 +208,15 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
SV_LinkEdict (ent, true);
return true;
}
VectorCopy (oldorg, ent->v.origin);
VectorCopy (oldorg, SVFIELD (ent, origin, vector));
return false;
}
if ((int) ent->v.flags & FL_PARTIALGROUND) {
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) {
// Con_Printf ("back on ground\n");
ent->v.flags = (int) ent->v.flags & ~FL_PARTIALGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) & ~FL_PARTIALGROUND;
}
ent->v.groundentity = EDICT_TO_PROG (trace.ent);
SVFIELD (ent, groundentity, entity) = EDICT_TO_PROG (&sv_pr_state, trace.ent);
// the move is ok
if (relink)
@ -236,27 +236,26 @@ facing it.
======================
*/
void PF_changeyaw (void);
qboolean
SV_StepDirection (edict_t *ent, float yaw, float dist)
{
vec3_t move, oldorigin;
float delta;
ent->v.ideal_yaw = yaw;
PF_changeyaw ();
SVFIELD (ent, ideal_yaw, float) = yaw;
PF_changeyaw (&sv_pr_state);
yaw = yaw * M_PI * 2 / 360;
move[0] = cos (yaw) * dist;
move[1] = sin (yaw) * dist;
move[2] = 0;
VectorCopy (ent->v.origin, oldorigin);
VectorCopy (SVFIELD (ent, origin, vector), oldorigin);
if (SV_movestep (ent, move, false)) {
delta = ent->v.angles[YAW] - ent->v.ideal_yaw;
delta = SVFIELD (ent, angles, vector)[YAW] - SVFIELD (ent, ideal_yaw, float);
if (delta > 45 && delta < 315) { // not turned far enough, so
// don't take the step
VectorCopy (oldorigin, ent->v.origin);
VectorCopy (oldorigin, SVFIELD (ent, origin, vector));
}
SV_LinkEdict (ent, true);
return true;
@ -277,7 +276,7 @@ SV_FixCheckBottom (edict_t *ent)
{
// Con_Printf ("SV_FixCheckBottom\n");
ent->v.flags = (int) ent->v.flags | FL_PARTIALGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) | FL_PARTIALGROUND;
}
@ -296,11 +295,11 @@ SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
float d[3];
float tdir, olddir, turnaround;
olddir = anglemod ((int) (actor->v.ideal_yaw / 45) * 45);
olddir = anglemod ((int) (SVFIELD (actor, ideal_yaw, float) / 45) * 45);
turnaround = anglemod (olddir - 180);
deltax = enemy->v.origin[0] - actor->v.origin[0];
deltay = enemy->v.origin[1] - actor->v.origin[1];
deltax = SVFIELD (enemy, origin, vector)[0] - SVFIELD (actor, origin, vector)[0];
deltay = SVFIELD (enemy, origin, vector)[1] - SVFIELD (actor, origin, vector)[1];
if (deltax > 10)
d[1] = 0;
else if (deltax < -10)
@ -356,7 +355,7 @@ SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
if (turnaround != DI_NODIR && SV_StepDirection (actor, turnaround, dist))
return;
actor->v.ideal_yaw = olddir; // can't move
SVFIELD (actor, ideal_yaw, float) = olddir; // can't move
// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all
@ -378,9 +377,9 @@ SV_CloseEnough (edict_t *ent, edict_t *goal, float dist)
int i;
for (i = 0; i < 3; i++) {
if (goal->v.absmin[i] > ent->v.absmax[i] + dist)
if (SVFIELD (goal, absmin, vector)[i] > SVFIELD (ent, absmax, vector)[i] + dist)
return false;
if (goal->v.absmax[i] < ent->v.absmin[i] - dist)
if (SVFIELD (goal, absmax, vector)[i] < SVFIELD (ent, absmin, vector)[i] - dist)
return false;
}
return true;
@ -393,7 +392,7 @@ SV_MoveToGoal
======================
*/
void
SV_MoveToGoal (void)
SV_MoveToGoal (progs_t * pr)
{
edict_t *ent, *goal;
float dist;
@ -402,26 +401,26 @@ SV_MoveToGoal (void)
edict_t *enemy;
#endif
ent = PROG_TO_EDICT (pr_global_struct->self);
goal = PROG_TO_EDICT (ent->v.goalentity);
dist = G_FLOAT (OFS_PARM0);
ent = PROG_TO_EDICT (pr, *pr->globals.self);
goal = PROG_TO_EDICT (pr, SVFIELD (ent, goalentity, entity));
dist = G_FLOAT (pr, OFS_PARM0);
if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
G_FLOAT (OFS_RETURN) = 0;
if (!((int) SVFIELD (ent, flags, float) & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
G_FLOAT (pr, OFS_RETURN) = 0;
return;
}
// if the next step hits the enemy, return immediately
#ifdef QUAKE2
enemy = PROG_TO_EDICT (ent->v.enemy);
enemy = PROG_TO_EDICT (pr->, SVFIELD (ent, enemy, entity));
if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist))
#else
if (PROG_TO_EDICT (ent->v.enemy) != sv.edicts
if (PROG_TO_EDICT (pr, SVFIELD (ent, enemy, entity)) != sv.edicts
&& SV_CloseEnough (ent, goal, dist))
#endif
return;
// bump around...
if ((rand () & 3) == 1 || !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) {
if ((rand () & 3) == 1 || !SV_StepDirection (ent, SVFIELD (ent, ideal_yaw, float), dist)) {
SV_NewChaseDir (ent, goal, dist);
}
}

File diff suppressed because it is too large Load diff

310
nq/source/sv_progs.c Normal file
View file

@ -0,0 +1,310 @@
/*
sv_progs.c
Quick QuakeC server code
Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
#include "string.h"
#endif
#ifdef HAVE_STRINGS_H
#include "strings.h"
#endif
#include "cmd.h"
#include "console.h"
#include "host.h"
#include "progdefs.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
progs_t sv_pr_state;
sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
cvar_t *r_skyname;
cvar_t *sv_progs;
cvar_t *nomonsters;
cvar_t *gamecfg;
cvar_t *scratch1;
cvar_t *scratch2;
cvar_t *scratch3;
cvar_t *scratch4;
cvar_t *savedgamecfg;
cvar_t *saved1;
cvar_t *saved2;
cvar_t *saved3;
cvar_t *saved4;
int
ED_Prune_Edict (progs_t *pr, edict_t *ent)
{
// remove things from different skill levels or deathmatch
if (deathmatch->int_val) {
if (((int) SVFIELD (ent, spawnflags, float) & SPAWNFLAG_NOT_DEATHMATCH)) {
return 1;
}
} else if (
(current_skill == 0
&& ((int) SVFIELD (ent, spawnflags, float) & SPAWNFLAG_NOT_EASY))
|| (current_skill == 1
&& ((int) SVFIELD (ent, spawnflags, float) & SPAWNFLAG_NOT_MEDIUM))
|| (current_skill >= 2
&& ((int) SVFIELD (ent, spawnflags, float) & SPAWNFLAG_NOT_HARD))) {
return 1;
}
return 0;
}
void
ED_PrintEdicts_f (void)
{
ED_PrintEdicts (&sv_pr_state);
}
/*
ED_PrintEdict_f
For debugging, prints a single edicy
*/
void
ED_PrintEdict_f (void)
{
int i;
i = atoi (Cmd_Argv (1));
Con_Printf ("\n EDICT %i:\n", i);
ED_PrintNum (&sv_pr_state, i);
}
void
ED_Count_f (void)
{
ED_Count (&sv_pr_state);
}
void
PR_Profile_f (void)
{
PR_Profile (&sv_pr_state);
}
int
ED_Parse_Extra_Fields (progs_t * pr, char *key, char *value)
{
return 0;
}
void
SV_LoadProgs (void)
{
PR_LoadProgs (&sv_pr_state, sv_progs->string);
if (!sv_pr_state.progs)
Host_Error ("SV_LoadProgs: couldn't load %s", sv_progs->string);
if (sv_pr_state.progs->crc != PROGHEADER_CRC)
Host_Error ("You must have the progs.dat from Quake installed");
// progs engine needs these globals anyway
sv_globals.self = sv_pr_state.globals.self;
sv_globals.time = sv_pr_state.globals.time;
(void *) sv_globals.self = PR_GetGlobalPointer (&sv_pr_state, "self");
(void *) sv_globals.other = PR_GetGlobalPointer (&sv_pr_state, "other");
(void *) sv_globals.world = PR_GetGlobalPointer (&sv_pr_state, "world");
(void *) sv_globals.time = PR_GetGlobalPointer (&sv_pr_state, "time");
(void *) sv_globals.frametime = PR_GetGlobalPointer (&sv_pr_state, "frametime");
(void *) sv_globals.force_retouch = PR_GetGlobalPointer (&sv_pr_state, "force_retouch");
(void *) sv_globals.mapname = PR_GetGlobalPointer (&sv_pr_state, "mapname");
(void *) sv_globals.startspot = PR_GetGlobalPointer (&sv_pr_state, "startspot");
(void *) sv_globals.deathmatch = PR_GetGlobalPointer (&sv_pr_state, "deathmatch");
(void *) sv_globals.coop = PR_GetGlobalPointer (&sv_pr_state, "coop");
(void *) sv_globals.teamplay = PR_GetGlobalPointer (&sv_pr_state, "teamplay");
(void *) sv_globals.serverflags = PR_GetGlobalPointer (&sv_pr_state, "serverflags");
(void *) sv_globals.total_secrets = PR_GetGlobalPointer (&sv_pr_state, "total_secrets");
(void *) sv_globals.total_monsters = PR_GetGlobalPointer (&sv_pr_state, "total_monsters");
(void *) sv_globals.found_secrets = PR_GetGlobalPointer (&sv_pr_state, "found_secrets");
(void *) sv_globals.killed_monsters = PR_GetGlobalPointer (&sv_pr_state, "killed_monsters");
(void *) sv_globals.parms = PR_GetGlobalPointer (&sv_pr_state, "parm1");
(void *) sv_globals.v_forward = PR_GetGlobalPointer (&sv_pr_state, "v_forward");
(void *) sv_globals.v_up = PR_GetGlobalPointer (&sv_pr_state, "v_up");
(void *) sv_globals.v_right = PR_GetGlobalPointer (&sv_pr_state, "v_right");
(void *) sv_globals.trace_allsolid = PR_GetGlobalPointer (&sv_pr_state, "trace_allsolid");
(void *) sv_globals.trace_startsolid = PR_GetGlobalPointer (&sv_pr_state, "trace_startsolid");
(void *) sv_globals.trace_fraction = PR_GetGlobalPointer (&sv_pr_state, "trace_fraction");
(void *) sv_globals.trace_endpos = PR_GetGlobalPointer (&sv_pr_state, "trace_endpos");
(void *) sv_globals.trace_plane_normal = PR_GetGlobalPointer (&sv_pr_state, "trace_plane_normal");
(void *) sv_globals.trace_plane_dist = PR_GetGlobalPointer (&sv_pr_state, "trace_plane_dist");
(void *) sv_globals.trace_ent = PR_GetGlobalPointer (&sv_pr_state, "trace_ent");
(void *) sv_globals.trace_inopen = PR_GetGlobalPointer (&sv_pr_state, "trace_inopen");
(void *) sv_globals.trace_inwater = PR_GetGlobalPointer (&sv_pr_state, "trace_inwater");
(void *) sv_globals.msg_entity = PR_GetGlobalPointer (&sv_pr_state, "msg_entity");
(void *) sv_globals.null = PR_GetGlobalPointer (&sv_pr_state, "null");
sv_funcs.main = ED_FindFunction (&sv_pr_state, "main") - sv_pr_state. pr_functions;
sv_funcs.StartFrame = ED_FindFunction (&sv_pr_state, "StartFrame") - sv_pr_state. pr_functions;
sv_funcs.PlayerPreThink = ED_FindFunction (&sv_pr_state, "PlayerPreThink") - sv_pr_state. pr_functions;
sv_funcs.PlayerPostThink = ED_FindFunction (&sv_pr_state, "PlayerPostThink") - sv_pr_state. pr_functions;
sv_funcs.ClientKill = ED_FindFunction (&sv_pr_state, "ClientKill") - sv_pr_state. pr_functions;
sv_funcs.ClientConnect = ED_FindFunction (&sv_pr_state, "ClientConnect") - sv_pr_state. pr_functions;
sv_funcs.PutClientInServer = ED_FindFunction (&sv_pr_state, "PutClientInServer") - sv_pr_state. pr_functions;
sv_funcs.ClientDisconnect = ED_FindFunction (&sv_pr_state, "ClientDisconnect") - sv_pr_state. pr_functions;
sv_funcs.SetNewParms = ED_FindFunction (&sv_pr_state, "SetNewParms") - sv_pr_state. pr_functions;
sv_funcs.SetChangeParms = ED_FindFunction (&sv_pr_state, "SetChangeParms") - sv_pr_state. pr_functions;
sv_fields.modelindex = ED_GetFieldIndex (&sv_pr_state, "modelindex");
sv_fields.absmin = ED_GetFieldIndex (&sv_pr_state, "absmin");
sv_fields.absmax = ED_GetFieldIndex (&sv_pr_state, "absmax");
sv_fields.ltime = ED_GetFieldIndex (&sv_pr_state, "ltime");
sv_fields.movetype = ED_GetFieldIndex (&sv_pr_state, "movetype");
sv_fields.solid = ED_GetFieldIndex (&sv_pr_state, "solid");
sv_fields.origin = ED_GetFieldIndex (&sv_pr_state, "origin");
sv_fields.oldorigin = ED_GetFieldIndex (&sv_pr_state, "oldorigin");
sv_fields.velocity = ED_GetFieldIndex (&sv_pr_state, "velocity");
sv_fields.angles = ED_GetFieldIndex (&sv_pr_state, "angles");
sv_fields.avelocity = ED_GetFieldIndex (&sv_pr_state, "avelocity");
sv_fields.basevelocity = ED_GetFieldIndex (&sv_pr_state, "basevelocity");
sv_fields.punchangle = ED_GetFieldIndex (&sv_pr_state, "punchangle");
sv_fields.classname = ED_GetFieldIndex (&sv_pr_state, "classname");
sv_fields.model = ED_GetFieldIndex (&sv_pr_state, "model");
sv_fields.frame = ED_GetFieldIndex (&sv_pr_state, "frame");
sv_fields.skin = ED_GetFieldIndex (&sv_pr_state, "skin");
sv_fields.effects = ED_GetFieldIndex (&sv_pr_state, "effects");
sv_fields.drawPercent = ED_GetFieldIndex (&sv_pr_state, "drawPercent");
sv_fields.gravity = ED_GetFieldIndex (&sv_pr_state, "gravity");
sv_fields.mass = ED_GetFieldIndex (&sv_pr_state, "mass");
sv_fields.light_level = ED_GetFieldIndex (&sv_pr_state, "light_level");
sv_fields.mins = ED_GetFieldIndex (&sv_pr_state, "mins");
sv_fields.maxs = ED_GetFieldIndex (&sv_pr_state, "maxs");
sv_fields.size = ED_GetFieldIndex (&sv_pr_state, "size");
sv_fields.touch = ED_GetFieldIndex (&sv_pr_state, "touch");
sv_fields.use = ED_GetFieldIndex (&sv_pr_state, "use");
sv_fields.think = ED_GetFieldIndex (&sv_pr_state, "think");
sv_fields.blocked = ED_GetFieldIndex (&sv_pr_state, "blocked");
sv_fields.nextthink = ED_GetFieldIndex (&sv_pr_state, "nextthink");
sv_fields.groundentity = ED_GetFieldIndex (&sv_pr_state, "groundentity");
sv_fields.health = ED_GetFieldIndex (&sv_pr_state, "health");
sv_fields.frags = ED_GetFieldIndex (&sv_pr_state, "frags");
sv_fields.weapon = ED_GetFieldIndex (&sv_pr_state, "weapon");
sv_fields.weaponmodel = ED_GetFieldIndex (&sv_pr_state, "weaponmodel");
sv_fields.weaponframe = ED_GetFieldIndex (&sv_pr_state, "weaponframe");
sv_fields.currentammo = ED_GetFieldIndex (&sv_pr_state, "currentammo");
sv_fields.ammo_shells = ED_GetFieldIndex (&sv_pr_state, "ammo_shells");
sv_fields.ammo_nails = ED_GetFieldIndex (&sv_pr_state, "ammo_nails");
sv_fields.ammo_rockets = ED_GetFieldIndex (&sv_pr_state, "ammo_rockets");
sv_fields.ammo_cells = ED_GetFieldIndex (&sv_pr_state, "ammo_cells");
sv_fields.items = ED_GetFieldIndex (&sv_pr_state, "items");
sv_fields.items2 = ED_GetFieldIndex (&sv_pr_state, "items2");
sv_fields.takedamage = ED_GetFieldIndex (&sv_pr_state, "takedamage");
sv_fields.chain = ED_GetFieldIndex (&sv_pr_state, "chain");
sv_fields.deadflag = ED_GetFieldIndex (&sv_pr_state, "deadflag");
sv_fields.view_ofs = ED_GetFieldIndex (&sv_pr_state, "view_ofs");
sv_fields.button0 = ED_GetFieldIndex (&sv_pr_state, "button0");
sv_fields.button1 = ED_GetFieldIndex (&sv_pr_state, "button1");
sv_fields.button2 = ED_GetFieldIndex (&sv_pr_state, "button2");
sv_fields.impulse = ED_GetFieldIndex (&sv_pr_state, "impulse");
sv_fields.fixangle = ED_GetFieldIndex (&sv_pr_state, "fixangle");
sv_fields.v_angle = ED_GetFieldIndex (&sv_pr_state, "v_angle");
sv_fields.idealpitch = ED_GetFieldIndex (&sv_pr_state, "idealpitch");
sv_fields.pitch_speed = ED_GetFieldIndex (&sv_pr_state, "pitch_speed");
sv_fields.netname = ED_GetFieldIndex (&sv_pr_state, "netname");
sv_fields.enemy = ED_GetFieldIndex (&sv_pr_state, "enemy");
sv_fields.flags = ED_GetFieldIndex (&sv_pr_state, "flags");
sv_fields.colormap = ED_GetFieldIndex (&sv_pr_state, "colormap");
sv_fields.team = ED_GetFieldIndex (&sv_pr_state, "team");
sv_fields.max_health = ED_GetFieldIndex (&sv_pr_state, "max_health");
sv_fields.teleport_time = ED_GetFieldIndex (&sv_pr_state, "teleport_time");
sv_fields.armortype = ED_GetFieldIndex (&sv_pr_state, "armortype");
sv_fields.armorvalue = ED_GetFieldIndex (&sv_pr_state, "armorvalue");
sv_fields.waterlevel = ED_GetFieldIndex (&sv_pr_state, "waterlevel");
sv_fields.watertype = ED_GetFieldIndex (&sv_pr_state, "watertype");
sv_fields.ideal_yaw = ED_GetFieldIndex (&sv_pr_state, "ideal_yaw");
sv_fields.yaw_speed = ED_GetFieldIndex (&sv_pr_state, "yaw_speed");
sv_fields.aiment = ED_GetFieldIndex (&sv_pr_state, "aiment");
sv_fields.goalentity = ED_GetFieldIndex (&sv_pr_state, "goalentity");
sv_fields.spawnflags = ED_GetFieldIndex (&sv_pr_state, "spawnflags");
sv_fields.target = ED_GetFieldIndex (&sv_pr_state, "target");
sv_fields.targetname = ED_GetFieldIndex (&sv_pr_state, "targetname");
sv_fields.dmg_take = ED_GetFieldIndex (&sv_pr_state, "dmg_take");
sv_fields.dmg_save = ED_GetFieldIndex (&sv_pr_state, "dmg_save");
sv_fields.dmg_inflictor = ED_GetFieldIndex (&sv_pr_state, "dmg_inflictor");
sv_fields.owner = ED_GetFieldIndex (&sv_pr_state, "owner");
sv_fields.movedir = ED_GetFieldIndex (&sv_pr_state, "movedir");
sv_fields.message = ED_GetFieldIndex (&sv_pr_state, "message");
sv_fields.sounds = ED_GetFieldIndex (&sv_pr_state, "sounds");
sv_fields.noise = ED_GetFieldIndex (&sv_pr_state, "noise");
sv_fields.noise1 = ED_GetFieldIndex (&sv_pr_state, "noise1");
sv_fields.noise2 = ED_GetFieldIndex (&sv_pr_state, "noise2");
sv_fields.noise3 = ED_GetFieldIndex (&sv_pr_state, "noise3");
sv_fields.dmg = ED_GetFieldIndex (&sv_pr_state, "dmg");
sv_fields.dmgtime = ED_GetFieldIndex (&sv_pr_state, "dmgtime");
sv_fields.air_finished = ED_GetFieldIndex (&sv_pr_state, "air_finished");
sv_fields.pain_finished = ED_GetFieldIndex (&sv_pr_state, "pain_finished");
sv_fields.radsuit_finished = ED_GetFieldIndex (&sv_pr_state, "radsuit_finished");
sv_fields.speed = ED_GetFieldIndex (&sv_pr_state, "speed");
}
void
SV_Progs_Init (void)
{
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.time = &sv.time;
sv_pr_state.reserved_edicts = &svs.maxclients;
sv_pr_state.unlink = SV_UnlinkEdict;
Cmd_AddCommand ("edict", ED_PrintEdict_f,
"Report information on a given edict in the game. (edict (edict number))");
Cmd_AddCommand ("edicts", ED_PrintEdicts_f,
"Display information on all edicts in the game.");
Cmd_AddCommand ("edictcount", ED_Count_f,
"Display summary information on the edicts in the game.");
Cmd_AddCommand ("profile", PR_Profile_f,
"FIXME: Report information about QuakeC Stuff (???) No Description");
}
void
SV_Progs_Init_Cvars (void)
{
r_skyname = Cvar_Get ("r_skyname", "", CVAR_SERVERINFO, "name of skybox");
sv_progs = Cvar_Get ("sv_progs", "progs.dat", CVAR_ROM,
"Allows selectable game progs if you have several "
"of them in the gamedir");
nomonsters = Cvar_Get ("nomonsters", "0", CVAR_NONE, "No Description");
gamecfg = Cvar_Get ("gamecfg", "0", CVAR_NONE, "No Description");
scratch1 = Cvar_Get ("scratch1", "0", CVAR_NONE, "No Description");
scratch2 = Cvar_Get ("scratch2", "0", CVAR_NONE, "No Description");
scratch3 = Cvar_Get ("scratch3", "0", CVAR_NONE, "No Description");
scratch4 = Cvar_Get ("scratch4", "0", CVAR_NONE, "No Description");
savedgamecfg = Cvar_Get ("savedgamecfg", "0", CVAR_ARCHIVE, "No Description");
saved1 = Cvar_Get ("saved1", "0", CVAR_ARCHIVE, "No Description");
saved2 = Cvar_Get ("saved2", "0", CVAR_ARCHIVE, "No Description");
saved3 = Cvar_Get ("saved3", "0", CVAR_ARCHIVE, "No Description");
saved4 = Cvar_Get ("saved4", "0", CVAR_ARCHIVE, "No Description");
}

View file

@ -1,3 +1,4 @@
/*
sv_user.c
@ -38,7 +39,9 @@
#include "view.h"
#include "cmd.h"
#include "host.h"
#include "sv_progs.h"
#include "sys.h"
edict_t *sv_player;
cvar_t *sv_edgefriction;
@ -77,17 +80,17 @@ SV_SetIdealPitch (void)
int i, j;
int step, dir, steps;
if (!((int) sv_player->v.flags & FL_ONGROUND))
if (!((int) SVFIELD (sv_player, flags, float) & FL_ONGROUND))
return;
angleval = sv_player->v.angles[YAW] * M_PI * 2 / 360;
angleval = SVFIELD (sv_player, angles, vector)[YAW] * M_PI * 2 / 360;
sinval = sin (angleval);
cosval = cos (angleval);
for (i = 0; i < MAX_FORWARD; i++) {
top[0] = sv_player->v.origin[0] + cosval * (i + 3) * 12;
top[1] = sv_player->v.origin[1] + sinval * (i + 3) * 12;
top[2] = sv_player->v.origin[2] + sv_player->v.view_ofs[2];
top[0] = SVFIELD (sv_player, origin, vector)[0] + cosval * (i + 3) * 12;
top[1] = SVFIELD (sv_player, origin, vector)[1] + sinval * (i + 3) * 12;
top[2] = SVFIELD (sv_player, origin, vector)[2] + SVFIELD (sv_player, view_ofs, vector)[2];
bottom[0] = top[0];
bottom[1] = top[1];
@ -120,13 +123,13 @@ SV_SetIdealPitch (void)
}
if (!dir) {
sv_player->v.idealpitch = 0;
SVFIELD (sv_player, idealpitch, float) = 0;
return;
}
if (steps < 2)
return;
sv_player->v.idealpitch = -dir * sv_idealpitchscale->value;
SVFIELD (sv_player, idealpitch, float) = -dir * sv_idealpitchscale->value;
}
@ -154,7 +157,7 @@ SV_UserFriction (void)
// if the leading edge is over a dropoff, increase friction
start[0] = stop[0] = origin[0] + vel[0] / speed * 16;
start[1] = stop[1] = origin[1] + vel[1] / speed * 16;
start[2] = origin[2] + sv_player->v.mins[2];
start[2] = origin[2] + SVFIELD (sv_player, mins, vector)[2];
stop[2] = start[2] - 34;
trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player);
@ -253,12 +256,12 @@ DropPunchAngle (void)
{
float len;
len = VectorNormalize (sv_player->v.punchangle);
len = VectorNormalize (SVFIELD (sv_player, punchangle, vector));
len -= 10 * host_frametime;
if (len < 0)
len = 0;
VectorScale (sv_player->v.punchangle, len, sv_player->v.punchangle);
VectorScale (SVFIELD (sv_player, punchangle, vector), len, SVFIELD (sv_player, punchangle, vector));
}
/*
@ -277,7 +280,7 @@ SV_WaterMove (void)
//
// user intentions
//
AngleVectors (sv_player->v.v_angle, forward, right, up);
AngleVectors (SVFIELD (sv_player, v_angle, vector), forward, right, up);
for (i = 0; i < 3; i++)
wishvel[i] = forward[i] * cmd.forwardmove + right[i] * cmd.sidemove;
@ -328,12 +331,12 @@ SV_WaterMove (void)
void
SV_WaterJump (void)
{
if (sv.time > sv_player->v.teleport_time || !sv_player->v.waterlevel) {
sv_player->v.flags = (int) sv_player->v.flags & ~FL_WATERJUMP;
sv_player->v.teleport_time = 0;
if (sv.time > SVFIELD (sv_player, teleport_time, float) || !SVFIELD (sv_player, waterlevel, float)) {
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) & ~FL_WATERJUMP;
SVFIELD (sv_player, teleport_time, float) = 0;
}
sv_player->v.velocity[0] = sv_player->v.movedir[0];
sv_player->v.velocity[1] = sv_player->v.movedir[1];
SVFIELD (sv_player, velocity, vector)[0] = SVFIELD (sv_player, movedir, vector)[0];
SVFIELD (sv_player, velocity, vector)[1] = SVFIELD (sv_player, movedir, vector)[1];
}
@ -350,19 +353,19 @@ SV_AirMove (void)
vec3_t wishvel;
float fmove, smove;
AngleVectors (sv_player->v.angles, forward, right, up);
AngleVectors (SVFIELD (sv_player, angles, vector), forward, right, up);
fmove = cmd.forwardmove;
smove = cmd.sidemove;
// hack to not let you back into teleporter
if (sv.time < sv_player->v.teleport_time && fmove < 0)
if (sv.time < SVFIELD (sv_player, teleport_time, float) && fmove < 0)
fmove = 0;
for (i = 0; i < 3; i++)
wishvel[i] = forward[i] * fmove + right[i] * smove;
if ((int) sv_player->v.movetype != MOVETYPE_WALK)
if ((int) SVFIELD (sv_player, movetype, float) != MOVETYPE_WALK)
wishvel[2] = cmd.upmove;
else
wishvel[2] = 0;
@ -374,7 +377,7 @@ SV_AirMove (void)
wishspeed = sv_maxspeed->value;
}
if (sv_player->v.movetype == MOVETYPE_NOCLIP) { // noclip
if (SVFIELD (sv_player, movetype, float) == MOVETYPE_NOCLIP) { // noclip
VectorCopy (wishvel, velocity);
} else if (onground) {
SV_UserFriction ();
@ -399,44 +402,45 @@ SV_ClientThink (void)
{
vec3_t v_angle;
if (sv_player->v.movetype == MOVETYPE_NONE)
if (SVFIELD (sv_player, movetype, float) == MOVETYPE_NONE)
return;
onground = (int) sv_player->v.flags & FL_ONGROUND;
onground = (int) SVFIELD (sv_player, flags, float) & FL_ONGROUND;
origin = sv_player->v.origin;
velocity = sv_player->v.velocity;
origin = SVFIELD (sv_player, origin, vector);
velocity = SVFIELD (sv_player, velocity, vector);
DropPunchAngle ();
//
// if dead, behave differently
//
if (sv_player->v.health <= 0)
if (SVFIELD (sv_player, health, float) <= 0)
return;
//
// angles
// show 1/3 the pitch angle and all the roll angle
cmd = host_client->cmd;
angles = sv_player->v.angles;
angles = SVFIELD (sv_player, angles, vector);
VectorAdd (sv_player->v.v_angle, sv_player->v.punchangle, v_angle);
angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity) * 4;
if (!sv_player->v.fixangle) {
VectorAdd (SVFIELD (sv_player, v_angle, vector), SVFIELD (sv_player, punchangle, vector), v_angle);
angles[ROLL] =
V_CalcRoll (SVFIELD (sv_player, angles, vector), SVFIELD (sv_player, velocity, vector)) * 4;
if (!SVFIELD (sv_player, fixangle, float)) {
angles[PITCH] = -v_angle[PITCH] / 3;
angles[YAW] = v_angle[YAW];
}
if ((int) sv_player->v.flags & FL_WATERJUMP) {
if ((int) SVFIELD (sv_player, flags, float) & FL_WATERJUMP) {
SV_WaterJump ();
return;
}
//
// walk
//
if ((sv_player->v.waterlevel >= 2)
&& (sv_player->v.movetype != MOVETYPE_NOCLIP)) {
if ((SVFIELD (sv_player, waterlevel, float) >= 2)
&& (SVFIELD (sv_player, movetype, float) != MOVETYPE_NOCLIP)) {
SV_WaterMove ();
return;
}
@ -466,7 +470,7 @@ SV_ReadClientMove (usercmd_t *move)
for (i = 0; i < 3; i++)
angle[i] = MSG_ReadAngle (net_message);
VectorCopy (angle, host_client->edict->v.v_angle);
VectorCopy (angle, SVFIELD (host_client->edict, v_angle, vector));
// read movement
move->forwardmove = MSG_ReadShort (net_message);
@ -475,16 +479,16 @@ SV_ReadClientMove (usercmd_t *move)
// read buttons
bits = MSG_ReadByte (net_message);
host_client->edict->v.button0 = bits & 1;
host_client->edict->v.button2 = (bits & 2) >> 1;
SVFIELD (host_client->edict, button0, float) = bits & 1;
SVFIELD (host_client->edict, button2, float) = (bits & 2) >> 1;
i = MSG_ReadByte (net_message);
if (i)
host_client->edict->v.impulse = i;
SVFIELD (host_client->edict, impulse, float) = i;
#ifdef QUAKE2
// read light level
host_client->edict->v.light_level = MSG_ReadByte (net_message);
SVFIELD (host_client->edict, light_level, float) = MSG_ReadByte (net_message);
#endif
}

View file

@ -36,6 +36,7 @@
#include "server.h"
#include "sys.h"
#include "console.h"
#include "sv_progs.h"
/*
@ -153,11 +154,11 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
hull_t *hull;
// decide which clipping hull to use, based on the size
if (ent->v.solid == SOLID_BSP) { // explicit hulls in the BSP model
if (ent->v.movetype != MOVETYPE_PUSH)
if (SVFIELD (ent, solid, float) == SOLID_BSP) { // explicit hulls in the BSP model
if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH)
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");
model = sv.models[(int) ent->v.modelindex];
model = sv.models[(int) SVFIELD (ent, modelindex, float)];
if (!model || model->type != mod_brush)
Sys_Error ("MOVETYPE_PUSH with a non bsp model");
@ -172,15 +173,15 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->v.origin, offset);
VectorAdd (offset, SVFIELD (ent, origin, vector), offset);
} else { // create a temp hull from bounding
// box sizes
VectorSubtract (ent->v.mins, maxs, hullmins);
VectorSubtract (ent->v.maxs, mins, hullmaxs);
VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins);
VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (ent->v.origin, offset);
VectorCopy (SVFIELD (ent, origin, vector), offset);
}
@ -305,34 +306,35 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
touch = EDICT_FROM_AREA (l);
if (touch == ent)
continue;
if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER)
if (!SVFIELD (touch, touch, func) || SVFIELD (touch, solid, float) != SOLID_TRIGGER)
continue;
if (ent->v.absmin[0] > touch->v.absmax[0]
|| ent->v.absmin[1] > touch->v.absmax[1]
|| ent->v.absmin[2] > touch->v.absmax[2]
|| ent->v.absmax[0] < touch->v.absmin[0]
|| ent->v.absmax[1] < touch->v.absmin[1]
|| ent->v.absmax[2] < touch->v.absmin[2])
if (SVFIELD (ent, absmin, vector)[0] > SVFIELD (touch, absmax, vector)[0]
|| SVFIELD (ent, absmin, vector)[1] > SVFIELD (touch, absmax, vector)[1]
|| SVFIELD (ent, absmin, vector)[2] > SVFIELD (touch, absmax, vector)[2]
|| SVFIELD (ent, absmax, vector)[0] < SVFIELD (touch, absmin, vector)[0]
|| SVFIELD (ent, absmax, vector)[1] < SVFIELD (touch, absmin, vector)[1]
|| SVFIELD (ent, absmax, vector)[2] < SVFIELD (touch, absmin, vector)[2])
continue;
old_self = pr_global_struct->self;
old_other = pr_global_struct->other;
old_self = *sv_globals.self;
old_other = *sv_globals.other;
pr_global_struct->self = EDICT_TO_PROG (touch);
pr_global_struct->other = EDICT_TO_PROG (ent);
pr_global_struct->time = sv.time;
PR_ExecuteProgram (touch->v.touch);
*sv_globals.self =
EDICT_TO_PROG (&sv_pr_state, touch);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.time = sv.time;
PR_ExecuteProgram (&sv_pr_state, SVFIELD (touch, touch, func));
pr_global_struct->self = old_self;
pr_global_struct->other = old_other;
*sv_globals.self = old_self;
*sv_globals.other = old_other;
}
// recurse down both sides
if (node->axis == -1)
return;
if (ent->v.absmax[node->axis] > node->dist)
if (SVFIELD (ent, absmax, vector)[node->axis] > node->dist)
SV_TouchLinks (ent, node->children[0]);
if (ent->v.absmin[node->axis] < node->dist)
if (SVFIELD (ent, absmin, vector)[node->axis] < node->dist)
SV_TouchLinks (ent, node->children[1]);
}
@ -370,7 +372,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
// NODE_MIXED
splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE (ent->v.absmin, ent->v.absmax, splitplane);
sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector), SVFIELD (ent, absmax, vector), splitplane);
// recurse down the contacted sides
if (sides & 1)
@ -403,9 +405,9 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
// set the abs box
#ifdef QUAKE2
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) { // expand
//
if (SVFIELD (ent, solid, float) == SOLID_BSP &&
(SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1] || SVFIELD (ent, angles, float)[2])) { // expand
//
// for
// rotation
float max, v;
@ -413,50 +415,50 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
max = 0;
for (i = 0; i < 3; i++) {
v = fabs (ent->v.mins[i]);
v = fabs (SVFIELD (ent, mins, float)[i]);
if (v > max)
max = v;
v = fabs (ent->v.maxs[i]);
v = fabs (SVFIELD (ent, maxs, float)[i]);
if (v > max)
max = v;
}
for (i = 0; i < 3; i++) {
ent->v.absmin[i] = ent->v.origin[i] - max;
ent->v.absmax[i] = ent->v.origin[i] + max;
SVFIELD (ent, absmin, float)[i] = SVFIELD (ent, origin, float)[i] - max;
SVFIELD (ent, absmax, float)[i] = SVFIELD (ent, origin, float)[i] + max;
}
} else
#endif
{
VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, absmin, vector));
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, absmax, vector));
}
//
// to make items easier to pick up and allow them to be grabbed off
// of shelves, the abs sizes are expanded
//
if ((int) ent->v.flags & FL_ITEM) {
ent->v.absmin[0] -= 15;
ent->v.absmin[1] -= 15;
ent->v.absmax[0] += 15;
ent->v.absmax[1] += 15;
if ((int) SVFIELD (ent, flags, float) & FL_ITEM) {
SVFIELD (ent, absmin, vector)[0] -= 15;
SVFIELD (ent, absmin, vector)[1] -= 15;
SVFIELD (ent, absmax, vector)[0] += 15;
SVFIELD (ent, absmax, vector)[1] += 15;
} else { // because movement is clipped an
// epsilon away from an actual edge,
// we must fully check even when bounding boxes don't quite touch
ent->v.absmin[0] -= 1;
ent->v.absmin[1] -= 1;
ent->v.absmin[2] -= 1;
ent->v.absmax[0] += 1;
ent->v.absmax[1] += 1;
ent->v.absmax[2] += 1;
SVFIELD (ent, absmin, vector)[0] -= 1;
SVFIELD (ent, absmin, vector)[1] -= 1;
SVFIELD (ent, absmin, vector)[2] -= 1;
SVFIELD (ent, absmax, vector)[0] += 1;
SVFIELD (ent, absmax, vector)[1] += 1;
SVFIELD (ent, absmax, vector)[2] += 1;
}
// link to PVS leafs
ent->num_leafs = 0;
if (ent->v.modelindex)
if (SVFIELD (ent, modelindex, float))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
if (ent->v.solid == SOLID_NOT)
if (SVFIELD (ent, solid, float) == SOLID_NOT)
return;
// find the first node that the ent's box crosses
@ -464,9 +466,9 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
while (1) {
if (node->axis == -1)
break;
if (ent->v.absmin[node->axis] > node->dist)
if (SVFIELD (ent, absmin, vector)[node->axis] > node->dist)
node = node->children[0];
else if (ent->v.absmax[node->axis] < node->dist)
else if (SVFIELD (ent, absmax, vector)[node->axis] < node->dist)
node = node->children[1];
else
break; // crosses the node
@ -474,7 +476,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
// link it in
if (ent->v.solid == SOLID_TRIGGER)
if (SVFIELD (ent, solid, float) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts);
else
InsertLinkBefore (&ent->area, &node->solid_edicts);
@ -570,8 +572,8 @@ SV_TestEntityPosition (edict_t *ent)
trace_t trace;
trace =
SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, 0,
ent);
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, origin, vector),
0, ent);
if (trace.startsolid)
return sv.edicts;
@ -758,13 +760,13 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
#ifdef QUAKE2
// rotate start and end into the models frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) {
if (SVFIELD (ent, solid, float) == SOLID_BSP &&
(SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1] || SVFIELD (ent, angles, float)[2])) {
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
AngleVectors (ent->v.angles, forward, right, up);
AngleVectors (SVFIELD (ent, angles, float), forward, right, up);
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
@ -784,14 +786,14 @@ SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs,
#ifdef QUAKE2
// rotate endpos back to world frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2])) {
if (SVFIELD (ent, solid, float) == SOLID_BSP &&
(SVFIELD (ent, angles, float)[0] || SVFIELD (ent, angles, float)[1] || SVFIELD (ent, angles, float)[2])) {
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
if (trace.fraction != 1) {
VectorSubtract (vec3_origin, ent->v.angles, a);
VectorSubtract (vec3_origin, SVFIELD (ent, angles, float), a);
AngleVectors (a, forward, right, up);
VectorCopy (trace.endpos, temp);
@ -838,38 +840,40 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next;
touch = EDICT_FROM_AREA (l);
if (touch->v.solid == SOLID_NOT)
if (SVFIELD (touch, solid, float) == SOLID_NOT)
continue;
if (touch == clip->passedict)
continue;
if (touch->v.solid == SOLID_TRIGGER)
if (SVFIELD (touch, solid, float) == SOLID_TRIGGER)
Sys_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP)
if (clip->type == MOVE_NOMONSTERS && SVFIELD (touch, solid, float) != SOLID_BSP)
continue;
if (clip->boxmins[0] > touch->v.absmax[0]
|| clip->boxmins[1] > touch->v.absmax[1]
|| clip->boxmins[2] > touch->v.absmax[2]
|| clip->boxmaxs[0] < touch->v.absmin[0]
|| clip->boxmaxs[1] < touch->v.absmin[1]
|| clip->boxmaxs[2] < touch->v.absmin[2])
if (clip->boxmins[0] > SVFIELD (touch, absmax, vector)[0]
|| clip->boxmins[1] > SVFIELD (touch, absmax, vector)[1]
|| clip->boxmins[2] > SVFIELD (touch, absmax, vector)[2]
|| clip->boxmaxs[0] < SVFIELD (touch, absmin, vector)[0]
|| clip->boxmaxs[1] < SVFIELD (touch, absmin, vector)[1]
|| clip->boxmaxs[2] < SVFIELD (touch, absmin, vector)[2])
continue;
if (clip->passedict && clip->passedict->v.size[0] && !touch->v.size[0])
if (clip->passedict && SVFIELD (clip->passedict, size, vector)[0]
&& !SVFIELD (touch, size, vector)[0])
continue; // points never interact
// might intersect, so do an exact clip
if (clip->trace.allsolid)
return;
if (clip->passedict) {
if (PROG_TO_EDICT (touch->v.owner) == clip->passedict)
continue; // don't clip against own missiles
if (PROG_TO_EDICT (clip->passedict->v.owner) == touch)
continue; // don't clip against owner
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (touch, owner, entity)) ==
clip->passedict) continue; // don't clip against own
// missiles
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (clip->passedict, owner, entity)) ==
touch) continue; // don't clip against owner
}
if ((int) touch->v.flags & FL_MONSTER)
if ((int) SVFIELD (touch, flags, float) & FL_MONSTER)
trace =
SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
clip->maxs2, clip->end);

View file

@ -43,19 +43,19 @@ extern int nanmask;
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
#define DotProduct(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}
#define VectorCopy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}
/*
* VectorDistance, the distance between two points.
* Yes, this is the same as sqrt(VectorSubtract then DotProduct),
* however that way would involve more vars, this is cheaper.
*/
#define VectorDistance_fast(a, b) (((a[0] - b[0]) * (a[0] - b[0])) + \
((a[1] - b[1]) * (a[1] - b[1])) + \
((a[2] - b[2]) * (a[2] - b[2])))
#define VectorDistance_fast(a, b) ((((a)[0] - (b)[0]) * ((a)[0] - (b)[0])) + \
(((a)[1] - (b)[1]) * ((a)[1] - (b)[1])) + \
(((a)[2] - (b)[2]) * ((a)[2] - (b)[2])))
#define VectorDistance(a, b) sqrt(VectorDistance_fast(a, b))

View file

@ -29,135 +29,135 @@
/* file generated by qcc, do not modify */
typedef struct
{ int pad[28];
int self;
int other;
int world;
float time;
float frametime;
int newmis;
float force_retouch;
{ int pad[28];
int self;
int other;
int world;
float time;
float frametime;
int newmis;
float force_retouch;
string_t mapname;
float serverflags;
float total_secrets;
float total_monsters;
float found_secrets;
float killed_monsters;
float parm1;
float parm2;
float parm3;
float parm4;
float parm5;
float parm6;
float parm7;
float parm8;
float parm9;
float parm10;
float parm11;
float parm12;
float parm13;
float parm14;
float parm15;
float parm16;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
int trace_ent;
float trace_inopen;
float trace_inwater;
int msg_entity;
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
float serverflags;
float total_secrets;
float total_monsters;
float found_secrets;
float killed_monsters;
float parm1;
float parm2;
float parm3;
float parm4;
float parm5;
float parm6;
float parm7;
float parm8;
float parm9;
float parm10;
float parm11;
float parm12;
float parm13;
float parm14;
float parm15;
float parm16;
vec3_t v_forward;
vec3_t v_up;
vec3_t v_right;
float trace_allsolid;
float trace_startsolid;
float trace_fraction;
vec3_t trace_endpos;
vec3_t trace_plane_normal;
float trace_plane_dist;
int trace_ent;
float trace_inopen;
float trace_inwater;
int msg_entity;
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
} globalvars_t;
typedef struct
{
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
float lastruntime;
float movetype;
float solid;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t angles;
vec3_t avelocity;
float modelindex;
vec3_t absmin;
vec3_t absmax;
float ltime;
float lastruntime;
float movetype;
float solid;
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
vec3_t angles;
vec3_t avelocity;
string_t classname;
string_t model;
float frame;
float skin;
float effects;
vec3_t mins;
vec3_t maxs;
vec3_t size;
func_t touch;
func_t use;
func_t think;
func_t blocked;
float nextthink;
int groundentity;
float health;
float frags;
float weapon;
float frame;
float skin;
float effects;
vec3_t mins;
vec3_t maxs;
vec3_t size;
func_t touch;
func_t use;
func_t think;
func_t blocked;
float nextthink;
int groundentity;
float health;
float frags;
float weapon;
string_t weaponmodel;
float weaponframe;
float currentammo;
float ammo_shells;
float ammo_nails;
float ammo_rockets;
float ammo_cells;
float items;
float takedamage;
int chain;
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button2;
float impulse;
float fixangle;
vec3_t v_angle;
float weaponframe;
float currentammo;
float ammo_shells;
float ammo_nails;
float ammo_rockets;
float ammo_cells;
float items;
float takedamage;
int chain;
float deadflag;
vec3_t view_ofs;
float button0;
float button1;
float button2;
float impulse;
float fixangle;
vec3_t v_angle;
string_t netname;
int enemy;
float flags;
float colormap;
float team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
float waterlevel;
float watertype;
float ideal_yaw;
float yaw_speed;
int aiment;
int goalentity;
float spawnflags;
int enemy;
float flags;
float colormap;
float team;
float max_health;
float teleport_time;
float armortype;
float armorvalue;
float waterlevel;
float watertype;
float ideal_yaw;
float yaw_speed;
int aiment;
int goalentity;
float spawnflags;
string_t target;
string_t targetname;
float dmg_take;
float dmg_save;
int dmg_inflictor;
int owner;
vec3_t movedir;
float dmg_take;
float dmg_save;
int dmg_inflictor;
int owner;
vec3_t movedir;
string_t message;
float sounds;
float sounds;
string_t noise;
string_t noise1;
string_t noise2;

173
qw/include/sv_progs.h Normal file
View file

@ -0,0 +1,173 @@
/*
sv_progs.h
server specific progs definitions
Copyright (C) 2000 Bill Currie
Author: Bill Currie
Date: 28 Feb 2001
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.
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.
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$
*/
#ifndef __sv_progs_h
#define __sv_progs_h
#include "progs.h"
typedef struct {
int *self;
int *other;
int *world;
float *time;
float *frametime;
int *newmis;
float *force_retouch;
string_t *mapname;
float *serverflags;
float *total_secrets;
float *total_monsters;
float *found_secrets;
float *killed_monsters;
float *parms; // an actual array
vec3_t *v_forward;
vec3_t *v_up;
vec3_t *v_right;
float *trace_allsolid;
float *trace_startsolid;
float *trace_fraction;
vec3_t *trace_endpos;
vec3_t *trace_plane_normal;
float *trace_plane_dist;
int *trace_ent;
float *trace_inopen;
float *trace_inwater;
int *msg_entity;
} sv_globals_t;
extern sv_globals_t sv_globals;
typedef struct {
func_t main;
func_t StartFrame;
func_t PlayerPreThink;
func_t PlayerPostThink;
func_t ClientKill;
func_t ClientConnect;
func_t PutClientInServer;
func_t ClientDisconnect;
func_t SetNewParms;
func_t SetChangeParms;
} sv_funcs_t;
extern sv_funcs_t sv_funcs;
typedef struct
{
int modelindex; //float
int absmin; //vec3_t
int absmax; //vec3_t
int ltime; //float
int lastruntime; //float
int movetype; //float
int solid; //float
int origin; //vec3_t
int oldorigin; //vec3_t
int velocity; //vec3_t
int angles; //vec3_t
int avelocity; //vec3_t
int classname; //string_t
int model; //string_t
int frame; //float
int skin; //float
int effects; //float
int mins; //vec3_t
int maxs; //vec3_t
int size; //vec3_t
int touch; //func_t
int think; //func_t
int blocked; //func_t
int nextthink; //float
int groundentity; //int
int health; //float
int frags; //float
int weapon; //float
int weaponmodel; //string_t
int weaponframe; //float
int currentammo; //float
int ammo_shells; //float
int ammo_nails; //float
int ammo_rockets; //float
int ammo_cells; //float
int items; //float
int takedamage; //float
int chain; //int
int view_ofs; //vec3_t
int button0; //float
int button1; //float
int button2; //float
int impulse; //float
int fixangle; //float
int v_angle; //vec3_t
int netname; //string_t
int enemy; //int
int flags; //float
int colormap; //float
int team; //float
int teleport_time; //float
int armorvalue; //float
int waterlevel; //float
int watertype; //float
int ideal_yaw; //float
int yaw_speed; //float
int goalentity; //int
int spawnflags; //float
int dmg_take; //float
int dmg_save; //float
int dmg_inflictor; //int
int owner; //int
int message; //string_t
int sounds; //float
int alpha;
int scale;
int glowsize;
int glowcolor;
int colormod;
} sv_fields_t;
extern sv_fields_t sv_fields;
#if 1
#define SVFIELD(e,f,t) ((ED_FindField (&sv_pr_state, #f)->type == ev_##t) ? E_var (e, sv_fields.f, t) : PR_Error (&sv_pr_state, "bad type access %s:%d", __FILE__, __LINE__), E_var (e, sv_fields.f, t))
#else
#define SVFIELD(e,f,t) E_var (e, sv_fields.f, t)
#endif
#define PROGHEADER_CRC 54730
extern func_t EndFrame;
extern func_t SpectatorConnect;
extern func_t SpectatorThink;
extern func_t SpectatorDisconnect;
#endif // __sv_progs_h

View file

@ -1,42 +0,0 @@
/*
va.h
Definitions common to client and server.
Copyright (C) 1996-1997 Id Software, Inc.
Copyright (C) 2000 Marcus Sundberg <mackan@stacken.kth.se>
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.
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.
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$
*/
#ifndef __va_h
#define __va_h
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gcc_attr.h"
char *va(char *format, ...) __attribute__((format(printf,1,2)));
// does a varargs printf into a temp buffer
#endif // __va_h

View file

@ -80,14 +80,14 @@ if ASM_ARCH
world_ASM= worlda.S
endif
server_SOURCES= pr_edict.c pr_exec.c pr_offs.c sv_ccmds.c sv_cvar.c \
server_SOURCES= sv_ccmds.c sv_cvar.c \
sv_ents.c sv_init.c sv_main.c sv_misc.c sv_model.c \
sv_move.c sv_nchan.c sv_phys.c sv_pr_cmds.c sv_progs.c sv_send.c \
sv_user.c ver_check.c world.c $(world_ASM)
qw_server_SOURCES= $(common_SOURCES) $(server_SOURCES)
qw_server_LDADD= -L. -L../../libs -lqfnet -lqfsys_sv -lqfutil $(NET_LIBS) $(Z_LIBS) $(DL_LIBS)
qw_server_DEPENDENCIES= libqfnet.a libqfsys_sv.a ../../libs/libqfutil.a
qw_server_LDADD= -L. -L../../libs -lqfnet -lqfsys_sv -lqfgamecode -lqfutil $(NET_LIBS) $(Z_LIBS) $(DL_LIBS)
qw_server_DEPENDENCIES= libqfnet.a libqfsys_sv.a ../../libs/libqfgamecode.a ../../libs/libqfutil.a
#
# Client builds
@ -170,8 +170,8 @@ endif
libqfjs_a_CFLAGS= $(JOY_CFLAGS)
EXTRA_libqfjs_a_SOURCES= joy_linux.c joy_win.c joy_null.c
CLIENT_LIBS= -L. -L../../libs -lqfnet -lqfsys_cl -lqfsnd -lqfcd -lqfjs -lqfutil $(SOUND_LIBS) $(NET_LIBS) $(CD_LIBS) $(JOY_LIBS) $(Z_LIBS)
CLIENT_LIB_DEPS= libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a ../../libs/libqfutil.a
CLIENT_LIBS= -L. -L../../libs -lqfnet -lqfsys_cl -lqfsnd -lqfcd -lqfjs -lqfgamecode -lqfutil $(SOUND_LIBS) $(NET_LIBS) $(CD_LIBS) $(JOY_LIBS) $(Z_LIBS)
CLIENT_LIB_DEPS= libqfnet.a libqfsys_cl.a libqfsnd.a libqfcd.a libqfjs.a ../../libs/libqfgamecode.a ../../libs/libqfutil.a
if ASM_ARCH
client_ASM= snd_mixa.S cl_math.S

View file

@ -1021,7 +1021,7 @@ CL_ReadPackets (void)
while (CL_GetMessage ()) {
#ifdef PACKET_LOGGING
if (cls.demoplayback) Log_Incoming_Packet(net_message.data,net_message.cursize);
if (cls.demoplayback) Log_Incoming_Packet(net_message->message->data,net_message->message->cursize);
#endif
//
// remote command packet

View file

@ -319,72 +319,72 @@ Log_Delta(int bits)
bits &= ~511;
if (bits & U_MOREBITS) { // read in the low order bits
i = MSG_ReadByte ();
i = MSG_ReadByte (net_message);
bits |= i;
}
// LordHavoc: Endy neglected to mark this as being part of the QSG
// version 2 stuff...
if (bits & U_EXTEND1) {
bits |= MSG_ReadByte () << 16;
bits |= MSG_ReadByte (net_message) << 16;
if (bits & U_EXTEND2)
bits |= MSG_ReadByte () << 24;
bits |= MSG_ReadByte (net_message) << 24;
}
to.flags = bits;
if (bits & U_MODEL)
Net_LogPrintf (" MdlIdx: %d", MSG_ReadByte ());
Net_LogPrintf (" MdlIdx: %d", MSG_ReadByte (net_message));
if (bits & U_FRAME) {
to.frame = MSG_ReadByte ();
to.frame = MSG_ReadByte (net_message);
Net_LogPrintf (" Frame: %d", to.frame);
}
if (bits & U_COLORMAP)
Net_LogPrintf (" Colormap: %d", MSG_ReadByte ());
Net_LogPrintf (" Colormap: %d", MSG_ReadByte (net_message));
if (bits & U_SKIN)
Net_LogPrintf (" Skinnum: %d", MSG_ReadByte ());
Net_LogPrintf (" Skinnum: %d", MSG_ReadByte (net_message));
if (bits & U_EFFECTS) {
to.effects = MSG_ReadByte ();
to.effects = MSG_ReadByte (net_message);
Net_LogPrintf (" Effects: %d", to.effects);
}
if (bits & U_ORIGIN1)
Net_LogPrintf (" X: %f", MSG_ReadCoord ());
Net_LogPrintf (" X: %f", MSG_ReadCoord (net_message));
if (bits & U_ANGLE1)
Net_LogPrintf (" Pitch: %d", MSG_ReadAngle ());
Net_LogPrintf (" Pitch: %d", MSG_ReadAngle (net_message));
if (bits & U_ORIGIN2)
Net_LogPrintf (" Y: %f", MSG_ReadCoord ());
Net_LogPrintf (" Y: %f", MSG_ReadCoord (net_message));
if (bits & U_ANGLE2)
Net_LogPrintf (" Yaw: %d", MSG_ReadAngle ());
Net_LogPrintf (" Yaw: %d", MSG_ReadAngle (net_message));
if (bits & U_ORIGIN3)
Net_LogPrintf (" Z: %f", MSG_ReadCoord ());
Net_LogPrintf (" Z: %f", MSG_ReadCoord (net_message));
if (bits & U_ANGLE3)
Net_LogPrintf (" Roll: %d", MSG_ReadAngle ());
Net_LogPrintf (" Roll: %d", MSG_ReadAngle (net_message));
// Ender (QSG - Begin)
if (bits & U_ALPHA)
Net_LogPrintf(" Alpha: %d", MSG_ReadByte ());
Net_LogPrintf(" Alpha: %d", MSG_ReadByte (net_message));
if (bits & U_SCALE)
Net_LogPrintf(" Scale: %d", MSG_ReadByte ());
Net_LogPrintf(" Scale: %d", MSG_ReadByte (net_message));
if (bits & U_EFFECTS2)
Net_LogPrintf(" U_EFFECTS2: %d", (to.effects & 0xFF) | (MSG_ReadByte () << 8));
Net_LogPrintf(" U_EFFECTS2: %d", (to.effects & 0xFF) | (MSG_ReadByte (net_message) << 8));
if (bits & U_GLOWSIZE)
Net_LogPrintf(" GlowSize: %d", MSG_ReadByte ());
Net_LogPrintf(" GlowSize: %d", MSG_ReadByte (net_message));
if (bits & U_GLOWCOLOR)
Net_LogPrintf(" ColorGlow: %d", MSG_ReadByte ());
Net_LogPrintf(" ColorGlow: %d", MSG_ReadByte (net_message));
if (bits & U_COLORMOD)
Net_LogPrintf(" Colormod: %d", MSG_ReadByte ());
Net_LogPrintf(" Colormod: %d", MSG_ReadByte (net_message));
if (bits & U_FRAME2)
Net_LogPrintf(" Uframe2: %d", ((to.frame & 0xFF) | (MSG_ReadByte () << 8)));
Net_LogPrintf(" Uframe2: %d", ((to.frame & 0xFF) | (MSG_ReadByte (net_message) << 8)));
// Ender (QSG - End)
return;
@ -398,16 +398,16 @@ Analyze_Server_Packet (byte * data, int len)
byte *safe;
int slen;
// FIXME: quick-hack
safe=net_message.data;
slen=net_message.cursize;
safe=net_message->message->data;
slen=net_message->message->cursize;
net_message.data = data;
net_message.cursize = len;
MSG_BeginReading ();
net_message->message->data = data;
net_message->message->cursize = len;
MSG_BeginReading (net_message);
Parse_Server_Packet ();
// net_message.data = net_message_buffer;
net_message.data = safe;
net_message.cursize = slen;
net_message->message->data = safe;
net_message->message->cursize = slen;
}
@ -418,15 +418,15 @@ Parse_Server_Packet ()
int c, i, ii, iii, mask1, mask2;
char *s;
seq1 = MSG_ReadLong ();
if (msg_badread)
seq1 = MSG_ReadLong (net_message);
if (net_message->badread)
return;
if (seq1 == -1) {
Net_LogPrintf ("Special Packet");
} else {
seq2 = MSG_ReadLong ();
seq2 = MSG_ReadLong (net_message);
// FIXME: display seqs right when reliable
Net_LogPrintf ("\nSeq: %ld Ack: %ld ", seq1 & 0x7FFFFFFF,
seq2 & 0x7FFFFFFF);
@ -438,19 +438,19 @@ Parse_Server_Packet ()
Net_LogPrintf ("\n");
while (1) {
if (msg_badread)
if (net_message->badread)
break;
c = MSG_ReadByte ();
c = MSG_ReadByte (net_message);
if (c == -1)
break;
// Net_LogPrintf("\n<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
Net_LogPrintf ("<%06x> [0x%02x] ", MSG_GetReadCount (), c);
Net_LogPrintf ("<%06x> [0x%02x] ", MSG_GetReadCount (net_message), c);
if (c < 53)
Net_LogPrintf ("%s: ", svc_string[c]);
// else Net_LogPrintf("(UNK: %d): ",c);
if (MSG_GetReadCount () > net_message.cursize)
if (MSG_GetReadCount (net_message) > net_message->message->cursize)
return;
switch (c) {
@ -463,8 +463,8 @@ Parse_Server_Packet ()
Net_LogPrintf (" <Quit>");
break;
case svc_updatestat:
i = MSG_ReadByte ();
Net_LogPrintf (" index: %d value: %d", i, MSG_ReadByte ());
i = MSG_ReadByte (net_message);
Net_LogPrintf (" index: %d value: %d", i, MSG_ReadByte (net_message));
break;
case svc_version:
#ifdef QUAKEWORLD
@ -475,25 +475,25 @@ Parse_Server_Packet ()
#ifdef QUAKEWORLD
Net_LogPrintf ("**QW OBSOLETE**");
#else
MSG_ReadShort ();
MSG_ReadShort (net_message);
#endif
break;
case svc_sound:
i = MSG_ReadShort ();
i = MSG_ReadShort (net_message);
Net_LogPrintf (": (%d) ", i);
if (i & SND_VOLUME)
Net_LogPrintf ("Volume %d ", MSG_ReadByte ());
Net_LogPrintf ("Volume %d ", MSG_ReadByte (net_message));
if (i & SND_ATTENUATION)
Net_LogPrintf ("Ann: %f",
(float) MSG_ReadByte () / 64.0);
ii = MSG_ReadByte ();
(float) MSG_ReadByte (net_message) / 64.0);
ii = MSG_ReadByte (net_message);
// FIXME: well, cl. for client :-)
// Net_LogPrintf ("%d (%s) ", ii, sv.sound_precache[ii]);
Net_LogPrintf ("%d (%s) ", ii);
Net_LogPrintf ("Pos: ");
for (ii = 0; ii < 3; ii++)
Net_LogPrintf ("%f ", MSG_ReadCoord ());
Net_LogPrintf ("%f ", MSG_ReadCoord (net_message));
Net_LogPrintf ("Ent: %d ", (i >> 3) & 1023);
Net_LogPrintf ("Channel %d ", i & 7);
break;
@ -501,49 +501,49 @@ Parse_Server_Packet ()
#ifdef QUAKEWORLD
Net_LogPrintf ("**QW OBSOLETE**\n");
#else
MSG_ReadFloat ();
MSG_ReadFloat (net_message);
#endif
break;
case svc_print:
// FIXME: i==PRINT_CHAT
Net_LogPrintf (" [%d]", MSG_ReadByte ());
Net_LogPrintf (" %s", MSG_ReadString ());
Net_LogPrintf (" [%d]", MSG_ReadByte (net_message));
Net_LogPrintf (" %s", MSG_ReadString (net_message));
break;
case svc_stufftext:
Net_LogPrintf ("%s", MSG_ReadString ());
Net_LogPrintf ("%s", MSG_ReadString (net_message));
break;
case svc_setangle:
for (i = 0; i < 3; i++)
Net_LogPrintf ("%f ", MSG_ReadAngle ());
Net_LogPrintf ("%f ", MSG_ReadAngle (net_message));
break;
#ifdef QUAKEWORLD
case svc_serverdata:
Net_LogPrintf ("Ver: %ld", MSG_ReadLong ());
Net_LogPrintf (" Client ID: %ld", MSG_ReadLong ());
Net_LogPrintf (" Dir: %s", MSG_ReadString ());
Net_LogPrintf (" User ID: %d", MSG_ReadByte ());
Net_LogPrintf (" Map: %s", MSG_ReadString ());
Net_LogPrintf ("Ver: %ld", MSG_ReadLong (net_message));
Net_LogPrintf (" Client ID: %ld", MSG_ReadLong (net_message));
Net_LogPrintf (" Dir: %s", MSG_ReadString (net_message));
Net_LogPrintf (" User ID: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Map: %s", MSG_ReadString (net_message));
for (i = 0; i < 10; i++)
MSG_ReadFloat ();
MSG_ReadFloat (net_message);
break;
#endif
case svc_lightstyle:
i = MSG_ReadByte ();
i = MSG_ReadByte (net_message);
if (i >= MAX_LIGHTSTYLES)
return;
Net_LogPrintf ("%d %s", i, MSG_ReadString ());
Net_LogPrintf ("%d %s", i, MSG_ReadString (net_message));
break;
case svc_updatename:
#ifdef QUAKEWORLD
Net_LogPrintf ("**QW OBSOLETE**");
#else
Net_LogPrintf ("%d %s", MSG_ReadByte (), MSG_ReadString ());
Net_LogPrintf ("%d %s", MSG_ReadByte (net_message), MSG_ReadString ());
#endif
break;
case svc_updatefrags:
Net_LogPrintf ("player: %d frags: %d", MSG_ReadByte (),
MSG_ReadShort ());
Net_LogPrintf ("player: %d frags: %d", MSG_ReadByte (net_message),
MSG_ReadShort (net_message));
break;
case svc_clientdata:
#ifdef QUAKEWORLD
@ -551,14 +551,14 @@ Parse_Server_Packet ()
#endif
break;
case svc_stopsound:
Net_LogPrintf ("%d", MSG_ReadShort ());
Net_LogPrintf ("%d", MSG_ReadShort (net_message));
break;
case svc_updatecolors:
#ifdef QUAKEWORLD
Net_LogPrintf ("**QW OBSOLETE**");
#else
Net_LogPrintf ("%d %d", MSG_ReadByte (), MSG_ReadByte ());
Net_LogPrintf ("%d %d", MSG_ReadByte (net_message), MSG_ReadByte ());
#endif
break;
case svc_particle:
@ -566,46 +566,46 @@ Parse_Server_Packet ()
Net_LogPrintf ("**QW OBSOLETE**");
#else
for (i = 0; i < 3; i++)
Net_LogPrintf (" %f", MSG_ReadCoord ());
Net_LogPrintf (" %f", MSG_ReadCoord (net_message));
for (i = 0; i < 3; i++)
Net_LogPrintf (" %d", MSG_ReadChar ());
Net_LogPrintf (" Count: %d", MSG_ReadByte ());
Net_LogPrintf (" Color: %d", MSG_ReadByte ());
Net_LogPrintf (" %d", MSG_ReadChar (net_message));
Net_LogPrintf (" Count: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Color: %d", MSG_ReadByte (net_message));
#endif
break;
case svc_damage:
// FIXME: parse damage
Net_LogPrintf ("armor: %d health: %d", MSG_ReadByte (),
MSG_ReadByte ());
Net_LogPrintf (" from %f,%f,%f", MSG_ReadCoord (),
MSG_ReadCoord (), MSG_ReadCoord ());
Net_LogPrintf ("armor: %d health: %d", MSG_ReadByte (net_message),
MSG_ReadByte (net_message));
Net_LogPrintf (" from %f,%f,%f", MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message));
break;
case svc_spawnstatic:
Net_LogPrintf ("%d", MSG_ReadByte ());
Net_LogPrintf ("Model: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Frame: %d Color: %d Skin: %",
MSG_ReadByte (), MSG_ReadByte (),
MSG_ReadByte ());
MSG_ReadByte (net_message), MSG_ReadByte (net_message),
MSG_ReadByte (net_message));
for (i = 0; i < 3; i++)
Net_LogPrintf ("%d: %f %f", i + 1, MSG_ReadCoord (),
MSG_ReadAngle ());
Net_LogPrintf ("%d: %f %f", i + 1, MSG_ReadCoord (net_message),
MSG_ReadAngle (net_message));
break;
case svc_spawnbinary:
Net_LogPrintf ("**OBSOLETE**");
break;
case svc_spawnbaseline:
Net_LogPrintf ("%d", MSG_ReadShort ());
Net_LogPrintf (" idx: %d", MSG_ReadByte ());
Net_LogPrintf (" Frame: %d", MSG_ReadByte ());
Net_LogPrintf (" Colormap: %d", MSG_ReadByte ());
Net_LogPrintf (" Skin: %d", MSG_ReadByte ());
Net_LogPrintf ("%d", MSG_ReadShort (net_message));
Net_LogPrintf (" idx: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Frame: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Colormap: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Skin: %d", MSG_ReadByte (net_message));
for (i = 0; i < 3; i++) {
Net_LogPrintf (" %f", MSG_ReadCoord ());
Net_LogPrintf (" %d", MSG_ReadAngle ());
Net_LogPrintf (" %f", MSG_ReadCoord (net_message));
Net_LogPrintf (" %d", MSG_ReadAngle (net_message));
};
break;
case svc_temp_entity:
i = MSG_ReadByte ();
i = MSG_ReadByte (net_message);
switch (i) {
case 0:
case 1:
@ -616,25 +616,25 @@ Parse_Server_Packet ()
case 10:
case 11:
case 13:
Net_LogPrintf (" origin %f %f %f", MSG_ReadCoord (),
MSG_ReadCoord (), MSG_ReadCoord ());
Net_LogPrintf (" origin %f %f %f", MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message));
break;
case 5:
case 6:
case 9:
Net_LogPrintf (" created by %d", MSG_ReadShort ());
Net_LogPrintf (" created by %d", MSG_ReadShort (net_message));
Net_LogPrintf (" origin: %f,%f,%f",
MSG_ReadCoord (), MSG_ReadCoord (),
MSG_ReadCoord ());
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message));
Net_LogPrintf (" trace endpos: %f,%f,%f",
MSG_ReadCoord (), MSG_ReadCoord (),
MSG_ReadCoord ());
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message));
break;
case 2:
case 12:
Net_LogPrintf (" count: %d", MSG_ReadByte ());
printf (" origin: %f,%f,%f", MSG_ReadCoord (),
MSG_ReadCoord (), MSG_ReadCoord ());
Net_LogPrintf (" count: %d", MSG_ReadByte (net_message));
printf (" origin: %f,%f,%f", MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message));
break;
default:
Net_LogPrintf (" unknown value %d for tempentity",
@ -644,40 +644,40 @@ Parse_Server_Packet ()
break;
case svc_setpause:
Net_LogPrintf (" %d", MSG_ReadByte ());
Net_LogPrintf (" %d", MSG_ReadByte (net_message));
break;
case svc_signonnum:
#ifdef QUAKEWORLD
Net_LogPrintf ("**QW OBSOLETE**");
#else
Net_LogPrintf ("%d", MSG_ReadByte ());
Net_LogPrintf ("%d", MSG_ReadByte (net_message));
#endif
break;
case svc_centerprint:
Net_LogPrintf (MSG_ReadString ());
Net_LogPrintf (MSG_ReadString (net_message));
break;
case svc_killedmonster:
break;
case svc_foundsecret:
break;
case svc_spawnstaticsound:
Net_LogPrintf ("pos %f,%f,%f", MSG_ReadCoord (),
MSG_ReadCoord (), MSG_ReadCoord ());
Net_LogPrintf ("%d %d %d", MSG_ReadByte (), MSG_ReadByte (),
MSG_ReadByte ());
Net_LogPrintf ("pos %f,%f,%f", MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message));
Net_LogPrintf ("%d %d %d", MSG_ReadByte (net_message), MSG_ReadByte (net_message),
MSG_ReadByte (net_message));
break;
case svc_intermission:
for (i = 0; i < 3; i++)
Net_LogPrintf ("%f ", MSG_ReadCoord ());
Net_LogPrintf ("%f ", MSG_ReadCoord (net_message));
Net_LogPrintf ("\n");
for (i = 0; i < 3; i++)
Net_LogPrintf ("%f ", MSG_ReadAngle ());
Net_LogPrintf ("%f ", MSG_ReadAngle (net_message));
break;
case svc_finale:
Net_LogPrintf ("%s", MSG_ReadString ());
Net_LogPrintf ("%s", MSG_ReadString (net_message));
break;
case svc_cdtrack:
Net_LogPrintf ("%d", MSG_ReadByte ());
Net_LogPrintf ("%d", MSG_ReadByte (net_message));
break;
case svc_sellscreen:
break;
@ -686,98 +686,98 @@ Parse_Server_Packet ()
case svc_bigkick:
break;
case svc_updateping:
Net_LogPrintf ("Player: %d ", MSG_ReadByte ());
Net_LogPrintf ("Ping: %d", MSG_ReadShort ());
Net_LogPrintf ("Player: %d ", MSG_ReadByte (net_message));
Net_LogPrintf ("Ping: %d", MSG_ReadShort (net_message));
break;
case svc_updateentertime:
Net_LogPrintf ("Player: %d ", MSG_ReadByte ());
Net_LogPrintf ("Time: %f", MSG_ReadFloat ());
Net_LogPrintf ("Player: %d ", MSG_ReadByte (net_message));
Net_LogPrintf ("Time: %f", MSG_ReadFloat (net_message));
break;
case svc_updatestatlong:
i = MSG_ReadByte ();
Net_LogPrintf ("%d value: %ld", i, MSG_ReadLong ());
i = MSG_ReadByte (net_message);
Net_LogPrintf ("%d value: %ld", i, MSG_ReadLong (net_message));
break;
case svc_muzzleflash:
Net_LogPrintf ("%d", MSG_ReadShort ());
Net_LogPrintf ("%d", MSG_ReadShort (net_message));
break;
case svc_updateuserinfo:
Net_LogPrintf ("Player: %d ", MSG_ReadByte ());
Net_LogPrintf ("ID: %ld ", MSG_ReadLong ());
Net_LogPrintf ("Info: %s", MSG_ReadString ());
Net_LogPrintf ("Player: %d ", MSG_ReadByte (net_message));
Net_LogPrintf ("ID: %ld ", MSG_ReadLong (net_message));
Net_LogPrintf ("Info: %s", MSG_ReadString (net_message));
break;
case svc_download:
ii = MSG_ReadShort ();
Net_LogPrintf ("%d bytes at %d", ii, MSG_ReadByte ());
ii = MSG_ReadShort (net_message);
Net_LogPrintf ("%d bytes at %d", ii, MSG_ReadByte (net_message));
for (i = 0; i < ii; i++)
MSG_ReadByte ();
MSG_ReadByte (net_message);
break;
case svc_playerinfo:
Net_LogPrintf ("\n\tPlayer: %d", MSG_ReadByte ());
mask1 = MSG_ReadShort ();
Net_LogPrintf ("\n\tPlayer: %d", MSG_ReadByte (net_message));
mask1 = MSG_ReadShort (net_message);
Net_LogPrintf (" Mask1: %d", mask1);
Net_LogPrintf (" Origin: %f,%f,%f", MSG_ReadCoord (),
MSG_ReadCoord (), MSG_ReadCoord ());
Net_LogPrintf (" Frame: %d", MSG_ReadByte ());
Net_LogPrintf (" Origin: %f,%f,%f", MSG_ReadCoord (net_message),
MSG_ReadCoord (net_message), MSG_ReadCoord (net_message));
Net_LogPrintf (" Frame: %d", MSG_ReadByte (net_message));
if (mask1 & PF_MSEC)
Net_LogPrintf (" Ping: %d", MSG_ReadByte ());
Net_LogPrintf (" Ping: %d", MSG_ReadByte (net_message));
if (mask1 & PF_COMMAND) {
mask2 = MSG_ReadByte (); // command
mask2 = MSG_ReadByte (net_message); // command
if (mask2 & 0x01)
Net_LogPrintf (" Pitch: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Pitch: %f", MSG_ReadAngle16 (net_message));
if (mask2 & 0x80)
Net_LogPrintf (" Yaw: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Yaw: %f", MSG_ReadAngle16 (net_message));
if (mask2 & 0x02)
Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 (net_message));
if (mask2 & 0x04)
Net_LogPrintf (" Speed1: %d", MSG_ReadShort ());
Net_LogPrintf (" Speed1: %d", MSG_ReadShort (net_message));
if (mask2 & 0x08)
Net_LogPrintf (" Speed2: %d", MSG_ReadShort ());
Net_LogPrintf (" Speed2: %d", MSG_ReadShort (net_message));
if (mask2 & 0x10)
Net_LogPrintf (" Speed3: %d", MSG_ReadShort ());
Net_LogPrintf (" Speed3: %d", MSG_ReadShort (net_message));
if (mask2 & 0x20)
Net_LogPrintf (" Flag: %d", MSG_ReadByte ());
Net_LogPrintf (" Flag: %d", MSG_ReadByte (net_message));
if (mask2 & 0x40)
Net_LogPrintf (" Impulse: %d", MSG_ReadByte ());
Net_LogPrintf (" Msec: %d", MSG_ReadByte ());
Net_LogPrintf (" Impulse: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Msec: %d", MSG_ReadByte (net_message));
}
if (mask1 & PF_VELOCITY1)
Net_LogPrintf (" Xspd: %f", MSG_ReadCoord ());
Net_LogPrintf (" Xspd: %f", MSG_ReadCoord (net_message));
if (mask1 & PF_VELOCITY2)
Net_LogPrintf (" Yspd: %f", MSG_ReadCoord ());
Net_LogPrintf (" Yspd: %f", MSG_ReadCoord (net_message));
if (mask1 & PF_VELOCITY3)
Net_LogPrintf (" ZSpd: %f", MSG_ReadCoord ());
Net_LogPrintf (" ZSpd: %f", MSG_ReadCoord (net_message));
if (mask1 & PF_MODEL)
Net_LogPrintf (" Model: %d", MSG_ReadByte ());
Net_LogPrintf (" Model: %d", MSG_ReadByte (net_message));
if (mask1 & PF_SKINNUM)
Net_LogPrintf (" Skin: %d", MSG_ReadByte ());
Net_LogPrintf (" Skin: %d", MSG_ReadByte (net_message));
if (mask1 & PF_EFFECTS)
Net_LogPrintf (" Effects: %d", MSG_ReadByte ());
Net_LogPrintf (" Effects: %d", MSG_ReadByte (net_message));
if (mask1 & PF_WEAPONFRAME)
Net_LogPrintf (" Weapon frame: %d", MSG_ReadByte ());
Net_LogPrintf (" Weapon frame: %d", MSG_ReadByte (net_message));
break;
case svc_nails:
ii = MSG_ReadByte ();
ii = MSG_ReadByte (net_message);
Net_LogPrintf (" %d (bits not parsed)", ii);
for (i = 0; i < ii; i++) {
for (iii = 0; iii < 6; iii++)
MSG_ReadByte ();
MSG_ReadByte (net_message);
}
break;
case svc_chokecount:
Net_LogPrintf ("%d", MSG_ReadByte ());
Net_LogPrintf ("%d", MSG_ReadByte (net_message));
break;
case svc_modellist:
ii = MSG_ReadByte ();
ii = MSG_ReadByte (net_message);
Net_LogPrintf ("start %d", ii);
for (i = ii; i < 256; i++) {
s = MSG_ReadString ();
if (msg_badread)
s = MSG_ReadString (net_message);
if (net_message->badread)
break;
if (!s)
break;
@ -785,18 +785,18 @@ Parse_Server_Packet ()
break;
Net_LogPrintf ("\n\tModel %d: %s", i, s);
}
i = MSG_ReadByte ();
i = MSG_ReadByte (net_message);
if (i)
Net_LogPrintf ("\n\tnext at %d", i);
else
Net_LogPrintf ("\n\t*End of modellist*");
break;
case svc_soundlist:
ii = MSG_ReadByte ();
ii = MSG_ReadByte (net_message);
Net_LogPrintf ("start %d", ii);
for (i = ii; i < 256; i++) {
s = MSG_ReadString ();
if (msg_badread)
s = MSG_ReadString (net_message);
if (net_message->badread)
break;
if (!s)
break;
@ -804,7 +804,7 @@ Parse_Server_Packet ()
break;
Net_LogPrintf ("\n\tSound %d: %s", i, s);
}
i = MSG_ReadByte ();
i = MSG_ReadByte (net_message);
if (i)
Net_LogPrintf ("\n\tnext at %d", i);
@ -814,8 +814,8 @@ Parse_Server_Packet ()
case svc_packetentities:
while (1) {
mask1 = (unsigned short) MSG_ReadShort();
if (msg_badread) {
mask1 = (unsigned short) MSG_ReadShort(net_message);
if (net_message->badread) {
Net_LogPrintf ("Badread\n");
return;
}
@ -825,27 +825,27 @@ Parse_Server_Packet ()
}
break;
case svc_deltapacketentities:
Net_LogPrintf ("idx: %d", MSG_ReadByte ());
Net_LogPrintf ("idx: %d", MSG_ReadByte (net_message));
return;
break;
case svc_maxspeed:
Net_LogPrintf ("%f", MSG_ReadFloat ());
Net_LogPrintf ("%f", MSG_ReadFloat (net_message));
break;
case svc_entgravity:
Net_LogPrintf ("%f", MSG_ReadFloat ());
Net_LogPrintf ("%f", MSG_ReadFloat (net_message));
break;
case svc_setinfo:
Net_LogPrintf ("Player: %d ", MSG_ReadByte ());
Net_LogPrintf ("Keyname: %s ", MSG_ReadString ());
Net_LogPrintf ("Value: %s", MSG_ReadString ());
Net_LogPrintf ("Player: %d ", MSG_ReadByte (net_message));
Net_LogPrintf ("Keyname: %s ", MSG_ReadString (net_message));
Net_LogPrintf ("Value: %s", MSG_ReadString (net_message));
break;
case svc_serverinfo:
Net_LogPrintf ("Name: %s Value: %s", MSG_ReadString (),
MSG_ReadString ());
Net_LogPrintf ("Name: %s Value: %s", MSG_ReadString (net_message),
MSG_ReadString (net_message));
break;
case svc_updatepl:
Net_LogPrintf ("Player: %d Ploss: %d", MSG_ReadByte (),
MSG_ReadByte ());
Net_LogPrintf ("Player: %d Ploss: %d", MSG_ReadByte (net_message),
MSG_ReadByte (net_message));
break;
default:
Net_LogPrintf ("**UNKNOWN**: [%d]", c);
@ -860,11 +860,11 @@ void
Analyze_Client_Packet (byte * data, int len)
{
// FIXME: quick-hack
net_message.data = data;
net_message.cursize = len;
MSG_BeginReading ();
net_message->message->data = data;
net_message->message->cursize = len;
MSG_BeginReading (net_message);
Parse_Client_Packet ();
net_message.data = net_message_buffer;
net_message->message->data = net_message_buffer;
}
void
@ -874,13 +874,13 @@ Parse_Client_Packet (void)
long seq1, seq2;
int mask;
seq1 = MSG_ReadLong ();
seq1 = MSG_ReadLong (net_message);
if (seq1 == -1) {
Net_LogPrintf ("Special: %s\n", MSG_ReadString ());
Net_LogPrintf ("Special: %s\n", MSG_ReadString (net_message));
return;
} else {
// FIXME: display seqs right when reliable
seq2 = MSG_ReadLong ();
seq2 = MSG_ReadLong (net_message);
Net_LogPrintf ("\nSeq: %ld Ack: %ld ", seq1 & 0x7FFFFFFF,
seq2 & 0x7FFFFFFF);
@ -889,16 +889,16 @@ Parse_Client_Packet (void)
if ((seq2 >>31) &0x01) Net_LogPrintf("CL_RELACK ");
*/
Net_LogPrintf ("QP: %u\n", MSG_ReadShort ());
Net_LogPrintf ("QP: %u\n", MSG_ReadShort (net_message));
while (1) {
if (msg_badread)
if (net_message->badread)
break;
c = MSG_ReadByte ();
c = MSG_ReadByte (net_message);
if (c == -1)
break;
// Net_LogPrintf("<%ld,%ld> ",seq1 & 0x7FFFFFFF,seq2 & 0x7FFFFFFF);
Net_LogPrintf ("\n<%06x> [0x%02x] ", MSG_GetReadCount (), c);
Net_LogPrintf ("\n<%06x> [0x%02x] ", MSG_GetReadCount (net_message), c);
if (c < 8)
Net_LogPrintf ("%s: ", clc_string[c]);
@ -906,46 +906,46 @@ Parse_Client_Packet (void)
case clc_nop:
break;
case clc_delta:
Net_LogPrintf ("%d", MSG_ReadByte ());
Net_LogPrintf ("%d", MSG_ReadByte (net_message));
break;
case clc_move:
Net_LogPrintf ("checksum = %02x ", MSG_ReadByte ());
Net_LogPrintf ("PacketLoss: %d", MSG_ReadByte ());
Net_LogPrintf ("checksum = %02x ", MSG_ReadByte (net_message));
Net_LogPrintf ("PacketLoss: %d", MSG_ReadByte (net_message));
for (i = 0; i < 3; i++) {
mask = MSG_ReadByte ();
mask = MSG_ReadByte (net_message);
Net_LogPrintf ("\n\t(%d) mask = %02x", i, mask);
if (mask & 0x01)
Net_LogPrintf (" Tilt: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Tilt: %f", MSG_ReadAngle16 (net_message));
if (mask & 0x80)
Net_LogPrintf (" Yaw: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Yaw: %f", MSG_ReadAngle16 (net_message));
if (mask & 0x02)
Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 ());
Net_LogPrintf (" Roll: %f", MSG_ReadAngle16 (net_message));
if (mask & 0x04)
Net_LogPrintf (" Fwd: %d", MSG_ReadShort ());
Net_LogPrintf (" Fwd: %d", MSG_ReadShort (net_message));
if (mask & 0x08)
Net_LogPrintf (" Right: %d", MSG_ReadShort ());
Net_LogPrintf (" Right: %d", MSG_ReadShort (net_message));
if (mask & 0x10)
Net_LogPrintf (" Up: %d", MSG_ReadShort ());
Net_LogPrintf (" Up: %d", MSG_ReadShort (net_message));
if (mask & 0x20)
Net_LogPrintf (" Flags: %d", MSG_ReadByte ());
Net_LogPrintf (" Flags: %d", MSG_ReadByte (net_message));
if (mask & 0x40)
Net_LogPrintf (" Impulse: %d", MSG_ReadByte ());
Net_LogPrintf (" Msec: %d", MSG_ReadByte ());
Net_LogPrintf (" Impulse: %d", MSG_ReadByte (net_message));
Net_LogPrintf (" Msec: %d", MSG_ReadByte (net_message));
}
break;
case clc_stringcmd:
Net_LogPrintf ("%s", MSG_ReadString ());
Net_LogPrintf ("%s", MSG_ReadString (net_message));
break;
case clc_tmove:
for (i = 0; i < 3; i++)
Net_LogPrintf ("%f ", MSG_ReadCoord ());
Net_LogPrintf ("%f ", MSG_ReadCoord (net_message));
break;
case clc_upload:
ii = MSG_ReadShort ();
Net_LogPrintf ("%d bytes at %d", ii, MSG_ReadByte ());
ii = MSG_ReadShort (net_message);
Net_LogPrintf ("%d bytes at %d", ii, MSG_ReadByte (net_message));
for (i = 0; i < ii; i++)
MSG_ReadByte ();
MSG_ReadByte (net_message);
break;
default:
Net_LogPrintf ("**UNKNOWN**: [%d]", c);

View file

@ -1,54 +0,0 @@
/*
pr_offs.c
Quick QuakeC offset access
Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
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$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "progs.h"
int
FindFieldOffset (progs_t *pr, char *field)
{
ddef_t *d;
d = ED_FindField (pr, field);
if (!d)
return 0;
return d->ofs * 4;
}
eval_t *
GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset)
{
if (!fieldoffset)
return NULL;
return (eval_t *) ((char *) &ed->v + fieldoffset);
}

View file

@ -45,6 +45,7 @@
#include "qendian.h"
#include "quakefs.h"
#include "server.h"
#include "sv_progs.h"
#include "sys.h"
#include "va.h"
@ -216,8 +217,8 @@ SV_God_f (void)
if (!SV_SetPlayer ())
return;
sv_player->v.v.flags = (int) sv_player->v.v.flags ^ FL_GODMODE;
if (!((int) sv_player->v.v.flags & FL_GODMODE))
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) ^ FL_GODMODE;
if (!((int) SVFIELD (sv_player, flags, float) & FL_GODMODE))
SV_ClientPrintf (host_client, PRINT_HIGH, "godmode OFF\n");
else
SV_ClientPrintf (host_client, PRINT_HIGH, "godmode ON\n");
@ -236,11 +237,11 @@ SV_Noclip_f (void)
if (!SV_SetPlayer ())
return;
if (sv_player->v.v.movetype != MOVETYPE_NOCLIP) {
sv_player->v.v.movetype = MOVETYPE_NOCLIP;
if (SVFIELD (sv_player, movetype, float) != MOVETYPE_NOCLIP) {
SVFIELD (sv_player, movetype, float) = MOVETYPE_NOCLIP;
SV_ClientPrintf (host_client, PRINT_HIGH, "noclip ON\n");
} else {
sv_player->v.v.movetype = MOVETYPE_WALK;
SVFIELD (sv_player, movetype, float) = MOVETYPE_WALK;
SV_ClientPrintf (host_client, PRINT_HIGH, "noclip OFF\n");
}
}
@ -276,24 +277,24 @@ SV_Give_f (void)
case '7':
case '8':
case '9':
sv_player->v.v.items =
(int) sv_player->v.v.items | IT_SHOTGUN << (t[0] - '2');
SVFIELD (sv_player, items, float) =
(int) SVFIELD (sv_player, items, float) | IT_SHOTGUN << (t[0] - '2');
break;
case 's':
sv_player->v.v.ammo_shells = v;
SVFIELD (sv_player, ammo_shells, float) = v;
break;
case 'n':
sv_player->v.v.ammo_nails = v;
SVFIELD (sv_player, ammo_nails, float) = v;
break;
case 'r':
sv_player->v.v.ammo_rockets = v;
SVFIELD (sv_player, ammo_rockets, float) = v;
break;
case 'h':
sv_player->v.v.health = v;
SVFIELD (sv_player, health, float) = v;
break;
case 'c':
sv_player->v.v.ammo_cells = v;
SVFIELD (sv_player, ammo_cells, float) = v;
break;
}
}
@ -414,7 +415,7 @@ SV_Status_f (void)
Con_Printf ("%-16.16s ", cl->name);
Con_Printf ("%6i %5i", cl->userid, (int) cl->edict->v.v.frags);
Con_Printf ("%6i %5i", cl->userid, (int) SVFIELD (cl->edict, frags, float));
if (cl->spectator)
Con_Printf (" (s)\n");
else
@ -444,7 +445,7 @@ SV_Status_f (void)
for (i = 0, cl = svs.clients; i < MAX_CLIENTS; i++, cl++) {
if (!cl->state)
continue;
Con_Printf ("%5i %6i ", (int) cl->edict->v.v.frags, cl->userid);
Con_Printf ("%5i %6i ", (int) SVFIELD (cl->edict, frags, float), cl->userid);
s = NET_BaseAdrToString (cl->netchan.remote_address);

View file

@ -39,16 +39,9 @@
#include "msg.h"
#include "msg_ucmd.h"
#include "server.h"
#include "sv_progs.h"
#include "sys.h"
// LordHavoc: added and removed certain eval_ items
// Ender Extends (QSG - Begin)
extern int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor,
eval_colormod;
// Ender Extends (QSG - End)
extern eval_t *GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset);
/*
The PVS must include a small area around the client to allow head
bobbing or other small motion on the client side. Otherwise, a bob
@ -119,8 +112,8 @@ extern int sv_nailmodel, sv_supernailmodel, sv_playermodel;
qboolean
SV_AddNailUpdate (edict_t *ent)
{
if (ent->v.v.modelindex != sv_nailmodel
&& ent->v.v.modelindex != sv_supernailmodel) return false;
if (SVFIELD (ent, modelindex, float) != sv_nailmodel
&& SVFIELD (ent, modelindex, float) != sv_supernailmodel) return false;
if (numnails == MAX_NAILS)
return true;
nails[numnails] = ent;
@ -144,11 +137,11 @@ SV_EmitNailUpdate (sizebuf_t *msg)
for (n = 0; n < numnails; n++) {
ent = nails[n];
x = (int) (ent->v.v.origin[0] + 4096) >> 1;
y = (int) (ent->v.v.origin[1] + 4096) >> 1;
z = (int) (ent->v.v.origin[2] + 4096) >> 1;
p = (int) (16 * ent->v.v.angles[0] / 360) & 15;
yaw = (int) (256 * ent->v.v.angles[1] / 360) & 255;
x = (int) (SVFIELD (ent, origin, vector)[0] + 4096) >> 1;
y = (int) (SVFIELD (ent, origin, vector)[1] + 4096) >> 1;
z = (int) (SVFIELD (ent, origin, vector)[2] + 4096) >> 1;
p = (int) (16 * SVFIELD (ent, angles, vector)[0] / 360) & 15;
yaw = (int) (256 * SVFIELD (ent, angles, vector)[1] / 360) & 255;
bits[0] = x;
bits[1] = (x >> 8) | (y << 4);
@ -364,7 +357,7 @@ SV_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t *msg)
// the baseline
ent = EDICT_NUM (&sv_pr_state, newnum);
//Con_Printf ("baseline %i\n", newnum);
SV_WriteDelta (&ent->baseline, &to->entities[newindex], msg, true,
SV_WriteDelta (ent->data, &to->entities[newindex], msg, true,
client->stdver);
newindex++;
continue;
@ -418,18 +411,18 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
pflags = PF_MSEC | PF_COMMAND;
if (ent->v.v.modelindex != sv_playermodel)
if (SVFIELD (ent, modelindex, float) != sv_playermodel)
pflags |= PF_MODEL;
for (i = 0; i < 3; i++)
if (ent->v.v.velocity[i])
if (SVFIELD (ent, velocity, vector)[i])
pflags |= PF_VELOCITY1 << i;
if (ent->v.v.effects)
if (SVFIELD (ent, effects, float))
pflags |= PF_EFFECTS;
if (ent->v.v.skin)
if (SVFIELD (ent, skin, float))
pflags |= PF_SKINNUM;
if (ent->v.v.health <= 0)
if (SVFIELD (ent, health, float) <= 0)
pflags |= PF_DEAD;
if (ent->v.v.mins[2] != -24)
if (SVFIELD (ent, mins, vector)[2] != -24)
pflags |= PF_GIB;
if (cl->spectator) { // only sent origin and velocity to
@ -438,21 +431,21 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
} else if (ent == clent) { // don't send a lot of data on
// personal entity
pflags &= ~(PF_MSEC | PF_COMMAND);
if (ent->v.v.weaponframe)
if (SVFIELD (ent, weaponframe, float))
pflags |= PF_WEAPONFRAME;
}
if (client->spec_track && client->spec_track - 1 == j &&
ent->v.v.weaponframe) pflags |= PF_WEAPONFRAME;
SVFIELD (ent, weaponframe, float)) pflags |= PF_WEAPONFRAME;
MSG_WriteByte (msg, svc_playerinfo);
MSG_WriteByte (msg, j);
MSG_WriteShort (msg, pflags);
for (i = 0; i < 3; i++)
MSG_WriteCoord (msg, ent->v.v.origin[i]);
MSG_WriteCoord (msg, SVFIELD (ent, origin, vector)[i]);
MSG_WriteByte (msg, ent->v.v.frame);
MSG_WriteByte (msg, SVFIELD (ent, frame, float));
if (pflags & PF_MSEC) {
msec = 1000 * (sv.time - cl->localtime);
@ -464,10 +457,10 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
if (pflags & PF_COMMAND) {
cmd = cl->lastcmd;
if (ent->v.v.health <= 0) { // don't show the corpse looking
if (SVFIELD (ent, health, float) <= 0) { // don't show the corpse looking
// around...
cmd.angles[0] = 0;
cmd.angles[1] = ent->v.v.angles[1];
cmd.angles[1] = SVFIELD (ent, angles, vector)[1];
cmd.angles[0] = 0;
}
@ -479,19 +472,19 @@ SV_WritePlayersToClient (client_t *client, edict_t *clent, byte * pvs,
for (i = 0; i < 3; i++)
if (pflags & (PF_VELOCITY1 << i))
MSG_WriteShort (msg, ent->v.v.velocity[i]);
MSG_WriteShort (msg, SVFIELD (ent, velocity, vector)[i]);
if (pflags & PF_MODEL)
MSG_WriteByte (msg, ent->v.v.modelindex);
MSG_WriteByte (msg, SVFIELD (ent, modelindex, float));
if (pflags & PF_SKINNUM)
MSG_WriteByte (msg, ent->v.v.skin);
MSG_WriteByte (msg, SVFIELD (ent, skin, float));
if (pflags & PF_EFFECTS)
MSG_WriteByte (msg, ent->v.v.effects);
MSG_WriteByte (msg, SVFIELD (ent, effects, float));
if (pflags & PF_WEAPONFRAME)
MSG_WriteByte (msg, ent->v.v.weaponframe);
MSG_WriteByte (msg, SVFIELD (ent, weaponframe, float));
}
}
@ -521,7 +514,7 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
// find the client's PVS
clent = client->edict;
VectorAdd (clent->v.v.origin, clent->v.v.view_ofs, org);
VectorAdd (SVFIELD (clent, origin, vector), SVFIELD (clent, view_ofs, vector), org);
pvs = SV_FatPVS (org);
// send over the players in the PVS
@ -537,7 +530,7 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
for (e = MAX_CLIENTS + 1, ent = EDICT_NUM (&sv_pr_state, e); e < sv.num_edicts;
e++, ent = NEXT_EDICT (&sv_pr_state, ent)) {
// ignore ents without visible models
if (!ent->v.v.modelindex || !*PR_GetString (&sv_pr_state, ent->v.v.model))
if (!SVFIELD (ent, modelindex, float) || !*PR_GetString (&sv_pr_state, SVFIELD (ent, model, string)))
continue;
// ignore if not touching a PV leaf
@ -560,49 +553,44 @@ SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg)
state->number = e;
state->flags = 0;
VectorCopy (ent->v.v.origin, state->origin);
VectorCopy (ent->v.v.angles, state->angles);
state->modelindex = ent->v.v.modelindex;
state->frame = ent->v.v.frame;
state->colormap = ent->v.v.colormap;
state->skinnum = ent->v.v.skin;
state->effects = ent->v.v.effects;
VectorCopy (SVFIELD (ent, origin, vector), state->origin);
VectorCopy (SVFIELD (ent, angles, vector), state->angles);
state->modelindex = SVFIELD (ent, modelindex, float);
state->frame = SVFIELD (ent, frame, float);
state->colormap = SVFIELD (ent, colormap, float);
state->skinnum = SVFIELD (ent, skin, float);
state->effects = SVFIELD (ent, effects, float);
// LordHavoc: cleaned up Endy's coding style, shortened the code,
// and implemented missing effects
// Ender: EXTEND (QSG - Begin)
{
eval_t *val;
state->alpha = 255;
state->scale = 16;
state->glowsize = 0;
state->glowcolor = 254;
state->colormod = 255;
if ((val = GETEDICTFIELDVALUE (ent, eval_alpha))
&& val->_float != 0)
state->alpha = bound (0, val->_float, 1) * 255.0;
if (sv_fields.alpha != -1 && SVFIELD (ent, alpha, float))
state->alpha = bound (0, SVFIELD (ent, alpha, float), 1) * 255.0;
if ((val = GETEDICTFIELDVALUE (ent, eval_scale))
&& val->_float != 0)
state->scale = bound (0, val->_float, 15.9375) * 16.0;
if (sv_fields.scale != -1 && SVFIELD (ent, scale, float))
state->scale = bound (0, SVFIELD (ent, scale, float), 15.9375) * 16.0;
if ((val = GETEDICTFIELDVALUE (ent, eval_glowsize))
&& val->_float != 0)
state->glowsize = bound (-1024, (int) val->_float, 1016) >> 3;
if (sv_fields.glowsize != -1 && SVFIELD (ent, glowsize, float))
state->glowsize = bound (-1024, (int) SVFIELD (ent, glowsize, float), 1016) >> 3;
if ((val = GETEDICTFIELDVALUE (ent, eval_glowcolor))
&& val->_float != 0)
state->glowcolor = (int) val->_float;
if (sv_fields.glowcolor != -1 && SVFIELD (ent, glowcolor, float))
state->glowcolor = (int) SVFIELD (ent, glowcolor, float);
if ((val = GETEDICTFIELDVALUE (ent, eval_colormod))
&& (val->vector[0] != 0 || val->vector[1] != 0
|| val->vector[2] != 0))
if (sv_fields.colormod != -1
&& SVFIELD (ent, colormod, vector)[0]
&& SVFIELD (ent, colormod, vector)[1]
&& SVFIELD (ent, colormod, vector)[2])
state->colormod =
((int) (bound (0, val->vector[0], 1) * 7.0) << 5) |
((int) (bound (0, val->vector[1], 1) * 7.0) << 2) |
(int) (bound (0, val->vector[2], 1) * 3.0);
((int) (bound (0, SVFIELD (ent, colormod, vector)[0], 1) * 7.0) << 5) |
((int) (bound (0, SVFIELD (ent, colormod, vector)[1], 1) * 7.0) << 2) |
(int) (bound (0, SVFIELD (ent, colormod, vector)[2], 1) * 3.0);
}
// Ender: EXTEND (QSG - End)
}

View file

@ -40,6 +40,7 @@
#include "msg.h"
#include "quakefs.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
#include "va.h"
@ -49,6 +50,8 @@ char localmodels[MAX_MODELS][5]; // inline model names for precache
char localinfo[MAX_LOCALINFO_STRING + 1]; // local game info
entity_state_t baselines[MAX_EDICTS];
/*
SV_ModelIndex
*/
@ -108,30 +111,30 @@ SV_CreateBaseline (void)
continue;
// create baselines for all player slots,
// and any other edict that has a visible model
if (entnum > MAX_CLIENTS && !svent->v.v.modelindex)
if (entnum > MAX_CLIENTS && !SVFIELD (svent, modelindex, float))
continue;
//
// create entity baseline
//
VectorCopy (svent->v.v.origin, svent->baseline.origin);
VectorCopy (svent->v.v.angles, svent->baseline.angles);
svent->baseline.frame = svent->v.v.frame;
svent->baseline.skinnum = svent->v.v.skin;
VectorCopy (SVFIELD (svent, origin, vector), ((entity_state_t*)svent->data)->origin);
VectorCopy (SVFIELD (svent, angles, vector), ((entity_state_t*)svent->data)->angles);
((entity_state_t*)svent->data)->frame = SVFIELD (svent, frame, float);
((entity_state_t*)svent->data)->skinnum = SVFIELD (svent, skin, float);
if (entnum > 0 && entnum <= MAX_CLIENTS) {
svent->baseline.colormap = entnum;
svent->baseline.modelindex = SV_ModelIndex ("progs/player.mdl");
((entity_state_t*)svent->data)->colormap = entnum;
((entity_state_t*)svent->data)->modelindex = SV_ModelIndex ("progs/player.mdl");
} else {
svent->baseline.colormap = 0;
svent->baseline.modelindex =
SV_ModelIndex (PR_GetString (&sv_pr_state, svent->v.v.model));
((entity_state_t*)svent->data)->colormap = 0;
((entity_state_t*)svent->data)->modelindex =
SV_ModelIndex (PR_GetString (&sv_pr_state, SVFIELD (svent, model, string)));
}
// LordHavoc: setup baseline to include new effects
svent->baseline.alpha = 255;
svent->baseline.scale = 16;
svent->baseline.glowsize = 0;
svent->baseline.glowcolor = 254;
svent->baseline.colormap = 255;
((entity_state_t*)svent->data)->alpha = 255;
((entity_state_t*)svent->data)->scale = 16;
((entity_state_t*)svent->data)->glowsize = 0;
((entity_state_t*)svent->data)->glowcolor = 254;
((entity_state_t*)svent->data)->colormap = 255;
//
// flush the signon message out to a seperate buffer if
@ -145,13 +148,13 @@ SV_CreateBaseline (void)
MSG_WriteByte (&sv.signon, svc_spawnbaseline);
MSG_WriteShort (&sv.signon, entnum);
MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
MSG_WriteByte (&sv.signon, svent->baseline.frame);
MSG_WriteByte (&sv.signon, svent->baseline.colormap);
MSG_WriteByte (&sv.signon, svent->baseline.skinnum);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->modelindex);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->frame);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->colormap);
MSG_WriteByte (&sv.signon, ((entity_state_t*)svent->data)->skinnum);
for (i = 0; i < 3; i++) {
MSG_WriteCoord (&sv.signon, svent->baseline.origin[i]);
MSG_WriteAngle (&sv.signon, svent->baseline.angles[i]);
MSG_WriteCoord (&sv.signon, ((entity_state_t*)svent->data)->origin[i]);
MSG_WriteAngle (&sv.signon, ((entity_state_t*)svent->data)->angles[i]);
}
}
}
@ -173,7 +176,7 @@ SV_SaveSpawnparms (void)
return; // no progs loaded yet
// serverflags is the only game related thing maintained
svs.serverflags = sv_pr_state.pr_global_struct->serverflags;
svs.serverflags = *sv_globals.serverflags;
for (i = 0, host_client = svs.clients; i < MAX_CLIENTS; i++, host_client++) {
if (host_client->state != cs_spawned)
@ -183,10 +186,10 @@ SV_SaveSpawnparms (void)
host_client->state = cs_connected;
// call the progs to get default spawn parms for the new client
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, host_client->edict);
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->SetChangeParms);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, host_client->edict);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.SetChangeParms);
for (j = 0; j < NUM_SPAWN_PARMS; j++)
host_client->spawn_parms[j] = (&sv_pr_state.pr_global_struct->parm1)[j];
host_client->spawn_parms[j] = sv_globals.parms[j];
}
}
@ -339,7 +342,14 @@ SV_SpawnServer (char *server)
MAX_SERVERINFO_STRING);
// allocate edicts
sv.edicts = Hunk_AllocName (MAX_EDICTS * sv_pr_state.pr_edict_size, "edicts");
sv_pr_state.pr_edictareasize = sv_pr_state.pr_edict_size * MAX_EDICTS;
sv.edicts = Hunk_AllocName (sv_pr_state.pr_edictareasize, "edicts");
// init the data field of the edicts
for (i = 0; i < MAX_EDICTS; i++) {
ent = EDICT_NUM (&sv_pr_state, i);
ent->data = &baselines[i];
}
// leave slots at start for clients only
sv.num_edicts = MAX_CLIENTS + 1;
@ -387,14 +397,14 @@ SV_SpawnServer (char *server)
ent = EDICT_NUM (&sv_pr_state, 0);
ent->free = false;
ent->v.v.model = PR_SetString (&sv_pr_state, sv.worldmodel->name);
ent->v.v.modelindex = 1; // world model
ent->v.v.solid = SOLID_BSP;
ent->v.v.movetype = MOVETYPE_PUSH;
SVFIELD (ent, model, string) = PR_SetString (&sv_pr_state, sv.worldmodel->name);
SVFIELD (ent, modelindex, float) = 1; // world model
SVFIELD (ent, solid, float) = SOLID_BSP;
SVFIELD (ent, movetype, float) = MOVETYPE_PUSH;
sv_pr_state.pr_global_struct->mapname = PR_SetString (&sv_pr_state, sv.name);
*sv_globals.mapname = PR_SetString (&sv_pr_state, sv.name);
// serverflags are for cross level information (sigils)
sv_pr_state.pr_global_struct->serverflags = svs.serverflags;
*sv_globals.serverflags = svs.serverflags;
// run the frame start qc function to let progs check cvars
SV_ProgStartFrame ();

View file

@ -49,6 +49,7 @@
#include "qargs.h"
#include "quakefs.h"
#include "server.h"
#include "sv_progs.h"
#include "sys.h"
#include "va.h"
#include "ver_check.h"
@ -250,12 +251,12 @@ SV_DropClient (client_t *drop)
if (!drop->spectator) {
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, drop->edict);
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->ClientDisconnect);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, drop->edict);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientDisconnect);
} else if (SpectatorDisconnect) {
// call the prog function for removing a client
// this will set the body to a dead frame, among other things
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, drop->edict);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, drop->edict);
PR_ExecuteProgram (&sv_pr_state, SpectatorDisconnect);
}
}
@ -278,7 +279,7 @@ SV_DropClient (client_t *drop)
drop->connection_started = realtime; // for zombie timeout
drop->old_frags = 0;
drop->edict->v.v.frags = 0;
SVFIELD (drop->edict, frags, float) = 0;
drop->name[0] = 0;
memset (drop->userinfo, 0, sizeof (drop->userinfo));
@ -841,9 +842,9 @@ SVC_DirectConnect (void)
newcl->lockedtill = 0;
// call the progs to get default spawn parms for the new client
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->SetNewParms);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.SetNewParms);
for (i = 0; i < NUM_SPAWN_PARMS; i++)
newcl->spawn_parms[i] = (&sv_pr_state.pr_global_struct->parm1)[i];
newcl->spawn_parms[i] = sv_globals.parms[i];
if (newcl->spectator)
Con_Printf ("Spectator %s connected\n", newcl->name);

View file

@ -33,9 +33,11 @@
#include <stdlib.h>
#include <math.h>
#include "qtypes.h"
#include "pmove.h"
#include "server.h"
#include "sv_pr_cmds.h"
#include "sv_progs.h"
#include "world.h"
#define STEPSIZE 18
@ -56,8 +58,8 @@ SV_CheckBottom (edict_t *ent)
int x, y;
float mid, bottom;
VectorAdd (ent->v.v.origin, ent->v.v.mins, mins);
VectorAdd (ent->v.v.origin, ent->v.v.maxs, maxs);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), mins);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), maxs);
// if all of the points under the corners are solid world, don't bother
// with the tougher checks
@ -128,34 +130,34 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
edict_t *enemy;
// try the move
VectorCopy (ent->v.v.origin, oldorg);
VectorAdd (ent->v.v.origin, move, neworg);
VectorCopy (SVFIELD (ent, origin, vector), oldorg);
VectorAdd (SVFIELD (ent, origin, vector), move, neworg);
// flying monsters don't step up
if ((int) ent->v.v.flags & (FL_SWIM | FL_FLY)) {
if ((int) SVFIELD (ent, flags, float) & (FL_SWIM | FL_FLY)) {
// try one move with vertical motion, then one without
for (i = 0; i < 2; i++) {
VectorAdd (ent->v.v.origin, move, neworg);
enemy = PROG_TO_EDICT (&sv_pr_state, ent->v.v.enemy);
VectorAdd (SVFIELD (ent, origin, vector), move, neworg);
enemy = PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, enemy, entity));
if (i == 0 && enemy != sv.edicts) {
dz =
ent->v.v.origin[2] -
PROG_TO_EDICT (&sv_pr_state, ent->v.v.enemy)->v.v.origin[2];
SVFIELD (ent, origin, vector)[2] -
SVFIELD (PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, enemy, entity)), origin, vector)[2];
if (dz > 40)
neworg[2] -= 8;
if (dz < 30)
neworg[2] += 8;
}
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, neworg, false,
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), neworg, false,
ent);
if (trace.fraction == 1) {
if (((int) ent->v.v.flags & FL_SWIM)
if (((int) SVFIELD (ent, flags, float) & FL_SWIM)
&& SV_PointContents (trace.endpos) == CONTENTS_EMPTY)
return false; // swim monster left water
VectorCopy (trace.endpos, ent->v.v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
if (relink)
SV_LinkEdict (ent, true);
return true;
@ -172,24 +174,24 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
VectorCopy (neworg, end);
end[2] -= STEPSIZE * 2;
trace = SV_Move (neworg, ent->v.v.mins, ent->v.v.maxs, end, false, ent);
trace = SV_Move (neworg, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.allsolid)
return false;
if (trace.startsolid) {
neworg[2] -= STEPSIZE;
trace = SV_Move (neworg, ent->v.v.mins, ent->v.v.maxs, end, false, ent);
trace = SV_Move (neworg, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.allsolid || trace.startsolid)
return false;
}
if (trace.fraction == 1) {
// if monster had the ground pulled out, go ahead and fall
if ((int) ent->v.v.flags & FL_PARTIALGROUND) {
VectorAdd (ent->v.v.origin, move, ent->v.v.origin);
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) {
VectorAdd (SVFIELD (ent, origin, vector), move, SVFIELD (ent, origin, vector));
if (relink)
SV_LinkEdict (ent, true);
ent->v.v.flags = (int) ent->v.v.flags & ~FL_ONGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) & ~FL_ONGROUND;
// Con_Printf ("fall down\n");
return true;
}
@ -197,10 +199,10 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
return false; // walked off an edge
}
// check point traces down for dangling corners
VectorCopy (trace.endpos, ent->v.v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
if (!SV_CheckBottom (ent)) {
if ((int) ent->v.v.flags & FL_PARTIALGROUND) { // entity had floor
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) { // entity had floor
// mostly pulled out
// from underneath it
// and is trying to correct
@ -208,15 +210,15 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
SV_LinkEdict (ent, true);
return true;
}
VectorCopy (oldorg, ent->v.v.origin);
VectorCopy (oldorg, SVFIELD (ent, origin, vector));
return false;
}
if ((int) ent->v.v.flags & FL_PARTIALGROUND) {
if ((int) SVFIELD (ent, flags, float) & FL_PARTIALGROUND) {
// Con_Printf ("back on ground\n");
ent->v.v.flags = (int) ent->v.v.flags & ~FL_PARTIALGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) & ~FL_PARTIALGROUND;
}
ent->v.v.groundentity = EDICT_TO_PROG (&sv_pr_state, trace.ent);
SVFIELD (ent, groundentity, entity) = EDICT_TO_PROG (&sv_pr_state, trace.ent);
// the move is ok
if (relink)
@ -239,7 +241,7 @@ SV_StepDirection (edict_t *ent, float yaw, float dist)
vec3_t move, oldorigin;
float delta;
ent->v.v.ideal_yaw = yaw;
SVFIELD (ent, ideal_yaw, float) = yaw;
PF_changeyaw (&sv_pr_state);
yaw = yaw * M_PI * 2 / 360;
@ -247,12 +249,12 @@ SV_StepDirection (edict_t *ent, float yaw, float dist)
move[1] = sin (yaw) * dist;
move[2] = 0;
VectorCopy (ent->v.v.origin, oldorigin);
VectorCopy (SVFIELD (ent, origin, vector), oldorigin);
if (SV_movestep (ent, move, false)) {
delta = ent->v.v.angles[YAW] - ent->v.v.ideal_yaw;
delta = SVFIELD (ent, angles, vector)[YAW] - SVFIELD (ent, ideal_yaw, float);
if (delta > 45 && delta < 315) { // not turned far enough, so
// don't take the step
VectorCopy (oldorigin, ent->v.v.origin);
VectorCopy (oldorigin, SVFIELD (ent, origin, vector));
}
SV_LinkEdict (ent, true);
return true;
@ -270,7 +272,7 @@ SV_FixCheckBottom (edict_t *ent)
{
// Con_Printf ("SV_FixCheckBottom\n");
ent->v.v.flags = (int) ent->v.v.flags | FL_PARTIALGROUND;
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) | FL_PARTIALGROUND;
}
@ -286,11 +288,11 @@ SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
float d[3];
float tdir, olddir, turnaround;
olddir = anglemod ((int) (actor->v.v.ideal_yaw / 45) * 45);
olddir = anglemod ((int) (SVFIELD (actor, ideal_yaw, float) / 45) * 45);
turnaround = anglemod (olddir - 180);
deltax = enemy->v.v.origin[0] - actor->v.v.origin[0];
deltay = enemy->v.v.origin[1] - actor->v.v.origin[1];
deltax = SVFIELD (enemy, origin, vector)[0] - SVFIELD (actor, origin, vector)[0];
deltay = SVFIELD (enemy, origin, vector)[1] - SVFIELD (actor, origin, vector)[1];
if (deltax > 10)
d[1] = 0;
else if (deltax < -10)
@ -346,7 +348,7 @@ SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
if (turnaround != DI_NODIR && SV_StepDirection (actor, turnaround, dist))
return;
actor->v.v.ideal_yaw = olddir; // can't move
SVFIELD (actor, ideal_yaw, float) = olddir; // can't move
// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all
@ -365,9 +367,9 @@ SV_CloseEnough (edict_t *ent, edict_t *goal, float dist)
int i;
for (i = 0; i < 3; i++) {
if (goal->v.v.absmin[i] > ent->v.v.absmax[i] + dist)
if (SVFIELD (goal, absmin, vector)[i] > SVFIELD (ent, absmax, vector)[i] + dist)
return false;
if (goal->v.v.absmax[i] < ent->v.v.absmin[i] - dist)
if (SVFIELD (goal, absmax, vector)[i] < SVFIELD (ent, absmin, vector)[i] - dist)
return false;
}
return true;
@ -382,20 +384,20 @@ SV_MoveToGoal (progs_t *pr)
edict_t *ent, *goal;
float dist;
ent = PROG_TO_EDICT (&sv_pr_state, sv_pr_state.pr_global_struct->self);
goal = PROG_TO_EDICT (&sv_pr_state, ent->v.v.goalentity);
ent = PROG_TO_EDICT (&sv_pr_state, *sv_globals.self);
goal = PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, goalentity, entity));
dist = G_FLOAT (&sv_pr_state, OFS_PARM0);
if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
if (!((int) SVFIELD (ent, flags, float) & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
G_FLOAT (&sv_pr_state, OFS_RETURN) = 0;
return;
}
// if the next step hits the enemy, return immediately
if (PROG_TO_EDICT (&sv_pr_state, ent->v.v.enemy) != sv.edicts
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, enemy, entity)) != sv.edicts
&& SV_CloseEnough (ent, goal, dist)) return;
// bump around...
if ((rand () & 3) == 1 || !SV_StepDirection (ent, ent->v.v.ideal_yaw, dist)) {
if ((rand () & 3) == 1 || !SV_StepDirection (ent, SVFIELD (ent, ideal_yaw, float), dist)) {
SV_NewChaseDir (ent, goal, dist);
}
}

View file

@ -33,6 +33,7 @@
#include "cvar.h"
#include "pmove.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
/*
@ -86,9 +87,9 @@ SV_CheckAllEnts (void)
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) {
if (check->free)
continue;
if (check->v.v.movetype == MOVETYPE_PUSH
|| check->v.v.movetype == MOVETYPE_NONE
|| check->v.v.movetype == MOVETYPE_NOCLIP) continue;
if (SVFIELD (check, movetype, float) == MOVETYPE_PUSH
|| SVFIELD (check, movetype, float) == MOVETYPE_NONE
|| SVFIELD (check, movetype, float) == MOVETYPE_NOCLIP) continue;
if (SV_TestEntityPosition (check))
Con_Printf ("entity in invalid position\n");
@ -108,23 +109,23 @@ SV_CheckVelocity (edict_t *ent)
// bound velocity
//
for (i = 0; i < 3; i++) {
if (IS_NAN (ent->v.v.velocity[i])) {
if (IS_NAN (SVFIELD (ent, velocity, vector)[i])) {
Con_Printf ("Got a NaN velocity on %s\n",
PR_GetString (&sv_pr_state, ent->v.v.classname));
ent->v.v.velocity[i] = 0;
PR_GetString (&sv_pr_state, SVFIELD (ent, classname, string)));
SVFIELD (ent, velocity, vector)[i] = 0;
}
if (IS_NAN (ent->v.v.origin[i])) {
if (IS_NAN (SVFIELD (ent, origin, vector)[i])) {
Con_Printf ("Got a NaN origin on %s\n",
PR_GetString (&sv_pr_state, ent->v.v.classname));
ent->v.v.origin[i] = 0;
PR_GetString (&sv_pr_state, SVFIELD (ent, classname, string)));
SVFIELD (ent, origin, vector)[i] = 0;
}
}
// 1999-10-18 SV_MAXVELOCITY fix by Maddes start
wishspeed = Length (ent->v.v.velocity);
wishspeed = Length (SVFIELD (ent, velocity, vector));
if (wishspeed > sv_maxvelocity->value) {
VectorScale (ent->v.v.velocity, sv_maxvelocity->value / wishspeed,
ent->v.v.velocity);
VectorScale (SVFIELD (ent, velocity, vector), sv_maxvelocity->value / wishspeed,
SVFIELD (ent, velocity, vector));
}
// 1999-10-18 SV_MAXVELOCITY fix by Maddes end
}
@ -143,7 +144,7 @@ SV_RunThink (edict_t *ent)
float thinktime;
do {
thinktime = ent->v.v.nextthink;
thinktime = SVFIELD (ent, nextthink, float);
if (thinktime <= 0)
return true;
if (thinktime > sv.time + sv_frametime)
@ -153,11 +154,11 @@ SV_RunThink (edict_t *ent)
thinktime = sv.time; // don't let things stay in the past.
// it is possible to start that way
// by a trigger with a local time.
ent->v.v.nextthink = 0;
sv_pr_state.pr_global_struct->time = thinktime;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, ent->v.v.think);
SVFIELD (ent, nextthink, float) = 0;
*sv_globals.time = thinktime;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (ent, think, func));
if (ent->free)
return false;
@ -176,24 +177,24 @@ SV_Impact (edict_t *e1, edict_t *e2)
{
int old_self, old_other;
old_self = sv_pr_state.pr_global_struct->self;
old_other = sv_pr_state.pr_global_struct->other;
old_self = *sv_globals.self;
old_other = *sv_globals.other;
sv_pr_state.pr_global_struct->time = sv.time;
if (e1->v.v.touch && e1->v.v.solid != SOLID_NOT) {
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, e1);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, e2);
PR_ExecuteProgram (&sv_pr_state, e1->v.v.touch);
*sv_globals.time = sv.time;
if (SVFIELD (e1, touch, func) && SVFIELD (e1, solid, float) != SOLID_NOT) {
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, e1);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, e2);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (e1, touch, func));
}
if (e2->v.v.touch && e2->v.v.solid != SOLID_NOT) {
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, e2);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, e1);
PR_ExecuteProgram (&sv_pr_state, e2->v.v.touch);
if (SVFIELD (e2, touch, func) && SVFIELD (e2, solid, float) != SOLID_NOT) {
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, e2);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, e1);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (e2, touch, func));
}
sv_pr_state.pr_global_struct->self = old_self;
sv_pr_state.pr_global_struct->other = old_other;
*sv_globals.self = old_self;
*sv_globals.other = old_other;
}
@ -258,27 +259,27 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
numbumps = 4;
blocked = 0;
VectorCopy (ent->v.v.velocity, original_velocity);
VectorCopy (ent->v.v.velocity, primal_velocity);
VectorCopy (SVFIELD (ent, velocity, vector), original_velocity);
VectorCopy (SVFIELD (ent, velocity, vector), primal_velocity);
numplanes = 0;
time_left = time;
for (bumpcount = 0; bumpcount < numbumps; bumpcount++) {
for (i = 0; i < 3; i++)
end[i] = ent->v.v.origin[i] + time_left * ent->v.v.velocity[i];
end[i] = SVFIELD (ent, origin, vector)[i] + time_left * SVFIELD (ent, velocity, vector)[i];
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, false, ent);
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.allsolid) { // entity is trapped in another solid
VectorCopy (vec3_origin, ent->v.v.velocity);
VectorCopy (vec3_origin, SVFIELD (ent, velocity, vector));
return 3;
}
if (trace.fraction > 0) { // actually covered some distance
VectorCopy (trace.endpos, ent->v.v.origin);
VectorCopy (ent->v.v.velocity, original_velocity);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
VectorCopy (SVFIELD (ent, velocity, vector), original_velocity);
numplanes = 0;
}
@ -290,10 +291,10 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
if (trace.plane.normal[2] > 0.7) {
blocked |= 1; // floor
if ((trace.ent->v.v.solid == SOLID_BSP)
|| (trace.ent->v.v.movetype == MOVETYPE_PPUSH)) {
ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND;
ent->v.v.groundentity = EDICT_TO_PROG (&sv_pr_state, trace.ent);
if ((SVFIELD (trace.ent, solid, float) == SOLID_BSP)
|| (SVFIELD (trace.ent, movetype, float) == MOVETYPE_PPUSH)) {
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) | FL_ONGROUND;
SVFIELD (ent, groundentity, entity) = EDICT_TO_PROG (&sv_pr_state, trace.ent);
}
}
if (!trace.plane.normal[2]) {
@ -313,7 +314,7 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
// cliped to another plane
if (numplanes >= MAX_CLIP_PLANES) { // this shouldn't really happen
VectorCopy (vec3_origin, ent->v.v.velocity);
VectorCopy (vec3_origin, SVFIELD (ent, velocity, vector));
return 3;
}
@ -335,24 +336,24 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
}
if (i != numplanes) { // go along this plane
VectorCopy (new_velocity, ent->v.v.velocity);
VectorCopy (new_velocity, SVFIELD (ent, velocity, vector));
} else { // go along the crease
if (numplanes != 2) {
// Con_Printf ("clip velocity, numplanes == %i\n",numplanes);
VectorCopy (vec3_origin, ent->v.v.velocity);
VectorCopy (vec3_origin, SVFIELD (ent, velocity, vector));
return 7;
}
CrossProduct (planes[0], planes[1], dir);
d = DotProduct (dir, ent->v.v.velocity);
VectorScale (dir, d, ent->v.v.velocity);
d = DotProduct (dir, SVFIELD (ent, velocity, vector));
VectorScale (dir, d, SVFIELD (ent, velocity, vector));
}
//
// if original velocity is against the original velocity, stop dead
// to avoid tiny occilations in sloping corners
//
if (DotProduct (ent->v.v.velocity, primal_velocity) <= 0) {
VectorCopy (vec3_origin, ent->v.v.velocity);
if (DotProduct (SVFIELD (ent, velocity, vector), primal_velocity) <= 0) {
VectorCopy (vec3_origin, SVFIELD (ent, velocity, vector));
return blocked;
}
}
@ -367,7 +368,7 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
void
SV_AddGravity (edict_t *ent, float scale)
{
ent->v.v.velocity[2] -= scale * movevars.gravity * sv_frametime;
SVFIELD (ent, velocity, vector)[2] -= scale * movevars.gravity * sv_frametime;
}
/*
@ -385,23 +386,23 @@ SV_PushEntity (edict_t *ent, vec3_t push)
trace_t trace;
vec3_t end;
VectorAdd (ent->v.v.origin, push, end);
VectorAdd (SVFIELD (ent, origin, vector), push, end);
if (ent->v.v.movetype == MOVETYPE_FLYMISSILE)
if (SVFIELD (ent, movetype, float) == MOVETYPE_FLYMISSILE)
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, MOVE_MISSILE,
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, MOVE_MISSILE,
ent);
else if (ent->v.v.solid == SOLID_TRIGGER || ent->v.v.solid == SOLID_NOT)
else if (SVFIELD (ent, solid, float) == SOLID_TRIGGER || SVFIELD (ent, solid, float) == SOLID_NOT)
// only clip against bmodels
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end,
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end,
MOVE_NOMONSTERS, ent);
else
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, MOVE_NORMAL,
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, MOVE_NORMAL,
ent);
VectorCopy (trace.endpos, ent->v.v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
SV_LinkEdict (ent, true);
if (trace.ent)
@ -429,15 +430,15 @@ SV_Push (edict_t *pusher, vec3_t move)
// --KB
for (i = 0; i < 3; i++) {
mins[i] = pusher->v.v.absmin[i] + move[i];
maxs[i] = pusher->v.v.absmax[i] + move[i];
mins[i] = SVFIELD (pusher, absmin, vector)[i] + move[i];
maxs[i] = SVFIELD (pusher, absmax, vector)[i] + move[i];
}
VectorCopy (pusher->v.v.origin, pushorig);
VectorCopy (SVFIELD (pusher, origin, vector), pushorig);
// move the pusher to it's final position
VectorAdd (pusher->v.v.origin, move, pusher->v.v.origin);
VectorAdd (SVFIELD (pusher, origin, vector), move, SVFIELD (pusher, origin, vector));
SV_LinkEdict (pusher, false);
// see if any solid entities are inside the final position
@ -446,30 +447,30 @@ SV_Push (edict_t *pusher, vec3_t move)
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) {
if (check->free)
continue;
if (check->v.v.movetype == MOVETYPE_PUSH
|| check->v.v.movetype == MOVETYPE_NONE
|| check->v.v.movetype == MOVETYPE_PPUSH
|| check->v.v.movetype == MOVETYPE_NOCLIP) continue;
if (SVFIELD (check, movetype, float) == MOVETYPE_PUSH
|| SVFIELD (check, movetype, float) == MOVETYPE_NONE
|| SVFIELD (check, movetype, float) == MOVETYPE_PPUSH
|| SVFIELD (check, movetype, float) == MOVETYPE_NOCLIP) continue;
// Don't assume SOLID_BSP ! --KB
solid_save = pusher->v.v.solid;
pusher->v.v.solid = SOLID_NOT;
solid_save = SVFIELD (pusher, solid, float);
SVFIELD (pusher, solid, float) = SOLID_NOT;
block = SV_TestEntityPosition (check);
// pusher->v.v.solid = SOLID_BSP;
pusher->v.v.solid = solid_save;
// SVFIELD (pusher, solid, float) = SOLID_BSP;
SVFIELD (pusher, solid, float) = solid_save;
if (block)
continue;
// if the entity is standing on the pusher, it will definately be
// moved
if (!(((int) check->v.v.flags & FL_ONGROUND)
&& PROG_TO_EDICT (&sv_pr_state, check->v.v.groundentity) == pusher)) {
if (check->v.v.absmin[0] >= maxs[0]
|| check->v.v.absmin[1] >= maxs[1]
|| check->v.v.absmin[2] >= maxs[2]
|| check->v.v.absmax[0] <= mins[0]
|| check->v.v.absmax[1] <= mins[1]
|| check->v.v.absmax[2] <= mins[2])
if (!(((int) SVFIELD (check, flags, float) & FL_ONGROUND)
&& PROG_TO_EDICT (&sv_pr_state, SVFIELD (check, groundentity, entity)) == pusher)) {
if (SVFIELD (check, absmin, vector)[0] >= maxs[0]
|| SVFIELD (check, absmin, vector)[1] >= maxs[1]
|| SVFIELD (check, absmin, vector)[2] >= maxs[2]
|| SVFIELD (check, absmax, vector)[0] <= mins[0]
|| SVFIELD (check, absmax, vector)[1] <= mins[1]
|| SVFIELD (check, absmax, vector)[2] <= mins[2])
continue;
// see if the ent's bbox is inside the pusher's final position
@ -477,49 +478,49 @@ SV_Push (edict_t *pusher, vec3_t move)
continue;
}
VectorCopy (check->v.v.origin, moved_from[num_moved]);
VectorCopy (SVFIELD (check, origin, vector), moved_from[num_moved]);
moved_edict[num_moved] = check;
num_moved++;
// try moving the contacted entity
VectorAdd (check->v.v.origin, move, check->v.v.origin);
VectorAdd (SVFIELD (check, origin, vector), move, SVFIELD (check, origin, vector));
block = SV_TestEntityPosition (check);
if (!block) { // pushed ok
SV_LinkEdict (check, false);
continue;
}
// if it is ok to leave in the old position, do it
VectorSubtract (check->v.v.origin, move, check->v.v.origin);
VectorSubtract (SVFIELD (check, origin, vector), move, SVFIELD (check, origin, vector));
block = SV_TestEntityPosition (check);
if (!block) {
num_moved--;
continue;
}
// if it is still inside the pusher, block
if (check->v.v.mins[0] == check->v.v.maxs[0]) {
if (SVFIELD (check, mins, vector)[0] == SVFIELD (check, maxs, vector)[0]) {
SV_LinkEdict (check, false);
continue;
}
if (check->v.v.solid == SOLID_NOT || check->v.v.solid == SOLID_TRIGGER) { // corpse
check->v.v.mins[0] = check->v.v.mins[1] = 0;
VectorCopy (check->v.v.mins, check->v.v.maxs);
if (SVFIELD (check, solid, float) == SOLID_NOT || SVFIELD (check, solid, float) == SOLID_TRIGGER) { // corpse
SVFIELD (check, mins, vector)[0] = SVFIELD (check, mins, vector)[1] = 0;
VectorCopy (SVFIELD (check, mins, vector), SVFIELD (check, maxs, vector));
SV_LinkEdict (check, false);
continue;
}
VectorCopy (pushorig, pusher->v.v.origin);
VectorCopy (pushorig, SVFIELD (pusher, origin, vector));
SV_LinkEdict (pusher, false);
// if the pusher has a "blocked" function, call it
// otherwise, just stay in place until the obstacle is gone
if (pusher->v.v.blocked) {
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, pusher);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, check);
PR_ExecuteProgram (&sv_pr_state, pusher->v.v.blocked);
if (SVFIELD (pusher, blocked, func)) {
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, pusher);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, check);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (pusher, blocked, func));
}
// move back any entities we already moved
for (i = 0; i < num_moved; i++) {
VectorCopy (moved_from[i], moved_edict[i]->v.v.origin);
VectorCopy (moved_from[i], SVFIELD (moved_edict[i], origin, vector));
SV_LinkEdict (moved_edict[i], false);
}
return false;
@ -537,17 +538,17 @@ SV_PushMove (edict_t *pusher, float movetime)
int i;
vec3_t move;
if (!pusher->v.v.velocity[0] && !pusher->v.v.velocity[1]
&& !pusher->v.v.velocity[2]) {
pusher->v.v.ltime += movetime;
if (!SVFIELD (pusher, velocity, vector)[0] && !SVFIELD (pusher, velocity, vector)[1]
&& !SVFIELD (pusher, velocity, vector)[2]) {
SVFIELD (pusher, ltime, float) += movetime;
return;
}
for (i = 0; i < 3; i++)
move[i] = pusher->v.v.velocity[i] * movetime;
move[i] = SVFIELD (pusher, velocity, vector)[i] * movetime;
if (SV_Push (pusher, move))
pusher->v.v.ltime += movetime;
SVFIELD (pusher, ltime, float) += movetime;
}
@ -563,36 +564,36 @@ SV_Physics_Pusher (edict_t *ent)
vec3_t oldorg, move;
float l;
oldltime = ent->v.v.ltime;
oldltime = SVFIELD (ent, ltime, float);
thinktime = ent->v.v.nextthink;
if (thinktime < ent->v.v.ltime + sv_frametime) {
movetime = thinktime - ent->v.v.ltime;
thinktime = SVFIELD (ent, nextthink, float);
if (thinktime < SVFIELD (ent, ltime, float) + sv_frametime) {
movetime = thinktime - SVFIELD (ent, ltime, float);
if (movetime < 0)
movetime = 0;
} else
movetime = sv_frametime;
if (movetime) {
SV_PushMove (ent, movetime); // advances ent->v.v.ltime if not
SV_PushMove (ent, movetime); // advances SVFIELD (ent, ltime, float) if not
// blocked
}
if (thinktime > oldltime && thinktime <= ent->v.v.ltime) {
VectorCopy (ent->v.v.origin, oldorg);
ent->v.v.nextthink = 0;
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, ent->v.v.think);
if (thinktime > oldltime && thinktime <= SVFIELD (ent, ltime, float)) {
VectorCopy (SVFIELD (ent, origin, vector), oldorg);
SVFIELD (ent, nextthink, float) = 0;
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (ent, think, func));
if (ent->free)
return;
VectorSubtract (ent->v.v.origin, oldorg, move);
VectorSubtract (SVFIELD (ent, origin, vector), oldorg, move);
l = Length (move);
if (l > 1.0 / 64) {
// Con_Printf ("**** snap: %f\n", Length (l));
VectorCopy (oldorg, ent->v.v.origin);
VectorCopy (oldorg, SVFIELD (ent, origin, vector));
SV_Push (ent, move);
}
}
@ -624,8 +625,8 @@ SV_Physics_Noclip (edict_t *ent)
if (!SV_RunThink (ent))
return;
VectorMA (ent->v.v.angles, sv_frametime, ent->v.v.avelocity, ent->v.v.angles);
VectorMA (ent->v.v.origin, sv_frametime, ent->v.v.velocity, ent->v.v.origin);
VectorMA (SVFIELD (ent, angles, vector), sv_frametime, SVFIELD (ent, avelocity, vector), SVFIELD (ent, angles, vector));
VectorMA (SVFIELD (ent, origin, vector), sv_frametime, SVFIELD (ent, velocity, vector), SVFIELD (ent, origin, vector));
SV_LinkEdict (ent, false);
}
@ -642,27 +643,27 @@ SV_CheckWaterTransition (edict_t *ent)
{
int cont;
cont = SV_PointContents (ent->v.v.origin);
if (!ent->v.v.watertype) { // just spawned here
ent->v.v.watertype = cont;
ent->v.v.waterlevel = 1;
cont = SV_PointContents (SVFIELD (ent, origin, vector));
if (!SVFIELD (ent, watertype, float)) { // just spawned here
SVFIELD (ent, watertype, float) = cont;
SVFIELD (ent, waterlevel, float) = 1;
return;
}
if (cont <= CONTENTS_WATER) {
if (ent->v.v.watertype == CONTENTS_EMPTY) { // just crossed into
if (SVFIELD (ent, watertype, float) == CONTENTS_EMPTY) { // just crossed into
// water
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
}
ent->v.v.watertype = cont;
ent->v.v.waterlevel = 1;
SVFIELD (ent, watertype, float) = cont;
SVFIELD (ent, waterlevel, float) = 1;
} else {
if (ent->v.v.watertype != CONTENTS_EMPTY) { // just crossed into
if (SVFIELD (ent, watertype, float) != CONTENTS_EMPTY) { // just crossed into
// water
SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1);
}
ent->v.v.watertype = CONTENTS_EMPTY;
ent->v.v.waterlevel = cont;
SVFIELD (ent, watertype, float) = CONTENTS_EMPTY;
SVFIELD (ent, waterlevel, float) = cont;
}
}
@ -682,45 +683,45 @@ SV_Physics_Toss (edict_t *ent)
if (!SV_RunThink (ent))
return;
if (ent->v.v.velocity[2] > 0)
ent->v.v.flags = (int) ent->v.v.flags & ~FL_ONGROUND;
if (SVFIELD (ent, velocity, vector)[2] > 0)
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) & ~FL_ONGROUND;
// if onground, return without moving
if (((int) ent->v.v.flags & FL_ONGROUND))
if (((int) SVFIELD (ent, flags, float) & FL_ONGROUND))
return;
SV_CheckVelocity (ent);
// add gravity
if (ent->v.v.movetype != MOVETYPE_FLY
&& ent->v.v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent, 1.0);
if (SVFIELD (ent, movetype, float) != MOVETYPE_FLY
&& SVFIELD (ent, movetype, float) != MOVETYPE_FLYMISSILE) SV_AddGravity (ent, 1.0);
// move angles
VectorMA (ent->v.v.angles, sv_frametime, ent->v.v.avelocity, ent->v.v.angles);
VectorMA (SVFIELD (ent, angles, vector), sv_frametime, SVFIELD (ent, avelocity, vector), SVFIELD (ent, angles, vector));
// move origin
VectorScale (ent->v.v.velocity, sv_frametime, move);
VectorScale (SVFIELD (ent, velocity, vector), sv_frametime, move);
trace = SV_PushEntity (ent, move);
if (trace.fraction == 1)
return;
if (ent->free)
return;
if (ent->v.v.movetype == MOVETYPE_BOUNCE)
if (SVFIELD (ent, movetype, float) == MOVETYPE_BOUNCE)
backoff = 1.5;
else
backoff = 1;
ClipVelocity (ent->v.v.velocity, trace.plane.normal, ent->v.v.velocity,
ClipVelocity (SVFIELD (ent, velocity, vector), trace.plane.normal, SVFIELD (ent, velocity, vector),
backoff);
// stop if on ground
if (trace.plane.normal[2] > 0.7) {
if (ent->v.v.velocity[2] < 60 || ent->v.v.movetype != MOVETYPE_BOUNCE) {
ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND;
ent->v.v.groundentity = EDICT_TO_PROG (&sv_pr_state, trace.ent);
VectorCopy (vec3_origin, ent->v.v.velocity);
VectorCopy (vec3_origin, ent->v.v.avelocity);
if (SVFIELD (ent, velocity, vector)[2] < 60 || SVFIELD (ent, movetype, float) != MOVETYPE_BOUNCE) {
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) | FL_ONGROUND;
SVFIELD (ent, groundentity, entity) = EDICT_TO_PROG (&sv_pr_state, trace.ent);
VectorCopy (vec3_origin, SVFIELD (ent, velocity, vector));
VectorCopy (vec3_origin, SVFIELD (ent, avelocity, vector));
}
}
// check for in water
@ -747,8 +748,8 @@ SV_Physics_Step (edict_t *ent)
qboolean hitsound;
// freefall if not on ground
if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
if (ent->v.v.velocity[2] < movevars.gravity * -0.1)
if (!((int) SVFIELD (ent, flags, float) & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
if (SVFIELD (ent, velocity, vector)[2] < movevars.gravity * -0.1)
hitsound = true;
else
hitsound = false;
@ -758,7 +759,7 @@ SV_Physics_Step (edict_t *ent)
SV_FlyMove (ent, sv_frametime, NULL);
SV_LinkEdict (ent, true);
if ((int) ent->v.v.flags & FL_ONGROUND) // just hit ground
if ((int) SVFIELD (ent, flags, float) & FL_ONGROUND) // just hit ground
{
if (hitsound)
SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
@ -781,27 +782,27 @@ SV_PPushMove (edict_t *pusher, float movetime) // player push
SV_CheckVelocity (pusher);
for (i = 0; i < 3; i++) {
move[i] = pusher->v.v.velocity[i] * movetime;
mins[i] = pusher->v.v.absmin[i] + move[i];
maxs[i] = pusher->v.v.absmax[i] + move[i];
move[i] = SVFIELD (pusher, velocity, vector)[i] * movetime;
mins[i] = SVFIELD (pusher, absmin, vector)[i] + move[i];
maxs[i] = SVFIELD (pusher, absmax, vector)[i] + move[i];
}
VectorCopy (pusher->v.v.origin, pusher->v.v.oldorigin); // Backup origin
VectorCopy (SVFIELD (pusher, origin, vector), SVFIELD (pusher, oldorigin, vector)); // Backup origin
trace =
SV_Move (pusher->v.v.origin, pusher->v.v.mins, pusher->v.v.maxs, move,
SV_Move (SVFIELD (pusher, origin, vector), SVFIELD (pusher, mins, vector), SVFIELD (pusher, maxs, vector), move,
MOVE_NOMONSTERS, pusher);
if (trace.fraction == 1) {
VectorCopy (pusher->v.v.origin, pusher->v.v.oldorigin); // Revert
VectorCopy (SVFIELD (pusher, origin, vector), SVFIELD (pusher, oldorigin, vector)); // Revert
return;
}
VectorAdd (pusher->v.v.origin, move, pusher->v.v.origin); // Move
VectorAdd (SVFIELD (pusher, origin, vector), move, SVFIELD (pusher, origin, vector)); // Move
SV_LinkEdict (pusher, false);
pusher->v.v.ltime += movetime;
SVFIELD (pusher, ltime, float) += movetime;
oldsolid = pusher->v.v.solid;
oldsolid = SVFIELD (pusher, solid, float);
check = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) {
@ -813,25 +814,25 @@ SV_PPushMove (edict_t *pusher, float movetime) // player push
continue;
// Stage 2: Is it a player we can push?
if (check->v.v.movetype == MOVETYPE_WALK) {
if (SVFIELD (check, movetype, float) == MOVETYPE_WALK) {
Con_Printf ("Pusher encountered a player\n"); // Yes!@#!@
pusher->v.v.solid = SOLID_NOT;
SVFIELD (pusher, solid, float) = SOLID_NOT;
SV_PushEntity (check, move);
pusher->v.v.solid = oldsolid;
SVFIELD (pusher, solid, float) = oldsolid;
continue;
}
// Stage 3: No.. Is it something that blocks us?
if (check->v.v.mins[0] == check->v.v.maxs[0])
if (SVFIELD (check, mins, vector)[0] == SVFIELD (check, maxs, vector)[0])
continue;
if (check->v.v.solid == SOLID_NOT || check->v.v.solid == SOLID_TRIGGER)
if (SVFIELD (check, solid, float) == SOLID_NOT || SVFIELD (check, solid, float) == SOLID_TRIGGER)
continue;
// Stage 4: Yes, it must be. Fail the move.
VectorCopy (pusher->v.v.origin, pusher->v.v.oldorigin); // Revert
if (pusher->v.v.blocked) { // Blocked func?
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, pusher);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, check);
PR_ExecuteProgram (&sv_pr_state, pusher->v.v.blocked);
VectorCopy (SVFIELD (pusher, origin, vector), SVFIELD (pusher, oldorigin, vector)); // Revert
if (SVFIELD (pusher, blocked, func)) { // Blocked func?
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, pusher);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, check);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (pusher, blocked, func));
}
return;
@ -847,11 +848,11 @@ SV_Physics_PPusher (edict_t *ent)
// float l;
oldltime = ent->v.v.ltime;
oldltime = SVFIELD (ent, ltime, float);
thinktime = ent->v.v.nextthink;
if (thinktime < ent->v.v.ltime + sv_frametime) {
movetime = thinktime - ent->v.v.ltime;
thinktime = SVFIELD (ent, nextthink, float);
if (thinktime < SVFIELD (ent, ltime, float) + sv_frametime) {
movetime = thinktime - SVFIELD (ent, ltime, float);
if (movetime < 0)
movetime = 0;
} else
@ -859,16 +860,16 @@ SV_Physics_PPusher (edict_t *ent)
// if (movetime)
// {
SV_PPushMove (ent, 0.0009); // advances ent->v.v.ltime if not
SV_PPushMove (ent, 0.0009); // advances SVFIELD (ent, ltime, float) if not
// blocked
// }
if (thinktime > oldltime && thinktime <= ent->v.v.ltime) {
ent->v.v.nextthink = 0;
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, ent->v.v.think);
if (thinktime > oldltime && thinktime <= SVFIELD (ent, ltime, float)) {
SVFIELD (ent, nextthink, float) = 0;
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (ent, think, func));
if (ent->free)
return;
}
@ -880,10 +881,10 @@ void
SV_ProgStartFrame (void)
{
// let the progs know that a new frame has started
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
sv_pr_state.pr_global_struct->time = sv.time;
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->StartFrame);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
*sv_globals.time = sv.time;
PR_ExecuteProgram (&sv_pr_state, sv_funcs.StartFrame);
}
/*
@ -892,11 +893,11 @@ SV_ProgStartFrame (void)
void
SV_RunEntity (edict_t *ent)
{
if (ent->v.v.lastruntime == (float) realtime)
if (SVFIELD (ent, lastruntime, float) == (float) realtime)
return;
ent->v.v.lastruntime = (float) realtime;
SVFIELD (ent, lastruntime, float) = (float) realtime;
switch ((int) ent->v.v.movetype) {
switch ((int) SVFIELD (ent, movetype, float)) {
case MOVETYPE_PUSH:
SV_Physics_Pusher (ent);
break;
@ -919,7 +920,7 @@ SV_RunEntity (edict_t *ent)
SV_Physics_Toss (ent);
break;
default:
SV_Error ("SV_Physics: bad movetype %i", (int) ent->v.v.movetype);
SV_Error ("SV_Physics: bad movetype %i", (int) SVFIELD (ent, movetype, float));
}
}
@ -931,11 +932,11 @@ SV_RunNewmis (void)
{
edict_t *ent;
if (!sv_pr_state.pr_global_struct->newmis)
if (!*sv_globals.newmis)
return;
ent = PROG_TO_EDICT (&sv_pr_state, sv_pr_state.pr_global_struct->newmis);
ent = PROG_TO_EDICT (&sv_pr_state, *sv_globals.newmis);
sv_frametime = 0.05;
sv_pr_state.pr_global_struct->newmis = 0;
*sv_globals.newmis = 0;
SV_RunEntity (ent);
}
@ -958,7 +959,7 @@ SV_Physics (void)
sv_frametime = sv_maxtic->value;
old_time = realtime;
sv_pr_state.pr_global_struct->frametime = sv_frametime;
*sv_globals.frametime = sv_frametime;
SV_ProgStartFrame ();
@ -971,7 +972,7 @@ SV_Physics (void)
if (ent->free)
continue;
if (sv_pr_state.pr_global_struct->force_retouch)
if (*sv_globals.force_retouch)
SV_LinkEdict (ent, true); // force retouch even for stationary
if (i > 0 && i <= MAX_CLIENTS)
@ -982,15 +983,15 @@ SV_Physics (void)
SV_RunNewmis ();
}
if (sv_pr_state.pr_global_struct->force_retouch)
sv_pr_state.pr_global_struct->force_retouch--;
if (*sv_globals.force_retouch)
(*sv_globals.force_retouch)--;
// 2000-01-02 EndFrame function by Maddes/FrikaC start
if (EndFrame) {
// let the progs know that the frame has ended
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
sv_pr_state.pr_global_struct->time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv.edicts);
*sv_globals.time = sv.time;
PR_ExecuteProgram (&sv_pr_state, EndFrame);
}
// 2000-01-02 EndFrame function by Maddes/FrikaC end

View file

@ -37,11 +37,12 @@
#include "msg.h"
#include "server.h"
#include "sv_pr_cmds.h"
#include "sv_progs.h"
#include "world.h"
#include "va.h"
#define RETURN_EDICT(p, e) (((int *)(p)->pr_globals)[OFS_RETURN] = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) (((int *)(p)->pr_globals)[OFS_RETURN] = PR_SetString((p), s))
#define RETURN_EDICT(p, e) ((p)->pr_globals[OFS_RETURN].int_var = EDICT_TO_PROG(p, e))
#define RETURN_STRING(p, s) ((p)->pr_globals[OFS_RETURN].int_var = PR_SetString((p), s))
/*
BUILT-IN FUNCTIONS
@ -79,7 +80,7 @@ PF_error (progs_t *pr)
s = PF_VarString (pr, 0);
Con_Printf ("======SERVER ERROR in %s:\n%s\n",
PR_GetString (pr, pr->pr_xfunction->s_name), s);
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
ed = PROG_TO_EDICT (pr, *sv_globals.self);
ED_Print (pr, ed);
SV_Error ("Program error");
@ -102,7 +103,7 @@ PF_objerror (progs_t *pr)
s = PF_VarString (pr, 0);
Con_Printf ("======OBJECT ERROR in %s:\n%s\n",
PR_GetString (pr, pr->pr_xfunction->s_name), s);
ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
ed = PROG_TO_EDICT (pr, *sv_globals.self);
ED_Print (pr, ed);
ED_Free (pr, ed);
@ -120,8 +121,8 @@ PF_objerror (progs_t *pr)
void
PF_makevectors (progs_t *pr)
{
AngleVectors (G_VECTOR (pr, OFS_PARM0), pr->pr_global_struct->v_forward,
pr->pr_global_struct->v_right, pr->pr_global_struct->v_up);
AngleVectors (G_VECTOR (pr, OFS_PARM0), *sv_globals.v_forward,
*sv_globals.v_right, *sv_globals.v_up);
}
/*
@ -139,7 +140,7 @@ PF_setorigin (progs_t *pr)
e = G_EDICT (pr, OFS_PARM0);
org = G_VECTOR (pr, OFS_PARM1);
VectorCopy (org, e->v.v.origin);
VectorCopy (org, SVFIELD (e, origin, vector));
SV_LinkEdict (e, false);
}
@ -160,9 +161,9 @@ PF_setsize (progs_t *pr)
e = G_EDICT (pr, OFS_PARM0);
min = G_VECTOR (pr, OFS_PARM1);
max = G_VECTOR (pr, OFS_PARM2);
VectorCopy (min, e->v.v.mins);
VectorCopy (max, e->v.v.maxs);
VectorSubtract (max, min, e->v.v.size);
VectorCopy (min, SVFIELD (e, mins, vector));
VectorCopy (max, SVFIELD (e, maxs, vector));
VectorSubtract (max, min, SVFIELD (e, size, vector));
SV_LinkEdict (e, false);
}
@ -192,15 +193,15 @@ PF_setmodel (progs_t *pr)
if (!*check)
PR_RunError (pr, "no precache: %s\n", m);
e->v.v.model = PR_SetString (pr, m);
e->v.v.modelindex = i;
SVFIELD (e, model, string) = PR_SetString (pr, m);
SVFIELD (e, modelindex, float) = i;
// if it is an inline model, get the size information for it
if (m[0] == '*') {
mod = Mod_ForName (m, true);
VectorCopy (mod->mins, e->v.v.mins);
VectorCopy (mod->maxs, e->v.v.maxs);
VectorSubtract (mod->maxs, mod->mins, e->v.v.size);
VectorCopy (mod->mins, SVFIELD (e, mins, vector));
VectorCopy (mod->maxs, SVFIELD (e, maxs, vector));
VectorSubtract (mod->maxs, mod->mins, SVFIELD (e, size, vector));
SV_LinkEdict (e, false);
}
@ -518,18 +519,18 @@ PF_traceline (progs_t *pr)
trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent);
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;
*sv_globals.trace_allsolid = trace.allsolid;
*sv_globals.trace_startsolid = trace.startsolid;
*sv_globals.trace_fraction = trace.fraction;
*sv_globals.trace_inwater = trace.inwater;
*sv_globals.trace_inopen = trace.inopen;
VectorCopy (trace.endpos, *sv_globals.trace_endpos);
VectorCopy (trace.plane.normal, *sv_globals.trace_plane_normal);
*sv_globals.trace_plane_dist = trace.plane.dist;
if (trace.ent)
pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, trace.ent);
*sv_globals.trace_ent = EDICT_TO_PROG (pr, trace.ent);
else
pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, sv.edicts);
*sv_globals.trace_ent = EDICT_TO_PROG (pr, sv.edicts);
}
/*
@ -581,9 +582,9 @@ PF_newcheckclient (progs_t *pr, int check)
if (ent->free)
continue;
if (ent->v.v.health <= 0)
if (SVFIELD (ent, health, float) <= 0)
continue;
if ((int) ent->v.v.flags & FL_NOTARGET)
if ((int) SVFIELD (ent, flags, float) & FL_NOTARGET)
continue;
// anything that is a client, or has a client as an enemy
@ -591,7 +592,7 @@ PF_newcheckclient (progs_t *pr, int check)
}
// get the PVS for the entity
VectorAdd (ent->v.v.origin, ent->v.v.view_ofs, org);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, view_ofs, vector), org);
leaf = Mod_PointInLeaf (org, sv.worldmodel);
pvs = Mod_LeafPVS (leaf, sv.worldmodel);
memcpy (checkpvs, pvs, (sv.worldmodel->numleafs + 7) >> 3);
@ -629,13 +630,13 @@ PF_checkclient (progs_t *pr)
}
// return check if it might be visible
ent = EDICT_NUM (pr, sv.lastcheck);
if (ent->free || ent->v.v.health <= 0) {
if (ent->free || SVFIELD (ent, health, float) <= 0) {
RETURN_EDICT (pr, sv.edicts);
return;
}
// if current entity can't possibly see the check entity, return 0
self = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
VectorAdd (self->v.v.origin, self->v.v.view_ofs, view);
self = PROG_TO_EDICT (pr, *sv_globals.self);
VectorAdd (SVFIELD (self, origin, vector), SVFIELD (self, view_ofs, vector), view);
leaf = Mod_PointInLeaf (view, sv.worldmodel);
l = (leaf - sv.worldmodel->leafs) - 1;
if ((l < 0) || !(checkpvs[l >> 3] & (1 << (l & 7)))) {
@ -779,16 +780,16 @@ PF_findradius (progs_t *pr)
for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (pr, ent)) {
if (ent->free)
continue;
if (ent->v.v.solid == SOLID_NOT)
if (SVFIELD (ent, solid, float) == SOLID_NOT)
continue;
for (j = 0; j < 3; j++)
eorg[j] =
org[j] - (ent->v.v.origin[j] +
(ent->v.v.mins[j] + ent->v.v.maxs[j]) * 0.5);
org[j] - (SVFIELD (ent, origin, vector)[j] +
(SVFIELD (ent, mins, vector)[j] + SVFIELD (ent, maxs, vector)[j]) * 0.5);
if (Length (eorg) > rad)
continue;
ent->v.v.chain = EDICT_TO_PROG (pr, chain);
SVFIELD (ent, chain, entity) = EDICT_TO_PROG (pr, chain);
chain = ent;
}
@ -1002,11 +1003,11 @@ PF_walkmove (progs_t *pr)
dfunction_t *oldf;
int oldself;
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
ent = PROG_TO_EDICT (pr, *sv_globals.self);
yaw = G_FLOAT (pr, OFS_PARM0);
dist = G_FLOAT (pr, OFS_PARM1);
if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
if (!((int) SVFIELD (ent, flags, float) & (FL_ONGROUND | FL_FLY | FL_SWIM))) {
G_FLOAT (pr, OFS_RETURN) = 0;
return;
}
@ -1019,14 +1020,14 @@ PF_walkmove (progs_t *pr)
// save program state, because SV_movestep may call other progs
oldf = pr->pr_xfunction;
oldself = pr->pr_global_struct->self;
oldself = *sv_globals.self;
G_FLOAT (pr, OFS_RETURN) = SV_movestep (ent, move, true);
// restore program state
pr->pr_xfunction = oldf;
pr->pr_global_struct->self = oldself;
*sv_globals.self = oldself;
}
/*
@ -1041,20 +1042,20 @@ PF_droptofloor (progs_t *pr)
vec3_t end;
trace_t trace;
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
ent = PROG_TO_EDICT (pr, *sv_globals.self);
VectorCopy (ent->v.v.origin, end);
VectorCopy (SVFIELD (ent, origin, vector), end);
end[2] -= 256;
trace = SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, false, ent);
trace = SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), end, false, ent);
if (trace.fraction == 1 || trace.allsolid)
G_FLOAT (pr, OFS_RETURN) = 0;
else {
VectorCopy (trace.endpos, ent->v.v.origin);
VectorCopy (trace.endpos, SVFIELD (ent, origin, vector));
SV_LinkEdict (ent, false);
ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND;
ent->v.v.groundentity = EDICT_TO_PROG (pr, trace.ent);
SVFIELD (ent, flags, float) = (int) SVFIELD (ent, flags, float) | FL_ONGROUND;
SVFIELD (ent, groundentity, entity) = EDICT_TO_PROG (pr, trace.ent);
G_FLOAT (pr, OFS_RETURN) = 1;
}
}
@ -1189,7 +1190,7 @@ PF_aim (progs_t *pr)
ent = G_EDICT (pr, OFS_PARM0);
speed = G_FLOAT (pr, OFS_PARM1);
VectorCopy (ent->v.v.origin, start);
VectorCopy (SVFIELD (ent, origin, vector), start);
start[2] += 20;
// noaim option
@ -1197,18 +1198,18 @@ PF_aim (progs_t *pr)
if (i > 0 && i < MAX_CLIENTS) {
noaim = Info_ValueForKey (svs.clients[i - 1].userinfo, "noaim");
if (atoi (noaim) > 0) {
VectorCopy (pr->pr_global_struct->v_forward, G_VECTOR (pr, OFS_RETURN));
VectorCopy (*sv_globals.v_forward, G_VECTOR (pr, OFS_RETURN));
return;
}
}
// try sending a trace straight
VectorCopy (pr->pr_global_struct->v_forward, dir);
VectorCopy (*sv_globals.v_forward, dir);
VectorMA (start, 2048, dir, end);
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
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)) {
VectorCopy (pr->pr_global_struct->v_forward, G_VECTOR (pr, OFS_RETURN));
if (tr.ent && SVFIELD (tr.ent, takedamage, float) == DAMAGE_AIM
&& (!teamplay->int_val || SVFIELD (ent, team, float) <= 0
|| SVFIELD (ent, team, float) != SVFIELD (tr.ent, team, float))) {
VectorCopy (*sv_globals.v_forward, G_VECTOR (pr, OFS_RETURN));
return;
}
@ -1219,19 +1220,19 @@ PF_aim (progs_t *pr)
check = NEXT_EDICT (pr, sv.edicts);
for (i = 1; i < sv.num_edicts; i++, check = NEXT_EDICT (pr, check)) {
if (check->v.v.takedamage != DAMAGE_AIM)
if (SVFIELD (check, takedamage, float) != DAMAGE_AIM)
continue;
if (check == ent)
continue;
if (teamplay->int_val && ent->v.v.team > 0
&& ent->v.v.team == check->v.v.team) continue; // don't aim at
if (teamplay->int_val && SVFIELD (ent, team, float) > 0
&& SVFIELD (ent, team, float) == SVFIELD (check, team, float)) continue; // don't aim at
// teammate
for (j = 0; j < 3; j++)
end[j] = check->v.v.origin[j]
+ 0.5 * (check->v.v.mins[j] + check->v.v.maxs[j]);
end[j] = SVFIELD (check, origin, vector)[j]
+ 0.5 * (SVFIELD (check, mins, vector)[j] + SVFIELD (check, maxs, vector)[j]);
VectorSubtract (end, start, dir);
VectorNormalize (dir);
dist = DotProduct (dir, pr->pr_global_struct->v_forward);
dist = DotProduct (dir, *sv_globals.v_forward);
if (dist < bestdist)
continue; // to far to turn
tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent);
@ -1242,9 +1243,9 @@ PF_aim (progs_t *pr)
}
if (bestent) {
VectorSubtract (bestent->v.v.origin, ent->v.v.origin, dir);
dist = DotProduct (dir, pr->pr_global_struct->v_forward);
VectorScale (pr->pr_global_struct->v_forward, dist, end);
VectorSubtract (SVFIELD (bestent, origin, vector), SVFIELD (ent, origin, vector), dir);
dist = DotProduct (dir, *sv_globals.v_forward);
VectorScale (*sv_globals.v_forward, dist, end);
end[2] = dir[2];
VectorNormalize (end);
VectorCopy (end, G_VECTOR (pr, OFS_RETURN));
@ -1264,10 +1265,10 @@ PF_changeyaw (progs_t *pr)
edict_t *ent;
float ideal, current, move, speed;
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self);
current = anglemod (ent->v.v.angles[1]);
ideal = ent->v.v.ideal_yaw;
speed = ent->v.v.yaw_speed;
ent = PROG_TO_EDICT (pr, *sv_globals.self);
current = anglemod (SVFIELD (ent, angles, vector)[1]);
ideal = SVFIELD (ent, ideal_yaw, float);
speed = SVFIELD (ent, yaw_speed, float);
if (current == ideal)
return;
@ -1287,7 +1288,7 @@ PF_changeyaw (progs_t *pr)
move = -speed;
}
ent->v.v.angles[1] = anglemod (current + move);
SVFIELD (ent, angles, vector)[1] = anglemod (current + move);
}
/*
@ -1313,7 +1314,7 @@ WriteDest (progs_t *pr)
case MSG_ONE:
SV_Error ("Shouldn't be at MSG_ONE");
#if 0
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->msg_entity);
ent = PROG_TO_EDICT (pr, *sv_globals.msg_entity);
entnum = NUM_FOR_EDICT (pr, ent);
if (entnum < 1 || entnum > MAX_CLIENTS)
PR_RunError (pr, "WriteDest: not a client");
@ -1346,7 +1347,7 @@ Write_GetClient (progs_t *pr)
int entnum;
edict_t *ent;
ent = PROG_TO_EDICT (pr, pr->pr_global_struct->msg_entity);
ent = PROG_TO_EDICT (pr, *sv_globals.msg_entity);
entnum = NUM_FOR_EDICT (pr, ent);
if (entnum < 1 || entnum > MAX_CLIENTS)
PR_RunError (pr, "Write_GetClient: not a client");
@ -1460,19 +1461,22 @@ PF_makestatic (progs_t *pr)
{
edict_t *ent;
int i;
char *model;
ent = G_EDICT (pr, OFS_PARM0);
MSG_WriteByte (&sv.signon, svc_spawnstatic);
MSG_WriteByte (&sv.signon, SV_ModelIndex (PR_GetString (pr, ent->v.v.model)));
model = PR_GetString (pr, SVFIELD (ent, model, string));
//Con_Printf ("Model: %d %s\n", SVFIELD (ent, model, string), model);
MSG_WriteByte (&sv.signon, SV_ModelIndex (model));
MSG_WriteByte (&sv.signon, ent->v.v.frame);
MSG_WriteByte (&sv.signon, ent->v.v.colormap);
MSG_WriteByte (&sv.signon, ent->v.v.skin);
MSG_WriteByte (&sv.signon, SVFIELD (ent, frame, float));
MSG_WriteByte (&sv.signon, SVFIELD (ent, colormap, float));
MSG_WriteByte (&sv.signon, SVFIELD (ent, skin, float));
for (i = 0; i < 3; i++) {
MSG_WriteCoord (&sv.signon, ent->v.v.origin[i]);
MSG_WriteAngle (&sv.signon, ent->v.v.angles[i]);
MSG_WriteCoord (&sv.signon, SVFIELD (ent, origin, vector)[i]);
MSG_WriteAngle (&sv.signon, SVFIELD (ent, angles, vector)[i]);
}
// throw the entity away now
@ -1500,7 +1504,7 @@ PF_setspawnparms (progs_t *pr)
client = svs.clients + (i - 1);
for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&pr->pr_global_struct->parm1)[i] = client->spawn_parms[i];
sv_globals.parms[i] = client->spawn_parms[i];
}
/*

View file

@ -38,11 +38,15 @@
#endif
#include "cmd.h"
#include "progs.h"
#include "server.h"
#include "progdefs.h"
#include "sv_progs.h"
#include "world.h"
int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor, eval_colormod;
sv_globals_t sv_globals;
sv_funcs_t sv_funcs;
sv_fields_t sv_fields;
progs_t sv_pr_state;
cvar_t *r_skyname;
cvar_t *sv_progs;
@ -52,33 +56,14 @@ func_t SpectatorConnect;
func_t SpectatorDisconnect;
func_t SpectatorThink;
void
FindEdictFieldOffsets (progs_t *pr)
static int reserved_edicts = MAX_CLIENTS;
int
ED_Prune_Edict (progs_t *pr, edict_t *ent)
{
dfunction_t *f;
if (pr == &sv_pr_state) {
// Zoid, find the spectator functions
SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorConnect")) != NULL)
SpectatorConnect = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorThink")) != NULL)
SpectatorThink = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorDisconnect")) != NULL)
SpectatorDisconnect = (func_t) (f - sv_pr_state.pr_functions);
// 2000-01-02 EndFrame function by Maddes/FrikaC
EndFrame = 0;
if ((f = ED_FindFunction (&sv_pr_state, "EndFrame")) != NULL)
EndFrame = (func_t) (f - sv_pr_state.pr_functions);
eval_alpha = FindFieldOffset (&sv_pr_state, "alpha");
eval_scale = FindFieldOffset (&sv_pr_state, "scale");
eval_glowsize = FindFieldOffset (&sv_pr_state, "glow_size");
eval_glowcolor = FindFieldOffset (&sv_pr_state, "glow_color");
eval_colormod = FindFieldOffset (&sv_pr_state, "colormod");
}
if (((int) SVFIELD (ent, spawnflags, float) & SPAWNFLAG_NOT_DEATHMATCH))
return 1;
return 0;
}
void
@ -135,9 +120,149 @@ ED_Parse_Extra_Fields (progs_t *pr, char *key, char *value)
void
SV_LoadProgs (void)
{
dfunction_t *f;
PR_LoadProgs (&sv_pr_state, sv_progs->string);
if (!sv_pr_state.progs)
SV_Error ("SV_LoadProgs: couldn't load %s", sv_progs->string);
if (sv_pr_state.progs->crc != PROGHEADER_CRC)
SV_Error ("You must have the qwprogs.dat from QuakeWorld installed");
// progs engine needs these globals anyway
sv_globals.self = sv_pr_state.globals.self;
sv_globals.time = sv_pr_state.globals.time;
(void *) sv_globals.other = PR_GetGlobalPointer (&sv_pr_state, "other");
(void *) sv_globals.world = PR_GetGlobalPointer (&sv_pr_state, "world");
(void *) sv_globals.frametime = PR_GetGlobalPointer (&sv_pr_state, "frametime");
(void *) sv_globals.newmis = PR_GetGlobalPointer (&sv_pr_state, "newmis");
(void *) sv_globals.force_retouch = PR_GetGlobalPointer (&sv_pr_state, "force_retouch");
(void *) sv_globals.mapname = PR_GetGlobalPointer (&sv_pr_state, "mapname");
(void *) sv_globals.serverflags = PR_GetGlobalPointer (&sv_pr_state, "serverflags");
(void *) sv_globals.total_secrets = PR_GetGlobalPointer (&sv_pr_state, "total_secrets");
(void *) sv_globals.total_monsters = PR_GetGlobalPointer (&sv_pr_state, "total_monsters");
(void *) sv_globals.found_secrets = PR_GetGlobalPointer (&sv_pr_state, "found_secrets");
(void *) sv_globals.killed_monsters = PR_GetGlobalPointer (&sv_pr_state, "killed_monsters");
(void *) sv_globals.parms = PR_GetGlobalPointer (&sv_pr_state, "parm1");
(void *) sv_globals.v_forward = PR_GetGlobalPointer (&sv_pr_state, "v_forward");
(void *) sv_globals.v_up = PR_GetGlobalPointer (&sv_pr_state, "v_up");
(void *) sv_globals.v_right = PR_GetGlobalPointer (&sv_pr_state, "v_right");
(void *) sv_globals.trace_allsolid = PR_GetGlobalPointer (&sv_pr_state, "trace_allsolid");
(void *) sv_globals.trace_startsolid = PR_GetGlobalPointer (&sv_pr_state, "trace_startsolid");
(void *) sv_globals.trace_fraction = PR_GetGlobalPointer (&sv_pr_state, "trace_fraction");
(void *) sv_globals.trace_endpos = PR_GetGlobalPointer (&sv_pr_state, "trace_endpos");
(void *) sv_globals.trace_plane_normal = PR_GetGlobalPointer (&sv_pr_state, "trace_plane_normal");
(void *) sv_globals.trace_plane_dist = PR_GetGlobalPointer (&sv_pr_state, "trace_plane_dist");
(void *) sv_globals.trace_ent = PR_GetGlobalPointer (&sv_pr_state, "trace_ent");
(void *) sv_globals.trace_inopen = PR_GetGlobalPointer (&sv_pr_state, "trace_inopen");
(void *) sv_globals.trace_inwater = PR_GetGlobalPointer (&sv_pr_state, "trace_inwater");
(void *) sv_globals.msg_entity = PR_GetGlobalPointer (&sv_pr_state, "msg_entity");
sv_funcs.main =
ED_FindFunction (&sv_pr_state, "main") - sv_pr_state.pr_functions;
sv_funcs.StartFrame =
ED_FindFunction (&sv_pr_state, "StartFrame") - sv_pr_state.pr_functions;
sv_funcs.PlayerPreThink =
ED_FindFunction (&sv_pr_state, "PlayerPreThink") - sv_pr_state.pr_functions;
sv_funcs.PlayerPostThink =
ED_FindFunction (&sv_pr_state, "PlayerPostThink") - sv_pr_state.pr_functions;
sv_funcs.ClientKill =
ED_FindFunction (&sv_pr_state, "ClientKill") - sv_pr_state.pr_functions;
sv_funcs.ClientConnect =
ED_FindFunction (&sv_pr_state, "ClientConnect") - sv_pr_state.pr_functions;
sv_funcs.PutClientInServer =
ED_FindFunction (&sv_pr_state, "PutClientInServer") - sv_pr_state.pr_functions;
sv_funcs.ClientDisconnect =
ED_FindFunction (&sv_pr_state, "ClientDisconnect") - sv_pr_state.pr_functions;
sv_funcs.SetNewParms =
ED_FindFunction (&sv_pr_state, "SetNewParms") - sv_pr_state.pr_functions;
sv_funcs.SetChangeParms =
ED_FindFunction (&sv_pr_state, "SetChangeParms") - sv_pr_state.pr_functions;
sv_fields.modelindex = ED_FindField (&sv_pr_state, "modelindex")->ofs;
sv_fields.absmin = ED_FindField (&sv_pr_state, "absmin")->ofs;
sv_fields.absmax = ED_FindField (&sv_pr_state, "absmax")->ofs;
sv_fields.ltime = ED_FindField (&sv_pr_state, "ltime")->ofs;
sv_fields.lastruntime = ED_FindField (&sv_pr_state, "lastruntime")->ofs;
sv_fields.movetype = ED_FindField (&sv_pr_state, "movetype")->ofs;
sv_fields.solid = ED_FindField (&sv_pr_state, "solid")->ofs;
sv_fields.origin = ED_FindField (&sv_pr_state, "origin")->ofs;
sv_fields.oldorigin = ED_FindField (&sv_pr_state, "oldorigin")->ofs;
sv_fields.velocity = ED_FindField (&sv_pr_state, "velocity")->ofs;
sv_fields.angles = ED_FindField (&sv_pr_state, "angles")->ofs;
sv_fields.avelocity = ED_FindField (&sv_pr_state, "avelocity")->ofs;
sv_fields.classname = ED_FindField (&sv_pr_state, "classname")->ofs;
sv_fields.model = ED_FindField (&sv_pr_state, "model")->ofs;
sv_fields.frame = ED_FindField (&sv_pr_state, "frame")->ofs;
sv_fields.skin = ED_FindField (&sv_pr_state, "skin")->ofs;
sv_fields.effects = ED_FindField (&sv_pr_state, "effects")->ofs;
sv_fields.mins = ED_FindField (&sv_pr_state, "mins")->ofs;
sv_fields.maxs = ED_FindField (&sv_pr_state, "maxs")->ofs;
sv_fields.size = ED_FindField (&sv_pr_state, "size")->ofs;
sv_fields.touch = ED_FindField (&sv_pr_state, "touch")->ofs;
sv_fields.think = ED_FindField (&sv_pr_state, "think")->ofs;
sv_fields.blocked = ED_FindField (&sv_pr_state, "blocked")->ofs;
sv_fields.nextthink = ED_FindField (&sv_pr_state, "nextthink")->ofs;
sv_fields.groundentity = ED_FindField (&sv_pr_state, "groundentity")->ofs;
sv_fields.health = ED_FindField (&sv_pr_state, "health")->ofs;
sv_fields.frags = ED_FindField (&sv_pr_state, "frags")->ofs;
sv_fields.weapon = ED_FindField (&sv_pr_state, "weapon")->ofs;
sv_fields.weaponmodel = ED_FindField (&sv_pr_state, "weaponmodel")->ofs;
sv_fields.weaponframe = ED_FindField (&sv_pr_state, "weaponframe")->ofs;
sv_fields.currentammo = ED_FindField (&sv_pr_state, "currentammo")->ofs;
sv_fields.ammo_shells = ED_FindField (&sv_pr_state, "ammo_shells")->ofs;
sv_fields.ammo_nails = ED_FindField (&sv_pr_state, "ammo_nails")->ofs;
sv_fields.ammo_rockets = ED_FindField (&sv_pr_state, "ammo_rockets")->ofs;
sv_fields.ammo_cells = ED_FindField (&sv_pr_state, "ammo_cells")->ofs;
sv_fields.items = ED_FindField (&sv_pr_state, "items")->ofs;
sv_fields.takedamage = ED_FindField (&sv_pr_state, "takedamage")->ofs;
sv_fields.chain = ED_FindField (&sv_pr_state, "chain")->ofs;
sv_fields.view_ofs = ED_FindField (&sv_pr_state, "view_ofs")->ofs;
sv_fields.button0 = ED_FindField (&sv_pr_state, "button0")->ofs;
sv_fields.button1 = ED_FindField (&sv_pr_state, "button1")->ofs;
sv_fields.button2 = ED_FindField (&sv_pr_state, "button2")->ofs;
sv_fields.impulse = ED_FindField (&sv_pr_state, "impulse")->ofs;
sv_fields.fixangle = ED_FindField (&sv_pr_state, "fixangle")->ofs;
sv_fields.v_angle = ED_FindField (&sv_pr_state, "v_angle")->ofs;
sv_fields.netname = ED_FindField (&sv_pr_state, "netname")->ofs;
sv_fields.enemy = ED_FindField (&sv_pr_state, "enemy")->ofs;
sv_fields.flags = ED_FindField (&sv_pr_state, "flags")->ofs;
sv_fields.colormap = ED_FindField (&sv_pr_state, "colormap")->ofs;
sv_fields.team = ED_FindField (&sv_pr_state, "team")->ofs;
sv_fields.teleport_time = ED_FindField (&sv_pr_state, "teleport_time")->ofs;
sv_fields.armorvalue = ED_FindField (&sv_pr_state, "armorvalue")->ofs;
sv_fields.waterlevel = ED_FindField (&sv_pr_state, "waterlevel")->ofs;
sv_fields.watertype = ED_FindField (&sv_pr_state, "watertype")->ofs;
sv_fields.ideal_yaw = ED_FindField (&sv_pr_state, "ideal_yaw")->ofs;
sv_fields.yaw_speed = ED_FindField (&sv_pr_state, "yaw_speed")->ofs;
sv_fields.goalentity = ED_FindField (&sv_pr_state, "goalentity")->ofs;
sv_fields.spawnflags = ED_FindField (&sv_pr_state, "spawnflags")->ofs;
sv_fields.dmg_take = ED_FindField (&sv_pr_state, "dmg_take")->ofs;
sv_fields.dmg_save = ED_FindField (&sv_pr_state, "dmg_save")->ofs;
sv_fields.dmg_inflictor = ED_FindField (&sv_pr_state, "dmg_inflictor")->ofs;
sv_fields.owner = ED_FindField (&sv_pr_state, "owner")->ofs;
sv_fields.message = ED_FindField (&sv_pr_state, "message")->ofs;
sv_fields.sounds = ED_FindField (&sv_pr_state, "sounds")->ofs;
// Zoid, find the spectator functions
SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorConnect")) != NULL)
SpectatorConnect = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorThink")) != NULL)
SpectatorThink = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorDisconnect")) != NULL)
SpectatorDisconnect = (func_t) (f - sv_pr_state.pr_functions);
// 2000-01-02 EndFrame function by Maddes/FrikaC
EndFrame = 0;
if ((f = ED_FindFunction (&sv_pr_state, "EndFrame")) != NULL)
EndFrame = (func_t) (f - sv_pr_state.pr_functions);
sv_fields.alpha = ED_GetFieldIndex (&sv_pr_state, "alpha");
sv_fields.scale = ED_GetFieldIndex (&sv_pr_state, "scale");
sv_fields.glowsize = ED_GetFieldIndex (&sv_pr_state, "glow_size");
sv_fields.glowcolor = ED_GetFieldIndex (&sv_pr_state, "glow_color");
sv_fields.colormod = ED_GetFieldIndex (&sv_pr_state, "colormod");
}
void
@ -146,6 +271,7 @@ SV_Progs_Init (void)
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.time = &sv.time;
sv_pr_state.reserved_edicts = &reserved_edicts;
sv_pr_state.unlink = SV_UnlinkEdict;
sv_pr_state.flush = SV_FlushSignon;

View file

@ -40,6 +40,7 @@
#include "bothdefs.h"
#include "msg.h"
#include "server.h"
#include "sv_progs.h"
#include "sys.h"
#define CHAN_AUTO 0
@ -332,12 +333,12 @@ SV_Multicast (vec3_t origin, int to)
if (to == MULTICAST_PHS_R || to == MULTICAST_PHS) {
vec3_t delta;
VectorSubtract (origin, client->edict->v.v.origin, delta);
VectorSubtract (origin, SVFIELD (client->edict, origin, vector), delta);
if (Length (delta) <= 1024)
goto inrange;
}
leaf = Mod_PointInLeaf (client->edict->v.v.origin, sv.worldmodel);
leaf = Mod_PointInLeaf (SVFIELD (client->edict, origin, vector), sv.worldmodel);
if (leaf) {
// -1 is because pvs rows are 1 based, not 0 based like leafs
leafnum = leaf - sv.worldmodel->leafs - 1;
@ -429,13 +430,13 @@ SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
channel |= SND_ATTENUATION;
// use the entity origin unless it is a bmodel
if (entity->v.v.solid == SOLID_BSP) {
if (SVFIELD (entity, solid, float) == SOLID_BSP) {
for (i = 0; i < 3; i++)
origin[i] =
entity->v.v.origin[i] + 0.5 * (entity->v.v.mins[i] +
entity->v.v.maxs[i]);
SVFIELD (entity, origin, vector)[i] + 0.5 * (SVFIELD (entity, mins, vector)[i] +
SVFIELD (entity, maxs, vector)[i]);
} else {
VectorCopy (entity->v.v.origin, origin);
VectorCopy (SVFIELD (entity, origin, vector), origin);
}
MSG_WriteByte (&sv.multicast, svc_sound);
@ -502,25 +503,25 @@ SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
client->chokecount = 0;
}
// send a damage message if the player got hit this frame
if (ent->v.v.dmg_take || ent->v.v.dmg_save) {
other = PROG_TO_EDICT (&sv_pr_state, ent->v.v.dmg_inflictor);
if (SVFIELD (ent, dmg_take, float) || SVFIELD (ent, dmg_save, float)) {
other = PROG_TO_EDICT (&sv_pr_state, SVFIELD (ent, dmg_inflictor, entity));
MSG_WriteByte (msg, svc_damage);
MSG_WriteByte (msg, ent->v.v.dmg_save);
MSG_WriteByte (msg, ent->v.v.dmg_take);
MSG_WriteByte (msg, SVFIELD (ent, dmg_save, float));
MSG_WriteByte (msg, SVFIELD (ent, dmg_take, float));
for (i = 0; i < 3; i++)
MSG_WriteCoord (msg,
other->v.v.origin[i] + 0.5 * (other->v.v.mins[i] +
other->v.v.maxs[i]));
SVFIELD (other, origin, vector)[i] + 0.5 * (SVFIELD (other, mins, vector)[i] +
SVFIELD (other, maxs, vector)[i]));
ent->v.v.dmg_take = 0;
ent->v.v.dmg_save = 0;
SVFIELD (ent, dmg_take, float) = 0;
SVFIELD (ent, dmg_save, float) = 0;
}
// a fixangle might get lost in a dropped packet. Oh well.
if (ent->v.v.fixangle) {
if (SVFIELD (ent, fixangle, float)) {
MSG_WriteByte (msg, svc_setangle);
for (i = 0; i < 3; i++)
MSG_WriteAngle (msg, ent->v.v.angles[i]);
ent->v.v.fixangle = 0;
MSG_WriteAngle (msg, SVFIELD (ent, angles, vector)[i]);
SVFIELD (ent, fixangle, float) = 0;
}
}
@ -545,29 +546,29 @@ SV_UpdateClientStats (client_t *client)
if (client->spectator && client->spec_track > 0)
ent = svs.clients[client->spec_track - 1].edict;
stats[STAT_HEALTH] = ent->v.v.health;
stats[STAT_WEAPON] = SV_ModelIndex (PR_GetString (&sv_pr_state, ent->v.v.weaponmodel));
stats[STAT_AMMO] = ent->v.v.currentammo;
stats[STAT_ARMOR] = ent->v.v.armorvalue;
stats[STAT_SHELLS] = ent->v.v.ammo_shells;
stats[STAT_NAILS] = ent->v.v.ammo_nails;
stats[STAT_ROCKETS] = ent->v.v.ammo_rockets;
stats[STAT_CELLS] = ent->v.v.ammo_cells;
stats[STAT_HEALTH] = SVFIELD (ent, health, float);
stats[STAT_WEAPON] = SV_ModelIndex (PR_GetString (&sv_pr_state, SVFIELD (ent, weaponmodel, string)));
stats[STAT_AMMO] = SVFIELD (ent, currentammo, float);
stats[STAT_ARMOR] = SVFIELD (ent, armorvalue, float);
stats[STAT_SHELLS] = SVFIELD (ent, ammo_shells, float);
stats[STAT_NAILS] = SVFIELD (ent, ammo_nails, float);
stats[STAT_ROCKETS] = SVFIELD (ent, ammo_rockets, float);
stats[STAT_CELLS] = SVFIELD (ent, ammo_cells, float);
if (!client->spectator)
stats[STAT_ACTIVEWEAPON] = ent->v.v.weapon;
stats[STAT_ACTIVEWEAPON] = SVFIELD (ent, weapon, float);
// stuff the sigil bits into the high bits of items for sbar
stats[STAT_ITEMS] =
(int) ent->v.v.items | ((int) sv_pr_state.pr_global_struct->serverflags << 28);
(int) SVFIELD (ent, items, float) | ((int) *sv_globals.serverflags << 28);
// Extensions to the QW 2.40 protocol for Mega2k --KB
stats[STAT_VIEWHEIGHT] = (int) ent->v.v.view_ofs[2];
stats[STAT_VIEWHEIGHT] = (int) SVFIELD (ent, view_ofs, vector)[2];
// FIXME: this should become a * key! --KB
if (ent->v.v.movetype == MOVETYPE_FLY && !atoi (Info_ValueForKey
if (SVFIELD (ent, movetype, float) == MOVETYPE_FLY && !atoi (Info_ValueForKey
(svs.info, "playerfly")))
ent->v.v.movetype = MOVETYPE_WALK;
SVFIELD (ent, movetype, float) = MOVETYPE_WALK;
stats[STAT_FLYMODE] = (ent->v.v.movetype == MOVETYPE_FLY);
stats[STAT_FLYMODE] = (SVFIELD (ent, movetype, float) == MOVETYPE_FLY);
for (i = 0; i < MAX_CL_STATS; i++)
@ -649,16 +650,16 @@ SV_UpdateToReliableMessages (void)
host_client->sendinfo = false;
SV_FullClientUpdate (host_client, &sv.reliable_datagram);
}
if (host_client->old_frags != host_client->edict->v.v.frags) {
if (host_client->old_frags != SVFIELD (host_client->edict, frags, float)) {
for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) {
if (client->state < cs_connected)
continue;
ClientReliableWrite_Begin (client, svc_updatefrags, 4);
ClientReliableWrite_Byte (client, i);
ClientReliableWrite_Short (client, host_client->edict->v.v.frags);
ClientReliableWrite_Short (client, SVFIELD (host_client->edict, frags, float));
}
host_client->old_frags = host_client->edict->v.v.frags;
host_client->old_frags = SVFIELD (host_client->edict, frags, float);
}
// maxspeed/entgravity changes
ent = host_client->edict;

View file

@ -50,6 +50,7 @@
#include "pmove.h"
#include "quakefs.h"
#include "server.h"
#include "sv_progs.h"
#include "sys.h"
#include "va.h"
#include "world.h"
@ -131,7 +132,7 @@ SV_New_f (void)
// send full levelname
MSG_WriteString (&host_client->netchan.message,
PR_GetString (&sv_pr_state, sv.edicts->v.v.message));
PR_GetString (&sv_pr_state, SVFIELD (sv.edicts, message, string)));
// send the movevars
MSG_WriteFloat (&host_client->netchan.message, movevars.gravity);
@ -147,7 +148,7 @@ SV_New_f (void)
// send music
MSG_WriteByte (&host_client->netchan.message, svc_cdtrack);
MSG_WriteByte (&host_client->netchan.message, sv.edicts->v.v.sounds);
MSG_WriteByte (&host_client->netchan.message, SVFIELD (sv.edicts, sounds, float));
// send server info string
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
@ -378,9 +379,9 @@ SV_Spawn_f (void)
ent = host_client->edict;
memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
ent->v.v.colormap = NUM_FOR_EDICT (&sv_pr_state, ent);
ent->v.v.team = 0; // FIXME
ent->v.v.netname = PR_SetString (&sv_pr_state, host_client->name);
SVFIELD (ent, colormap, float) = NUM_FOR_EDICT (&sv_pr_state, ent);
SVFIELD (ent, team, float) = 0; // FIXME
SVFIELD (ent, netname, string) = PR_SetString (&sv_pr_state, host_client->name);
host_client->entgravity = 1.0;
val = GetEdictFieldValue (&sv_pr_state, ent, "gravity");
@ -398,19 +399,19 @@ SV_Spawn_f (void)
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALSECRETS);
ClientReliableWrite_Long (host_client, sv_pr_state.pr_global_struct->total_secrets);
ClientReliableWrite_Long (host_client, *sv_globals.total_secrets);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_TOTALMONSTERS);
ClientReliableWrite_Long (host_client, sv_pr_state.pr_global_struct->total_monsters);
ClientReliableWrite_Long (host_client, *sv_globals.total_monsters);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_SECRETS);
ClientReliableWrite_Long (host_client, sv_pr_state.pr_global_struct->found_secrets);
ClientReliableWrite_Long (host_client, *sv_globals.found_secrets);
ClientReliableWrite_Begin (host_client, svc_updatestatlong, 6);
ClientReliableWrite_Byte (host_client, STAT_MONSTERS);
ClientReliableWrite_Long (host_client, sv_pr_state.pr_global_struct->killed_monsters);
ClientReliableWrite_Long (host_client, *sv_globals.killed_monsters);
// get the client to check and download skins
// when that is completed, a begin command will be issued
@ -427,15 +428,15 @@ SV_SpawnSpectator (void)
int i;
edict_t *e;
VectorCopy (vec3_origin, sv_player->v.v.origin);
VectorCopy (vec3_origin, sv_player->v.v.view_ofs);
sv_player->v.v.view_ofs[2] = 22;
VectorCopy (vec3_origin, SVFIELD (sv_player, origin, vector));
VectorCopy (vec3_origin, SVFIELD (sv_player, view_ofs, vector));
SVFIELD (sv_player, view_ofs, vector)[2] = 22;
// search for an info_playerstart to spawn the spectator at
for (i = MAX_CLIENTS - 1; i < sv.num_edicts; i++) {
e = EDICT_NUM (&sv_pr_state, i);
if (!strcmp (PR_GetString (&sv_pr_state, e->v.v.classname), "info_player_start")) {
VectorCopy (e->v.v.origin, sv_player->v.v.origin);
if (!strcmp (PR_GetString (&sv_pr_state, SVFIELD (e, classname, string)), "info_player_start")) {
VectorCopy (SVFIELD (e, origin, vector), SVFIELD (sv_player, origin, vector));
return;
}
}
@ -469,27 +470,27 @@ SV_Begin_f (void)
if (SpectatorConnect) {
// copy spawn parms out of the client_t
for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&sv_pr_state.pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
sv_globals.parms[i] = host_client->spawn_parms[i];
// call the spawn function
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv_player);
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, SpectatorConnect);
}
} else {
// copy spawn parms out of the client_t
for (i = 0; i < NUM_SPAWN_PARMS; i++)
(&sv_pr_state.pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
sv_globals.parms[i] = host_client->spawn_parms[i];
// call the spawn function
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->ClientConnect);
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientConnect);
// actually spawn the player
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->PutClientInServer);
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.PutClientInServer);
}
// clear the net statistics, because connecting gives a bogus picture
@ -524,7 +525,7 @@ SV_Begin_f (void)
ent = EDICT_NUM (&sv_pr_state, 1 + (host_client - svs.clients));
MSG_WriteByte (&host_client->netchan.message, svc_setangle);
for (i = 0; i < 2; i++)
MSG_WriteAngle (&host_client->netchan.message, ent->v.v.angles[i]);
MSG_WriteAngle (&host_client->netchan.message, SVFIELD (ent, angles, vector)[i]);
MSG_WriteAngle (&host_client->netchan.message, 0);
#endif
}
@ -898,7 +899,7 @@ SV_Pings_f (void)
void
SV_Kill_f (void)
{
if (sv_player->v.v.health <= 0) {
if (SVFIELD (sv_player, health, float) <= 0) {
SV_BeginRedirect (RD_CLIENT);
SV_ClientPrintf (host_client, PRINT_HIGH,
"Can't suicide -- already dead!\n");
@ -906,9 +907,9 @@ SV_Kill_f (void)
return;
}
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_pr_state.pr_global_struct->ClientKill);
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientKill);
}
/*
@ -1007,7 +1008,7 @@ SV_PTrack_f (void)
host_client->spec_track = 0;
ent = EDICT_NUM (&sv_pr_state, host_client - svs.clients + 1);
tent = EDICT_NUM (&sv_pr_state, 0);
ent->v.v.goalentity = EDICT_TO_PROG (&sv_pr_state, tent);
SVFIELD (ent, goalentity, entity) = EDICT_TO_PROG (&sv_pr_state, tent);
return;
}
@ -1018,14 +1019,14 @@ SV_PTrack_f (void)
host_client->spec_track = 0;
ent = EDICT_NUM (&sv_pr_state, host_client - svs.clients + 1);
tent = EDICT_NUM (&sv_pr_state, 0);
ent->v.v.goalentity = EDICT_TO_PROG (&sv_pr_state, tent);
SVFIELD (ent, goalentity, entity) = EDICT_TO_PROG (&sv_pr_state, tent);
return;
}
host_client->spec_track = i + 1; // now tracking
ent = EDICT_NUM (&sv_pr_state, host_client - svs.clients + 1);
tent = EDICT_NUM (&sv_pr_state, i + 1);
ent->v.v.goalentity = EDICT_TO_PROG (&sv_pr_state, tent);
SVFIELD (ent, goalentity, entity) = EDICT_TO_PROG (&sv_pr_state, tent);
}
@ -1286,16 +1287,16 @@ AddLinksToPmove (areanode_t *node)
next = l->next;
check = EDICT_FROM_AREA (l);
if (check->v.v.owner == pl)
if (SVFIELD (check, owner, entity) == pl)
continue; // player's own missile
if (check->v.v.solid == SOLID_BSP
|| check->v.v.solid == SOLID_BBOX || check->v.v.solid == SOLID_SLIDEBOX) {
if (SVFIELD (check, solid, float) == SOLID_BSP
|| SVFIELD (check, solid, float) == SOLID_BBOX || SVFIELD (check, solid, float) == SOLID_SLIDEBOX) {
if (check == sv_player)
continue;
for (i = 0; i < 3; i++)
if (check->v.v.absmin[i] > pmove_maxs[i]
|| check->v.v.absmax[i] < pmove_mins[i])
if (SVFIELD (check, absmin, vector)[i] > pmove_maxs[i]
|| SVFIELD (check, absmax, vector)[i] < pmove_mins[i])
break;
if (i != 3)
continue;
@ -1304,15 +1305,15 @@ AddLinksToPmove (areanode_t *node)
pe = &pmove.physents[pmove.numphysent];
pmove.numphysent++;
VectorCopy (check->v.v.origin, pe->origin);
VectorCopy (SVFIELD (check, origin, vector), pe->origin);
pe->info = NUM_FOR_EDICT (&sv_pr_state, check);
if (check->v.v.solid == SOLID_BSP) {
pe->model = sv.models[(int) (check->v.v.modelindex)];
if (SVFIELD (check, solid, float) == SOLID_BSP) {
pe->model = sv.models[(int) (SVFIELD (check, modelindex, float))];
} else {
pe->model = NULL;
VectorCopy (check->v.v.mins, pe->mins);
VectorCopy (check->v.v.maxs, pe->maxs);
VectorCopy (SVFIELD (check, mins, vector), pe->mins);
VectorCopy (SVFIELD (check, maxs, vector), pe->maxs);
}
}
}
@ -1349,30 +1350,30 @@ AddAllEntsToPmove (void)
check = NEXT_EDICT (&sv_pr_state, check)) {
if (check->free)
continue;
if (check->v.v.owner == pl)
if (SVFIELD (check, owner, entity) == pl)
continue;
if (check->v.v.solid == SOLID_BSP
|| check->v.v.solid == SOLID_BBOX
|| check->v.v.solid == SOLID_SLIDEBOX) {
if (SVFIELD (check, solid, float) == SOLID_BSP
|| SVFIELD (check, solid, float) == SOLID_BBOX
|| SVFIELD (check, solid, float) == SOLID_SLIDEBOX) {
if (check == sv_player)
continue;
for (i = 0; i < 3; i++)
if (check->v.v.absmin[i] > pmove_maxs[i]
|| check->v.v.absmax[i] < pmove_mins[i])
if (SVFIELD (check, absmin, vector)[i] > pmove_maxs[i]
|| SVFIELD (check, absmax, vector)[i] < pmove_mins[i])
break;
if (i != 3)
continue;
pe = &pmove.physents[pmove.numphysent];
VectorCopy (check->v.v.origin, pe->origin);
VectorCopy (SVFIELD (check, origin, vector), pe->origin);
pmove.physents[pmove.numphysent].info = e;
if (check->v.v.solid == SOLID_BSP)
pe->model = sv.models[(int) (check->v.v.modelindex)];
if (SVFIELD (check, solid, float) == SOLID_BSP)
pe->model = sv.models[(int) (SVFIELD (check, modelindex, float))];
else {
pe->model = NULL;
VectorCopy (check->v.v.mins, pe->mins);
VectorCopy (check->v.v.maxs, pe->maxs);
VectorCopy (SVFIELD (check, mins, vector), pe->mins);
VectorCopy (SVFIELD (check, maxs, vector), pe->maxs);
}
if (++pmove.numphysent == MAX_PHYSENTS)
@ -1455,59 +1456,59 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
return;
}
if (!sv_player->v.v.fixangle)
VectorCopy (ucmd->angles, sv_player->v.v.v_angle);
if (!SVFIELD (sv_player, fixangle, float))
VectorCopy (ucmd->angles, SVFIELD (sv_player, v_angle, vector));
sv_player->v.v.button0 = ucmd->buttons & 1;
SVFIELD (sv_player, button0, float) = ucmd->buttons & 1;
// 1999-10-29 +USE fix by Maddes start
if (!nouse) {
sv_player->v.v.button1 = (ucmd->buttons & 4) >> 2;
SVFIELD (sv_player, button1, float) = (ucmd->buttons & 4) >> 2;
}
// 1999-10-29 +USE fix by Maddes end
sv_player->v.v.button2 = (ucmd->buttons & 2) >> 1;
SVFIELD (sv_player, button2, float) = (ucmd->buttons & 2) >> 1;
if (ucmd->impulse)
sv_player->v.v.impulse = ucmd->impulse;
SVFIELD (sv_player, impulse, float) = ucmd->impulse;
//
// angles
// show 1/3 the pitch angle and all the roll angle
if (sv_player->v.v.health > 0) {
if (!sv_player->v.v.fixangle) {
sv_player->v.v.angles[PITCH] = -sv_player->v.v.v_angle[PITCH] / 3;
sv_player->v.v.angles[YAW] = sv_player->v.v.v_angle[YAW];
if (SVFIELD (sv_player, health, float) > 0) {
if (!SVFIELD (sv_player, fixangle, float)) {
SVFIELD (sv_player, angles, vector)[PITCH] = -SVFIELD (sv_player, v_angle, vector)[PITCH] / 3;
SVFIELD (sv_player, angles, vector)[YAW] = SVFIELD (sv_player, v_angle, vector)[YAW];
}
sv_player->v.v.angles[ROLL] =
SV_CalcRoll (sv_player->v.v.angles, sv_player->v.v.velocity) * 4;
SVFIELD (sv_player, angles, vector)[ROLL] =
SV_CalcRoll (SVFIELD (sv_player, angles, vector), SVFIELD (sv_player, velocity, vector)) * 4;
}
sv_frametime = min (0.1, ucmd->msec * 0.001);
if (!host_client->spectator) {
sv_pr_state.pr_global_struct->frametime = sv_frametime;
*sv_globals.frametime = sv_frametime;
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state,
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state,
sv_player);
PR_ExecuteProgram (&sv_pr_state,
sv_pr_state.pr_global_struct->PlayerPreThink);
sv_funcs.PlayerPreThink);
SV_RunThink (sv_player);
}
for (i = 0; i < 3; i++)
pmove.origin[i] =
sv_player->v.v.origin[i]
+ (sv_player->v.v.mins[i] - player_mins[i]);
VectorCopy (sv_player->v.v.velocity, pmove.velocity);
VectorCopy (sv_player->v.v.v_angle, pmove.angles);
SVFIELD (sv_player, origin, vector)[i]
+ (SVFIELD (sv_player, mins, vector)[i] - player_mins[i]);
VectorCopy (SVFIELD (sv_player, velocity, vector), pmove.velocity);
VectorCopy (SVFIELD (sv_player, v_angle, vector), pmove.angles);
pmove.flying = sv_player->v.v.movetype == MOVETYPE_FLY;
pmove.flying = SVFIELD (sv_player, movetype, float) == MOVETYPE_FLY;
pmove.spectator = host_client->spectator;
pmove.waterjumptime = sv_player->v.v.teleport_time;
pmove.waterjumptime = SVFIELD (sv_player, teleport_time, float);
pmove.numphysent = 1;
pmove.physents[0].model = sv.worldmodel;
pmove.cmd = *ucmd;
pmove.dead = sv_player->v.v.health <= 0;
pmove.dead = SVFIELD (sv_player, health, float) <= 0;
pmove.oldbuttons = host_client->oldbuttons;
movevars.entgravity = host_client->entgravity;
@ -1532,7 +1533,7 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
PlayerMove ();
after = PM_TestPlayerPosition (pmove.origin);
if (sv_player->v.v.health > 0 && before && !after)
if (SVFIELD (sv_player, health, float) > 0 && before && !after)
Con_Printf ("player %s got stuck in playermove!!!!\n",
host_client->name);
}
@ -1541,29 +1542,29 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
#endif
host_client->oldbuttons = pmove.oldbuttons;
sv_player->v.v.teleport_time = pmove.waterjumptime;
sv_player->v.v.waterlevel = waterlevel;
sv_player->v.v.watertype = watertype;
SVFIELD (sv_player, teleport_time, float) = pmove.waterjumptime;
SVFIELD (sv_player, waterlevel, float) = waterlevel;
SVFIELD (sv_player, watertype, float) = watertype;
if (onground != -1) {
sv_player->v.v.flags = (int) sv_player->v.v.flags | FL_ONGROUND;
sv_player->v.v.groundentity =
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) | FL_ONGROUND;
SVFIELD (sv_player, groundentity, entity) =
EDICT_TO_PROG (&sv_pr_state, EDICT_NUM (&sv_pr_state, pmove.physents[onground].info));
} else {
sv_player->v.v.flags = (int) sv_player->v.v.flags & ~FL_ONGROUND;
SVFIELD (sv_player, flags, float) = (int) SVFIELD (sv_player, flags, float) & ~FL_ONGROUND;
}
for (i = 0; i < 3; i++)
sv_player->v.v.origin[i] =
pmove.origin[i] - (sv_player->v.v.mins[i] - player_mins[i]);
SVFIELD (sv_player, origin, vector)[i] =
pmove.origin[i] - (SVFIELD (sv_player, mins, vector)[i] - player_mins[i]);
#if 0
// truncate velocity the same way the net protocol will
for (i = 0; i < 3; i++)
sv_player->v.v.velocity[i] = (int) pmove.velocity[i];
SVFIELD (sv_player, velocity, vector)[i] = (int) pmove.velocity[i];
#else
VectorCopy (pmove.velocity, sv_player->v.v.velocity);
VectorCopy (pmove.velocity, SVFIELD (sv_player, velocity, vector));
#endif
VectorCopy (pmove.angles, sv_player->v.v.v_angle);
VectorCopy (pmove.angles, SVFIELD (sv_player, v_angle, vector));
if (!host_client->spectator) {
// link into place and touch triggers
@ -1573,11 +1574,11 @@ SV_RunCmd (usercmd_t *ucmd, qboolean inside)
for (i = 0; i < pmove.numtouch; i++) {
n = pmove.physents[pmove.touchindex[i]].info;
ent = EDICT_NUM (&sv_pr_state, n);
if (!ent->v.v.touch || (playertouch[n / 8] & (1 << (n % 8))))
if (!SVFIELD (ent, touch, func) || (playertouch[n / 8] & (1 << (n % 8))))
continue;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, ent->v.v.touch);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, sv_player);
PR_ExecuteProgram (&sv_pr_state, SVFIELD (ent, touch, func));
playertouch[n / 8] |= 1 << (n % 8);
}
}
@ -1594,15 +1595,15 @@ SV_PostRunCmd (void)
// run post-think
if (!host_client->spectator) {
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state,
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state,
sv_player);
PR_ExecuteProgram (&sv_pr_state,
sv_pr_state.pr_global_struct->PlayerPostThink);
sv_funcs.PlayerPostThink);
SV_RunNewmis ();
} else if (SpectatorThink) {
sv_pr_state.pr_global_struct->time = sv.time;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state,
*sv_globals.time = sv.time;
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state,
sv_player);
PR_ExecuteProgram (&sv_pr_state, SpectatorThink);
}
@ -1745,7 +1746,7 @@ SV_ExecuteClientMessage (client_t *cl)
o[2] = MSG_ReadCoord (net_message);
// only allowed by spectators
if (host_client->spectator) {
VectorCopy (o, sv_player->v.v.origin);
VectorCopy (o, SVFIELD (sv_player, origin, vector));
SV_LinkEdict (sv_player, false);
}
break;

View file

@ -42,6 +42,7 @@
#include "console.h"
#include "crc.h"
#include "server.h"
#include "sv_progs.h"
#include "world.h"
/*
@ -150,12 +151,12 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
hull_t *hull;
// decide which clipping hull to use, based on the size
if (ent->v.v.solid == SOLID_BSP) {
if (SVFIELD (ent, solid, float) == SOLID_BSP) {
// explicit hulls in the BSP model
if (ent->v.v.movetype != MOVETYPE_PUSH)
if (SVFIELD (ent, movetype, float) != MOVETYPE_PUSH)
SV_Error ("SOLID_BSP without MOVETYPE_PUSH");
model = sv.models[(int) ent->v.v.modelindex];
model = sv.models[(int) SVFIELD (ent, modelindex, float)];
if (!model || model->type != mod_brush)
SV_Error ("SOLID_BSP with a non bsp model");
@ -170,15 +171,15 @@ SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->v.v.origin, offset);
VectorAdd (offset, SVFIELD (ent, origin, vector), offset);
} else { // create a temp hull from bounding
// box sizes
VectorSubtract (ent->v.v.mins, maxs, hullmins);
VectorSubtract (ent->v.v.maxs, mins, hullmaxs);
VectorSubtract (SVFIELD (ent, mins, vector), maxs, hullmins);
VectorSubtract (SVFIELD (ent, maxs, vector), mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (ent->v.v.origin, offset);
VectorCopy (SVFIELD (ent, origin, vector), offset);
}
@ -278,35 +279,35 @@ SV_TouchLinks (edict_t *ent, areanode_t *node)
touch = EDICT_FROM_AREA (l);
if (touch == ent)
continue;
if (!touch->v.v.touch || touch->v.v.solid != SOLID_TRIGGER)
if (!SVFIELD (touch, touch, func) || SVFIELD (touch, solid, float) != SOLID_TRIGGER)
continue;
if (ent->v.v.absmin[0] > touch->v.v.absmax[0]
|| ent->v.v.absmin[1] > touch->v.v.absmax[1]
|| ent->v.v.absmin[2] > touch->v.v.absmax[2]
|| ent->v.v.absmax[0] < touch->v.v.absmin[0]
|| ent->v.v.absmax[1] < touch->v.v.absmin[1]
|| ent->v.v.absmax[2] < touch->v.v.absmin[2])
if (SVFIELD (ent, absmin, vector)[0] > SVFIELD (touch, absmax, vector)[0]
|| SVFIELD (ent, absmin, vector)[1] > SVFIELD (touch, absmax, vector)[1]
|| SVFIELD (ent, absmin, vector)[2] > SVFIELD (touch, absmax, vector)[2]
|| SVFIELD (ent, absmax, vector)[0] < SVFIELD (touch, absmin, vector)[0]
|| SVFIELD (ent, absmax, vector)[1] < SVFIELD (touch, absmin, vector)[1]
|| SVFIELD (ent, absmax, vector)[2] < SVFIELD (touch, absmin, vector)[2])
continue;
old_self = sv_pr_state.pr_global_struct->self;
old_other = sv_pr_state.pr_global_struct->other;
old_self = *sv_globals.self;
old_other = *sv_globals.other;
sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, touch);
sv_pr_state.pr_global_struct->other = EDICT_TO_PROG (&sv_pr_state, ent);
sv_pr_state.pr_global_struct->time = sv.time;
PR_ExecuteProgram (&sv_pr_state, touch->v.v.touch);
*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, touch);
*sv_globals.other = EDICT_TO_PROG (&sv_pr_state, ent);
*sv_globals.time = sv.time;
PR_ExecuteProgram (&sv_pr_state, SVFIELD (touch, touch, func));
sv_pr_state.pr_global_struct->self = old_self;
sv_pr_state.pr_global_struct->other = old_other;
*sv_globals.self = old_self;
*sv_globals.other = old_other;
}
// recurse down both sides
if (node->axis == -1)
return;
if (ent->v.v.absmax[node->axis] > node->dist)
if (SVFIELD (ent, absmax, vector)[node->axis] > node->dist)
SV_TouchLinks (ent, node->children[0]);
if (ent->v.v.absmin[node->axis] < node->dist)
if (SVFIELD (ent, absmin, vector)[node->axis] < node->dist)
SV_TouchLinks (ent, node->children[1]);
}
@ -341,7 +342,7 @@ SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
// NODE_MIXED
splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE (ent->v.v.absmin, ent->v.v.absmax, splitplane);
sides = BOX_ON_PLANE_SIDE (SVFIELD (ent, absmin, vector), SVFIELD (ent, absmax, vector), splitplane);
// recurse down the contacted sides
if (sides & 1)
@ -369,35 +370,35 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
return;
// set the abs box
VectorAdd (ent->v.v.origin, ent->v.v.mins, ent->v.v.absmin);
VectorAdd (ent->v.v.origin, ent->v.v.maxs, ent->v.v.absmax);
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, absmin, vector));
VectorAdd (SVFIELD (ent, origin, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, absmax, vector));
//
// to make items easier to pick up and allow them to be grabbed off
// of shelves, the abs sizes are expanded
//
if ((int) ent->v.v.flags & FL_ITEM) {
ent->v.v.absmin[0] -= 15;
ent->v.v.absmin[1] -= 15;
ent->v.v.absmax[0] += 15;
ent->v.v.absmax[1] += 15;
if ((int) SVFIELD (ent, flags, float) & FL_ITEM) {
SVFIELD (ent, absmin, vector)[0] -= 15;
SVFIELD (ent, absmin, vector)[1] -= 15;
SVFIELD (ent, absmax, vector)[0] += 15;
SVFIELD (ent, absmax, vector)[1] += 15;
} else { // because movement is clipped an
// epsilon away from an actual edge,
// we must fully check even when bounding boxes don't quite touch
ent->v.v.absmin[0] -= 1;
ent->v.v.absmin[1] -= 1;
ent->v.v.absmin[2] -= 1;
ent->v.v.absmax[0] += 1;
ent->v.v.absmax[1] += 1;
ent->v.v.absmax[2] += 1;
SVFIELD (ent, absmin, vector)[0] -= 1;
SVFIELD (ent, absmin, vector)[1] -= 1;
SVFIELD (ent, absmin, vector)[2] -= 1;
SVFIELD (ent, absmax, vector)[0] += 1;
SVFIELD (ent, absmax, vector)[1] += 1;
SVFIELD (ent, absmax, vector)[2] += 1;
}
// link to PVS leafs
ent->num_leafs = 0;
if (ent->v.v.modelindex)
if (SVFIELD (ent, modelindex, float))
SV_FindTouchedLeafs (ent, sv.worldmodel->nodes);
if (ent->v.v.solid == SOLID_NOT)
if (SVFIELD (ent, solid, float) == SOLID_NOT)
return;
// find the first node that the ent's box crosses
@ -405,9 +406,9 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
while (1) {
if (node->axis == -1)
break;
if (ent->v.v.absmin[node->axis] > node->dist)
if (SVFIELD (ent, absmin, vector)[node->axis] > node->dist)
node = node->children[0];
else if (ent->v.v.absmax[node->axis] < node->dist)
else if (SVFIELD (ent, absmax, vector)[node->axis] < node->dist)
node = node->children[1];
else
break; // crosses the node
@ -415,7 +416,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
// link it in
if (ent->v.v.solid == SOLID_TRIGGER)
if (SVFIELD (ent, solid, float) == SOLID_TRIGGER)
InsertLinkBefore (&ent->area, &node->trigger_edicts);
else
InsertLinkBefore (&ent->area, &node->solid_edicts);
@ -489,7 +490,7 @@ SV_TestEntityPosition (edict_t *ent)
trace_t trace;
trace =
SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, ent->v.v.origin, 0,
SV_Move (SVFIELD (ent, origin, vector), SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), SVFIELD (ent, origin, vector), 0,
ent);
if (trace.startsolid)
@ -698,38 +699,38 @@ SV_ClipToLinks (areanode_t *node, moveclip_t * clip)
for (l = node->solid_edicts.next; l != &node->solid_edicts; l = next) {
next = l->next;
touch = EDICT_FROM_AREA (l);
if (touch->v.v.solid == SOLID_NOT)
if (SVFIELD (touch, solid, float) == SOLID_NOT)
continue;
if (touch == clip->passedict)
continue;
if (touch->v.v.solid == SOLID_TRIGGER)
if (SVFIELD (touch, solid, float) == SOLID_TRIGGER)
SV_Error ("Trigger in clipping list");
if (clip->type == MOVE_NOMONSTERS && touch->v.v.solid != SOLID_BSP)
if (clip->type == MOVE_NOMONSTERS && SVFIELD (touch, solid, float) != SOLID_BSP)
continue;
if (clip->boxmins[0] > touch->v.v.absmax[0]
|| clip->boxmins[1] > touch->v.v.absmax[1]
|| clip->boxmins[2] > touch->v.v.absmax[2]
|| clip->boxmaxs[0] < touch->v.v.absmin[0]
|| clip->boxmaxs[1] < touch->v.v.absmin[1]
|| clip->boxmaxs[2] < touch->v.v.absmin[2])
if (clip->boxmins[0] > SVFIELD (touch, absmax, vector)[0]
|| clip->boxmins[1] > SVFIELD (touch, absmax, vector)[1]
|| clip->boxmins[2] > SVFIELD (touch, absmax, vector)[2]
|| clip->boxmaxs[0] < SVFIELD (touch, absmin, vector)[0]
|| clip->boxmaxs[1] < SVFIELD (touch, absmin, vector)[1]
|| clip->boxmaxs[2] < SVFIELD (touch, absmin, vector)[2])
continue;
if (clip->passedict != 0 && clip->passedict->v.v.size[0]
&& !touch->v.v.size[0]) continue; // points never interact
if (clip->passedict != 0 && SVFIELD (clip->passedict, size, vector)[0]
&& !SVFIELD (touch, size, vector)[0]) continue; // points never interact
// might intersect, so do an exact clip
if (clip->trace.allsolid)
return;
if (clip->passedict) {
if (PROG_TO_EDICT (&sv_pr_state, touch->v.v.owner) == clip->passedict)
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (touch, owner, entity)) == clip->passedict)
continue; // don't clip against own missiles
if (PROG_TO_EDICT (&sv_pr_state, clip->passedict->v.v.owner) == touch)
if (PROG_TO_EDICT (&sv_pr_state, SVFIELD (clip->passedict, owner, entity)) == touch)
continue; // don't clip against owner
}
if ((int) touch->v.v.flags & FL_MONSTER)
if ((int) SVFIELD (touch, flags, float) & FL_MONSTER)
trace =
SV_ClipMoveToEntity (touch, clip->start, clip->mins2,
clip->maxs2, clip->end);
@ -848,30 +849,30 @@ SV_TestPlayerPosition (edict_t *ent, vec3_t origin)
CONTENTS_EMPTY) return sv.edicts;
// check all entities
VectorAdd (origin, ent->v.v.mins, boxmins);
VectorAdd (origin, ent->v.v.maxs, boxmaxs);
VectorAdd (origin, SVFIELD (ent, mins, vector), boxmins);
VectorAdd (origin, SVFIELD (ent, maxs, vector), boxmaxs);
check = NEXT_EDICT (&sv_pr_state, sv.edicts);
for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (&sv_pr_state, check)) {
if (check->free)
continue;
if (check->v.v.solid != SOLID_BSP &&
check->v.v.solid != SOLID_BBOX && check->v.v.solid != SOLID_SLIDEBOX)
if (SVFIELD (check, solid, float) != SOLID_BSP &&
SVFIELD (check, solid, float) != SOLID_BBOX && SVFIELD (check, solid, float) != SOLID_SLIDEBOX)
continue;
if (boxmins[0] > check->v.v.absmax[0]
|| boxmins[1] > check->v.v.absmax[1]
|| boxmins[2] > check->v.v.absmax[2]
|| boxmaxs[0] < check->v.v.absmin[0]
|| boxmaxs[1] < check->v.v.absmin[1]
|| boxmaxs[2] < check->v.v.absmin[2])
if (boxmins[0] > SVFIELD (check, absmax, vector)[0]
|| boxmins[1] > SVFIELD (check, absmax, vector)[1]
|| boxmins[2] > SVFIELD (check, absmax, vector)[2]
|| boxmaxs[0] < SVFIELD (check, absmin, vector)[0]
|| boxmaxs[1] < SVFIELD (check, absmin, vector)[1]
|| boxmaxs[2] < SVFIELD (check, absmin, vector)[2])
continue;
if (check == ent)
continue;
// get the clipping hull
hull = SV_HullForEntity (check, ent->v.v.mins, ent->v.v.maxs, offset);
hull = SV_HullForEntity (check, SVFIELD (ent, mins, vector), SVFIELD (ent, maxs, vector), offset);
VectorSubtract (origin, offset, offset);