initial work at bringing nq's progs code up-to-snuff with qw's. Doesn't work

yet :( nq segs due to either mangled strings or mangled functions, not sure
yet.
This commit is contained in:
Bill Currie 2001-02-26 20:52:14 +00:00
parent f6d047712d
commit 2367b0dc5f
16 changed files with 2462 additions and 1654 deletions

View file

@ -1,7 +1,7 @@
/* /*
progs.h progs.h
@description@ (description)
Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 1996-1997 Id Software, Inc.
@ -26,8 +26,8 @@
$Id$ $Id$
*/ */
#ifndef __progs_h #ifndef _PROGS_H
#define __progs_h #define _PROGS_H
#include "gcc_attr.h" #include "gcc_attr.h"
#include "protocol.h" #include "protocol.h"
@ -36,7 +36,6 @@
#include "link.h" #include "link.h"
#include "quakeio.h" #include "quakeio.h"
typedef union eval_s typedef union eval_s
{ {
string_t string; string_t string;
@ -47,6 +46,13 @@ typedef union eval_s
int edict; int edict;
} eval_t; } eval_t;
typedef union pr_type_u {
float float_var;
int int_var;
string_t string_t_var;
func_t func_t_var;
} pr_type_t;
#define MAX_ENT_LEAFS 16 #define MAX_ENT_LEAFS 16
typedef struct edict_s typedef struct edict_s
{ {
@ -59,93 +65,167 @@ typedef struct edict_s
entity_state_t baseline; entity_state_t baseline;
float freetime; // sv.time when the object was freed float freetime; // sv.time when the object was freed
entvars_t v; // C exported fields from progs union {
entvars_t v; // C exported fields from progs
pr_type_t vv[1];
} v;
// other fields from progs come immediately after // other fields from progs come immediately after
} edict_t; } edict_t;
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) #define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
//============================================================================ #ifndef PROGS_T
typedef struct progs_s progs_t;
extern dprograms_t *progs; #define PROGS_T
extern dfunction_t *pr_functions; #endif
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_Init (void);
void PR_Init_Cvars (void);
void PR_ExecuteProgram (func_t fnum); void PR_ExecuteProgram (progs_t *pr, func_t fnum);
void PR_LoadProgs (void); void PR_LoadProgs (progs_t *pr, char *progsname);
void PR_Profile_f (void); void PR_Profile_f (void);
edict_t *ED_Alloc (void); edict_t *ED_Alloc (progs_t *pr);
void ED_Free (edict_t *ed); void ED_Free (progs_t *pr, edict_t *ed);
char *ED_NewString (char *string); char *ED_NewString (progs_t *pr, char *string);
// returns a copy of the string allocated from the server's string heap // returns a copy of the string allocated from the server's string heap
void ED_Print (edict_t *ed); void ED_Print (progs_t *pr, edict_t *ed);
void ED_Write (QFile *f, edict_t *ed); void ED_Write (progs_t *pr, QFile *f, edict_t *ed);
char *ED_ParseEdict (char *data, edict_t *ent); char *ED_ParseEdict (progs_t *pr, char *data, edict_t *ent);
void ED_WriteGlobals (QFile *f); void ED_WriteGlobals (progs_t *pr, QFile *f);
void ED_ParseGlobals (char *data); void ED_ParseGlobals (progs_t *pr, char *data);
void ED_LoadFromFile (char *data); void ED_LoadFromFile (progs_t *pr, char *data);
//define EDICT_NUM(n) ((edict_t *)(sv.edicts+ (n)*pr_edict_size)) ddef_t *ED_FindField (progs_t *pr, char *name);
//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size) dfunction_t *ED_FindFunction (progs_t *pr, char *name);
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_NUM(p,n) ((edict_t *)(*(p)->edicts+ (n)*(p)->pr_edict_size))
//define NUM_FOR_EDICT(p,e) (((byte *)(e) - *(p)->edicts)/(p)->pr_edict_size)
#define EDICT_TO_PROG(e) ((byte *)e - (byte *)sv.edicts) edict_t *EDICT_NUM(progs_t *pr, int n);
#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) int NUM_FOR_EDICT(progs_t *pr, edict_t *e);
#define NEXT_EDICT(p,e) ((edict_t *)( (byte *)e + (p)->pr_edict_size))
#define PR_edicts(p) ((byte *)*(p)->edicts)
#define EDICT_TO_PROG(p,e) ((byte *)(e) - PR_edicts (p))
#define PROG_TO_EDICT(p,e) ((edict_t *)(PR_edicts (p) + (e)))
//============================================================================ //============================================================================
#define G_FLOAT(o) (pr_globals[o]) #define G_var(p,o,t) ((p)->pr_globals[o].t##_var)
#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 G_FLOAT(p,o) G_var (p, o, float)
#define E_INT(e,o) (*(int *)&((float*)&e->v)[o]) #define G_INT(p,o) G_var (p, o, int)
#define E_VECTOR(e,o) (&((float*)&e->v)[o]) #define G_EDICT(p,o) ((edict_t *)(PR_edicts (p) + G_INT (p, o)))
#define E_STRING(e,o) (pr_strings + *(string_t *)&((float*)&e->v)[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 E_var(e,o,t) ((e)->v.vv[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)))
extern int type_size[8]; extern int type_size[8];
typedef void (*builtin_t) (void); typedef void (*builtin_t) (progs_t *pr);
extern builtin_t *pr_builtins; extern builtin_t *pr_builtins;
extern int pr_numbuiltins; extern int pr_numbuiltins;
extern int pr_argc; int FindFieldOffset (progs_t *pr, char *field);
extern qboolean pr_trace; extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC
extern dfunction_t *pr_xfunction;
extern int pr_xstatement;
extern unsigned short pr_crc; extern func_t SpectatorConnect;
extern func_t SpectatorThink;
extern func_t SpectatorDisconnect;
void PR_RunError (char *error, ...); void PR_RunError (progs_t *pr, char *error, ...) __attribute__((format(printf,2,3)));
void ED_PrintEdicts (void); void ED_PrintEdicts (progs_t *pr);
void ED_PrintNum (int ent); void ED_PrintNum (progs_t *pr, int ent);
void ED_Count (progs_t *pr);
void PR_Profile (progs_t *pr);
eval_t *GetEdictFieldValue(edict_t *ed, char *field); char *PR_GlobalString (progs_t *pr, int ofs);
char *PR_GlobalStringNoContents (progs_t *pr, int ofs);
#endif // __progs_h eval_t *GetEdictFieldValue(progs_t *pr, edict_t *ed, char *field);
//
// PR STrings stuff
//
#define MAX_PRSTR 1024
char *PR_GetString(progs_t *pr, int num);
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);
//============================================================================
#define MAX_STACK_DEPTH 32
#define LOCALSTACK_SIZE 2048
typedef struct {
int s;
dfunction_t *f;
} prstack_t;
struct progs_s {
dprograms_t *progs;
dfunction_t *pr_functions;
char *pr_strings;
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_argc;
qboolean pr_trace;
dfunction_t *pr_xfunction;
int pr_xstatement;
char *pr_strtbl[MAX_PRSTR];
int num_prstr;
prstack_t pr_stack[MAX_STACK_DEPTH];
int pr_depth;
int localstack[LOCALSTACK_SIZE];
int localstack_used;
edict_t **edicts;
int *num_edicts;
double *time;
int null_bad;
unsigned short crc;
void (*unlink)(edict_t *ent);
void (*flush)(void);
};
#endif // _PROGS_H

View file

@ -42,6 +42,8 @@
#include "quakeio.h" #include "quakeio.h"
#include "client.h" #include "client.h"
extern progs_t sv_pr_state;
typedef struct typedef struct
{ {
int maxclients; 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_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg);
void SV_MoveToGoal (void); void SV_MoveToGoal (progs_t *pr);
void SV_CheckForNewClients (void); void SV_CheckForNewClients (void);
void SV_RunClients (void); void SV_RunClients (void);
@ -293,4 +295,8 @@ void SV_SpawnServer (char *server, char *startspot);
void SV_SpawnServer (char *server); void SV_SpawnServer (char *server);
#endif #endif
void SV_LoadProgs (void);
void SV_Progs_Init (void);
void SV_Progs_Init_Cvars (void);
#endif // __server_h #endif // __server_h

View file

@ -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 gib_interpret.c gib_modules.c gib_parse.c gib_stack.c vid.c
server_SOURCES= host.c host_cmd.c \ server_SOURCES= host.c host_cmd.c \
pr_cmds.c pr_edict.c pr_exec.c \ pr_cmds.c pr_edict.c pr_exec.c pr_offs.c \
sv_cvar.c sv_main.c sv_move.c sv_phys.c sv_user.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) combined_SOURCES= $(common_SOURCES) $(client_SOURCES) $(server_SOURCES)

View file

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

View file

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

View file

@ -145,8 +145,8 @@ NET_Ban_f (void)
} }
print = Con_Printf; print = Con_Printf;
} else { } else {
if (pr_global_struct->deathmatch && !host_client->privileged) if (sv_pr_state.pr_global_struct->deathmatch
return; && !host_client->privileged) return;
print = SV_ClientPrintf; print = SV_ClientPrintf;
} }
@ -945,7 +945,7 @@ _Datagram_CheckNewConnections (void)
MSG_WriteByte (net_message->message, playerNumber); MSG_WriteByte (net_message->message, playerNumber);
MSG_WriteString (net_message->message, client->name); MSG_WriteString (net_message->message, client->name);
MSG_WriteLong (net_message->message, client->colors); MSG_WriteLong (net_message->message, client->colors);
MSG_WriteLong (net_message->message, (int) client->edict->v.frags); MSG_WriteLong (net_message->message, (int) client->edict->v.v.frags);
MSG_WriteLong (net_message->message, MSG_WriteLong (net_message->message,
(int) (net_time - client->netconnection->connecttime)); (int) (net_time - client->netconnection->connecttime));
MSG_WriteString (net_message->message, client->netconnection->address); 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

File diff suppressed because it is too large Load diff

54
nq/source/pr_offs.c Normal file
View file

@ -0,0 +1,54 @@
/*
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

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

View file

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

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,160 @@
/*
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 "progs.h"
#include "server.h"
#include "world.h"
int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor,
eval_colormod;
progs_t sv_pr_state;
cvar_t *r_skyname;
cvar_t *sv_progs;
func_t EndFrame;
func_t SpectatorConnect;
func_t SpectatorDisconnect;
func_t SpectatorThink;
void
FindEdictFieldOffsets (progs_t * pr)
{
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");
}
}
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);
}
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.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");
}

View file

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

View file

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