From 2367b0dc5f35f14283f62ec84540f5c4064bc969 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Mon, 26 Feb 2001 20:52:14 +0000 Subject: [PATCH] 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. --- nq/include/progs.h | 194 +++++++--- nq/include/server.h | 8 +- nq/source/Makefile.am | 4 +- nq/source/host.c | 18 +- nq/source/host_cmd.c | 217 ++++++----- nq/source/net_dgrm.c | 6 +- nq/source/pr_cmds.c | 770 +++++++++++++++++++------------------ nq/source/pr_edict.c | 583 ++++++++++++++++------------ nq/source/pr_exec.c | 863 ++++++++++++++++++++++++++++-------------- nq/source/pr_offs.c | 54 +++ nq/source/sv_main.c | 232 ++++++------ nq/source/sv_move.c | 89 ++--- nq/source/sv_phys.c | 693 +++++++++++++++++---------------- nq/source/sv_progs.c | 160 ++++++++ nq/source/sv_user.c | 76 ++-- nq/source/world.c | 149 ++++---- 16 files changed, 2462 insertions(+), 1654 deletions(-) create mode 100644 nq/source/pr_offs.c create mode 100644 nq/source/sv_progs.c diff --git a/nq/include/progs.h b/nq/include/progs.h index 7743300a4..fbaf0d0ff 100644 --- a/nq/include/progs.h +++ b/nq/include/progs.h @@ -1,7 +1,7 @@ /* progs.h - @description@ + (description) Copyright (C) 1996-1997 Id Software, Inc. @@ -26,8 +26,8 @@ $Id$ */ -#ifndef __progs_h -#define __progs_h +#ifndef _PROGS_H +#define _PROGS_H #include "gcc_attr.h" #include "protocol.h" @@ -36,7 +36,6 @@ #include "link.h" #include "quakeio.h" - typedef union eval_s { string_t string; @@ -47,6 +46,13 @@ typedef union eval_s int edict; } 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 typedef struct edict_s { @@ -59,93 +65,167 @@ typedef struct edict_s entity_state_t baseline; 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 } 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 +#ifndef PROGS_T +typedef struct progs_s progs_t; +#define PROGS_T +#endif //============================================================================ void PR_Init (void); +void PR_Init_Cvars (void); -void PR_ExecuteProgram (func_t fnum); -void PR_LoadProgs (void); +void PR_ExecuteProgram (progs_t *pr, func_t fnum); +void PR_LoadProgs (progs_t *pr, char *progsname); void PR_Profile_f (void); -edict_t *ED_Alloc (void); -void ED_Free (edict_t *ed); +edict_t *ED_Alloc (progs_t *pr); +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 -void ED_Print (edict_t *ed); -void ED_Write (QFile *f, edict_t *ed); -char *ED_ParseEdict (char *data, edict_t *ent); +void ED_Print (progs_t *pr, edict_t *ed); +void ED_Write (progs_t *pr, QFile *f, edict_t *ed); +char *ED_ParseEdict (progs_t *pr, char *data, edict_t *ent); -void ED_WriteGlobals (QFile *f); -void ED_ParseGlobals (char *data); +void ED_WriteGlobals (progs_t *pr, QFile *f); +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)) -//define NUM_FOR_EDICT(e) (((byte *)(e) - sv.edicts)/pr_edict_size) +ddef_t *ED_FindField (progs_t *pr, char *name); +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) -#define PROG_TO_EDICT(e) ((edict_t *)((byte *)sv.edicts + e)) +edict_t *EDICT_NUM(progs_t *pr, int n); +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_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 G_var(p,o,t) ((p)->pr_globals[o].t##_var) -#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]) +#define G_FLOAT(p,o) G_var (p, o, float) +#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 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]; -typedef void (*builtin_t) (void); +typedef void (*builtin_t) (progs_t *pr); extern builtin_t *pr_builtins; extern int pr_numbuiltins; -extern int pr_argc; +int FindFieldOffset (progs_t *pr, char *field); -extern qboolean pr_trace; -extern dfunction_t *pr_xfunction; -extern int pr_xstatement; +extern func_t EndFrame; // 2000-01-02 EndFrame function by Maddes/FrikaC -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_PrintNum (int ent); +void ED_PrintEdicts (progs_t *pr); +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 diff --git a/nq/include/server.h b/nq/include/server.h index dc72514bf..4fc9cdf04 100644 --- a/nq/include/server.h +++ b/nq/include/server.h @@ -42,6 +42,8 @@ #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 diff --git a/nq/source/Makefile.am b/nq/source/Makefile.am index 0db392758..9c98fadbd 100644 --- a/nq/source/Makefile.am +++ b/nq/source/Makefile.am @@ -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 pr_edict.c pr_exec.c pr_offs.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) diff --git a/nq/source/host.c b/nq/source/host.c index cf4599773..73836e041 100644 --- a/nq/source/host.c +++ b/nq/source/host.c @@ -394,10 +394,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_pr_state.pr_global_struct->self; + 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->ClientDisconnect); + sv_pr_state.pr_global_struct->self = saveSelf; } Sys_Printf ("Client %s removed\n", host_client->name); @@ -590,7 +592,7 @@ void _Host_ServerFrame (void) { // run the world state - pr_global_struct->frametime = host_frametime; + sv_pr_state.pr_global_struct->frametime = host_frametime; // read client messages SV_RunClients (); @@ -608,7 +610,7 @@ Host_ServerFrame (void) float temp_host_frametime; // 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 SV_ClearDatagram (); @@ -637,7 +639,7 @@ void Host_ServerFrame (void) { // 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 SV_ClearDatagram (); @@ -944,6 +946,8 @@ Host_Init (quakeparms_t *parms) Con_Init (); M_Init (); PR_Init (); + SV_Progs_Init_Cvars (); + SV_Progs_Init (); Mod_Init (); NET_Init (); SV_Init (); diff --git a/nq/source/host_cmd.c b/nq/source/host_cmd.c index f548834dc..52d37c8e4 100644 --- a/nq/source/host_cmd.c +++ b/nq/source/host_cmd.c @@ -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) client->edict->v.v.frags, 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_pr_state.pr_global_struct->deathmatch && !host_client->privileged) return; - sv_player->v.flags = (int) sv_player->v.flags ^ FL_GODMODE; - if (!((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.v.flags & 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_pr_state.pr_global_struct->deathmatch && !host_client->privileged) return; - sv_player->v.flags = (int) sv_player->v.flags ^ FL_NOTARGET; - if (!((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.v.flags & 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_pr_state.pr_global_struct->deathmatch && !host_client->privileged) return; - if (sv_player->v.movetype != MOVETYPE_NOCLIP) { + if (sv_player->v.v.movetype != MOVETYPE_NOCLIP) { noclip_anglehack = true; - sv_player->v.movetype = MOVETYPE_NOCLIP; + sv_player->v.v.movetype = MOVETYPE_NOCLIP; SV_ClientPrintf ("noclip ON\n"); } else { noclip_anglehack = false; - sv_player->v.movetype = MOVETYPE_WALK; + sv_player->v.v.movetype = 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_pr_state.pr_global_struct->deathmatch && !host_client->privileged) return; - if (sv_player->v.movetype != MOVETYPE_FLY) { - sv_player->v.movetype = MOVETYPE_FLY; + if (sv_player->v.v.movetype != MOVETYPE_FLY) { + sv_player->v.v.movetype = MOVETYPE_FLY; SV_ClientPrintf ("flymode ON\n"); } else { - sv_player->v.movetype = MOVETYPE_WALK; + sv_player->v.v.movetype = 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 && (svs.clients[i].edict->v.v.health <= 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) ent->v.v.flags & 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; + host_client->edict->v.v.netname = + host_client->name - sv_pr_state.pr_strings; // 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; + && client->edict->v.v.team != save->edict->v.v.team) 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; + host_client->edict->v.v.team = 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 (sv_player->v.v.health <= 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_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); } @@ -1168,10 +1170,12 @@ Host_Pause_f (void) if (sv.paused) { SV_BroadcastPrintf ("%s paused the game\n", - pr_strings + sv_player->v.netname); + sv_pr_state.pr_strings + + sv_player->v.v.netname); } else { 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 @@ -1237,26 +1241,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); + ent->v.v.colormap = NUM_FOR_EDICT (&sv_pr_state, ent); + ent->v.v.team = (host_client->colors & 15) + 1; + ent->v.v.netname = host_client->name - sv_pr_state.pr_strings; // 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_pr_state.pr_global_struct->parm1)[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_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); 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_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, 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, 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, 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, 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 // 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, ent->v.v.angles[i]); MSG_WriteAngle (&host_client->message, 0); SV_WriteClientdataToMessage (sv_player, &host_client->message); @@ -1365,8 +1376,9 @@ Host_Kick_f (void) Cmd_ForwardToServer (); 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; @@ -1447,7 +1459,7 @@ Host_Give_f (void) return; } - if (pr_global_struct->deathmatch && !host_client->privileged) + if (sv_pr_state.pr_global_struct->deathmatch && !host_client->privileged) return; t = Cmd_Argv (1); @@ -1468,101 +1480,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; + sv_player->v.v.items = + (int) sv_player->v.v.items | HIT_PROXIMITY_GUN; else - sv_player->v.items = - (int) sv_player->v.items | IT_GRENADE_LAUNCHER; + sv_player->v.v.items = + (int) sv_player->v.v.items | IT_GRENADE_LAUNCHER; } else if (t[0] == '9') - sv_player->v.items = - (int) sv_player->v.items | HIT_LASER_CANNON; + sv_player->v.v.items = + (int) sv_player->v.v.items | HIT_LASER_CANNON; 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') - sv_player->v.items = - (int) sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + sv_player->v.v.items = + (int) sv_player->v.v.items | (IT_SHOTGUN << (t[0] - '2')); } else { if (t[0] >= '2') - sv_player->v.items = - (int) sv_player->v.items | (IT_SHOTGUN << (t[0] - '2')); + sv_player->v.v.items = + (int) sv_player->v.v.items | (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; + sv_player->v.v.ammo_shells = 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 (sv_player->v.v.weapon <= IT_LIGHTNING) + sv_player->v.v.ammo_nails = v; } } else { - sv_player->v.ammo_nails = v; + sv_player->v.v.ammo_nails = 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 (sv_player->v.v.weapon > IT_LIGHTNING) + sv_player->v.v.ammo_nails = 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 (sv_player->v.v.weapon <= IT_LIGHTNING) + sv_player->v.v.ammo_rockets = v; } } else { - sv_player->v.ammo_rockets = v; + sv_player->v.v.ammo_rockets = 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 (sv_player->v.v.weapon > IT_LIGHTNING) + sv_player->v.v.ammo_rockets = v; } } break; case 'h': - sv_player->v.health = v; + sv_player->v.v.health = 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 (sv_player->v.v.weapon <= IT_LIGHTNING) + sv_player->v.v.ammo_cells = v; } } else { - sv_player->v.ammo_cells = v; + sv_player->v.v.ammo_cells = 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 (sv_player->v.v.weapon > IT_LIGHTNING) + sv_player->v.v.ammo_cells = v; } } break; @@ -1576,8 +1591,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 (sv_pr_state.pr_strings + e->v.v.classname, "viewthing")) return e; } Con_Printf ("No viewthing on map\n"); @@ -1605,8 +1620,8 @@ Host_Viewmodel_f (void) return; } - e->v.frame = 0; - cl.model_precache[(int) e->v.modelindex] = m; + e->v.v.frame = 0; + cl.model_precache[(int) e->v.v.modelindex] = m; } /* @@ -1624,13 +1639,13 @@ Host_Viewframe_f (void) e = FindViewthing (); if (!e) return; - m = cl.model_precache[(int) e->v.modelindex]; + m = cl.model_precache[(int) e->v.v.modelindex]; f = atoi (Cmd_Argv (1)); if (f >= m->numframes) f = m->numframes - 1; - e->v.frame = f; + e->v.v.frame = f; } @@ -1662,13 +1677,13 @@ Host_Viewnext_f (void) e = FindViewthing (); if (!e) 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; - if (e->v.frame >= m->numframes) - e->v.frame = m->numframes - 1; + e->v.v.frame = e->v.v.frame + 1; + if (e->v.v.frame >= m->numframes) + 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) 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; - if (e->v.frame < 0) - e->v.frame = 0; + e->v.v.frame = e->v.v.frame - 1; + if (e->v.v.frame < 0) + e->v.v.frame = 0; - PrintFrameName (m, e->v.frame); + PrintFrameName (m, e->v.v.frame); } /* diff --git a/nq/source/net_dgrm.c b/nq/source/net_dgrm.c index fe3b87901..324fa6876 100644 --- a/nq/source/net_dgrm.c +++ b/nq/source/net_dgrm.c @@ -145,8 +145,8 @@ NET_Ban_f (void) } print = Con_Printf; } else { - if (pr_global_struct->deathmatch && !host_client->privileged) - return; + if (sv_pr_state.pr_global_struct->deathmatch + && !host_client->privileged) return; print = SV_ClientPrintf; } @@ -945,7 +945,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, (int) client->edict->v.v.frags); MSG_WriteLong (net_message->message, (int) (net_time - client->netconnection->connecttime)); MSG_WriteString (net_message->message, client->netconnection->address); diff --git a/nq/source/pr_cmds.c b/nq/source/pr_cmds.c index afdb488c9..6022c433a 100644 --- a/nq/source/pr_cmds.c +++ b/nq/source/pr_cmds.c @@ -1,5 +1,5 @@ /* - pr_cmds.c + pr->pr_cmds.c @description@ @@ -42,7 +42,7 @@ #include "msg.h" #include "server.h" -#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e)) +#define RETURN_EDICT(p,e) (((int *)p->pr_globals)[OFS_RETURN] = EDICT_TO_PROG(p, e)) /* =============================================================================== @@ -53,14 +53,14 @@ */ char * -PF_VarString (int first) +PF_VarString (progs_t * pr, int first) { int i; static char out[256]; out[0] = 0; - for (i = first; i < pr_argc; i++) { - strcat (out, G_STRING ((OFS_PARM0 + i * 3))); + for (i = first; i < pr->pr_argc; i++) { + strcat (out, G_STRING (pr, (OFS_PARM0 + i * 3))); } return out; } @@ -77,16 +77,16 @@ error(value) ================= */ void -PF_error (void) +PF_error (progs_t * pr) { char *s; edict_t *ed; - s = PF_VarString (0); + s = PF_VarString (pr, 0); Con_Printf ("======SERVER ERROR in %s:\n%s\n", - pr_strings + pr_xfunction->s_name, s); - ed = PROG_TO_EDICT (pr_global_struct->self); - ED_Print (ed); + pr->pr_strings + pr->pr_xfunction->s_name, s); + ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self); + ED_Print (pr, ed); Host_Error ("Program error"); } @@ -102,17 +102,17 @@ objerror(value) ================= */ void -PF_objerror (void) +PF_objerror (progs_t * pr) { char *s; edict_t *ed; - s = PF_VarString (0); + s = PF_VarString (pr, 0); Con_Printf ("======OBJECT ERROR in %s:\n%s\n", - pr_strings + pr_xfunction->s_name, s); - ed = PROG_TO_EDICT (pr_global_struct->self); - ED_Print (ed); - ED_Free (ed); + pr->pr_strings + pr->pr_xfunction->s_name, s); + ed = PROG_TO_EDICT (pr, pr->pr_global_struct->self); + ED_Print (pr, ed); + ED_Free (pr, ed); Host_Error ("Program error"); } @@ -128,10 +128,10 @@ makevectors(vector) ============== */ void -PF_makevectors (void) +PF_makevectors (progs_t * pr) { - AngleVectors (G_VECTOR (OFS_PARM0), pr_global_struct->v_forward, - pr_global_struct->v_right, pr_global_struct->v_up); + AngleVectors (G_VECTOR (pr, OFS_PARM0), pr->pr_global_struct->v_forward, + pr->pr_global_struct->v_right, pr->pr_global_struct->v_up); } /* @@ -144,20 +144,21 @@ setorigin (entity, origin) ================= */ void -PF_setorigin (void) +PF_setorigin (progs_t * pr) { edict_t *e; float *org; - e = G_EDICT (OFS_PARM0); - org = G_VECTOR (OFS_PARM1); - VectorCopy (org, e->v.origin); + e = G_EDICT (pr, OFS_PARM0); + org = G_VECTOR (pr, OFS_PARM1); + VectorCopy (org, e->v.v.origin); SV_LinkEdict (e, false); } void -SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) +SetMinMaxSize (progs_t * pr, edict_t *e, float *min, float *max, + qboolean rotate) { float *angles; vec3_t rmin, rmax; @@ -169,10 +170,11 @@ SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) for (i = 0; i < 3; i++) if (min[i] > max[i]) - PR_RunError ("backwards mins/maxs"); + PR_RunError (pr, "backwards mins/maxs"); rotate = false; // FIXME: implement rotation properly // + // // again if (!rotate) { @@ -180,7 +182,7 @@ SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) VectorCopy (max, rmax); } else { // find min / max for rotations - angles = e->v.angles; + angles = e->v.v.angles; a = angles[1] / 180 * M_PI; @@ -221,9 +223,9 @@ SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) } // set derived values - VectorCopy (rmin, e->v.mins); - VectorCopy (rmax, e->v.maxs); - VectorSubtract (max, min, e->v.size); + VectorCopy (rmin, e->v.v.mins); + VectorCopy (rmax, e->v.v.maxs); + VectorSubtract (max, min, e->v.v.size); SV_LinkEdict (e, false); } @@ -238,15 +240,15 @@ setsize (entity, minvector, maxvector) ================= */ void -PF_setsize (void) +PF_setsize (progs_t * pr) { edict_t *e; float *min, *max; - e = G_EDICT (OFS_PARM0); - min = G_VECTOR (OFS_PARM1); - max = G_VECTOR (OFS_PARM2); - SetMinMaxSize (e, min, max, false); + e = G_EDICT (pr, OFS_PARM0); + min = G_VECTOR (pr, OFS_PARM1); + max = G_VECTOR (pr, OFS_PARM2); + SetMinMaxSize (pr, e, min, max, false); } @@ -258,15 +260,15 @@ setmodel(entity, model) ================= */ void -PF_setmodel (void) +PF_setmodel (progs_t * pr) { edict_t *e; char *m, **check; model_t *mod; int i; - e = G_EDICT (OFS_PARM0); - m = G_STRING (OFS_PARM1); + e = G_EDICT (pr, OFS_PARM0); + m = G_STRING (pr, OFS_PARM1); // check to see if model was properly precached for (i = 0, check = sv.model_precache; *check; i++, check++) @@ -274,18 +276,18 @@ PF_setmodel (void) break; if (!*check) - PR_RunError ("no precache: %s\n", m); + PR_RunError (pr, "no precache: %s\n", m); - e->v.model = m - pr_strings; - e->v.modelindex = i; // SV_ModelIndex (m); + e->v.v.model = m - pr->pr_strings; + e->v.v.modelindex = i; // SV_ModelIndex (m); - mod = sv.models[(int) e->v.modelindex]; // Mod_ForName (m, true); + mod = sv.models[(int) e->v.v.modelindex]; // Mod_ForName (m, true); if (mod) - SetMinMaxSize (e, mod->mins, mod->maxs, true); + SetMinMaxSize (pr, e, mod->mins, mod->maxs, true); else - SetMinMaxSize (e, vec3_origin, vec3_origin, true); + SetMinMaxSize (pr, e, vec3_origin, vec3_origin, true); } /* @@ -298,11 +300,11 @@ bprint(value) ================= */ void -PF_bprint (void) +PF_bprint (progs_t * pr) { char *s; - s = PF_VarString (0); + s = PF_VarString (pr, 0); SV_BroadcastPrintf ("%s", s); } @@ -316,14 +318,14 @@ sprint(clientent, value) ================= */ void -PF_sprint (void) +PF_sprint (progs_t * pr) { char *s; client_t *client; int entnum; - entnum = G_EDICTNUM (OFS_PARM0); - s = PF_VarString (1); + entnum = G_EDICTNUM (pr, OFS_PARM0); + s = PF_VarString (pr, 1); if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); @@ -347,14 +349,14 @@ centerprint(clientent, value) ================= */ void -PF_centerprint (void) +PF_centerprint (progs_t * pr) { char *s; client_t *client; int entnum; - entnum = G_EDICTNUM (OFS_PARM0); - s = PF_VarString (1); + entnum = G_EDICTNUM (pr, OFS_PARM0); + s = PF_VarString (pr, 1); if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); @@ -376,13 +378,13 @@ vector normalize(vector) ================= */ void -PF_normalize (void) +PF_normalize (progs_t * pr) { float *value1; vec3_t newvalue; float new; - value1 = G_VECTOR (OFS_PARM0); + value1 = G_VECTOR (pr, OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2]; new = sqrt (new); @@ -396,7 +398,7 @@ PF_normalize (void) newvalue[2] = value1[2] * new; } - VectorCopy (newvalue, G_VECTOR (OFS_RETURN)); + VectorCopy (newvalue, G_VECTOR (pr, OFS_RETURN)); } /* @@ -407,17 +409,17 @@ scalar vlen(vector) ================= */ void -PF_vlen (void) +PF_vlen (progs_t * pr) { float *value1; float new; - value1 = G_VECTOR (OFS_PARM0); + value1 = G_VECTOR (pr, OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2] * value1[2]; new = sqrt (new); - G_FLOAT (OFS_RETURN) = new; + G_FLOAT (pr, OFS_RETURN) = new; } /* @@ -428,12 +430,12 @@ float vectoyaw(vector) ================= */ void -PF_vectoyaw (void) +PF_vectoyaw (progs_t * pr) { float *value1; float yaw; - value1 = G_VECTOR (OFS_PARM0); + value1 = G_VECTOR (pr, OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) yaw = 0; @@ -443,7 +445,7 @@ PF_vectoyaw (void) yaw += 360; } - G_FLOAT (OFS_RETURN) = yaw; + G_FLOAT (pr, OFS_RETURN) = yaw; } @@ -455,13 +457,13 @@ vector vectoangles(vector) ================= */ void -PF_vectoangles (void) +PF_vectoangles (progs_t * pr) { float *value1; float forward; float yaw, pitch; - value1 = G_VECTOR (OFS_PARM0); + value1 = G_VECTOR (pr, OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) { yaw = 0; @@ -480,9 +482,9 @@ PF_vectoangles (void) pitch += 360; } - G_FLOAT (OFS_RETURN + 0) = pitch; - G_FLOAT (OFS_RETURN + 1) = yaw; - G_FLOAT (OFS_RETURN + 2) = 0; + G_FLOAT (pr, OFS_RETURN + 0) = pitch; + G_FLOAT (pr, OFS_RETURN + 1) = yaw; + G_FLOAT (pr, OFS_RETURN + 2) = 0; } /* @@ -495,13 +497,13 @@ random() ================= */ void -PF_random (void) +PF_random (progs_t * pr) { float num; num = (rand () & 0x7fff) / ((float) 0x7fff); - G_FLOAT (OFS_RETURN) = num; + G_FLOAT (pr, OFS_RETURN) = num; } /* @@ -512,16 +514,16 @@ particle(origin, color, count) ================= */ void -PF_particle (void) +PF_particle (progs_t * pr) { float *org, *dir; float color; float count; - org = G_VECTOR (OFS_PARM0); - dir = G_VECTOR (OFS_PARM1); - color = G_FLOAT (OFS_PARM2); - count = G_FLOAT (OFS_PARM3); + org = G_VECTOR (pr, OFS_PARM0); + dir = G_VECTOR (pr, OFS_PARM1); + color = G_FLOAT (pr, OFS_PARM2); + count = G_FLOAT (pr, OFS_PARM3); SV_StartParticle (org, dir, color, count); } @@ -533,7 +535,7 @@ PF_ambientsound ================= */ void -PF_ambientsound (void) +PF_ambientsound (progs_t * pr) { char **check; char *samp; @@ -541,10 +543,10 @@ PF_ambientsound (void) float vol, attenuation; int i, soundnum; - pos = G_VECTOR (OFS_PARM0); - samp = G_STRING (OFS_PARM1); - vol = G_FLOAT (OFS_PARM2); - attenuation = G_FLOAT (OFS_PARM3); + pos = G_VECTOR (pr, OFS_PARM0); + samp = G_STRING (pr, OFS_PARM1); + vol = G_FLOAT (pr, OFS_PARM2); + attenuation = G_FLOAT (pr, OFS_PARM3); // check to see if samp was properly precached for (soundnum = 0, check = sv.sound_precache; *check; check++, soundnum++) @@ -584,7 +586,7 @@ Larger attenuations will drop off. ================= */ void -PF_sound (void) +PF_sound (progs_t * pr) { char *sample; int channel; @@ -592,11 +594,11 @@ PF_sound (void) int volume; float attenuation; - entity = G_EDICT (OFS_PARM0); - channel = G_FLOAT (OFS_PARM1); - sample = G_STRING (OFS_PARM2); - volume = G_FLOAT (OFS_PARM3) * 255; - attenuation = G_FLOAT (OFS_PARM4); + entity = G_EDICT (pr, OFS_PARM0); + channel = G_FLOAT (pr, OFS_PARM1); + sample = G_STRING (pr, OFS_PARM2); + volume = G_FLOAT (pr, OFS_PARM3) * 255; + attenuation = G_FLOAT (pr, OFS_PARM4); if (volume < 0 || volume > 255) Sys_Error ("SV_StartSound: volume = %i", volume); @@ -618,7 +620,7 @@ break() ================= */ void -PF_break (void) +PF_break (progs_t * pr) { Con_Printf ("break statement\n"); *(int *) -4 = 0; // dump to debugger @@ -637,32 +639,32 @@ traceline (vector1, vector2, tryents) ================= */ void -PF_traceline (void) +PF_traceline (progs_t * pr) { float *v1, *v2; trace_t trace; int nomonsters; edict_t *ent; - v1 = G_VECTOR (OFS_PARM0); - v2 = G_VECTOR (OFS_PARM1); - nomonsters = G_FLOAT (OFS_PARM2); - ent = G_EDICT (OFS_PARM3); + v1 = G_VECTOR (pr, OFS_PARM0); + v2 = G_VECTOR (pr, OFS_PARM1); + nomonsters = G_FLOAT (pr, OFS_PARM2); + ent = G_EDICT (pr, OFS_PARM3); trace = SV_Move (v1, vec3_origin, vec3_origin, v2, nomonsters, ent); - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + 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; if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG (trace.ent); + pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG (sv.edicts); + pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, sv.edicts); } @@ -670,29 +672,29 @@ PF_traceline (void) extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); void -PF_TraceToss (void) +PF_TraceToss (progs_t * pr) { trace_t trace; edict_t *ent; edict_t *ignore; - ent = G_EDICT (OFS_PARM0); - ignore = G_EDICT (OFS_PARM1); + ent = G_EDICT (pr, OFS_PARM0); + ignore = G_EDICT (pr, OFS_PARM1); trace = SV_Trace_Toss (ent, ignore); - pr_global_struct->trace_allsolid = trace.allsolid; - pr_global_struct->trace_startsolid = trace.startsolid; - pr_global_struct->trace_fraction = trace.fraction; - pr_global_struct->trace_inwater = trace.inwater; - pr_global_struct->trace_inopen = trace.inopen; - VectorCopy (trace.endpos, pr_global_struct->trace_endpos); - VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + 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; if (trace.ent) - pr_global_struct->trace_ent = EDICT_TO_PROG (trace.ent); + pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG (sv.edicts); + pr->pr_global_struct->trace_ent = EDICT_TO_PROG (pr, sv.edicts); } #endif @@ -708,7 +710,7 @@ scalar checkpos (entity, vector) ================= */ void -PF_checkpos (void) +PF_checkpos (progs_t * pr) { } @@ -717,7 +719,7 @@ PF_checkpos (void) byte checkpvs[MAX_MAP_LEAFS / 8]; int -PF_newcheckclient (int check) +PF_newcheckclient (progs_t * pr, int check) { int i; byte *pvs; @@ -741,16 +743,16 @@ PF_newcheckclient (int check) if (i == svs.maxclients + 1) i = 1; - ent = EDICT_NUM (i); + ent = EDICT_NUM (pr, i); if (i == check) break; // didn't find anything else if (ent->free) continue; - if (ent->v.health <= 0) + if (ent->v.v.health <= 0) continue; - if ((int) ent->v.flags & FL_NOTARGET) + if ((int) ent->v.v.flags & FL_NOTARGET) continue; // anything that is a client, or has a client as an enemy @@ -758,7 +760,7 @@ PF_newcheckclient (int check) } // get the PVS for the entity - VectorAdd (ent->v.origin, ent->v.view_ofs, org); + VectorAdd (ent->v.v.origin, ent->v.v.view_ofs, org); leaf = Mod_PointInLeaf (org, sv.worldmodel); pvs = Mod_LeafPVS (leaf, sv.worldmodel); memcpy (checkpvs, pvs, (sv.worldmodel->numleafs + 7) >> 3); @@ -784,7 +786,7 @@ name checkclient () #define MAX_CHECK 16 int c_invis, c_notvis; void -PF_checkclient (void) +PF_checkclient (progs_t * pr) { edict_t *ent, *self; mleaf_t *leaf; @@ -793,28 +795,28 @@ PF_checkclient (void) // find a new check if on a new frame if (sv.time - sv.lastchecktime >= 0.1) { - sv.lastcheck = PF_newcheckclient (sv.lastcheck); + sv.lastcheck = PF_newcheckclient (pr, sv.lastcheck); sv.lastchecktime = sv.time; } // return check if it might be visible - ent = EDICT_NUM (sv.lastcheck); - if (ent->free || ent->v.health <= 0) { - RETURN_EDICT (sv.edicts); + ent = EDICT_NUM (pr, sv.lastcheck); + if (ent->free || ent->v.v.health <= 0) { + RETURN_EDICT (pr, sv.edicts); return; } // if current entity can't possibly see the check entity, return 0 - self = PROG_TO_EDICT (pr_global_struct->self); - VectorAdd (self->v.origin, self->v.view_ofs, view); + self = PROG_TO_EDICT (pr, pr->pr_global_struct->self); + VectorAdd (self->v.v.origin, self->v.v.view_ofs, view); leaf = Mod_PointInLeaf (view, sv.worldmodel); l = (leaf - sv.worldmodel->leafs) - 1; if ((l < 0) || !(checkpvs[l >> 3] & (1 << (l & 7)))) { c_notvis++; - RETURN_EDICT (sv.edicts); + RETURN_EDICT (pr, sv.edicts); return; } // might be able to see it c_invis++; - RETURN_EDICT (ent); + RETURN_EDICT (pr, ent); } //============================================================================ @@ -830,16 +832,16 @@ stuffcmd (clientent, value) ================= */ void -PF_stuffcmd (void) +PF_stuffcmd (progs_t * pr) { int entnum; char *str; client_t *old; - entnum = G_EDICTNUM (OFS_PARM0); + entnum = G_EDICTNUM (pr, OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients) - PR_RunError ("Parm 0 not a client"); - str = G_STRING (OFS_PARM1); + PR_RunError (pr, "Parm 0 not a client"); + str = G_STRING (pr, OFS_PARM1); old = host_client; host_client = &svs.clients[entnum - 1]; @@ -857,11 +859,11 @@ localcmd (string) ================= */ void -PF_localcmd (void) +PF_localcmd (progs_t * pr) { char *str; - str = G_STRING (OFS_PARM0); + str = G_STRING (pr, OFS_PARM0); Cbuf_AddText (str); } @@ -873,13 +875,13 @@ float cvar (string) ================= */ void -PF_cvar (void) +PF_cvar (progs_t * pr) { char *str; - str = G_STRING (OFS_PARM0); + str = G_STRING (pr, OFS_PARM0); - G_FLOAT (OFS_RETURN) = Cvar_VariableValue (str); + G_FLOAT (pr, OFS_RETURN) = Cvar_VariableValue (str); } /* @@ -890,13 +892,13 @@ float cvar (string) ================= */ void -PF_cvar_set (void) +PF_cvar_set (progs_t * pr) { char *var_name, *val; cvar_t *var; - var_name = G_STRING (OFS_PARM0); - val = G_STRING (OFS_PARM1); + var_name = G_STRING (pr, OFS_PARM0); + val = G_STRING (pr, OFS_PARM1); var = Cvar_FindVar (var_name); if (!var) var = Cvar_FindAlias (var_name); @@ -919,7 +921,7 @@ findradius (origin, radius) ================= */ void -PF_findradius (void) +PF_findradius (progs_t * pr) { edict_t *ent, *chain; float rad; @@ -929,27 +931,27 @@ PF_findradius (void) chain = (edict_t *) sv.edicts; - org = G_VECTOR (OFS_PARM0); - rad = G_FLOAT (OFS_PARM1); + org = G_VECTOR (pr, OFS_PARM0); + rad = G_FLOAT (pr, OFS_PARM1); - ent = NEXT_EDICT (sv.edicts); - for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (ent)) { + ent = NEXT_EDICT (pr, sv.edicts); + for (i = 1; i < sv.num_edicts; i++, ent = NEXT_EDICT (pr, ent)) { if (ent->free) continue; - if (ent->v.solid == SOLID_NOT) + if (ent->v.v.solid == SOLID_NOT) continue; for (j = 0; j < 3; j++) eorg[j] = - org[j] - (ent->v.origin[j] + - (ent->v.mins[j] + ent->v.maxs[j]) * 0.5); + org[j] - (ent->v.v.origin[j] + + (ent->v.v.mins[j] + ent->v.v.maxs[j]) * 0.5); if (Length (eorg) > rad) continue; - ent->v.chain = EDICT_TO_PROG (chain); + ent->v.v.chain = EDICT_TO_PROG (pr, chain); chain = ent; } - RETURN_EDICT (chain); + RETURN_EDICT (pr, chain); } @@ -959,77 +961,78 @@ PF_dprint ========= */ void -PF_dprint (void) +PF_dprint (progs_t * pr) { - Con_DPrintf ("%s", PF_VarString (0)); + Con_DPrintf ("%s", PF_VarString (pr, 0)); } char pr_string_temp[128]; void -PF_ftos (void) +PF_ftos (progs_t * pr) { float v; - v = G_FLOAT (OFS_PARM0); + v = G_FLOAT (pr, OFS_PARM0); if (v == (int) v) snprintf (pr_string_temp, sizeof (pr_string_temp), "%d", (int) v); else snprintf (pr_string_temp, sizeof (pr_string_temp), "%5.1f", v); - G_INT (OFS_RETURN) = pr_string_temp - pr_strings; + G_INT (pr, OFS_RETURN) = pr_string_temp - pr->pr_strings; } void -PF_fabs (void) +PF_fabs (progs_t * pr) { float v; - v = G_FLOAT (OFS_PARM0); - G_FLOAT (OFS_RETURN) = fabs (v); + v = G_FLOAT (pr, OFS_PARM0); + G_FLOAT (pr, OFS_RETURN) = fabs (v); } void -PF_vtos (void) +PF_vtos (progs_t * pr) { - snprintf (pr_string_temp, sizeof (pr_string_temp), "'%5.1f %5.1f %5.1f'", - G_VECTOR (OFS_PARM0)[0], G_VECTOR (OFS_PARM0)[1], - G_VECTOR (OFS_PARM0)[2]); - G_INT (OFS_RETURN) = pr_string_temp - pr_strings; + snprintf (pr_string_temp, sizeof (pr_string_temp), + "'%5.1f %5.1f %5.1f'", G_VECTOR (pr, OFS_PARM0)[0], G_VECTOR (pr, + OFS_PARM0) + [1], G_VECTOR (pr, OFS_PARM0)[2]); + G_INT (pr, OFS_RETURN) = pr_string_temp - pr->pr_strings; } #ifdef QUAKE2 void -PF_etos (void) +PF_etos (progs_t * pr) { snprintf (pr_string_temp, sizeof (pr_string_temp), "entity %i", - G_EDICTNUM (OFS_PARM0)); - G_INT (OFS_RETURN) = pr_string_temp - pr_strings; + G_EDICTNUM (pr, OFS_PARM0)); + G_INT (pr, OFS_RETURN) = pr_string_temp - pr->pr_strings; } #endif void -PF_Spawn (void) +PF_Spawn (progs_t * pr) { edict_t *ed; - ed = ED_Alloc (); - RETURN_EDICT (ed); + ed = ED_Alloc (pr); + RETURN_EDICT (pr, ed); } void -PF_Remove (void) +PF_Remove (progs_t * pr) { edict_t *ed; - ed = G_EDICT (OFS_PARM0); - ED_Free (ed); + ed = G_EDICT (pr, OFS_PARM0); + ED_Free (pr, ed); } // entity (entity start, .string field, string match) find = #5; void -PF_Find (void) +PF_Find (progs_t * pr) #ifdef QUAKE2 { int e; @@ -1041,17 +1044,17 @@ PF_Find (void) edict_t *last; first = second = last = (edict_t *) sv.edicts; - e = G_EDICTNUM (OFS_PARM0); - f = G_INT (OFS_PARM1); - s = G_STRING (OFS_PARM2); + e = G_EDICTNUM (pr, OFS_PARM0); + f = G_INT (pr, OFS_PARM1); + s = G_STRING (pr, OFS_PARM2); if (!s) - PR_RunError ("PF_Find: bad search string"); + PR_RunError (pr, "PF_Find: bad search string"); for (e++; e < sv.num_edicts; e++) { - ed = EDICT_NUM (e); + ed = EDICT_NUM (pr, e); if (ed->free) continue; - t = E_STRING (ed, f); + t = E_STRING (pr, ed, f); if (!t) continue; if (!strcmp (t, s)) { @@ -1059,21 +1062,21 @@ PF_Find (void) first = ed; else if (second == (edict_t *) sv.edicts) second = ed; - ed->v.chain = EDICT_TO_PROG (last); + ed->v.v.chain = EDICT_TO_PROG (pr, last); last = ed; } } if (first != last) { if (last != second) - first->v.chain = last->v.chain; + first->v.v.chain = last->v.v.chain; else - first->v.chain = EDICT_TO_PROG (last); - last->v.chain = EDICT_TO_PROG ((edict_t *) sv.edicts); + first->v.v.chain = EDICT_TO_PROG (pr, last); + last->v.v.chain = EDICT_TO_PROG (pr, (edict_t *) sv.edicts); if (second && second != last) - second->v.chain = EDICT_TO_PROG (last); + second->v.v.chain = EDICT_TO_PROG (pr, last); } - RETURN_EDICT (first); + RETURN_EDICT (pr, first); } #else { @@ -1082,57 +1085,58 @@ PF_Find (void) char *s, *t; edict_t *ed; - e = G_EDICTNUM (OFS_PARM0); - f = G_INT (OFS_PARM1); - s = G_STRING (OFS_PARM2); + e = G_EDICTNUM (pr, OFS_PARM0); + f = G_INT (pr, OFS_PARM1); + s = G_STRING (pr, OFS_PARM2); if (!s) - PR_RunError ("PF_Find: bad search string"); + PR_RunError (pr, "PF_Find: bad search string"); for (e++; e < sv.num_edicts; e++) { - ed = EDICT_NUM (e); + ed = EDICT_NUM (pr, e); if (ed->free) continue; - t = E_STRING (ed, f); + t = E_STRING (pr, ed, f); if (!t) continue; if (!strcmp (t, s)) { - RETURN_EDICT (ed); + RETURN_EDICT (pr, ed); return; } } - RETURN_EDICT (sv.edicts); + RETURN_EDICT (pr, sv.edicts); } #endif void -PR_CheckEmptyString (char *s) +PR_CheckEmptyString (progs_t * pr, char *s) { if (s[0] <= ' ') - PR_RunError ("Bad string"); + PR_RunError (pr, "Bad string"); } void -PF_precache_file (void) +PF_precache_file (progs_t * pr) { // precache_file is only used to copy // + // // files with qcc, it does nothing - G_INT (OFS_RETURN) = G_INT (OFS_PARM0); + G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0); } void -PF_precache_sound (void) +PF_precache_sound (progs_t * pr) { char *s; int i; if (sv.state != ss_loading) PR_RunError - ("PF_Precache_*: Precache can only be done in spawn functions"); + (pr, "PF_Precache_*: Precache can only be done in spawn functions"); - s = G_STRING (OFS_PARM0); - G_INT (OFS_RETURN) = G_INT (OFS_PARM0); - PR_CheckEmptyString (s); + s = G_STRING (pr, OFS_PARM0); + G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0); + PR_CheckEmptyString (pr, s); for (i = 0; i < MAX_SOUNDS; i++) { if (!sv.sound_precache[i]) { @@ -1142,22 +1146,22 @@ PF_precache_sound (void) if (!strcmp (sv.sound_precache[i], s)) return; } - PR_RunError ("PF_precache_sound: overflow"); + PR_RunError (pr, "PF_precache_sound: overflow"); } void -PF_precache_model (void) +PF_precache_model (progs_t * pr) { char *s; int i; if (sv.state != ss_loading) PR_RunError - ("PF_Precache_*: Precache can only be done in spawn functions"); + (pr, "PF_Precache_*: Precache can only be done in spawn functions"); - s = G_STRING (OFS_PARM0); - G_INT (OFS_RETURN) = G_INT (OFS_PARM0); - PR_CheckEmptyString (s); + s = G_STRING (pr, OFS_PARM0); + G_INT (pr, OFS_RETURN) = G_INT (pr, OFS_PARM0); + PR_CheckEmptyString (pr, s); for (i = 0; i < MAX_MODELS; i++) { if (!sv.model_precache[i]) { @@ -1168,32 +1172,32 @@ PF_precache_model (void) if (!strcmp (sv.model_precache[i], s)) return; } - PR_RunError ("PF_precache_model: overflow"); + PR_RunError (pr, "PF_precache_model: overflow"); } void -PF_coredump (void) +PF_coredump (progs_t * pr) { - ED_PrintEdicts (); + ED_PrintEdicts (pr); } void -PF_traceon (void) +PF_traceon (progs_t * pr) { - pr_trace = true; + pr->pr_trace = true; } void -PF_traceoff (void) +PF_traceoff (progs_t * pr) { - pr_trace = false; + pr->pr_trace = false; } void -PF_eprint (void) +PF_eprint (progs_t * pr) { - ED_PrintNum (G_EDICTNUM (OFS_PARM0)); + ED_PrintNum (pr, G_EDICTNUM (pr, OFS_PARM0)); } /* @@ -1204,7 +1208,7 @@ float(float yaw, float dist) walkmove =============== */ void -PF_walkmove (void) +PF_walkmove (progs_t * pr) { edict_t *ent; float yaw, dist; @@ -1212,12 +1216,12 @@ PF_walkmove (void) dfunction_t *oldf; int oldself; - ent = PROG_TO_EDICT (pr_global_struct->self); - yaw = G_FLOAT (OFS_PARM0); - dist = G_FLOAT (OFS_PARM1); + ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self); + yaw = G_FLOAT (pr, OFS_PARM0); + dist = G_FLOAT (pr, OFS_PARM1); - if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { - G_FLOAT (OFS_RETURN) = 0; + if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { + G_FLOAT (pr, OFS_RETURN) = 0; return; } @@ -1228,15 +1232,15 @@ PF_walkmove (void) move[2] = 0; // save program state, because SV_movestep may call other progs - oldf = pr_xfunction; - oldself = pr_global_struct->self; + oldf = pr->pr_xfunction; + oldself = pr->pr_global_struct->self; - G_FLOAT (OFS_RETURN) = SV_movestep (ent, move, true); + G_FLOAT (pr, OFS_RETURN) = SV_movestep (ent, move, true); // restore program state - pr_xfunction = oldf; - pr_global_struct->self = oldself; + pr->pr_xfunction = oldf; + pr->pr_global_struct->self = oldself; } /* @@ -1247,27 +1251,29 @@ void() droptofloor =============== */ void -PF_droptofloor (void) +PF_droptofloor (progs_t * pr) { edict_t *ent; vec3_t end; trace_t trace; - ent = PROG_TO_EDICT (pr_global_struct->self); + ent = PROG_TO_EDICT (pr, pr->pr_global_struct->self); - VectorCopy (ent->v.origin, end); + VectorCopy (ent->v.v.origin, end); end[2] -= 256; - trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); + trace = + SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, false, + ent); if (trace.fraction == 1 || trace.allsolid) - G_FLOAT (OFS_RETURN) = 0; + G_FLOAT (pr, OFS_RETURN) = 0; else { - VectorCopy (trace.endpos, ent->v.origin); + VectorCopy (trace.endpos, ent->v.v.origin); SV_LinkEdict (ent, false); - ent->v.flags = (int) ent->v.flags | FL_ONGROUND; - ent->v.groundentity = EDICT_TO_PROG (trace.ent); - G_FLOAT (OFS_RETURN) = 1; + ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND; + ent->v.v.groundentity = EDICT_TO_PROG (pr, trace.ent); + G_FLOAT (pr, OFS_RETURN) = 1; } } @@ -1279,15 +1285,15 @@ void(float style, string value) lightstyle =============== */ void -PF_lightstyle (void) +PF_lightstyle (progs_t * pr) { int style; char *val; client_t *client; int j; - style = G_FLOAT (OFS_PARM0); - val = G_STRING (OFS_PARM1); + style = G_FLOAT (pr, OFS_PARM0); + val = G_STRING (pr, OFS_PARM1); // change the string in sv sv.lightstyles[style] = val; @@ -1305,27 +1311,27 @@ PF_lightstyle (void) } void -PF_rint (void) +PF_rint (progs_t * pr) { float f; - f = G_FLOAT (OFS_PARM0); + f = G_FLOAT (pr, OFS_PARM0); if (f > 0) - G_FLOAT (OFS_RETURN) = (int) (f + 0.5); + G_FLOAT (pr, OFS_RETURN) = (int) (f + 0.5); else - G_FLOAT (OFS_RETURN) = (int) (f - 0.5); + G_FLOAT (pr, OFS_RETURN) = (int) (f - 0.5); } void -PF_floor (void) +PF_floor (progs_t * pr) { - G_FLOAT (OFS_RETURN) = floor (G_FLOAT (OFS_PARM0)); + G_FLOAT (pr, OFS_RETURN) = floor (G_FLOAT (pr, OFS_PARM0)); } void -PF_ceil (void) +PF_ceil (progs_t * pr) { - G_FLOAT (OFS_RETURN) = ceil (G_FLOAT (OFS_PARM0)); + G_FLOAT (pr, OFS_RETURN) = ceil (G_FLOAT (pr, OFS_PARM0)); } @@ -1335,13 +1341,13 @@ PF_checkbottom ============= */ void -PF_checkbottom (void) +PF_checkbottom (progs_t * pr) { edict_t *ent; - ent = G_EDICT (OFS_PARM0); + ent = G_EDICT (pr, OFS_PARM0); - G_FLOAT (OFS_RETURN) = SV_CheckBottom (ent); + G_FLOAT (pr, OFS_RETURN) = SV_CheckBottom (ent); } /* @@ -1350,13 +1356,13 @@ PF_pointcontents ============= */ void -PF_pointcontents (void) +PF_pointcontents (progs_t * pr) { float *v; - v = G_VECTOR (OFS_PARM0); + v = G_VECTOR (pr, OFS_PARM0); - G_FLOAT (OFS_RETURN) = SV_PointContents (v); + G_FLOAT (pr, OFS_RETURN) = SV_PointContents (v); } /* @@ -1367,21 +1373,21 @@ entity nextent(entity) ============= */ void -PF_nextent (void) +PF_nextent (progs_t * pr) { int i; edict_t *ent; - i = G_EDICTNUM (OFS_PARM0); + i = G_EDICTNUM (pr, OFS_PARM0); while (1) { i++; if (i == sv.num_edicts) { - RETURN_EDICT (sv.edicts); + RETURN_EDICT (pr, sv.edicts); return; } - ent = EDICT_NUM (i); + ent = EDICT_NUM (pr, i); if (!ent->free) { - RETURN_EDICT (ent); + RETURN_EDICT (pr, ent); return; } } @@ -1397,7 +1403,7 @@ vector aim(entity, missilespeed) */ cvar_t *sv_aim; void -PF_aim (void) +PF_aim (progs_t * pr) { edict_t *ent, *check, *bestent; vec3_t start, dir, end, bestdir; @@ -1406,20 +1412,20 @@ PF_aim (void) float dist, bestdist; float speed; - ent = G_EDICT (OFS_PARM0); - speed = G_FLOAT (OFS_PARM1); + ent = G_EDICT (pr, OFS_PARM0); + speed = G_FLOAT (pr, OFS_PARM1); - VectorCopy (ent->v.origin, start); + VectorCopy (ent->v.v.origin, start); start[2] += 20; // try sending a trace straight - VectorCopy (pr_global_struct->v_forward, dir); + VectorCopy (pr->pr_global_struct->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.takedamage == DAMAGE_AIM - && (!teamplay->int_val || ent->v.team <= 0 - || ent->v.team != tr.ent->v.team)) { - VectorCopy (pr_global_struct->v_forward, G_VECTOR (OFS_RETURN)); + 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)); return; } // try all possible entities @@ -1427,21 +1433,21 @@ PF_aim (void) bestdist = sv_aim->value; bestent = NULL; - check = NEXT_EDICT (sv.edicts); - for (i = 1; i < sv.num_edicts; i++, check = NEXT_EDICT (check)) { - if (check->v.takedamage != DAMAGE_AIM) + 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) continue; if (check == ent) continue; - if (teamplay->int_val && ent->v.team > 0 - && ent->v.team == check->v.team) continue; // don't aim at + if (teamplay->int_val && ent->v.v.team > 0 + && ent->v.v.team == check->v.v.team) continue; // don't aim at // teammate for (j = 0; j < 3; j++) - end[j] = check->v.origin[j] - + 0.5 * (check->v.mins[j] + check->v.maxs[j]); + end[j] = check->v.v.origin[j] + + 0.5 * (check->v.v.mins[j] + check->v.v.maxs[j]); VectorSubtract (end, start, dir); VectorNormalize (dir); - dist = DotProduct (dir, pr_global_struct->v_forward); + dist = DotProduct (dir, pr->pr_global_struct->v_forward); if (dist < bestdist) continue; // to far to turn tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); @@ -1452,14 +1458,14 @@ PF_aim (void) } if (bestent) { - VectorSubtract (bestent->v.origin, ent->v.origin, dir); - dist = DotProduct (dir, pr_global_struct->v_forward); - VectorScale (pr_global_struct->v_forward, dist, end); + 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); end[2] = dir[2]; VectorNormalize (end); - VectorCopy (end, G_VECTOR (OFS_RETURN)); + VectorCopy (end, G_VECTOR (pr, OFS_RETURN)); } else { - VectorCopy (bestdir, G_VECTOR (OFS_RETURN)); + VectorCopy (bestdir, G_VECTOR (pr, OFS_RETURN)); } } @@ -1471,15 +1477,15 @@ This was a major timewaster in progs, so it was converted to C ============== */ void -PF_changeyaw (void) +PF_changeyaw (progs_t * pr) { edict_t *ent; float ideal, current, move, speed; - ent = PROG_TO_EDICT (pr_global_struct->self); - current = anglemod (ent->v.angles[1]); - ideal = ent->v.ideal_yaw; - speed = ent->v.yaw_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; if (current == ideal) return; @@ -1499,7 +1505,7 @@ PF_changeyaw (void) move = -speed; } - ent->v.angles[1] = anglemod (current + move); + ent->v.v.angles[1] = anglemod (current + move); } #ifdef QUAKE2 @@ -1509,15 +1515,15 @@ PF_changepitch ============== */ void -PF_changepitch (void) +PF_changepitch (progs_t * pr) { edict_t *ent; float ideal, current, move, speed; - ent = G_EDICT (OFS_PARM0); - current = anglemod (ent->v.angles[0]); - ideal = ent->v.idealpitch; - speed = ent->v.pitch_speed; + ent = G_EDICT (pr, OFS_PARM0); + current = anglemod (ent->v.v.angles[0]); + ideal = ent->v.v.idealpitch; + speed = ent->v.v.pitch_speed; if (current == ideal) return; @@ -1537,7 +1543,7 @@ PF_changepitch (void) move = -speed; } - ent->v.angles[0] = anglemod (current + move); + ent->v.v.angles[0] = anglemod (current + move); } #endif @@ -1555,22 +1561,22 @@ MESSAGE WRITING #define MSG_INIT 3 // write to the init string sizebuf_t * -WriteDest (void) +WriteDest (progs_t * pr) { int entnum; int dest; edict_t *ent; - dest = G_FLOAT (OFS_PARM0); + dest = G_FLOAT (pr, OFS_PARM0); switch (dest) { case MSG_BROADCAST: return &sv.datagram; case MSG_ONE: - ent = PROG_TO_EDICT (pr_global_struct->msg_entity); - entnum = NUM_FOR_EDICT (ent); + ent = PROG_TO_EDICT (pr, pr->pr_global_struct->msg_entity); + entnum = NUM_FOR_EDICT (pr, ent); if (entnum < 1 || entnum > svs.maxclients) - PR_RunError ("WriteDest: not a client"); + PR_RunError (pr, "WriteDest: not a client"); return &svs.clients[entnum - 1].message; case MSG_ALL: @@ -1580,7 +1586,7 @@ WriteDest (void) return &sv.signon; default: - PR_RunError ("WriteDest: bad destination"); + PR_RunError (pr, "WriteDest: bad destination"); break; } @@ -1588,52 +1594,52 @@ WriteDest (void) } void -PF_WriteByte (void) +PF_WriteByte (progs_t * pr) { - MSG_WriteByte (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteByte (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteChar (void) +PF_WriteChar (progs_t * pr) { - MSG_WriteChar (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteChar (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteShort (void) +PF_WriteShort (progs_t * pr) { - MSG_WriteShort (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteShort (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteLong (void) +PF_WriteLong (progs_t * pr) { - MSG_WriteLong (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteLong (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteAngle (void) +PF_WriteAngle (progs_t * pr) { - MSG_WriteAngle (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteAngle (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteCoord (void) +PF_WriteCoord (progs_t * pr) { - MSG_WriteCoord (WriteDest (), G_FLOAT (OFS_PARM1)); + MSG_WriteCoord (WriteDest (pr), G_FLOAT (pr, OFS_PARM1)); } void -PF_WriteString (void) +PF_WriteString (progs_t * pr) { - MSG_WriteString (WriteDest (), G_STRING (OFS_PARM1)); + MSG_WriteString (WriteDest (pr), G_STRING (pr, OFS_PARM1)); } void -PF_WriteEntity (void) +PF_WriteEntity (progs_t * pr) { - MSG_WriteShort (WriteDest (), G_EDICTNUM (OFS_PARM1)); + MSG_WriteShort (WriteDest (pr), G_EDICTNUM (pr, OFS_PARM1)); } //============================================================================= @@ -1641,27 +1647,27 @@ PF_WriteEntity (void) int SV_ModelIndex (char *name); void -PF_makestatic (void) +PF_makestatic (progs_t * pr) { edict_t *ent; int i; - ent = G_EDICT (OFS_PARM0); + ent = G_EDICT (pr, OFS_PARM0); MSG_WriteByte (&sv.signon, svc_spawnstatic); - MSG_WriteByte (&sv.signon, SV_ModelIndex (pr_strings + ent->v.model)); + MSG_WriteByte (&sv.signon, SV_ModelIndex (pr->pr_strings + ent->v.v.model)); - MSG_WriteByte (&sv.signon, ent->v.frame); - MSG_WriteByte (&sv.signon, ent->v.colormap); - MSG_WriteByte (&sv.signon, ent->v.skin); + MSG_WriteByte (&sv.signon, ent->v.v.frame); + MSG_WriteByte (&sv.signon, ent->v.v.colormap); + MSG_WriteByte (&sv.signon, ent->v.v.skin); for (i = 0; i < 3; i++) { - MSG_WriteCoord (&sv.signon, ent->v.origin[i]); - MSG_WriteAngle (&sv.signon, ent->v.angles[i]); + MSG_WriteCoord (&sv.signon, ent->v.v.origin[i]); + MSG_WriteAngle (&sv.signon, ent->v.v.angles[i]); } // throw the entity away now - ED_Free (ent); + ED_Free (pr, ent); } //============================================================================= @@ -1672,22 +1678,22 @@ PF_setspawnparms ============== */ void -PF_setspawnparms (void) +PF_setspawnparms (progs_t * pr) { edict_t *ent; int i; client_t *client; - ent = G_EDICT (OFS_PARM0); - i = NUM_FOR_EDICT (ent); + ent = G_EDICT (pr, OFS_PARM0); + i = NUM_FOR_EDICT (pr, ent); if (i < 1 || i > svs.maxclients) - PR_RunError ("Entity is not a client"); + PR_RunError (pr, "Entity is not a client"); // copy spawn parms out of the client_t client = svs.clients + (i - 1); for (i = 0; i < NUM_SPAWN_PARMS; i++) - (&pr_global_struct->parm1)[i] = client->spawn_parms[i]; + (&pr->pr_global_struct->parm1)[i] = client->spawn_parms[i]; } /* @@ -1696,7 +1702,7 @@ PF_changelevel ============== */ void -PF_changelevel (void) +PF_changelevel (progs_t * pr) { #ifdef QUAKE2 char *s1, *s2; @@ -1705,11 +1711,12 @@ PF_changelevel (void) return; svs.changelevel_issued = true; - s1 = G_STRING (OFS_PARM0); - s2 = G_STRING (OFS_PARM1); + s1 = G_STRING (pr, OFS_PARM0); + s2 = G_STRING (pr, OFS_PARM1); - if ((int) pr_global_struct->serverflags & (SFL_NEW_UNIT | SFL_NEW_EPISODE)) - Cbuf_AddText (va ("changelevel %s %s\n", s1, s2)); + if ((int) pr->pr_global_struct-> + serverflags & (SFL_NEW_UNIT | SFL_NEW_EPISODE)) + Cbuf_AddText (va ("changelevel %s %s\n", s1, s2)); else Cbuf_AddText (va ("changelevel2 %s %s\n", s1, s2)); #else @@ -1720,7 +1727,7 @@ PF_changelevel (void) return; svs.changelevel_issued = true; - s = G_STRING (OFS_PARM0); + s = G_STRING (pr, OFS_PARM0); Cbuf_AddText (va ("changelevel %s\n", s)); #endif } @@ -1742,7 +1749,7 @@ PF_changelevel (void) #define ATTN_NORM 1 void -PF_WaterMove (void) +PF_WaterMove (progs_t * pr) { edict_t *self; int flags; @@ -1751,51 +1758,51 @@ PF_WaterMove (void) float drownlevel; float damage = 0.0; - self = PROG_TO_EDICT (pr_global_struct->self); + self = PROG_TO_EDICT (pr, pr->pr_global_struct->self); - if (self->v.movetype == MOVETYPE_NOCLIP) { - self->v.air_finished = sv.time + 12; - G_FLOAT (OFS_RETURN) = damage; + if (self->v.v.movetype == MOVETYPE_NOCLIP) { + self->v.v.air_finished = sv.time + 12; + G_FLOAT (pr, OFS_RETURN) = damage; return; } - if (self->v.health < 0) { - G_FLOAT (OFS_RETURN) = damage; + if (self->v.v.health < 0) { + G_FLOAT (pr, OFS_RETURN) = damage; return; } - if (self->v.deadflag == DEAD_NO) + if (self->v.v.deadflag == DEAD_NO) drownlevel = 3; else drownlevel = 1; - flags = (int) self->v.flags; - waterlevel = (int) self->v.waterlevel; - watertype = (int) self->v.watertype; + flags = (int) self->v.v.flags; + waterlevel = (int) self->v.v.waterlevel; + watertype = (int) self->v.v.watertype; if (!(flags & (FL_IMMUNE_WATER + FL_GODMODE))) if (((flags & FL_SWIM) && (waterlevel < drownlevel)) || (waterlevel >= drownlevel)) { - if (self->v.air_finished < sv.time) - if (self->v.pain_finished < sv.time) { - self->v.dmg = self->v.dmg + 2; - if (self->v.dmg > 15) - self->v.dmg = 10; + if (self->v.v.air_finished < sv.time) + if (self->v.v.pain_finished < sv.time) { + self->v.v.dmg = self->v.v.dmg + 2; + if (self->v.v.dmg > 15) + self->v.v.dmg = 10; // T_Damage (self, world, world, self.dmg, 0, FALSE); - damage = self->v.dmg; - self->v.pain_finished = sv.time + 1.0; + damage = self->v.v.dmg; + self->v.v.pain_finished = sv.time + 1.0; } } else { - if (self->v.air_finished < sv.time) + if (self->v.v.air_finished < sv.time) // sound (self, CHAN_VOICE, "player/gasp2.wav", 1, ATTN_NORM); SV_StartSound (self, CHAN_VOICE, "player/gasp2.wav", 255, ATTN_NORM); - else if (self->v.air_finished < sv.time + 9) + else if (self->v.v.air_finished < sv.time + 9) // sound (self, CHAN_VOICE, "player/gasp1.wav", 1, ATTN_NORM); SV_StartSound (self, CHAN_VOICE, "player/gasp1.wav", 255, ATTN_NORM); - self->v.air_finished = sv.time + 12.0; - self->v.dmg = 2; + self->v.v.air_finished = sv.time + 12.0; + self->v.v.dmg = 2; } if (!waterlevel) { @@ -1804,27 +1811,28 @@ PF_WaterMove (void) // sound (self, CHAN_BODY, "misc/outwater.wav", 1, ATTN_NORM); SV_StartSound (self, CHAN_BODY, "misc/outwater.wav", 255, ATTN_NORM); - self->v.flags = (float) (flags & ~FL_INWATER); + self->v.v.flags = (float) (flags & ~FL_INWATER); } - self->v.air_finished = sv.time + 12.0; - G_FLOAT (OFS_RETURN) = damage; + self->v.v.air_finished = sv.time + 12.0; + G_FLOAT (pr, OFS_RETURN) = damage; return; } if (watertype == CONTENT_LAVA) { // do damage if (!(flags & (FL_IMMUNE_LAVA + FL_GODMODE))) - if (self->v.dmgtime < sv.time) { - if (self->v.radsuit_finished < sv.time) - self->v.dmgtime = sv.time + 0.2; + if (self->v.v.dmgtime < sv.time) { + if (self->v.v.radsuit_finished < sv.time) + self->v.v.dmgtime = sv.time + 0.2; else - self->v.dmgtime = sv.time + 1.0; + self->v.v.dmgtime = sv.time + 1.0; // T_Damage (self, world, world, 10*self.waterlevel, 0, TRUE); damage = (float) (10 * waterlevel); } } else if (watertype == CONTENT_SLIME) { // do damage if (!(flags & (FL_IMMUNE_SLIME + FL_GODMODE))) - if (self->v.dmgtime < sv.time && self->v.radsuit_finished < sv.time) { - self->v.dmgtime = sv.time + 1.0; + if (self->v.v.dmgtime < sv.time + && self->v.v.radsuit_finished < sv.time) { + self->v.v.dmgtime = sv.time + 1.0; // T_Damage (self, world, world, 4*self.waterlevel, 0, TRUE); damage = (float) (4 * waterlevel); } @@ -1845,44 +1853,45 @@ PF_WaterMove (void) SV_StartSound (self, CHAN_BODY, "player/slimbrn2.wav", 255, ATTN_NORM); - self->v.flags = (float) (flags | FL_INWATER); - self->v.dmgtime = 0; + self->v.v.flags = (float) (flags | FL_INWATER); + self->v.v.dmgtime = 0; } if (!(flags & FL_WATERJUMP)) { // self.velocity = self.velocity - 0.8*self.waterlevel*frametime*self.velocity; - VectorMA (self->v.velocity, -0.8 * self->v.waterlevel * host_frametime, - self->v.velocity, self->v.velocity); + VectorMA (self->v.v.velocity, + -0.8 * self->v.v.waterlevel * host_frametime, + self->v.v.velocity, self->v.v.velocity); } - G_FLOAT (OFS_RETURN) = damage; + G_FLOAT (pr, OFS_RETURN) = damage; } void -PF_sin (void) +PF_sin (progs_t * pr) { - G_FLOAT (OFS_RETURN) = sin (G_FLOAT (OFS_PARM0)); + G_FLOAT (pr, OFS_RETURN) = sin (G_FLOAT (pr, OFS_PARM0)); } void -PF_cos (void) +PF_cos (progs_t * pr) { - G_FLOAT (OFS_RETURN) = cos (G_FLOAT (OFS_PARM0)); + G_FLOAT (pr, OFS_RETURN) = cos (G_FLOAT (pr, OFS_PARM0)); } void -PF_sqrt (void) +PF_sqrt (progs_t * pr) { - G_FLOAT (OFS_RETURN) = sqrt (G_FLOAT (OFS_PARM0)); + G_FLOAT (pr, OFS_RETURN) = sqrt (G_FLOAT (pr, OFS_PARM0)); } #endif void -PF_Fixme (void) +PF_Fixme (progs_t * pr) { - PR_RunError ("unimplemented bulitin"); + PR_RunError (pr, "unimplemented bulitin"); } @@ -1901,6 +1910,7 @@ builtin_t pr_builtin[] = { // max) setabssize = #5; PF_break, // void() break = // + // // #6; PF_random, // float() random // = #7; @@ -1910,11 +1920,13 @@ builtin_t pr_builtin[] = { // = #9; PF_error, // void(string e) error = // + // // #10; PF_objerror, // void(string e) objerror // = #11; PF_vlen, // float(vector v) vlen = // + // // #12; PF_vectoyaw, // float(vector v) vectoyaw = // #13; @@ -1944,9 +1956,11 @@ builtin_t pr_builtin[] = { // = #25; PF_ftos, // void(string s) ftos = // + // // #26; PF_vtos, // void(string s) vtos = // + // // #27; PF_coredump, PF_traceon, diff --git a/nq/source/pr_edict.c b/nq/source/pr_edict.c index ebd6a7729..5a0172e37 100644 --- a/nq/source/pr_edict.c +++ b/nq/source/pr_edict.c @@ -1,6 +1,6 @@ /* - pr_edict.c + pr->pr_edict.c @description@ @@ -42,26 +42,17 @@ #include "crc.h" #include "world.h" -dprograms_t *progs; -dfunction_t *pr_functions; -char *pr_strings; -ddef_t *pr_fielddefs; -ddef_t *pr_globaldefs; -dstatement_t *pr_statements; -globalvars_t *pr_global_struct; -float *pr_globals; // same as pr_global_struct -int pr_edict_size; // in bytes - -unsigned short pr_crc; - -int type_size[8] = - { 1, sizeof (string_t) / 4, 1, 3, 1, 1, sizeof (func_t) / 4, +int type_size[8] = { + 1, + sizeof (string_t) / 4, + 1, + 3, + 1, + 1, + sizeof (func_t) / 4, sizeof (void *) / 4 }; -ddef_t *ED_FieldAtOfs (int ofs); -qboolean ED_ParseEpair (void *base, ddef_t *key, char *s); - cvar_t *nomonsters; cvar_t *gamecfg; cvar_t *scratch1; @@ -73,6 +64,10 @@ cvar_t *saved1; cvar_t *saved2; cvar_t *saved3; cvar_t *saved4; +cvar_t *pr_boundscheck; + +ddef_t *ED_FieldAtOfs (progs_t * pr, int ofs); +qboolean ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s); #define MAX_FIELD_LEN 64 #define GEFV_CACHESIZE 2 @@ -92,9 +87,9 @@ Sets everything to NULL ================= */ void -ED_ClearEdict (edict_t *e) +ED_ClearEdict (progs_t * pr, edict_t *e) { - memset (&e->v, 0, progs->entityfields * 4); + memset (&e->v, 0, pr->progs->entityfields * 4); e->free = false; } @@ -110,17 +105,17 @@ angles and bad trails. ================= */ edict_t * -ED_Alloc (void) +ED_Alloc (progs_t * pr) { int i; edict_t *e; - for (i = svs.maxclients + 1; i < sv.num_edicts; i++) { - e = EDICT_NUM (i); + for (i = svs.maxclients + 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 - if (e->free && (e->freetime < 2 || sv.time - e->freetime > 0.5)) { - ED_ClearEdict (e); + if (e->free && (e->freetime < 2 || *(pr)->time - e->freetime > 0.5)) { + ED_ClearEdict (pr, e); return e; } } @@ -128,9 +123,9 @@ ED_Alloc (void) if (i == MAX_EDICTS) Sys_Error ("ED_Alloc: no free edicts"); - sv.num_edicts++; - e = EDICT_NUM (i); - ED_ClearEdict (e); + (*(pr)->num_edicts)++; + e = EDICT_NUM (pr, i); + ED_ClearEdict (pr, e); return e; } @@ -144,23 +139,24 @@ FIXME: walk all entities and NULL out references to this entity ================= */ void -ED_Free (edict_t *ed) +ED_Free (progs_t * pr, edict_t *ed) { - SV_UnlinkEdict (ed); // unlink from world bsp + if (pr->unlink) + pr->unlink (ed); // unlink from world bsp ed->free = true; - ed->v.model = 0; - ed->v.takedamage = 0; - ed->v.modelindex = 0; - ed->v.colormap = 0; - ed->v.skin = 0; - ed->v.frame = 0; - VectorCopy (vec3_origin, ed->v.origin); - VectorCopy (vec3_origin, ed->v.angles); - ed->v.nextthink = -1; - ed->v.solid = 0; + 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 = sv.time; + ed->freetime = *(pr)->time; } //=========================================================================== @@ -171,13 +167,13 @@ ED_GlobalAtOfs ============ */ ddef_t * -ED_GlobalAtOfs (int ofs) +ED_GlobalAtOfs (progs_t * pr, int ofs) { ddef_t *def; int i; - for (i = 0; i < progs->numglobaldefs; i++) { - def = &pr_globaldefs[i]; + for (i = 0; i < pr->progs->numglobaldefs; i++) { + def = &pr->pr_globaldefs[i]; if (def->ofs == ofs) return def; } @@ -190,13 +186,13 @@ ED_FieldAtOfs ============ */ ddef_t * -ED_FieldAtOfs (int ofs) +ED_FieldAtOfs (progs_t * pr, int ofs) { ddef_t *def; int i; - for (i = 0; i < progs->numfielddefs; i++) { - def = &pr_fielddefs[i]; + for (i = 0; i < pr->progs->numfielddefs; i++) { + def = &pr->pr_fielddefs[i]; if (def->ofs == ofs) return def; } @@ -209,14 +205,14 @@ ED_FindField ============ */ ddef_t * -ED_FindField (char *name) +ED_FindField (progs_t * pr, char *name) { ddef_t *def; int i; - for (i = 0; i < progs->numfielddefs; i++) { - def = &pr_fielddefs[i]; - if (!strcmp (pr_strings + def->s_name, name)) + for (i = 0; i < pr->progs->numfielddefs; i++) { + def = &pr->pr_fielddefs[i]; + if (!strcmp (PR_GetString (pr, def->s_name), name)) return def; } return NULL; @@ -229,14 +225,14 @@ ED_FindGlobal ============ */ ddef_t * -ED_FindGlobal (char *name) +ED_FindGlobal (progs_t * pr, char *name) { ddef_t *def; int i; - for (i = 0; i < progs->numglobaldefs; i++) { - def = &pr_globaldefs[i]; - if (!strcmp (pr_strings + def->s_name, name)) + for (i = 0; i < pr->progs->numglobaldefs; i++) { + def = &pr->pr_globaldefs[i]; + if (!strcmp (PR_GetString (pr, def->s_name), name)) return def; } return NULL; @@ -249,14 +245,14 @@ ED_FindFunction ============ */ dfunction_t * -ED_FindFunction (char *name) +ED_FindFunction (progs_t * pr, char *name) { dfunction_t *func; int i; - for (i = 0; i < progs->numfunctions; i++) { - func = &pr_functions[i]; - if (!strcmp (pr_strings + func->s_name, name)) + for (i = 0; i < pr->progs->numfunctions; i++) { + func = &pr->pr_functions[i]; + if (!strcmp (PR_GetString (pr, func->s_name), name)) return func; } return NULL; @@ -264,7 +260,7 @@ ED_FindFunction (char *name) eval_t * -GetEdictFieldValue (edict_t *ed, char *field) +GetEdictFieldValue (progs_t * pr, edict_t *ed, char *field) { ddef_t *def = NULL; int i; @@ -277,7 +273,7 @@ GetEdictFieldValue (edict_t *ed, char *field) } } - def = ED_FindField (field); + def = ED_FindField (pr, field); if (strlen (field) < MAX_FIELD_LEN) { gefvCache[rep].pcache = def; @@ -301,7 +297,7 @@ Returns a string describing *data in a type specific manner ============= */ char * -PR_ValueString (etype_t type, eval_t *val) +PR_ValueString (progs_t * pr, etype_t type, eval_t *val) { static char line[256]; ddef_t *def; @@ -311,19 +307,19 @@ PR_ValueString (etype_t type, eval_t *val) switch (type) { case ev_string: - snprintf (line, sizeof (line), "%s", pr_strings + val->string); + snprintf (line, sizeof (line), "%s", PR_GetString (pr, val->string)); break; case ev_entity: snprintf (line, sizeof (line), "entity %i", - NUM_FOR_EDICT (PROG_TO_EDICT (val->edict))); + NUM_FOR_EDICT (pr, PROG_TO_EDICT (pr, val->edict))); break; case ev_function: - f = pr_functions + val->function; - snprintf (line, sizeof (line), "%s()", pr_strings + f->s_name); + f = pr->pr_functions + val->function; + snprintf (line, sizeof (line), "%s()", PR_GetString (pr, f->s_name)); break; case ev_field: - def = ED_FieldAtOfs (val->_int); - snprintf (line, sizeof (line), ".%s", pr_strings + def->s_name); + def = ED_FieldAtOfs (pr, val->_int); + snprintf (line, sizeof (line), ".%s", PR_GetString (pr, def->s_name)); break; case ev_void: snprintf (line, sizeof (line), "void"); @@ -355,7 +351,7 @@ Easier to parse than PR_ValueString ============= */ char * -PR_UglyValueString (etype_t type, eval_t *val) +PR_UglyValueString (progs_t * pr, etype_t type, eval_t *val) { static char line[256]; ddef_t *def; @@ -365,19 +361,19 @@ PR_UglyValueString (etype_t type, eval_t *val) switch (type) { case ev_string: - snprintf (line, sizeof (line), "%s", pr_strings + val->string); + snprintf (line, sizeof (line), "%s", PR_GetString (pr, val->string)); break; case ev_entity: snprintf (line, sizeof (line), "%i", - NUM_FOR_EDICT (PROG_TO_EDICT (val->edict))); + NUM_FOR_EDICT (pr, PROG_TO_EDICT (pr, val->edict))); break; case ev_function: - f = pr_functions + val->function; - snprintf (line, sizeof (line), "%s", pr_strings + f->s_name); + f = pr->pr_functions + val->function; + snprintf (line, sizeof (line), "%s", PR_GetString (pr, f->s_name)); break; case ev_field: - def = ED_FieldAtOfs (val->_int); - snprintf (line, sizeof (line), "%s", pr_strings + def->s_name); + def = ED_FieldAtOfs (pr, val->_int); + snprintf (line, sizeof (line), "%s", PR_GetString (pr, def->s_name)); break; case ev_void: snprintf (line, sizeof (line), "void"); @@ -406,7 +402,7 @@ padded to 20 field width ============ */ char * -PR_GlobalString (int ofs) +PR_GlobalString (progs_t * pr, int ofs) { char *s; int i; @@ -414,14 +410,14 @@ PR_GlobalString (int ofs) void *val; static char line[128]; - val = (void *) &pr_globals[ofs]; - def = ED_GlobalAtOfs (ofs); + val = (void *) &pr->pr_globals[ofs]; + def = ED_GlobalAtOfs (pr, ofs); if (!def) snprintf (line, sizeof (line), "%i(???)", ofs); else { - s = PR_ValueString (def->type, val); + s = PR_ValueString (pr, def->type, val); snprintf (line, sizeof (line), "%i(%s)%s", ofs, - pr_strings + def->s_name, s); + PR_GetString (pr, def->s_name), s); } i = strlen (line); @@ -433,17 +429,18 @@ PR_GlobalString (int ofs) } char * -PR_GlobalStringNoContents (int ofs) +PR_GlobalStringNoContents (progs_t * pr, int ofs) { int i; ddef_t *def; static char line[128]; - def = ED_GlobalAtOfs (ofs); + def = ED_GlobalAtOfs (pr, ofs); if (!def) snprintf (line, sizeof (line), "%i(???)", ofs); else - snprintf (line, sizeof (line), "%i(%s)", ofs, pr_strings + def->s_name); + snprintf (line, sizeof (line), "%i(%s)", ofs, + PR_GetString (pr, def->s_name)); i = strlen (line); for (; i < 20; i++) @@ -462,7 +459,7 @@ For debugging ============= */ void -ED_Print (edict_t *ed) +ED_Print (progs_t * pr, edict_t *ed) { int l; ddef_t *d; @@ -476,10 +473,10 @@ ED_Print (edict_t *ed) return; } - Con_Printf ("\nEDICT %i:\n", NUM_FOR_EDICT (ed)); - for (i = 1; i < progs->numfielddefs; i++) { - d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + 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 @@ -499,7 +496,7 @@ ED_Print (edict_t *ed) while (l++ < 15) Con_Printf (" "); - Con_Printf ("%s\n", PR_ValueString (d->type, (eval_t *) v)); + Con_Printf ("%s\n", PR_ValueString (pr, d->type, (eval_t *) v)); } } @@ -511,7 +508,7 @@ For savegames ============= */ void -ED_Write (QFile *f, edict_t *ed) +ED_Write (progs_t * pr, QFile *f, edict_t *ed) { ddef_t *d; int *v; @@ -526,9 +523,9 @@ ED_Write (QFile *f, edict_t *ed) return; } - for (i = 1; i < progs->numfielddefs; i++) { - d = &pr_fielddefs[i]; - name = pr_strings + d->s_name; + 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 @@ -543,16 +540,16 @@ ED_Write (QFile *f, edict_t *ed) continue; Qprintf (f, "\"%s\" ", name); - Qprintf (f, "\"%s\"\n", PR_UglyValueString (d->type, (eval_t *) v)); + Qprintf (f, "\"%s\"\n", PR_UglyValueString (pr, d->type, (eval_t *) v)); } Qprintf (f, "}\n"); } void -ED_PrintNum (int ent) +ED_PrintNum (progs_t * pr, int ent) { - ED_Print (EDICT_NUM (ent)); + ED_Print (pr, EDICT_NUM (pr, ent)); } /* @@ -563,33 +560,13 @@ For debugging, prints all the entities in the current server ============= */ void -ED_PrintEdicts (void) +ED_PrintEdicts (progs_t * pr) { int i; - Con_Printf ("%i entities\n", sv.num_edicts); - for (i = 0; i < sv.num_edicts; i++) - ED_PrintNum (i); -} - -/* -============= -ED_PrintEdict_f - -For debugging, prints a single edicy -============= -*/ -void -ED_PrintEdict_f (void) -{ - int i; - - i = atoi (Cmd_Argv (1)); - if (i >= sv.num_edicts) { - Con_Printf ("Bad edict number\n"); - return; - } - ED_PrintNum (i); + Con_Printf ("%i entities\n", *(pr)->num_edicts); + for (i = 0; i < *(pr)->num_edicts; i++) + ED_PrintNum (&sv_pr_state, i); } /* @@ -600,27 +577,27 @@ For debugging ============= */ void -ED_Count (void) +ED_Count (progs_t * pr) { int i; edict_t *ent; int active, models, solid, step; active = models = solid = step = 0; - for (i = 0; i < sv.num_edicts; i++) { - ent = EDICT_NUM (i); + for (i = 0; i < *(pr)->num_edicts; i++) { + ent = EDICT_NUM (pr, i); if (ent->free) continue; active++; - if (ent->v.solid) + if (ent->v.v.solid) solid++; - if (ent->v.model) + if (ent->v.v.model) models++; - if (ent->v.movetype == MOVETYPE_STEP) + if (ent->v.v.movetype == MOVETYPE_STEP) step++; } - Con_Printf ("num_edicts:%3i\n", sv.num_edicts); + 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); @@ -643,7 +620,7 @@ ED_WriteGlobals ============= */ void -ED_WriteGlobals (QFile *f) +ED_WriteGlobals (progs_t * pr, QFile *f) { ddef_t *def; int i; @@ -651,8 +628,8 @@ ED_WriteGlobals (QFile *f) int type; Qprintf (f, "{\n"); - for (i = 0; i < progs->numglobaldefs; i++) { - def = &pr_globaldefs[i]; + for (i = 0; i < pr->progs->numglobaldefs; i++) { + def = &pr->pr_globaldefs[i]; type = def->type; if (!(def->type & DEF_SAVEGLOBAL)) continue; @@ -661,10 +638,11 @@ ED_WriteGlobals (QFile *f) if (type != ev_string && type != ev_float && type != ev_entity) continue; - name = pr_strings + def->s_name; + name = PR_GetString (pr, def->s_name); Qprintf (f, "\"%s\" ", name); Qprintf (f, "\"%s\"\n", - PR_UglyValueString (type, (eval_t *) &pr_globals[def->ofs])); + PR_UglyValueString (pr, type, + (eval_t *) &pr->pr_globals[def->ofs])); } Qprintf (f, "}\n"); } @@ -675,7 +653,7 @@ ED_ParseGlobals ============= */ void -ED_ParseGlobals (char *data) +ED_ParseGlobals (progs_t * pr, char *data) { char keyname[64]; ddef_t *key; @@ -698,13 +676,13 @@ ED_ParseGlobals (char *data) if (com_token[0] == '}') Sys_Error ("ED_ParseEntity: closing brace without data"); - key = ED_FindGlobal (keyname); + key = ED_FindGlobal (pr, keyname); if (!key) { Con_Printf ("'%s' is not a global\n", keyname); continue; } - if (!ED_ParseEpair ((void *) pr_globals, key, com_token)) + if (!ED_ParseEpair (pr, (void *) pr->pr_globals, key, com_token)) Host_Error ("ED_ParseGlobals: parse error"); } } @@ -718,7 +696,7 @@ ED_NewString ============= */ char * -ED_NewString (char *string) +ED_NewString (progs_t * pr, char *string) { char *new, *new_p; int i, l; @@ -751,7 +729,7 @@ returns false if error ============= */ qboolean -ED_ParseEpair (void *base, ddef_t *key, char *s) +ED_ParseEpair (progs_t * pr, void *base, ddef_t *key, char *s) { int i; char string[128]; @@ -764,7 +742,7 @@ ED_ParseEpair (void *base, ddef_t *key, char *s) switch (key->type & ~DEF_SAVEGLOBAL) { case ev_string: - *(string_t *) d = ED_NewString (s) - pr_strings; + *(string_t *) d = PR_SetString (pr, ED_NewString (pr, s)); break; case ev_float: @@ -785,25 +763,25 @@ ED_ParseEpair (void *base, ddef_t *key, char *s) break; case ev_entity: - *(int *) d = EDICT_TO_PROG (EDICT_NUM (atoi (s))); + *(int *) d = EDICT_TO_PROG (pr, EDICT_NUM (pr, atoi (s))); break; case ev_field: - def = ED_FindField (s); + def = ED_FindField (pr, s); if (!def) { Con_Printf ("Can't find field %s\n", s); return false; } - *(int *) d = G_INT (def->ofs); + *(int *) d = G_INT (pr, def->ofs); break; case ev_function: - func = ED_FindFunction (s); + func = ED_FindFunction (pr, s); if (!func) { Con_Printf ("Can't find function %s\n", s); return false; } - *(func_t *) d = func - pr_functions; + *(func_t *) d = func - pr->pr_functions; break; default: @@ -822,7 +800,7 @@ Used for initial level load and for savegames. ==================== */ char * -ED_ParseEdict (char *data, edict_t *ent) +ED_ParseEdict (progs_t * pr, char *data, edict_t *ent) { ddef_t *key; qboolean anglehack; @@ -833,8 +811,8 @@ ED_ParseEdict (char *data, edict_t *ent) init = false; // clear it - if (ent != sv.edicts) // hack - memset (&ent->v, 0, progs->entityfields * 4); + if (ent != *(pr)->edicts) // hack + memset (&ent->v, 0, pr->progs->entityfields * 4); // go through all the dictionary pairs while (1) { @@ -881,21 +859,24 @@ ED_ParseEdict (char *data, edict_t *ent) if (keyname[0] == '_') continue; - key = ED_FindField (keyname); + key = ED_FindField (pr, keyname); if (!key) { - Con_Printf ("'%s' is not a field\n", keyname); - continue; + if (!ED_Parse_Extra_Fields (pr, keyname, com_token)) { + Con_Printf ("'%s' is not a field\n", keyname); + continue; + } + } else { + + if (anglehack) { + char temp[32]; + + strcpy (temp, com_token); + snprintf (com_token, sizeof (com_token), "0 %s 0", temp); + } + + if (!ED_ParseEpair (pr, (void *) &ent->v, key, com_token)) + Host_Error ("ED_ParseEdict: parse error"); } - - if (anglehack) { - char temp[32]; - - strcpy (temp, com_token); - snprintf (com_token, sizeof (com_token), "0 %s 0", temp); - } - - if (!ED_ParseEpair ((void *) &ent->v, key, com_token)) - Host_Error ("ED_ParseEdict: parse error"); } if (!init) @@ -921,7 +902,7 @@ to call ED_CallSpawnFunctions () to let the objects initialize themselves. ================ */ void -ED_LoadFromFile (char *data) +ED_LoadFromFile (progs_t * pr, char *data) { edict_t *ent; int inhibit; @@ -929,7 +910,7 @@ ED_LoadFromFile (char *data) ent = NULL; inhibit = 0; - pr_global_struct->time = sv.time; + pr->pr_global_struct->time = *(pr)->time; // parse ents while (1) { @@ -941,15 +922,15 @@ ED_LoadFromFile (char *data) Sys_Error ("ED_LoadFromFile: found %s when expecting {", com_token); if (!ent) - ent = EDICT_NUM (0); + ent = EDICT_NUM (pr, 0); else - ent = ED_Alloc (); - data = ED_ParseEdict (data, ent); + ent = ED_Alloc (pr); + data = ED_ParseEdict (pr, data, ent); // remove things from different skill levels or deathmatch if (deathmatch->int_val) { - if (((int) ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) { - ED_Free (ent); + if (((int) ent->v.v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) { + ED_Free (pr, ent); inhibit++; continue; } @@ -957,36 +938,38 @@ ED_LoadFromFile (char *data) else if ( (current_skill == 0 - && ((int) ent->v.spawnflags & SPAWNFLAG_NOT_EASY)) + && ((int) ent->v.v.spawnflags & SPAWNFLAG_NOT_EASY)) || (current_skill == 1 - && ((int) ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM)) + && ((int) ent->v.v.spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (current_skill >= 2 - && ((int) ent->v.spawnflags & SPAWNFLAG_NOT_HARD))) { - ED_Free (ent); + && ((int) ent->v.v.spawnflags & SPAWNFLAG_NOT_HARD))) { + ED_Free (pr, ent); inhibit++; continue; } // // immediately call spawn function // - if (!ent->v.classname) { + if (!ent->v.v.classname) { Con_Printf ("No classname for:\n"); - ED_Print (ent); - ED_Free (ent); + ED_Print (pr, ent); + ED_Free (pr, ent); continue; } // look for the spawn function - func = ED_FindFunction (pr_strings + ent->v.classname); + func = ED_FindFunction (pr, PR_GetString (pr, ent->v.v.classname)); if (!func) { Con_Printf ("No spawn function for:\n"); - ED_Print (ent); - ED_Free (ent); + ED_Print (pr, ent); + ED_Free (pr, ent); continue; } - pr_global_struct->self = EDICT_TO_PROG (ent); - PR_ExecuteProgram (func - pr_functions); + pr->pr_global_struct->self = EDICT_TO_PROG (pr, ent); + PR_ExecuteProgram (pr, func - pr->pr_functions); + if (pr->flush) + pr->flush (); } Con_DPrintf ("%i entities inhibited\n", inhibit); @@ -999,82 +982,212 @@ PR_LoadProgs =============== */ void -PR_LoadProgs (void) +PR_LoadProgs (progs_t * pr, char *progsname) { int i; + dstatement_t *st; // flush the non-C variable lookup cache for (i = 0; i < GEFV_CACHESIZE; i++) gefvCache[i].field[0] = 0; - CRC_Init (&pr_crc); + pr->progs = (dprograms_t *) COM_LoadHunkFile (progsname); + if (!pr->progs) + return; - progs = (dprograms_t *) COM_LoadHunkFile ("progs.dat"); - if (!progs) - Sys_Error ("PR_LoadProgs: couldn't load progs.dat"); Con_DPrintf ("Programs occupy %iK.\n", com_filesize / 1024); - for (i = 0; i < com_filesize; i++) - CRC_ProcessByte (&pr_crc, ((byte *) progs)[i]); +// store prog crc + pr->crc = CRC_Block ((byte *) pr->progs, com_filesize); // byte swap the header - for (i = 0; i < sizeof (*progs) / 4; i++) - ((int *) progs)[i] = LittleLong (((int *) progs)[i]); + for (i = 0; i < sizeof (*pr->progs) / 4; i++) + ((int *) pr->progs)[i] = LittleLong (((int *) pr->progs)[i]); - if (progs->version != PROG_VERSION) + if (pr->progs->version != PROG_VERSION) Sys_Error ("progs.dat has wrong version number (%i should be %i)", - progs->version, PROG_VERSION); - if (progs->crc != PROGHEADER_CRC) - Sys_Error - ("progs.dat system vars have been modified, progdefs.h is out of date"); + pr->progs->version, PROG_VERSION); + if (pr->progs->crc != PROGHEADER_CRC) + Sys_Error ("You must have the qwprogs.dat from QuakeWorld installed"); - pr_functions = (dfunction_t *) ((byte *) progs + progs->ofs_functions); - pr_strings = (char *) progs + progs->ofs_strings; - pr_globaldefs = (ddef_t *) ((byte *) progs + progs->ofs_globaldefs); - pr_fielddefs = (ddef_t *) ((byte *) progs + progs->ofs_fielddefs); - pr_statements = (dstatement_t *) ((byte *) progs + progs->ofs_statements); + 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_global_struct = (globalvars_t *) ((byte *) progs + progs->ofs_globals); - pr_globals = (float *) pr_global_struct; + pr->num_prstr = 0; - pr_edict_size = + pr->pr_global_struct = + (globalvars_t *) ((byte *) pr->progs + pr->progs->ofs_globals); + pr->pr_globals = (pr_type_t *) pr->pr_global_struct; - progs->entityfields * 4 + sizeof (edict_t) - sizeof (entvars_t); + pr->pr_edict_size = + + pr->progs->entityfields * 4 + sizeof (edict_t) - sizeof (entvars_t); + + pr->pr_edictareasize = pr->pr_edict_size * MAX_EDICTS; // byte swap the lumps - for (i = 0; i < progs->numstatements; i++) { - pr_statements[i].op = LittleShort (pr_statements[i].op); - pr_statements[i].a = LittleShort (pr_statements[i].a); - pr_statements[i].b = LittleShort (pr_statements[i].b); - pr_statements[i].c = LittleShort (pr_statements[i].c); + for (i = 0; i < pr->progs->numstatements; i++) { + pr->pr_statements[i].op = LittleShort (pr->pr_statements[i].op); + pr->pr_statements[i].a = LittleShort (pr->pr_statements[i].a); + pr->pr_statements[i].b = LittleShort (pr->pr_statements[i].b); + pr->pr_statements[i].c = LittleShort (pr->pr_statements[i].c); } - for (i = 0; i < progs->numfunctions; i++) { - pr_functions[i].first_statement = - LittleLong (pr_functions[i].first_statement); - pr_functions[i].parm_start = LittleLong (pr_functions[i].parm_start); - pr_functions[i].s_name = LittleLong (pr_functions[i].s_name); - pr_functions[i].s_file = LittleLong (pr_functions[i].s_file); - pr_functions[i].numparms = LittleLong (pr_functions[i].numparms); - pr_functions[i].locals = LittleLong (pr_functions[i].locals); + 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].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].locals = LittleLong (pr->pr_functions[i].locals); } - for (i = 0; i < progs->numglobaldefs; i++) { - pr_globaldefs[i].type = LittleShort (pr_globaldefs[i].type); - pr_globaldefs[i].ofs = LittleShort (pr_globaldefs[i].ofs); - pr_globaldefs[i].s_name = LittleLong (pr_globaldefs[i].s_name); + for (i = 0; i < pr->progs->numglobaldefs; i++) { + pr->pr_globaldefs[i].type = LittleShort (pr->pr_globaldefs[i].type); + pr->pr_globaldefs[i].ofs = LittleShort (pr->pr_globaldefs[i].ofs); + pr->pr_globaldefs[i].s_name = LittleLong (pr->pr_globaldefs[i].s_name); } - for (i = 0; i < progs->numfielddefs; i++) { - pr_fielddefs[i].type = LittleShort (pr_fielddefs[i].type); - if (pr_fielddefs[i].type & DEF_SAVEGLOBAL) + 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) Sys_Error ("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); - pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); - pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); + pr->pr_fielddefs[i].ofs = LittleShort (pr->pr_fielddefs[i].ofs); + pr->pr_fielddefs[i].s_name = LittleLong (pr->pr_fielddefs[i].s_name); } - for (i = 0; i < progs->numglobals; i++) - ((int *) pr_globals)[i] = LittleLong (((int *) pr_globals)[i]); + 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); + + // 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) + Sys_Error + ("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) + Sys_Error + ("PR_LoadProgs: out of bounds GOTO (statement %d)\n", i); + break; + // global global global + case OP_ADD_F: + case OP_ADD_V: + case OP_SUB_F: + case OP_SUB_V: + case OP_MUL_F: + case OP_MUL_V: + case OP_MUL_FV: + case OP_MUL_VF: + case OP_DIV_F: + case OP_BITAND: + case OP_BITOR: + case OP_GE: + case OP_LE: + case OP_GT: + case OP_LT: + case OP_AND: + case OP_OR: + case OP_EQ_F: + case OP_EQ_V: + case OP_EQ_S: + case OP_EQ_E: + case OP_EQ_FNC: + case OP_NE_F: + case OP_NE_V: + case OP_NE_S: + case OP_NE_E: + case OP_NE_FNC: + case OP_ADDRESS: + case OP_LOAD_F: + case OP_LOAD_FLD: + case OP_LOAD_ENT: + case OP_LOAD_S: + case OP_LOAD_FNC: + case OP_LOAD_V: + if ((unsigned short) st->a >= pr->progs->numglobals + || (unsigned short) st->b >= pr->progs->numglobals + || (unsigned short) st->c >= pr->progs->numglobals) + Sys_Error + ("PR_LoadProgs: out of bounds global index (statement %d)\n", + i); + break; + // global none global + case OP_NOT_F: + case OP_NOT_V: + case OP_NOT_S: + case OP_NOT_FNC: + case OP_NOT_ENT: + if ((unsigned short) st->a >= pr->progs->numglobals + || (unsigned short) st->c >= pr->progs->numglobals) + Sys_Error + ("PR_LoadProgs: out of bounds global index (statement %d)\n", + i); + break; + // 2 globals + case OP_STOREP_F: + case OP_STOREP_ENT: + case OP_STOREP_FLD: + case OP_STOREP_S: + case OP_STOREP_FNC: + case OP_STORE_F: + case OP_STORE_ENT: + case OP_STORE_FLD: + case OP_STORE_S: + case OP_STORE_FNC: + case OP_STATE: + case OP_STOREP_V: + case OP_STORE_V: + if ((unsigned short) st->a >= pr->progs->numglobals + || (unsigned short) st->b >= pr->progs->numglobals) + Sys_Error + ("PR_LoadProgs: out of bounds global index (statement %d)\n", + i); + break; + // 1 global + 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: + case OP_DONE: + case OP_RETURN: + if ((unsigned short) st->a >= pr->progs->numglobals) + Sys_Error + ("PR_LoadProgs: out of bounds global index (statement %d)\n", + i); + break; + default: + Sys_Error ("PR_LoadProgs: unknown opcode %d at statement %d\n", + st->op, i); + break; + } + } + + FindEdictFieldOffsets (pr); // LordHavoc: update field offset + // list } @@ -1086,10 +1199,10 @@ PR_Init void PR_Init (void) { - Cmd_AddCommand ("edict", ED_PrintEdict_f, "No Description"); - Cmd_AddCommand ("edicts", ED_PrintEdicts, "No Description"); - Cmd_AddCommand ("edictcount", ED_Count, "No Description"); Cmd_AddCommand ("profile", PR_Profile_f, "No Description"); + pr_boundscheck = + Cvar_Get ("pr_boundscheck", "1", CVAR_NONE, + "Server progs bounds checking"); nomonsters = Cvar_Get ("nomonsters", "0", CVAR_NONE, "None"); gamecfg = Cvar_Get ("gamecfg", "0", CVAR_NONE, "None"); scratch1 = Cvar_Get ("scratch1", "0", CVAR_NONE, "None"); @@ -1106,22 +1219,22 @@ PR_Init (void) edict_t * -EDICT_NUM (int n) +EDICT_NUM (progs_t * pr, int n) { - if (n < 0 || n >= sv.max_edicts) + if (n < 0 || n >= MAX_EDICTS) Sys_Error ("EDICT_NUM: bad number %i", n); - return (edict_t *) ((byte *) sv.edicts + (n) * pr_edict_size); + return (edict_t *) ((byte *) * (pr)->edicts + (n) * pr->pr_edict_size); } int -NUM_FOR_EDICT (edict_t *e) +NUM_FOR_EDICT (progs_t * pr, edict_t *e) { int b; - b = (byte *) e - (byte *) sv.edicts; - b = b / pr_edict_size; + b = (byte *) e - (byte *) * (pr)->edicts; + b = b / pr->pr_edict_size; - if (b < 0 || b >= sv.num_edicts) + if (b < 0 || b >= *(pr)->num_edicts) Sys_Error ("NUM_FOR_EDICT: bad pointer"); return b; } diff --git a/nq/source/pr_exec.c b/nq/source/pr_exec.c index ad87df0d4..8bf0794e0 100644 --- a/nq/source/pr_exec.c +++ b/nq/source/pr_exec.c @@ -1,7 +1,7 @@ /* pr_exec.c - @description@ + (description) Copyright (C) 1996-1997 Id Software, Inc. @@ -29,39 +29,21 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif +#ifdef HAVE_STRING_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif #include +#include "console.h" +#include "cvar.h" +#include "host.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", @@ -151,23 +133,17 @@ char *pr_opnames[] = { "BITOR" }; -char *PR_GlobalString (int ofs); -char *PR_GlobalStringNoContents (int ofs); - - //============================================================================= /* -================= -PR_PrintStatement -================= + PR_PrintStatement */ void -PR_PrintStatement (dstatement_t *s) +PR_PrintStatement (progs_t * pr, dstatement_t *s) { int i; - if ((unsigned) s->op < sizeof (pr_opnames) / sizeof (pr_opnames[0])) { + if ((unsigned int) 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++) @@ -175,60 +151,58 @@ PR_PrintStatement (dstatement_t *s) } if (s->op == OP_IF || s->op == OP_IFNOT) - Con_Printf ("%sbranch %i", PR_GlobalString (s->a), s->b); + Con_Printf ("%sbranch %i", PR_GlobalString (pr, (unsigned short) 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 ((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)); } else { if (s->a) - Con_Printf ("%s", PR_GlobalString (s->a)); + Con_Printf ("%s", PR_GlobalString (pr, (unsigned short) s->a)); if (s->b) - Con_Printf ("%s", PR_GlobalString (s->b)); + Con_Printf ("%s", PR_GlobalString (pr, (unsigned short) s->b)); if (s->c) - Con_Printf ("%s", PR_GlobalStringNoContents (s->c)); + Con_Printf ("%s", + PR_GlobalStringNoContents (pr, (unsigned short) s->c)); } Con_Printf ("\n"); } /* -============ -PR_StackTrace -============ + PR_StackTrace */ void -PR_StackTrace (void) +PR_StackTrace (progs_t * pr) { dfunction_t *f; int i; - if (pr_depth == 0) { + if (pr->pr_depth == 0) { Con_Printf ("\n"); return; } - pr_stack[pr_depth].f = pr_xfunction; - for (i = pr_depth; i >= 0; i--) { - f = pr_stack[i].f; + pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction; + for (i = pr->pr_depth; i >= 0; i--) { + f = pr->pr_stack[i].f; if (!f) { Con_Printf ("\n"); } else - Con_Printf ("%12s : %s\n", pr_strings + f->s_file, - pr_strings + f->s_name); + Con_Printf ("%12s : %s\n", PR_GetString (pr, f->s_file), + PR_GetString (pr, f->s_name)); } } /* -============ -PR_Profile_f - -============ + PR_Profile */ void -PR_Profile_f (void) +PR_Profile (progs_t * pr) { dfunction_t *f, *best; int max; @@ -239,8 +213,8 @@ PR_Profile_f (void) do { max = 0; best = NULL; - for (i = 0; i < progs->numfunctions; i++) { - f = &pr_functions[i]; + for (i = 0; i < pr->progs->numfunctions; i++) { + f = &pr->pr_functions[i]; if (f->profile > max) { max = f->profile; best = f; @@ -249,23 +223,20 @@ PR_Profile_f (void) if (best) { if (num < 10) Con_Printf ("%7i %s\n", best->profile, - pr_strings + best->s_name); + PR_GetString (pr, best->s_name)); num++; best->profile = 0; } } while (best); } - /* -============ -PR_RunError + PR_RunError -Aborts the currently executing function -============ + Aborts the currently executing function */ void -PR_RunError (char *error, ...) +PR_RunError (progs_t * pr, char *error, ...) { va_list argptr; char string[1024]; @@ -274,286 +245,270 @@ PR_RunError (char *error, ...) vsnprintf (string, sizeof (string), error, argptr); va_end (argptr); - PR_PrintStatement (pr_statements + pr_xstatement); - PR_StackTrace (); + PR_PrintStatement (pr, pr->pr_statements + pr->pr_xstatement); + PR_StackTrace (pr); Con_Printf ("%s\n", string); - pr_depth = 0; // dump the stack so host_error can + pr->pr_depth = 0; // dump the stack so Host_Error can // shutdown functions Host_Error ("Program error"); } /* -============================================================================ -PR_ExecuteProgram + PR_ExecuteProgram -The interpretation main loop -============================================================================ + The interpretation main loop */ /* -==================== -PR_EnterFunction + PR_EnterFunction -Returns the new program statement counter -==================== + Returns the new program statement counter */ int -PR_EnterFunction (dfunction_t *f) +PR_EnterFunction (progs_t * pr, 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"); + pr->pr_stack[pr->pr_depth].s = pr->pr_xstatement; + pr->pr_stack[pr->pr_depth].f = pr->pr_xfunction; + pr->pr_depth++; + if (pr->pr_depth >= MAX_STACK_DEPTH) + PR_RunError (pr, "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"); + if (pr->localstack_used + c > LOCALSTACK_SIZE) + PR_RunError (pr, "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; + pr->localstack[pr->localstack_used + i] = + ((int *) pr->pr_globals)[f->parm_start + i]; + pr->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]; + + ((int *) pr->pr_globals)[o] = + ((int *) pr->pr_globals)[OFS_PARM0 + i * 3 + j]; o++; } } - pr_xfunction = f; + pr->pr_xfunction = f; return f->first_statement - 1; // offset the s++ } /* -==================== -PR_LeaveFunction -==================== + PR_LeaveFunction */ int -PR_LeaveFunction (void) +PR_LeaveFunction (progs_t * pr) { int i, c; - if (pr_depth <= 0) - Sys_Error ("prog stack underflow"); + if (pr->pr_depth <= 0) + Host_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"); + c = pr->pr_xfunction->locals; + pr->localstack_used -= c; + if (pr->localstack_used < 0) + PR_RunError (pr, "PR_ExecuteProgram: locals stack underflow\n"); for (i = 0; i < c; i++) - ((int *) pr_globals)[pr_xfunction->parm_start + i] = - localstack[localstack_used + i]; + ((int *) pr->pr_globals)[pr->pr_xfunction->parm_start + i] = + pr->localstack[pr->localstack_used + i]; // up stack - pr_depth--; - pr_xfunction = pr_stack[pr_depth].f; - return pr_stack[pr_depth].s; + pr->pr_depth--; + pr->pr_xfunction = pr->pr_stack[pr->pr_depth].f; + return pr->pr_stack[pr->pr_depth].s; } /* -==================== -PR_ExecuteProgram -==================== + 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]) + +extern cvar_t *pr_boundscheck; + void -PR_ExecuteProgram (func_t fnum) +PR_ExecuteProgram (progs_t * pr, 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; + int profile, startprofile; - 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)); + if (!fnum || fnum >= pr->progs->numfunctions) { + if (pr->pr_global_struct->self) + ED_Print (pr, PROG_TO_EDICT (pr, pr->pr_global_struct->self)); Host_Error ("PR_ExecuteProgram: NULL function"); } - f = &pr_functions[fnum]; + f = &pr->pr_functions[fnum]; - runaway = 100000; - pr_trace = false; + pr->pr_trace = false; // make a stack frame - exitdepth = pr_depth; + exitdepth = pr->pr_depth; - s = PR_EnterFunction (f); + st = &pr->pr_statements[PR_EnterFunction (pr, f)]; + startprofile = profile = 0; while (1) { - s++; // next statement + st++; + if (++profile > 1000000) // LordHavoc: increased runaway loop + // limit 10x + { + pr->pr_xstatement = st - pr->pr_statements; + PR_RunError (pr, "runaway loop error"); + } - 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); + if (pr->pr_trace) + PR_PrintStatement (pr, st); switch (st->op) { case OP_ADD_F: - c->_float = a->_float + b->_float; + OPC->_float = OPA->_float + OPB->_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]; + 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]; break; - case OP_SUB_F: - c->_float = a->_float - b->_float; + OPC->_float = OPA->_float - OPB->_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]; + 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]; break; - case OP_MUL_F: - c->_float = a->_float * b->_float; + OPC->_float = OPA->_float * OPB->_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]; + OPC->_float = + OPA->vector[0] * OPB->vector[0] + + OPA->vector[1] * OPB->vector[1] + + OPA->vector[2] * OPB->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]; + OPC->vector[0] = OPA->_float * OPB->vector[0]; + OPC->vector[1] = OPA->_float * OPB->vector[1]; + OPC->vector[2] = OPA->_float * OPB->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]; + OPC->vector[0] = OPB->_float * OPA->vector[0]; + OPC->vector[1] = OPB->_float * OPA->vector[1]; + OPC->vector[2] = OPB->_float * OPA->vector[2]; break; - case OP_DIV_F: - c->_float = a->_float / b->_float; + OPC->_float = OPA->_float / OPB->_float; break; - case OP_BITAND: - c->_float = (int) a->_float & (int) b->_float; + OPC->_float = (int) OPA->_float & (int) OPB->_float; break; - case OP_BITOR: - c->_float = (int) a->_float | (int) b->_float; + OPC->_float = (int) OPA->_float | (int) OPB->_float; break; - - case OP_GE: - c->_float = a->_float >= b->_float; + OPC->_float = OPA->_float >= OPB->_float; break; case OP_LE: - c->_float = a->_float <= b->_float; + OPC->_float = OPA->_float <= OPB->_float; break; case OP_GT: - c->_float = a->_float > b->_float; + OPC->_float = OPA->_float > OPB->_float; break; case OP_LT: - c->_float = a->_float < b->_float; + OPC->_float = OPA->_float < OPB->_float; break; case OP_AND: - c->_float = a->_float && b->_float; + OPC->_float = OPA->_float && OPB->_float; break; case OP_OR: - c->_float = a->_float || b->_float; + OPC->_float = OPA->_float || OPB->_float; break; - case OP_NOT_F: - c->_float = !a->_float; + OPC->_float = !OPA->_float; break; case OP_NOT_V: - c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2]; + OPC->_float = !OPA->vector[0] && !OPA->vector[1] + && !OPA->vector[2]; break; case OP_NOT_S: - c->_float = !a->string || !pr_strings[a->string]; + OPC->_float = !OPA->string || !*PR_GetString (pr, OPA->string); break; case OP_NOT_FNC: - c->_float = !a->function; + OPC->_float = !OPA->function; break; case OP_NOT_ENT: - c->_float = (PROG_TO_EDICT (a->edict) == sv.edicts); + OPC->_float = (PROG_TO_EDICT (pr, OPA->edict) == *pr->edicts); break; - case OP_EQ_F: - c->_float = a->_float == b->_float; + OPC->_float = OPA->_float == OPB->_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]); + OPC->_float = (OPA->vector[0] == OPB->vector[0]) + && (OPA->vector[1] == OPB->vector[1]) + && (OPA->vector[2] == OPB->vector[2]); break; case OP_EQ_S: - c->_float = - !strcmp (pr_strings + a->string, pr_strings + b->string); + OPC->_float = + !strcmp (PR_GetString (pr, OPA->string), + PR_GetString (pr, OPB->string)); break; case OP_EQ_E: - c->_float = a->_int == b->_int; + OPC->_float = OPA->_int == OPB->_int; break; case OP_EQ_FNC: - c->_float = a->function == b->function; + OPC->_float = OPA->function == OPB->function; break; - - case OP_NE_F: - c->_float = a->_float != b->_float; + OPC->_float = OPA->_float != OPB->_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]); + OPC->_float = (OPA->vector[0] != OPB->vector[0]) + || (OPA->vector[1] != OPB->vector[1]) + || (OPA->vector[2] != OPB->vector[2]); break; case OP_NE_S: - c->_float = strcmp (pr_strings + a->string, pr_strings + b->string); + OPC->_float = + strcmp (PR_GetString (pr, OPA->string), + PR_GetString (pr, OPB->string)); break; case OP_NE_E: - c->_float = a->_int != b->_int; + OPC->_float = OPA->_int != OPB->_int; break; case OP_NE_FNC: - c->_float = a->function != b->function; + OPC->_float = OPA->function != 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 - b->_int = a->_int; + OPB->_int = OPA->_int; break; case OP_STORE_V: - b->vector[0] = a->vector[0]; - b->vector[1] = a->vector[1]; - b->vector[2] = a->vector[2]; + OPB->vector[0] = OPA->vector[0]; + OPB->vector[1] = OPA->vector[1]; + OPB->vector[2] = OPA->vector[2]; break; case OP_STOREP_F: @@ -561,66 +516,126 @@ PR_ExecuteProgram (func_t fnum) 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; + if (pr_boundscheck->int_val + && (OPB->_int < 0 || 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 < + ((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; 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]; + if (pr_boundscheck->int_val + && (OPB->_int < 0 || 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"); + 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]; 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; + if (pr_boundscheck->int_val + && (OPA->edict < 0 || 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)) { + 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)) { + pr->pr_xstatement = st - pr->pr_statements; + PR_RunError + (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; 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; + if (pr_boundscheck->int_val + && (OPA->edict < 0 || 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)) { + 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; 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]; + if (pr_boundscheck->int_val + && (OPA->edict < 0 || 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 + 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"); + 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]; break; - -//================== - + // ================== case OP_IFNOT: - if (!a->_int) - s += st->b - 1; // offset the s++ + if (!OPA->_int) + st += st->b - 1; // offset the s++ break; - case OP_IF: - if (a->_int) - s += st->b - 1; // offset the s++ + if (OPA->_int) + st += st->b - 1; // offset the s++ break; - case OP_GOTO: - s += st->a - 1; // offset the s++ + st += st->a - 1; // offset the s++ break; - case OP_CALL0: case OP_CALL1: case OP_CALL2: @@ -630,51 +645,349 @@ PR_ExecuteProgram (func_t fnum) 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 + pr->pr_xfunction->profile += profile - startprofile; + startprofile = profile; + pr->pr_xstatement = st - pr->pr_statements; + pr->pr_argc = st->op - OP_CALL0; + if (!OPA->function) + PR_RunError (pr, "NULL function"); + newf = &pr->pr_functions[OPA->function]; + if (newf->first_statement < 0) { // negative + // statements are // built in functions - i = -newf->first_statement; + int i = -newf->first_statement; + if (i >= pr_numbuiltins) - PR_RunError ("Bad builtin call number"); - pr_builtins[i] (); + PR_RunError (pr, "Bad builtin call number"); + pr_builtins[i] (pr); break; } - s = PR_EnterFunction (newf); + st = &pr->pr_statements[PR_EnterFunction (pr, 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) + 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]; + st = &pr->pr_statements[PR_LeaveFunction (pr)]; + if (pr->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; + 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; 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; + break; + case OP_ADD_IF: + OPC->_int = OPA->_int + (int) OPB->_float; + break; + case OP_ADD_FI: + OPC->_float = OPA->_float + (float) OPB->_int; + break; + case OP_SUB_I: + OPC->_int = OPA->_int - OPB->_int; + break; + case OP_SUB_IF: + OPC->_int = OPA->_int - (int) OPB->_float; + break; + case OP_SUB_FI: + OPC->_float = OPA->_float - (float) OPB->_int; + break; + case OP_MUL_I: + OPC->_int = OPA->_int * OPB->_int; + break; + case OP_MUL_IF: + OPC->_int = OPA->_int * (int) OPB->_float; + break; + case OP_MUL_FI: + OPC->_float = OPA->_float * (float) 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]; + break; + case OP_DIV_VF: + { + float temp = 1.0f / OPB->_float; + OPC->vector[0] = temp * OPA->vector[0]; + OPC->vector[1] = temp * OPA->vector[1]; + OPC->vector[2] = temp * OPA->vector[2]; + } + break; + case OP_DIV_I: + OPC->_int = OPA->_int / OPB->_int; + break; + case OP_DIV_IF: + OPC->_int = OPA->_int / (int) OPB->_float; + break; + case OP_DIV_FI: + OPC->_float = OPA->_float / (float) OPB->_int; + break; + case OP_CONV_IF: + OPC->_float = OPA->_int; + break; + case OP_CONV_FI: + OPC->_int = OPA->_float; + break; + case OP_BITAND_I: + OPC->_int = OPA->_int & OPB->_int; + break; + case OP_BITOR_I: + OPC->_int = OPA->_int | OPB->_int; + break; + case OP_BITAND_IF: + OPC->_int = OPA->_int & (int) OPB->_float; + break; + case OP_BITOR_IF: + OPC->_int = OPA->_int | (int) OPB->_float; + break; + case OP_BITAND_FI: + OPC->_float = (int) OPA->_float & OPB->_int; + break; + case OP_BITOR_FI: + OPC->_float = (int) OPA->_float | OPB->_int; + break; + case OP_GE_I: + OPC->_float = OPA->_int >= OPB->_int; + break; + case OP_LE_I: + OPC->_float = OPA->_int <= OPB->_int; + break; + case OP_GT_I: + OPC->_float = OPA->_int > OPB->_int; + break; + case OP_LT_I: + OPC->_float = OPA->_int < OPB->_int; + break; + case OP_AND_I: + OPC->_float = OPA->_int && OPB->_int; + break; + case OP_OR_I: + OPC->_float = OPA->_int || OPB->_int; + break; + case OP_GE_IF: + OPC->_float = (float) OPA->_int >= OPB->_float; + break; + case OP_LE_IF: + OPC->_float = (float) OPA->_int <= OPB->_float; + break; + case OP_GT_IF: + OPC->_float = (float) OPA->_int > OPB->_float; + break; + case OP_LT_IF: + OPC->_float = (float) OPA->_int < OPB->_float; + break; + case OP_AND_IF: + OPC->_float = (float) OPA->_int && OPB->_float; + break; + case OP_OR_IF: + OPC->_float = (float) OPA->_int || OPB->_float; + break; + case OP_GE_FI: + OPC->_float = OPA->_float >= (float) OPB->_int; + break; + case OP_LE_FI: + OPC->_float = OPA->_float <= (float) OPB->_int; + break; + case OP_GT_FI: + OPC->_float = OPA->_float > (float) OPB->_int; + break; + case OP_LT_FI: + OPC->_float = OPA->_float < (float) OPB->_int; + break; + case OP_AND_FI: + OPC->_float = OPA->_float && (float) OPB->_int; + break; + case OP_OR_FI: + OPC->_float = OPA->_float || (float) OPB->_int; + break; + case OP_NOT_I: + OPC->_float = !OPA->_int; + break; + case OP_EQ_I: + OPC->_float = OPA->_int == OPB->_int; + break; + case OP_EQ_IF: + OPC->_float = (float) OPA->_int == OPB->_float; + break; + case OP_EQ_FI: + OPC->_float = OPA->_float == (float) OPB->_int; + break; + case OP_NE_I: + OPC->_float = OPA->_int != OPB->_int; + break; + case OP_NE_IF: + OPC->_float = (float) OPA->_int != OPB->_float; + break; + case OP_NE_FI: + OPC->_float = OPA->_float != (float) OPB->_int; + break; + case OP_STORE_I: + OPB->_int = OPA->_int; + break; + case OP_STOREP_I: + if (pr_boundscheck->int_val + && (OPB->_int < 0 || 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 < + ((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; + break; + case OP_LOAD_I: + if (pr_boundscheck->int_val + && (OPA->edict < 0 || 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)) { + 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; + break; + + case OP_GSTOREP_I: + case OP_GSTOREP_F: + case OP_GSTOREP_ENT: + case OP_GSTOREP_FLD: // integers + case OP_GSTOREP_S: + case OP_GSTOREP_FNC: // pointers + if (pr_boundscheck->int_val + && (OPB->_int < 0 || 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; + break; + case OP_GSTOREP_V: + if (pr_boundscheck->int_val + && (OPB->_int < 0 || 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]; + break; + + case OP_GADDRESS: + i = OPA->_int + (int) OPB->_float; + if (pr_boundscheck->int_val + && (i < 0 || i >= pr->pr_globaldefs)) { + pr->pr_xstatement = st - pr->pr_statements; + PR_RunError + (pr, "Progs attempted to address an out of bounds global\n"); + return; + } + OPC->_float = pr->pr_globals[i]; + break; + + case OP_GLOAD_I: + case OP_GLOAD_F: + case OP_GLOAD_FLD: + case OP_GLOAD_ENT: + case OP_GLOAD_S: + case OP_GLOAD_FNC: + if (pr_boundscheck->int_val + && (OPA->_int < 0 || 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]; + break; + + case OP_GLOAD_V: + if (pr_boundscheck->int_val + && (OPA->_int < 0 || 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]; + break; + + case OP_BOUNDCHECK: + if (OPA->_int < 0 || 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", + st->b, st->c); + return; + } + break; + +*/ default: - PR_RunError ("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) +{ + if (num < 0) { + // Con_DPrintf("GET:%d == %s\n", num, pr->pr_strtbl[-num]); + return pr->pr_strtbl[-num]; + } + return pr->pr_strings + num; +} + +int +PR_SetString (progs_t * pr, char *s) +{ + int i; + + if (s - pr->pr_strings < 0) { + for (i = 0; i <= pr->num_prstr; i++) + if (pr->pr_strtbl[i] == s) + break; + if (i < pr->num_prstr) + return -i; + if (pr->num_prstr == MAX_PRSTR - 1) + Sys_Error ("MAX_PRSTR"); + pr->num_prstr++; + pr->pr_strtbl[pr->num_prstr] = s; + // Con_DPrintf("SET:%d == %s\n", -pr->num_prstr, s); + return -pr->num_prstr; + } + return (int) (s - pr->pr_strings); } diff --git a/nq/source/pr_offs.c b/nq/source/pr_offs.c new file mode 100644 index 000000000..1f4ec44f4 --- /dev/null +++ b/nq/source/pr_offs.c @@ -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); +} diff --git a/nq/source/sv_main.c b/nq/source/sv_main.c index 5a80f56d6..45e87fd0c 100644 --- a/nq/source/sv_main.c +++ b/nq/source/sv_main.c @@ -157,7 +157,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 +178,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])); + entity->v.v.origin[i] + 0.5 * (entity->v.v.mins[i] + + entity->v.v.maxs[i])); } /* @@ -206,7 +206,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 +218,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), + sv_pr_state.pr_strings + sv.edicts->v.v.message); MSG_WriteString (&client->message, message); @@ -232,12 +233,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, sv.edicts->v.v.sounds); + MSG_WriteByte (&client->message, sv.edicts->v.v.sounds); // 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 +272,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 +296,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_pr_state.pr_global_struct->SetNewParms); 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); @@ -444,15 +447,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 (clent->v.v.origin, clent->v.v.view_ofs, 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 (ent->v.v.effects == EF_NODRAW) continue; #endif @@ -460,7 +463,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 (!ent->v.v.modelindex || !sv_pr_state.pr_strings[ent->v.v.model]) continue; for (i = 0; i < ent->num_leafs; i++) @@ -479,36 +482,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 = ent->v.v.origin[i] - ent->baseline.origin[i]; if (miss < -0.1 || miss > 0.1) 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; - if (ent->v.angles[1] != ent->baseline.angles[1]) + if (ent->v.v.angles[1] != ent->baseline.angles[1]) 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; - if (ent->v.movetype == MOVETYPE_STEP) + if (ent->v.v.movetype == MOVETYPE_STEP) 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; - if (ent->baseline.skin != ent->v.skin) + if (ent->baseline.skin != ent->v.v.skin) bits |= U_SKIN; - if (ent->baseline.frame != ent->v.frame) + if (ent->baseline.frame != ent->v.v.frame) bits |= U_FRAME; - if (ent->baseline.effects != ent->v.effects) + if (ent->baseline.effects != ent->v.v.effects) bits |= U_EFFECTS; - if (ent->baseline.modelindex != ent->v.modelindex) + if (ent->baseline.modelindex != ent->v.v.modelindex) bits |= U_MODEL; if (e >= 256) @@ -530,27 +533,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, ent->v.v.modelindex); if (bits & U_FRAME) - MSG_WriteByte (msg, ent->v.frame); + MSG_WriteByte (msg, ent->v.v.frame); if (bits & U_COLORMAP) - MSG_WriteByte (msg, ent->v.colormap); + MSG_WriteByte (msg, ent->v.v.colormap); if (bits & U_SKIN) - MSG_WriteByte (msg, ent->v.skin); + MSG_WriteByte (msg, ent->v.v.skin); if (bits & U_EFFECTS) - MSG_WriteByte (msg, ent->v.effects); + MSG_WriteByte (msg, ent->v.v.effects); if (bits & U_ORIGIN1) - MSG_WriteCoord (msg, ent->v.origin[0]); + MSG_WriteCoord (msg, ent->v.v.origin[0]); if (bits & U_ANGLE1) - MSG_WriteAngle (msg, ent->v.angles[0]); + MSG_WriteAngle (msg, ent->v.v.angles[0]); if (bits & U_ORIGIN2) - MSG_WriteCoord (msg, ent->v.origin[1]); + MSG_WriteCoord (msg, ent->v.v.origin[1]); if (bits & U_ANGLE2) - MSG_WriteAngle (msg, ent->v.angles[1]); + MSG_WriteAngle (msg, ent->v.v.angles[1]); if (bits & U_ORIGIN3) - MSG_WriteCoord (msg, ent->v.origin[2]); + MSG_WriteCoord (msg, ent->v.v.origin[2]); 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; 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)) { + 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 // - if (ent->v.dmg_take || ent->v.dmg_save) { - other = PROG_TO_EDICT (ent->v.dmg_inflictor); + if (ent->v.v.dmg_take || ent->v.v.dmg_save) { + other = PROG_TO_EDICT (&sv_pr_state, ent->v.v.dmg_inflictor); MSG_WriteByte (msg, svc_damage); - MSG_WriteByte (msg, ent->v.dmg_save); - MSG_WriteByte (msg, ent->v.dmg_take); + MSG_WriteByte (msg, ent->v.v.dmg_save); + MSG_WriteByte (msg, ent->v.v.dmg_take); for (i = 0; i < 3; i++) MSG_WriteCoord (msg, - other->v.origin[i] + 0.5 * (other->v.mins[i] + - other->v.maxs[i])); + other->v.v.origin[i] + 0.5 * (other->v.v.mins[i] + + other->v.v.maxs[i])); - ent->v.dmg_take = 0; - ent->v.dmg_save = 0; + ent->v.v.dmg_take = 0; + ent->v.v.dmg_save = 0; } // // 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 // 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); for (i = 0; i < 3; i++) - MSG_WriteAngle (msg, ent->v.angles[i]); - ent->v.fixangle = 0; + MSG_WriteAngle (msg, ent->v.v.angles[i]); + ent->v.v.fixangle = 0; } bits = 0; - if (ent->v.view_ofs[2] != DEFAULT_VIEWHEIGHT) + if (ent->v.v.view_ofs[2] != DEFAULT_VIEWHEIGHT) bits |= SU_VIEWHEIGHT; - if (ent->v.idealpitch) + if (ent->v.v.idealpitch) 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) ent->v.v.items | ((int) ent->v.v.items2 << 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) ent->v.v.items | ((int) val->_float << 23); else 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 bits |= SU_ITEMS; - if ((int) ent->v.flags & FL_ONGROUND) + if ((int) ent->v.v.flags & FL_ONGROUND) bits |= SU_ONGROUND; - if (ent->v.waterlevel >= 2) + if (ent->v.v.waterlevel >= 2) bits |= SU_INWATER; for (i = 0; i < 3; i++) { - if (ent->v.punchangle[i]) + if (ent->v.v.punchangle[i]) bits |= (SU_PUNCH1 << i); - if (ent->v.velocity[i]) + if (ent->v.v.velocity[i]) bits |= (SU_VELOCITY1 << i); } - if (ent->v.weaponframe) + if (ent->v.v.weaponframe) bits |= SU_WEAPONFRAME; - if (ent->v.armorvalue) + if (ent->v.v.armorvalue) bits |= SU_ARMOR; -// if (ent->v.weapon) +// if (ent->v.v.weapon) bits |= SU_WEAPON; // send the data @@ -672,40 +676,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, ent->v.v.view_ofs[2]); if (bits & SU_IDEALPITCH) - MSG_WriteChar (msg, ent->v.idealpitch); + MSG_WriteChar (msg, ent->v.v.idealpitch); for (i = 0; i < 3; 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)) - MSG_WriteChar (msg, ent->v.velocity[i] / 16); + MSG_WriteChar (msg, ent->v.v.velocity[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, ent->v.v.weaponframe); if (bits & SU_ARMOR) - MSG_WriteByte (msg, ent->v.armorvalue); + MSG_WriteByte (msg, ent->v.v.armorvalue); 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_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, ent->v.v.health); + MSG_WriteByte (msg, ent->v.v.currentammo); + MSG_WriteByte (msg, ent->v.v.ammo_shells); + MSG_WriteByte (msg, ent->v.v.ammo_nails); + MSG_WriteByte (msg, ent->v.v.ammo_rockets); + MSG_WriteByte (msg, ent->v.v.ammo_cells); if (standard_quake) { - MSG_WriteByte (msg, ent->v.weapon); + MSG_WriteByte (msg, ent->v.v.weapon); } else { 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); break; } @@ -765,16 +771,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 != host_client->edict->v.v.frags) { 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, + 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++) { // 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 && !svent->v.v.modelindex) 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 (svent->v.v.origin, svent->baseline.origin); + VectorCopy (svent->v.v.angles, svent->baseline.angles); + svent->baseline.frame = svent->v.v.frame; + svent->baseline.skin = svent->v.v.skin; if (entnum > 0 && entnum <= svs.maxclients) { svent->baseline.colormap = entnum; svent->baseline.modelindex = SV_ModelIndex ("progs/player.mdl"); } else { svent->baseline.colormap = 0; 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; - 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; i++, host_client++) { @@ -1023,10 +1030,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_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); 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 // load progs to get entity field count - PR_LoadProgs (); + SV_LoadProgs (); // allocate server memory 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.cursize = 0; @@ -1114,7 +1125,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 +1149,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 +1161,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; + ent->v.v.model = sv.worldmodel->name - sv_pr_state.pr_strings; + ent->v.v.modelindex = 1; // world model + ent->v.v.solid = SOLID_BSP; + ent->v.v.movetype = MOVETYPE_PUSH; if (coop->int_val) - pr_global_struct->coop = coop->int_val; + sv_pr_state.pr_global_struct->coop = coop->int_val; 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 - pr_global_struct->startspot = sv.startspot - pr_strings; + sv_pr_state.pr_global_struct->startspot = + sv.startspot - sv_pr_state.pr_strings; #endif // 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; diff --git a/nq/source/sv_move.c b/nq/source/sv_move.c index bafe07773..f55707143 100644 --- a/nq/source/sv_move.c +++ b/nq/source/sv_move.c @@ -54,8 +54,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 (ent->v.v.origin, ent->v.v.mins, mins); + VectorAdd (ent->v.v.origin, ent->v.v.maxs, maxs); // if all of the points under the corners are solid world, don't bother // with the tougher checks @@ -128,34 +128,35 @@ 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 (ent->v.v.origin, oldorg); + VectorAdd (ent->v.v.origin, move, neworg); // 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 for (i = 0; i < 2; i++) { - VectorAdd (ent->v.origin, move, neworg); - enemy = PROG_TO_EDICT (ent->v.enemy); + VectorAdd (ent->v.v.origin, move, neworg); + enemy = PROG_TO_EDICT (&sv_pr_state, ent->v.v.enemy); if (i == 0 && enemy != sv.edicts) { dz = - ent->v.origin[2] - - PROG_TO_EDICT (ent->v.enemy)->v.origin[2]; + ent->v.v.origin[2] - PROG_TO_EDICT (&sv_pr_state, + ent->v.v.enemy)->v. + v.origin[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 (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, neworg, + false, ent); 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) return false; // swim monster left water - VectorCopy (trace.endpos, ent->v.origin); + VectorCopy (trace.endpos, ent->v.v.origin); if (relink) SV_LinkEdict (ent, true); return true; @@ -172,24 +173,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, ent->v.v.mins, ent->v.v.maxs, 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, ent->v.v.mins, ent->v.v.maxs, 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) ent->v.v.flags & FL_PARTIALGROUND) { + VectorAdd (ent->v.v.origin, move, ent->v.v.origin); if (relink) 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"); return true; } @@ -197,10 +198,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, ent->v.v.origin); 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 // from underneath it // and is trying to correct @@ -208,15 +209,15 @@ SV_movestep (edict_t *ent, vec3_t move, qboolean relink) SV_LinkEdict (ent, true); return true; } - VectorCopy (oldorg, ent->v.origin); + VectorCopy (oldorg, ent->v.v.origin); return false; } - if ((int) ent->v.flags & FL_PARTIALGROUND) { + if ((int) ent->v.v.flags & FL_PARTIALGROUND) { // 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 if (relink) @@ -243,7 +244,7 @@ SV_StepDirection (edict_t *ent, float yaw, float dist) vec3_t move, oldorigin; float delta; - ent->v.ideal_yaw = yaw; + ent->v.v.ideal_yaw = yaw; PF_changeyaw (); 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[2] = 0; - VectorCopy (ent->v.origin, oldorigin); + VectorCopy (ent->v.v.origin, oldorigin); 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 // don't take the step - VectorCopy (oldorigin, ent->v.origin); + VectorCopy (oldorigin, ent->v.v.origin); } SV_LinkEdict (ent, true); return true; @@ -277,7 +278,7 @@ SV_FixCheckBottom (edict_t *ent) { // 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 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); - deltax = enemy->v.origin[0] - actor->v.origin[0]; - deltay = enemy->v.origin[1] - actor->v.origin[1]; + deltax = enemy->v.v.origin[0] - actor->v.v.origin[0]; + deltay = enemy->v.v.origin[1] - actor->v.v.origin[1]; if (deltax > 10) d[1] = 0; 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)) 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 // a valid standing position at all @@ -378,9 +379,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 (goal->v.v.absmin[i] > ent->v.v.absmax[i] + dist) 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 true; @@ -393,7 +394,7 @@ SV_MoveToGoal ====================== */ void -SV_MoveToGoal (void) +SV_MoveToGoal (progs_t * pr) { edict_t *ent, *goal; float dist; @@ -402,26 +403,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->pr_global_struct->self); + goal = PROG_TO_EDICT (pr, ent->v.v.goalentity); + dist = G_FLOAT (pr, OFS_PARM0); - if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { - G_FLOAT (OFS_RETURN) = 0; + if (!((int) ent->v.v.flags & (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->, ent->v.v.enemy); if (enemy != sv.edicts && SV_CloseEnough (ent, enemy, dist)) #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)) #endif return; // 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); } } diff --git a/nq/source/sv_phys.c b/nq/source/sv_phys.c index 3958721ec..d38e4d444 100644 --- a/nq/source/sv_phys.c +++ b/nq/source/sv_phys.c @@ -80,16 +80,17 @@ SV_CheckAllEnts (void) edict_t *check; // see if any solid entities are inside the final position - check = NEXT_EDICT (sv.edicts); - for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { + 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.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE + if (check->v.v.movetype == MOVETYPE_PUSH + || check->v.v.movetype == MOVETYPE_NONE #ifdef QUAKE2 - || check->v.movetype == MOVETYPE_FOLLOW + || check->v.v.movetype == MOVETYPE_FOLLOW #endif - || check->v.movetype == MOVETYPE_NOCLIP) + || check->v.v.movetype == MOVETYPE_NOCLIP) continue; if (SV_TestEntityPosition (check)) @@ -111,20 +112,20 @@ SV_CheckVelocity (edict_t *ent) // bound velocity // for (i = 0; i < 3; i++) { - if (IS_NAN (ent->v.velocity[i])) { + if (IS_NAN (ent->v.v.velocity[i])) { Con_Printf ("Got a NaN velocity on %s\n", - pr_strings + ent->v.classname); - ent->v.velocity[i] = 0; + sv_pr_state.pr_strings + ent->v.v.classname); + ent->v.v.velocity[i] = 0; } - if (IS_NAN (ent->v.origin[i])) { + if (IS_NAN (ent->v.v.origin[i])) { Con_Printf ("Got a NaN origin on %s\n", - pr_strings + ent->v.classname); - ent->v.origin[i] = 0; + sv_pr_state.pr_strings + ent->v.v.classname); + ent->v.v.origin[i] = 0; } - if (ent->v.velocity[i] > sv_maxvelocity->value) - ent->v.velocity[i] = sv_maxvelocity->value; - else if (ent->v.velocity[i] < -sv_maxvelocity->value) - ent->v.velocity[i] = -sv_maxvelocity->value; + if (ent->v.v.velocity[i] > sv_maxvelocity->value) + ent->v.v.velocity[i] = sv_maxvelocity->value; + else if (ent->v.v.velocity[i] < -sv_maxvelocity->value) + ent->v.v.velocity[i] = -sv_maxvelocity->value; } } @@ -143,7 +144,7 @@ SV_RunThink (edict_t *ent) { float thinktime; - thinktime = ent->v.nextthink; + thinktime = ent->v.v.nextthink; if (thinktime <= 0 || thinktime > sv.time + host_frametime) return true; @@ -151,11 +152,12 @@ 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.nextthink = 0; - pr_global_struct->time = thinktime; - pr_global_struct->self = EDICT_TO_PROG (ent); - pr_global_struct->other = EDICT_TO_PROG (sv.edicts); - PR_ExecuteProgram (ent->v.think); + 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); return !ent->free; } @@ -171,24 +173,24 @@ SV_Impact (edict_t *e1, edict_t *e2) { int old_self, old_other; - old_self = pr_global_struct->self; - old_other = pr_global_struct->other; + old_self = sv_pr_state.pr_global_struct->self; + old_other = sv_pr_state.pr_global_struct->other; - pr_global_struct->time = sv.time; - if (e1->v.touch && e1->v.solid != SOLID_NOT) { - pr_global_struct->self = EDICT_TO_PROG (e1); - pr_global_struct->other = EDICT_TO_PROG (e2); - PR_ExecuteProgram (e1->v.touch); + 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); } - if (e2->v.touch && e2->v.solid != SOLID_NOT) { - pr_global_struct->self = EDICT_TO_PROG (e2); - pr_global_struct->other = EDICT_TO_PROG (e1); - PR_ExecuteProgram (e2->v.touch); + 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); } - pr_global_struct->self = old_self; - pr_global_struct->other = old_other; + sv_pr_state.pr_global_struct->self = old_self; + sv_pr_state.pr_global_struct->other = old_other; } @@ -259,30 +261,32 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) numbumps = 4; blocked = 0; - VectorCopy (ent->v.velocity, original_velocity); - VectorCopy (ent->v.velocity, primal_velocity); + VectorCopy (ent->v.v.velocity, original_velocity); + VectorCopy (ent->v.v.velocity, primal_velocity); numplanes = 0; time_left = time; for (bumpcount = 0; bumpcount < numbumps; bumpcount++) { - if (!ent->v.velocity[0] && !ent->v.velocity[1] && !ent->v.velocity[2]) + if (!ent->v.v.velocity[0] && !ent->v.v.velocity[1] + && !ent->v.v.velocity[2]) break; for (i = 0; i < 3; i++) - end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i]; + end[i] = ent->v.v.origin[i] + time_left * ent->v.v.velocity[i]; trace = - SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); + SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, false, + ent); if (trace.allsolid) { // entity is trapped in another solid - VectorCopy (vec3_origin, ent->v.velocity); + VectorCopy (vec3_origin, ent->v.v.velocity); return 3; } if (trace.fraction > 0) { // actually covered some distance - VectorCopy (trace.endpos, ent->v.origin); - VectorCopy (ent->v.velocity, original_velocity); + VectorCopy (trace.endpos, ent->v.v.origin); + VectorCopy (ent->v.v.velocity, original_velocity); numplanes = 0; } @@ -294,9 +298,9 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) if (trace.plane.normal[2] > 0.7) { blocked |= 1; // floor - if (trace.ent->v.solid == SOLID_BSP) { - ent->v.flags = (int) ent->v.flags | FL_ONGROUND; - ent->v.groundentity = EDICT_TO_PROG (trace.ent); + if (trace.ent->v.v.solid == SOLID_BSP) { + ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND; + ent->v.v.groundentity = EDICT_TO_PROG (&sv_pr_state, trace.ent); } } if (!trace.plane.normal[2]) { @@ -316,7 +320,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.velocity); + VectorCopy (vec3_origin, ent->v.v.velocity); return 3; } @@ -338,24 +342,24 @@ SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) } if (i != numplanes) { // go along this plane - VectorCopy (new_velocity, ent->v.velocity); + VectorCopy (new_velocity, ent->v.v.velocity); } else { // go along the crease if (numplanes != 2) { // Con_Printf ("clip velocity, numplanes == %i\n",numplanes); - VectorCopy (vec3_origin, ent->v.velocity); + VectorCopy (vec3_origin, ent->v.v.velocity); return 7; } CrossProduct (planes[0], planes[1], dir); - d = DotProduct (dir, ent->v.velocity); - VectorScale (dir, d, ent->v.velocity); + d = DotProduct (dir, ent->v.v.velocity); + VectorScale (dir, d, ent->v.v.velocity); } // // if original velocity is against the original velocity, stop dead // to avoid tiny occilations in sloping corners // - if (DotProduct (ent->v.velocity, primal_velocity) <= 0) { - VectorCopy (vec3_origin, ent->v.velocity); + if (DotProduct (ent->v.v.velocity, primal_velocity) <= 0) { + VectorCopy (vec3_origin, ent->v.v.velocity); return blocked; } } @@ -376,20 +380,20 @@ SV_AddGravity (edict_t *ent) float ent_gravity; #ifdef QUAKE2 - if (ent->v.gravity) - ent_gravity = ent->v.gravity; + if (ent->v.v.gravity) + ent_gravity = ent->v.v.gravity; else ent_gravity = 1.0; #else eval_t *val; - val = GetEdictFieldValue (ent, "gravity"); + val = GetEdictFieldValue (&sv_pr_state, ent, "gravity"); if (val && val->_float) ent_gravity = val->_float; else ent_gravity = 1.0; #endif - ent->v.velocity[2] -= ent_gravity * sv_gravity->value * host_frametime; + ent->v.v.velocity[2] -= ent_gravity * sv_gravity->value * host_frametime; } @@ -414,23 +418,23 @@ SV_PushEntity (edict_t *ent, vec3_t push) trace_t trace; vec3_t end; - VectorAdd (ent->v.origin, push, end); + VectorAdd (ent->v.v.origin, push, end); - if (ent->v.movetype == MOVETYPE_FLYMISSILE) + if (ent->v.v.movetype == MOVETYPE_FLYMISSILE) trace = - SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, - ent); - else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT) + SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, + MOVE_MISSILE, ent); + else if (ent->v.v.solid == SOLID_TRIGGER || ent->v.v.solid == SOLID_NOT) // only clip against bmodels trace = - SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, + SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, MOVE_NOMONSTERS, ent); else trace = - SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, - ent); + SV_Move (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, end, + MOVE_NORMAL, ent); - VectorCopy (trace.endpos, ent->v.origin); + VectorCopy (trace.endpos, ent->v.v.origin); SV_LinkEdict (ent, true); if (trace.ent) @@ -457,51 +461,53 @@ SV_PushMove (edict_t *pusher, float movetime) edict_t *moved_edict[MAX_EDICTS]; vec3_t moved_from[MAX_EDICTS]; - if (!pusher->v.velocity[0] && !pusher->v.velocity[1] - && !pusher->v.velocity[2]) { - pusher->v.ltime += movetime; + if (!pusher->v.v.velocity[0] && !pusher->v.v.velocity[1] + && !pusher->v.v.velocity[2]) { + pusher->v.v.ltime += movetime; return; } for (i = 0; i < 3; i++) { - move[i] = pusher->v.velocity[i] * movetime; - mins[i] = pusher->v.absmin[i] + move[i]; - maxs[i] = pusher->v.absmax[i] + move[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]; } - VectorCopy (pusher->v.origin, pushorig); + VectorCopy (pusher->v.v.origin, pushorig); // move the pusher to it's final position - VectorAdd (pusher->v.origin, move, pusher->v.origin); - pusher->v.ltime += movetime; + VectorAdd (pusher->v.v.origin, move, pusher->v.v.origin); + pusher->v.v.ltime += movetime; SV_LinkEdict (pusher, false); // see if any solid entities are inside the final position num_moved = 0; - check = NEXT_EDICT (sv.edicts); - for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { + 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.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE + if (check->v.v.movetype == MOVETYPE_PUSH + || check->v.v.movetype == MOVETYPE_NONE #ifdef QUAKE2 - || check->v.movetype == MOVETYPE_FOLLOW + || check->v.v.movetype == MOVETYPE_FOLLOW #endif - || check->v.movetype == MOVETYPE_NOCLIP) + || check->v.v.movetype == MOVETYPE_NOCLIP) continue; // if the entity is standing on the pusher, it will definately be // moved - if (!(((int) check->v.flags & FL_ONGROUND) - && PROG_TO_EDICT (check->v.groundentity) == pusher)) { - if (check->v.absmin[0] >= maxs[0] - || check->v.absmin[1] >= maxs[1] - || check->v.absmin[2] >= maxs[2] - || check->v.absmax[0] <= mins[0] - || check->v.absmax[1] <= mins[1] - || check->v.absmax[2] <= mins[2]) + 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]) continue; // see if the ent's bbox is inside the pusher's final position @@ -509,47 +515,49 @@ SV_PushMove (edict_t *pusher, float movetime) continue; } // remove the onground flag for non-players - if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int) check->v.flags & ~FL_ONGROUND; + if (check->v.v.movetype != MOVETYPE_WALK) + check->v.v.flags = (int) check->v.v.flags & ~FL_ONGROUND; - VectorCopy (check->v.origin, entorig); - VectorCopy (check->v.origin, moved_from[num_moved]); + VectorCopy (check->v.v.origin, entorig); + VectorCopy (check->v.v.origin, moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; // try moving the contacted entity - pusher->v.solid = SOLID_NOT; + pusher->v.v.solid = SOLID_NOT; SV_PushEntity (check, move); - pusher->v.solid = SOLID_BSP; + pusher->v.v.solid = SOLID_BSP; // if it is still inside the pusher, block block = SV_TestEntityPosition (check); if (block) { // fail the move - if (check->v.mins[0] == check->v.maxs[0]) + if (check->v.v.mins[0] == check->v.v.maxs[0]) continue; - if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) { // corpse - check->v.mins[0] = check->v.mins[1] = 0; - VectorCopy (check->v.mins, check->v.maxs); + 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); continue; } - VectorCopy (entorig, check->v.origin); + VectorCopy (entorig, check->v.v.origin); SV_LinkEdict (check, true); - VectorCopy (pushorig, pusher->v.origin); + VectorCopy (pushorig, pusher->v.v.origin); SV_LinkEdict (pusher, false); - pusher->v.ltime -= movetime; + pusher->v.v.ltime -= movetime; // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone - if (pusher->v.blocked) { - pr_global_struct->self = EDICT_TO_PROG (pusher); - pr_global_struct->other = EDICT_TO_PROG (check); - PR_ExecuteProgram (pusher->v.blocked); + 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); } // move back any entities we already moved for (i = 0; i < num_moved; i++) { - VectorCopy (moved_from[i], moved_edict[i]->v.origin); + VectorCopy (moved_from[i], moved_edict[i]->v.v.origin); SV_LinkEdict (moved_edict[i], false); } return; @@ -579,48 +587,50 @@ SV_PushRotate (edict_t *pusher, float movetime) vec3_t org, org2; vec3_t forward, right, up; - if (!pusher->v.avelocity[0] && !pusher->v.avelocity[1] - && !pusher->v.avelocity[2]) { - pusher->v.ltime += movetime; + if (!pusher->v.v.avelocity[0] && !pusher->v.v.avelocity[1] + && !pusher->v.v.avelocity[2]) { + pusher->v.v.ltime += movetime; return; } for (i = 0; i < 3; i++) - amove[i] = pusher->v.avelocity[i] * movetime; + amove[i] = pusher->v.v.avelocity[i] * movetime; VectorSubtract (vec3_origin, amove, a); AngleVectors (a, forward, right, up); - VectorCopy (pusher->v.angles, pushorig); + VectorCopy (pusher->v.v.angles, pushorig); // move the pusher to it's final position - VectorAdd (pusher->v.angles, amove, pusher->v.angles); - pusher->v.ltime += movetime; + VectorAdd (pusher->v.v.angles, amove, pusher->v.v.angles); + pusher->v.v.ltime += movetime; SV_LinkEdict (pusher, false); // see if any solid entities are inside the final position num_moved = 0; - check = NEXT_EDICT (sv.edicts); - for (e = 1; e < sv.num_edicts; e++, check = NEXT_EDICT (check)) { + 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.movetype == MOVETYPE_PUSH - || check->v.movetype == MOVETYPE_NONE - || check->v.movetype == MOVETYPE_FOLLOW - || check->v.movetype == MOVETYPE_NOCLIP) continue; + if (check->v.v.movetype == MOVETYPE_PUSH + || check->v.v.movetype == MOVETYPE_NONE + || check->v.v.movetype == MOVETYPE_FOLLOW + || check->v.v.movetype == MOVETYPE_NOCLIP) continue; // if the entity is standing on the pusher, it will definately be // moved - if (!(((int) check->v.flags & FL_ONGROUND) - && PROG_TO_EDICT (check->v.groundentity) == pusher)) { - if (check->v.absmin[0] >= pusher->v.absmax[0] - || check->v.absmin[1] >= pusher->v.absmax[1] - || check->v.absmin[2] >= pusher->v.absmax[2] - || check->v.absmax[0] <= pusher->v.absmin[0] - || check->v.absmax[1] <= pusher->v.absmin[1] - || check->v.absmax[2] <= pusher->v.absmin[2]) + 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] >= pusher->v.v.absmax[0] + || check->v.v.absmin[1] >= pusher->v.v.absmax[1] + || check->v.v.absmin[2] >= pusher->v.v.absmax[2] + || check->v.v.absmax[0] <= pusher->v.v.absmin[0] + || check->v.v.absmax[1] <= pusher->v.v.absmin[1] + || check->v.v.absmax[2] <= pusher->v.v.absmin[2]) continue; // see if the ent's bbox is inside the pusher's final position @@ -628,61 +638,63 @@ SV_PushRotate (edict_t *pusher, float movetime) continue; } // remove the onground flag for non-players - if (check->v.movetype != MOVETYPE_WALK) - check->v.flags = (int) check->v.flags & ~FL_ONGROUND; + if (check->v.v.movetype != MOVETYPE_WALK) + check->v.v.flags = (int) check->v.v.flags & ~FL_ONGROUND; - VectorCopy (check->v.origin, entorig); - VectorCopy (check->v.origin, moved_from[num_moved]); + VectorCopy (check->v.v.origin, entorig); + VectorCopy (check->v.v.origin, moved_from[num_moved]); moved_edict[num_moved] = check; num_moved++; // calculate destination position - VectorSubtract (check->v.origin, pusher->v.origin, org); + VectorSubtract (check->v.v.origin, pusher->v.v.origin, org); org2[0] = DotProduct (org, forward); org2[1] = -DotProduct (org, right); org2[2] = DotProduct (org, up); VectorSubtract (org2, org, move); // try moving the contacted entity - pusher->v.solid = SOLID_NOT; + pusher->v.v.solid = SOLID_NOT; SV_PushEntity (check, move); - pusher->v.solid = SOLID_BSP; + pusher->v.v.solid = SOLID_BSP; // if it is still inside the pusher, block block = SV_TestEntityPosition (check); if (block) { // fail the move - if (check->v.mins[0] == check->v.maxs[0]) + if (check->v.v.mins[0] == check->v.v.maxs[0]) continue; - if (check->v.solid == SOLID_NOT || check->v.solid == SOLID_TRIGGER) { // corpse - check->v.mins[0] = check->v.mins[1] = 0; - VectorCopy (check->v.mins, check->v.maxs); + 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); continue; } - VectorCopy (entorig, check->v.origin); + VectorCopy (entorig, check->v.v.origin); SV_LinkEdict (check, true); - VectorCopy (pushorig, pusher->v.angles); + VectorCopy (pushorig, pusher->v.v.angles); SV_LinkEdict (pusher, false); - pusher->v.ltime -= movetime; + pusher->v.v.ltime -= movetime; // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone - if (pusher->v.blocked) { - pr_global_struct->self = EDICT_TO_PROG (pusher); - pr_global_struct->other = EDICT_TO_PROG (check); - PR_ExecuteProgram (pusher->v.blocked); + 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); } // move back any entities we already moved for (i = 0; i < num_moved; i++) { - VectorCopy (moved_from[i], moved_edict[i]->v.origin); - VectorSubtract (moved_edict[i]->v.angles, amove, - moved_edict[i]->v.angles); + VectorCopy (moved_from[i], moved_edict[i]->v.v.origin); + VectorSubtract (moved_edict[i]->v.v.angles, amove, + moved_edict[i]->v.v.angles); SV_LinkEdict (moved_edict[i], false); } return; } else { - VectorAdd (check->v.angles, amove, check->v.angles); + VectorAdd (check->v.v.angles, amove, check->v.v.angles); } } @@ -703,11 +715,11 @@ SV_Physics_Pusher (edict_t *ent) float oldltime; float movetime; - oldltime = ent->v.ltime; + oldltime = ent->v.v.ltime; - thinktime = ent->v.nextthink; - if (thinktime < ent->v.ltime + host_frametime) { - movetime = thinktime - ent->v.ltime; + thinktime = ent->v.v.nextthink; + if (thinktime < ent->v.v.ltime + host_frametime) { + movetime = thinktime - ent->v.v.ltime; if (movetime < 0) movetime = 0; } else @@ -715,20 +727,23 @@ SV_Physics_Pusher (edict_t *ent) if (movetime) { #ifdef QUAKE2 - if (ent->v.avelocity[0] || ent->v.avelocity[1] || ent->v.avelocity[2]) + if (ent->v.v.avelocity[0] || ent->v.v.avelocity[1] + || ent->v.v.avelocity[2]) SV_PushRotate (ent, movetime); else #endif - SV_PushMove (ent, movetime); // advances ent->v.ltime if not + SV_PushMove (ent, movetime); // advances ent->v.v.ltime if not + // // blocked } - if (thinktime > oldltime && thinktime <= ent->v.ltime) { - ent->v.nextthink = 0; - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG (ent); - pr_global_struct->other = EDICT_TO_PROG (sv.edicts); - PR_ExecuteProgram (ent->v.think); + 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 (ent->free) return; } @@ -760,12 +775,12 @@ SV_CheckStuck (edict_t *ent) vec3_t org; if (!SV_TestEntityPosition (ent)) { - VectorCopy (ent->v.origin, ent->v.oldorigin); + VectorCopy (ent->v.v.origin, ent->v.v.oldorigin); return; } - VectorCopy (ent->v.origin, org); - VectorCopy (ent->v.oldorigin, ent->v.origin); + VectorCopy (ent->v.v.origin, org); + VectorCopy (ent->v.v.oldorigin, ent->v.v.origin); if (!SV_TestEntityPosition (ent)) { Con_DPrintf ("Unstuck.\n"); SV_LinkEdict (ent, true); @@ -775,9 +790,9 @@ SV_CheckStuck (edict_t *ent) for (z = 0; z < 18; z++) for (i = -1; i <= 1; i++) for (j = -1; j <= 1; j++) { - ent->v.origin[0] = org[0] + i; - ent->v.origin[1] = org[1] + j; - ent->v.origin[2] = org[2] + z; + ent->v.v.origin[0] = org[0] + i; + ent->v.v.origin[1] = org[1] + j; + ent->v.v.origin[2] = org[2] + z; if (!SV_TestEntityPosition (ent)) { Con_DPrintf ("Unstuck.\n"); SV_LinkEdict (ent, true); @@ -785,7 +800,7 @@ SV_CheckStuck (edict_t *ent) } } - VectorCopy (org, ent->v.origin); + VectorCopy (org, ent->v.v.origin); Con_DPrintf ("player is stuck.\n"); } @@ -805,27 +820,28 @@ SV_CheckWater (edict_t *ent) int truecont; #endif - point[0] = ent->v.origin[0]; - point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + point[0] = ent->v.v.origin[0]; + point[1] = ent->v.v.origin[1]; + point[2] = ent->v.v.origin[2] + ent->v.v.mins[2] + 1; - ent->v.waterlevel = 0; - ent->v.watertype = CONTENTS_EMPTY; + ent->v.v.waterlevel = 0; + ent->v.v.watertype = CONTENTS_EMPTY; cont = SV_PointContents (point); if (cont <= CONTENTS_WATER) { #ifdef QUAKE2 truecont = SV_TruePointContents (point); #endif - ent->v.watertype = cont; - ent->v.waterlevel = 1; - point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2]) * 0.5; + ent->v.v.watertype = cont; + ent->v.v.waterlevel = 1; + point[2] = + ent->v.v.origin[2] + (ent->v.v.mins[2] + ent->v.v.maxs[2]) * 0.5; cont = SV_PointContents (point); if (cont <= CONTENTS_WATER) { - ent->v.waterlevel = 2; - point[2] = ent->v.origin[2] + ent->v.view_ofs[2]; + ent->v.v.waterlevel = 2; + point[2] = ent->v.v.origin[2] + ent->v.v.view_ofs[2]; cont = SV_PointContents (point); if (cont <= CONTENTS_WATER) - ent->v.waterlevel = 3; + ent->v.v.waterlevel = 3; } #ifdef QUAKE2 if (truecont <= CONTENTS_CURRENT_0 && truecont >= CONTENTS_CURRENT_DOWN) { @@ -838,14 +854,14 @@ SV_CheckWater (edict_t *ent) {0, 0, -1} }; - VectorMA (ent->v.basevelocity, 150.0 * ent->v.waterlevel / 3.0, + VectorMA (ent->v.v.basevelocity, 150.0 * ent->v.v.waterlevel / 3.0, current_table[CONTENTS_CURRENT_0 - truecont], - ent->v.basevelocity); + ent->v.v.basevelocity); } #endif } - return ent->v.waterlevel > 1; + return ent->v.v.waterlevel > 1; } /* @@ -861,7 +877,7 @@ SV_WallFriction (edict_t *ent, trace_t *trace) float d, i; vec3_t into, side; - AngleVectors (ent->v.v_angle, forward, right, up); + AngleVectors (ent->v.v.v_angle, forward, right, up); d = DotProduct (trace->plane.normal, forward); d += 0.5; @@ -869,12 +885,12 @@ SV_WallFriction (edict_t *ent, trace_t *trace) return; // cut the tangential velocity - i = DotProduct (trace->plane.normal, ent->v.velocity); + i = DotProduct (trace->plane.normal, ent->v.v.velocity); VectorScale (trace->plane.normal, i, into); - VectorSubtract (ent->v.velocity, into, side); + VectorSubtract (ent->v.v.velocity, into, side); - ent->v.velocity[0] = side[0] * (1 + d); - ent->v.velocity[1] = side[1] * (1 + d); + ent->v.v.velocity[0] = side[0] * (1 + d); + ent->v.v.velocity[1] = side[1] * (1 + d); } /* @@ -898,7 +914,7 @@ SV_TryUnstick (edict_t *ent, vec3_t oldvel) int clip; trace_t steptrace; - VectorCopy (ent->v.origin, oldorg); + VectorCopy (ent->v.v.origin, oldorg); VectorCopy (vec3_origin, dir); for (i = 0; i < 8; i++) { @@ -941,21 +957,21 @@ SV_TryUnstick (edict_t *ent, vec3_t oldvel) SV_PushEntity (ent, dir); // retry the original move - ent->v.velocity[0] = oldvel[0]; - ent->v.velocity[1] = oldvel[1]; - ent->v.velocity[2] = 0; + ent->v.v.velocity[0] = oldvel[0]; + ent->v.v.velocity[1] = oldvel[1]; + ent->v.v.velocity[2] = 0; clip = SV_FlyMove (ent, 0.1, &steptrace); - if (fabs (oldorg[1] - ent->v.origin[1]) > 4 - || fabs (oldorg[0] - ent->v.origin[0]) > 4) { + if (fabs (oldorg[1] - ent->v.v.origin[1]) > 4 + || fabs (oldorg[0] - ent->v.v.origin[0]) > 4) { //Con_DPrintf ("unstuck!\n"); return clip; } // go back to the original pos and try again - VectorCopy (oldorg, ent->v.origin); + VectorCopy (oldorg, ent->v.v.origin); } - VectorCopy (vec3_origin, ent->v.velocity); + VectorCopy (vec3_origin, ent->v.v.velocity); return 7; // still not moving } @@ -980,36 +996,36 @@ SV_WalkMove (edict_t *ent) // // do a regular slide move unless it looks like you ran into a step // - oldonground = (int) ent->v.flags & FL_ONGROUND; - ent->v.flags = (int) ent->v.flags & ~FL_ONGROUND; + oldonground = (int) ent->v.v.flags & FL_ONGROUND; + ent->v.v.flags = (int) ent->v.v.flags & ~FL_ONGROUND; - VectorCopy (ent->v.origin, oldorg); - VectorCopy (ent->v.velocity, oldvel); + VectorCopy (ent->v.v.origin, oldorg); + VectorCopy (ent->v.v.velocity, oldvel); clip = SV_FlyMove (ent, host_frametime, &steptrace); if (!(clip & 2)) return; // move didn't block on a step - if (!oldonground && ent->v.waterlevel == 0) + if (!oldonground && ent->v.v.waterlevel == 0) return; // don't stair up while jumping - if (ent->v.movetype != MOVETYPE_WALK) + if (ent->v.v.movetype != MOVETYPE_WALK) return; // gibbed by a trigger if (sv_nostep->int_val) return; - if ((int) sv_player->v.flags & FL_WATERJUMP) + if ((int) sv_player->v.v.flags & FL_WATERJUMP) return; - VectorCopy (ent->v.origin, nosteporg); - VectorCopy (ent->v.velocity, nostepvel); + VectorCopy (ent->v.v.origin, nosteporg); + VectorCopy (ent->v.v.velocity, nostepvel); // // try moving up and forward to go up a step // - VectorCopy (oldorg, ent->v.origin); // back to start pos + VectorCopy (oldorg, ent->v.v.origin); // back to start pos VectorCopy (vec3_origin, upmove); VectorCopy (vec3_origin, downmove); @@ -1020,18 +1036,21 @@ SV_WalkMove (edict_t *ent) SV_PushEntity (ent, upmove); // FIXME: don't link? // move forward - ent->v.velocity[0] = oldvel[0]; - ent->v.velocity[1] = oldvel[1]; - ent->v.velocity[2] = 0; + ent->v.v.velocity[0] = oldvel[0]; + ent->v.v.velocity[1] = oldvel[1]; + ent->v.v.velocity[2] = 0; clip = SV_FlyMove (ent, host_frametime, &steptrace); // check for stuckness, possibly due to the limited precision of floats // in the clipping hulls if (clip) { - if (fabs (oldorg[1] - ent->v.origin[1]) < 0.03125 - && fabs (oldorg[0] - ent->v.origin[0]) < 0.03125) { // stepping - // up didn't - // make any + if (fabs (oldorg[1] - ent->v.v.origin[1]) < 0.03125 + && fabs (oldorg[0] - ent->v.v.origin[0]) < 0.03125) { // stepping + // + // up + // didn't + // make + // any // progress clip = SV_TryUnstick (ent, oldvel); } @@ -1044,16 +1063,16 @@ SV_WalkMove (edict_t *ent) downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link? if (downtrace.plane.normal[2] > 0.7) { - if (ent->v.solid == SOLID_BSP) { - ent->v.flags = (int) ent->v.flags | FL_ONGROUND; - ent->v.groundentity = EDICT_TO_PROG (downtrace.ent); + if (ent->v.v.solid == SOLID_BSP) { + ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND; + ent->v.v.groundentity = EDICT_TO_PROG (&sv_pr_state, downtrace.ent); } } else { // if the push down didn't end up on good ground, use the move without // the step up. This happens near wall / slope combinations, and can // cause the player to hop up higher on a slope too steep to climb - VectorCopy (nosteporg, ent->v.origin); - VectorCopy (nostepvel, ent->v.velocity); + VectorCopy (nosteporg, ent->v.v.origin); + VectorCopy (nostepvel, ent->v.v.velocity); } } @@ -1074,9 +1093,10 @@ SV_Physics_Client (edict_t *ent, int num) // // call standard client pre-think // - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG (ent); - PR_ExecuteProgram (pr_global_struct->PlayerPreThink); + sv_pr_state.pr_global_struct->time = sv.time; + sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent); + PR_ExecuteProgram (&sv_pr_state, + sv_pr_state.pr_global_struct->PlayerPreThink); // // do a move @@ -1086,7 +1106,7 @@ SV_Physics_Client (edict_t *ent, int num) // // decide which move function to call // - switch ((int) ent->v.movetype) { + switch ((int) ent->v.v.movetype) { case MOVETYPE_NONE: if (!SV_RunThink (ent)) return; @@ -1095,16 +1115,17 @@ SV_Physics_Client (edict_t *ent, int num) case MOVETYPE_WALK: if (!SV_RunThink (ent)) return; - if (!SV_CheckWater (ent) && !((int) ent->v.flags & FL_WATERJUMP)) + if (!SV_CheckWater (ent) && !((int) ent->v.v.flags & FL_WATERJUMP)) SV_AddGravity (ent); SV_CheckStuck (ent); #ifdef QUAKE2 - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorAdd (ent->v.v.velocity, ent->v.v.basevelocity, ent->v.v.velocity); #endif SV_WalkMove (ent); #ifdef QUAKE2 - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorSubtract (ent->v.v.velocity, ent->v.v.basevelocity, + ent->v.v.velocity); #endif break; @@ -1122,12 +1143,13 @@ SV_Physics_Client (edict_t *ent, int num) case MOVETYPE_NOCLIP: if (!SV_RunThink (ent)) return; - VectorMA (ent->v.origin, host_frametime, ent->v.velocity, - ent->v.origin); + VectorMA (ent->v.v.origin, host_frametime, ent->v.v.velocity, + ent->v.v.origin); break; default: - Sys_Error ("SV_Physics_client: bad movetype %i", (int) ent->v.movetype); + Sys_Error ("SV_Physics_client: bad movetype %i", + (int) ent->v.v.movetype); } // @@ -1135,9 +1157,10 @@ SV_Physics_Client (edict_t *ent, int num) // SV_LinkEdict (ent, true); - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG (ent); - PR_ExecuteProgram (pr_global_struct->PlayerPostThink); + sv_pr_state.pr_global_struct->time = sv.time; + sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent); + PR_ExecuteProgram (&sv_pr_state, + sv_pr_state.pr_global_struct->PlayerPostThink); } //============================================================================ @@ -1169,8 +1192,8 @@ SV_Physics_Follow (edict_t *ent) { // regular thinking SV_RunThink (ent); - VectorAdd (PROG_TO_EDICT (ent->v.aiment)->v.origin, ent->v.v_angle, - ent->v.origin); + VectorAdd (PROG_TO_EDICT (&sv_pr_state, ent->v.v.aiment)->v.v.origin, + ent->v.v.v_angle, ent->v.v.origin); SV_LinkEdict (ent, true); } @@ -1190,8 +1213,10 @@ SV_Physics_Noclip (edict_t *ent) if (!SV_RunThink (ent)) return; - VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); - VectorMA (ent->v.origin, host_frametime, ent->v.velocity, ent->v.origin); + VectorMA (ent->v.v.angles, host_frametime, ent->v.v.avelocity, + ent->v.v.angles); + VectorMA (ent->v.v.origin, host_frametime, ent->v.v.velocity, + ent->v.v.origin); SV_LinkEdict (ent, false); } @@ -1218,33 +1243,33 @@ SV_CheckWaterTransition (edict_t *ent) #ifdef QUAKE2 vec3_t point; - point[0] = ent->v.origin[0]; - point[1] = ent->v.origin[1]; - point[2] = ent->v.origin[2] + ent->v.mins[2] + 1; + point[0] = ent->v.v.origin[0]; + point[1] = ent->v.v.origin[1]; + point[2] = ent->v.v.origin[2] + ent->v.v.mins[2] + 1; cont = SV_PointContents (point); #else - cont = SV_PointContents (ent->v.origin); + cont = SV_PointContents (ent->v.v.origin); #endif - if (!ent->v.watertype) { // just spawned here - ent->v.watertype = cont; - ent->v.waterlevel = 1; + if (!ent->v.v.watertype) { // just spawned here + ent->v.v.watertype = cont; + ent->v.v.waterlevel = 1; return; } if (cont <= CONTENTS_WATER) { - if (ent->v.watertype == CONTENTS_EMPTY) { // just crossed into + if (ent->v.v.watertype == CONTENTS_EMPTY) { // just crossed into // water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } - ent->v.watertype = cont; - ent->v.waterlevel = 1; + ent->v.v.watertype = cont; + ent->v.v.waterlevel = 1; } else { - if (ent->v.watertype != CONTENTS_EMPTY) { // just crossed into + if (ent->v.v.watertype != CONTENTS_EMPTY) { // just crossed into // water SV_StartSound (ent, 0, "misc/h2ohit1.wav", 255, 1); } - ent->v.watertype = CONTENTS_EMPTY; - ent->v.waterlevel = cont; + ent->v.v.watertype = CONTENTS_EMPTY; + ent->v.v.waterlevel = cont; } } @@ -1265,12 +1290,12 @@ SV_Physics_Toss (edict_t *ent) #ifdef QUAKE2 edict_t *groundentity; - groundentity = PROG_TO_EDICT (ent->v.groundentity); - if ((int) groundentity->v.flags & FL_CONVEYOR) - VectorScale (groundentity->v.movedir, groundentity->v.speed, - ent->v.basevelocity); + groundentity = PROG_TO_EDICT (&sv_pr_state, ent->v.v.groundentity); + if ((int) groundentity->v.v.flags & FL_CONVEYOR) + VectorScale (groundentity->v.v.movedir, groundentity->v.v.speed, + ent->v.v.basevelocity); else - VectorCopy (vec_origin, ent->v.basevelocity); + VectorCopy (vec_origin, ent->v.v.basevelocity); SV_CheckWater (ent); #endif // regular thinking @@ -1278,77 +1303,79 @@ SV_Physics_Toss (edict_t *ent) return; #ifdef QUAKE2 - if (ent->v.velocity[2] > 0) - ent->v.flags = (int) ent->v.flags & ~FL_ONGROUND; + if (ent->v.v.velocity[2] > 0) + ent->v.v.flags = (int) ent->v.v.flags & ~FL_ONGROUND; - if (((int) ent->v.flags & FL_ONGROUND)) + if (((int) ent->v.v.flags & FL_ONGROUND)) //@@ - if (VectorCompare (ent->v.basevelocity, vec_origin)) + if (VectorCompare (ent->v.v.basevelocity, vec_origin)) return; SV_CheckVelocity (ent); // add gravity - if (!((int) ent->v.flags & FL_ONGROUND) - && ent->v.movetype != MOVETYPE_FLY - && ent->v.movetype != MOVETYPE_BOUNCEMISSILE - && ent->v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent); + if (!((int) ent->v.v.flags & FL_ONGROUND) + && ent->v.v.movetype != MOVETYPE_FLY + && ent->v.v.movetype != MOVETYPE_BOUNCEMISSILE + && ent->v.v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent); #else // if onground, return without moving - if (((int) ent->v.flags & FL_ONGROUND)) + if (((int) ent->v.v.flags & FL_ONGROUND)) return; SV_CheckVelocity (ent); // add gravity - if (ent->v.movetype != MOVETYPE_FLY - && ent->v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent); + if (ent->v.v.movetype != MOVETYPE_FLY + && ent->v.v.movetype != MOVETYPE_FLYMISSILE) SV_AddGravity (ent); #endif // move angles - VectorMA (ent->v.angles, host_frametime, ent->v.avelocity, ent->v.angles); + VectorMA (ent->v.v.angles, host_frametime, ent->v.v.avelocity, + ent->v.v.angles); // move origin #ifdef QUAKE2 - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorAdd (ent->v.v.velocity, ent->v.v.basevelocity, ent->v.v.velocity); #endif - VectorScale (ent->v.velocity, host_frametime, move); + VectorScale (ent->v.v.velocity, host_frametime, move); trace = SV_PushEntity (ent, move); #ifdef QUAKE2 - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorSubtract (ent->v.v.velocity, ent->v.v.basevelocity, + ent->v.v.velocity); #endif if (trace.fraction == 1) return; if (ent->free) return; - if (ent->v.movetype == MOVETYPE_BOUNCE) + if (ent->v.v.movetype == MOVETYPE_BOUNCE) backoff = 1.5; #ifdef QUAKE2 - else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE) + else if (ent->v.v.movetype == MOVETYPE_BOUNCEMISSILE) backoff = 2.0; #endif else backoff = 1; - ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, + ClipVelocity (ent->v.v.velocity, trace.plane.normal, ent->v.v.velocity, backoff); // stop if on ground if (trace.plane.normal[2] > 0.7) { #ifdef QUAKE2 - if (ent->v.velocity[2] < 60 - || (ent->v.movetype != MOVETYPE_BOUNCE - && ent->v.movetype != MOVETYPE_BOUNCEMISSILE)) + if (ent->v.v.velocity[2] < 60 + || (ent->v.v.movetype != MOVETYPE_BOUNCE + && ent->v.v.movetype != MOVETYPE_BOUNCEMISSILE)) #else - if (ent->v.velocity[2] < 60 || ent->v.movetype != MOVETYPE_BOUNCE) + if (ent->v.v.velocity[2] < 60 || ent->v.v.movetype != MOVETYPE_BOUNCE) #endif { - ent->v.flags = (int) ent->v.flags | FL_ONGROUND; - ent->v.groundentity = EDICT_TO_PROG (trace.ent); - VectorCopy (vec3_origin, ent->v.velocity); - VectorCopy (vec3_origin, ent->v.avelocity); + 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); } } // check for in water @@ -1386,43 +1413,44 @@ SV_Physics_Step (edict_t *ent) float friction; edict_t *groundentity; - groundentity = PROG_TO_EDICT (ent->v.groundentity); - if ((int) groundentity->v.flags & FL_CONVEYOR) - VectorScale (groundentity->v.movedir, groundentity->v.speed, - ent->v.basevelocity); + groundentity = PROG_TO_EDICT (&sv_pr_state, ent->v.v.groundentity); + if ((int) groundentity->v.v.flags & FL_CONVEYOR) + VectorScale (groundentity->v.v.movedir, groundentity->v.v.speed, + ent->v.v.basevelocity); else - VectorCopy (vec_origin, ent->v.basevelocity); + VectorCopy (vec_origin, ent->v.v.basevelocity); //@@ - pr_global_struct->time = sv.time; - pr_global_struct->self = EDICT_TO_PROG (ent); + sv_pr_state.pr_global_struct->time = sv.time; + sv_pr_state.pr_global_struct->self = EDICT_TO_PROG (&sv_pr_state, ent); PF_WaterMove (); SV_CheckVelocity (ent); - wasonground = (int) ent->v.flags & FL_ONGROUND; -// ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; + wasonground = (int) ent->v.v.flags & FL_ONGROUND; +// ent->v.v.flags = (int)ent->v.v.flags & ~FL_ONGROUND; // add gravity except: // flying monsters // swimming monsters who are in the water inwater = SV_CheckWater (ent); if (!wasonground) - if (!((int) ent->v.flags & FL_FLY)) - if (!(((int) ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0))) { - if (ent->v.velocity[2] < sv_gravity->value * -0.1) + if (!((int) ent->v.v.flags & FL_FLY)) + if (!(((int) ent->v.v.flags & FL_SWIM) + && (ent->v.v.waterlevel > 0))) { + if (ent->v.v.velocity[2] < sv_gravity->value * -0.1) hitsound = true; if (!inwater) SV_AddGravity (ent); } - if (!VectorCompare (ent->v.velocity, vec_origin) - || !VectorCompare (ent->v.basevelocity, vec_origin)) { - ent->v.flags = (int) ent->v.flags & ~FL_ONGROUND; + if (!VectorCompare (ent->v.v.velocity, vec_origin) + || !VectorCompare (ent->v.v.basevelocity, vec_origin)) { + ent->v.v.flags = (int) ent->v.v.flags & ~FL_ONGROUND; // apply friction // let dead monsters who aren't completely onground slide if (wasonground) - if (!(ent->v.health <= 0.0 && !SV_CheckBottom (ent))) { - vel = ent->v.velocity; + if (!(ent->v.v.health <= 0.0 && !SV_CheckBottom (ent))) { + vel = ent->v.v.velocity; speed = sqrt (vel[0] * vel[0] + vel[1] * vel[1]); if (speed) { friction = sv_friction->value; @@ -1441,17 +1469,18 @@ SV_Physics_Step (edict_t *ent) } } - VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorAdd (ent->v.v.velocity, ent->v.v.basevelocity, ent->v.v.velocity); SV_FlyMove (ent, host_frametime, NULL); - VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity); + VectorSubtract (ent->v.v.velocity, ent->v.v.basevelocity, + ent->v.v.velocity); // determine if it's on solid ground at all { vec3_t mins, maxs, point; int x, y; - VectorAdd (ent->v.origin, ent->v.mins, mins); - VectorAdd (ent->v.origin, ent->v.maxs, maxs); + VectorAdd (ent->v.v.origin, ent->v.v.mins, mins); + VectorAdd (ent->v.v.origin, ent->v.v.maxs, maxs); point[2] = mins[2] - 1; for (x = 0; x <= 1; x++) @@ -1459,7 +1488,7 @@ SV_Physics_Step (edict_t *ent) point[0] = x ? maxs[0] : mins[0]; point[1] = y ? maxs[1] : mins[1]; if (SV_PointContents (point) == CONTENTS_SOLID) { - ent->v.flags = (int) ent->v.flags | FL_ONGROUND; + ent->v.v.flags = (int) ent->v.v.flags | FL_ONGROUND; break; } } @@ -1468,7 +1497,7 @@ SV_Physics_Step (edict_t *ent) SV_LinkEdict (ent, true); - if ((int) ent->v.flags & FL_ONGROUND) + if ((int) ent->v.v.flags & FL_ONGROUND) if (!wasonground) if (hitsound) SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); @@ -1484,8 +1513,8 @@ SV_Physics_Step (edict_t *ent) qboolean hitsound; // freefall if not onground - if (!((int) ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { - if (ent->v.velocity[2] < sv_gravity->value * -0.1) + if (!((int) ent->v.v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM))) { + if (ent->v.v.velocity[2] < sv_gravity->value * -0.1) hitsound = true; else hitsound = false; @@ -1495,7 +1524,7 @@ SV_Physics_Step (edict_t *ent) SV_FlyMove (ent, host_frametime, NULL); SV_LinkEdict (ent, true); - if ((int) ent->v.flags & FL_ONGROUND) // just hit ground + if ((int) ent->v.v.flags & FL_ONGROUND) // just hit ground { if (hitsound) SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); @@ -1523,10 +1552,12 @@ SV_Physics (void) edict_t *ent; // let the progs know that a new frame has started - pr_global_struct->self = EDICT_TO_PROG (sv.edicts); - pr_global_struct->other = EDICT_TO_PROG (sv.edicts); - pr_global_struct->time = sv.time; - PR_ExecuteProgram (pr_global_struct->StartFrame); + 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_CheckAllEnts (); @@ -1534,42 +1565,42 @@ SV_Physics (void) // treat each object in turn // ent = sv.edicts; - for (i = 0; i < sv.num_edicts; i++, ent = NEXT_EDICT (ent)) { + for (i = 0; i < sv.num_edicts; i++, ent = NEXT_EDICT (&sv_pr_state, ent)) { if (ent->free) continue; - if (pr_global_struct->force_retouch) { + if (sv_pr_state.pr_global_struct->force_retouch) { SV_LinkEdict (ent, true); // force retouch even for stationary } if (i > 0 && i <= svs.maxclients) SV_Physics_Client (ent, i); - else if (ent->v.movetype == MOVETYPE_PUSH) + else if (ent->v.v.movetype == MOVETYPE_PUSH) SV_Physics_Pusher (ent); - else if (ent->v.movetype == MOVETYPE_NONE) + else if (ent->v.v.movetype == MOVETYPE_NONE) SV_Physics_None (ent); #ifdef QUAKE2 - else if (ent->v.movetype == MOVETYPE_FOLLOW) + else if (ent->v.v.movetype == MOVETYPE_FOLLOW) SV_Physics_Follow (ent); #endif - else if (ent->v.movetype == MOVETYPE_NOCLIP) + else if (ent->v.v.movetype == MOVETYPE_NOCLIP) SV_Physics_Noclip (ent); - else if (ent->v.movetype == MOVETYPE_STEP) + else if (ent->v.v.movetype == MOVETYPE_STEP) SV_Physics_Step (ent); - else if (ent->v.movetype == MOVETYPE_TOSS - || ent->v.movetype == MOVETYPE_BOUNCE + else if (ent->v.v.movetype == MOVETYPE_TOSS + || ent->v.v.movetype == MOVETYPE_BOUNCE #ifdef QUAKE2 - || ent->v.movetype == MOVETYPE_BOUNCEMISSILE + || ent->v.v.movetype == MOVETYPE_BOUNCEMISSILE #endif - || ent->v.movetype == MOVETYPE_FLY - || ent->v.movetype == MOVETYPE_FLYMISSILE) + || ent->v.v.movetype == MOVETYPE_FLY + || ent->v.v.movetype == MOVETYPE_FLYMISSILE) SV_Physics_Toss (ent); else - Sys_Error ("SV_Physics: bad movetype %i", (int) ent->v.movetype); + Sys_Error ("SV_Physics: bad movetype %i", (int) ent->v.v.movetype); } - if (pr_global_struct->force_retouch) - pr_global_struct->force_retouch--; + if (sv_pr_state.pr_global_struct->force_retouch) + sv_pr_state.pr_global_struct->force_retouch--; sv.time += host_frametime; } @@ -1599,14 +1630,14 @@ SV_Trace_Toss (edict_t *ent, edict_t *ignore) while (1) { SV_CheckVelocity (tent); SV_AddGravity (tent); - VectorMA (tent->v.angles, host_frametime, tent->v.avelocity, - tent->v.angles); - VectorScale (tent->v.velocity, host_frametime, move); - VectorAdd (tent->v.origin, move, end); + VectorMA (tent->v.v.angles, host_frametime, tent->v.v.avelocity, + tent->v.v.angles); + VectorScale (tent->v.v.velocity, host_frametime, move); + VectorAdd (tent->v.v.origin, move, end); trace = - SV_Move (tent->v.origin, tent->v.mins, tent->v.maxs, end, + SV_Move (tent->v.v.origin, tent->v.v.mins, tent->v.v.maxs, end, MOVE_NORMAL, tent); - VectorCopy (trace.endpos, tent->v.origin); + VectorCopy (trace.endpos, tent->v.v.origin); // p = free_particles; // if (p) @@ -1619,7 +1650,7 @@ SV_Trace_Toss (edict_t *ent, edict_t *ignore) // p->color = 15; // p->type = pt_static; // VectorCopy (vec3_origin, p->vel); -// VectorCopy (tent->v.origin, p->org); +// VectorCopy (tent->v.v.origin, p->org); // } if (trace.ent) diff --git a/nq/source/sv_progs.c b/nq/source/sv_progs.c new file mode 100644 index 000000000..a8edcc1ab --- /dev/null +++ b/nq/source/sv_progs.c @@ -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"); +} diff --git a/nq/source/sv_user.c b/nq/source/sv_user.c index 3b3c72bb4..121502a8c 100644 --- a/nq/source/sv_user.c +++ b/nq/source/sv_user.c @@ -1,3 +1,4 @@ + /* sv_user.c @@ -77,17 +78,17 @@ SV_SetIdealPitch (void) int i, j; int step, dir, steps; - if (!((int) sv_player->v.flags & FL_ONGROUND)) + if (!((int) sv_player->v.v.flags & FL_ONGROUND)) 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); 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] = sv_player->v.v.origin[0] + cosval * (i + 3) * 12; + top[1] = sv_player->v.v.origin[1] + sinval * (i + 3) * 12; + top[2] = sv_player->v.v.origin[2] + sv_player->v.v.view_ofs[2]; bottom[0] = top[0]; bottom[1] = top[1]; @@ -120,13 +121,13 @@ SV_SetIdealPitch (void) } if (!dir) { - sv_player->v.idealpitch = 0; + sv_player->v.v.idealpitch = 0; return; } if (steps < 2) 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 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] + sv_player->v.v.mins[2]; stop[2] = start[2] - 34; trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player); @@ -253,12 +254,12 @@ DropPunchAngle (void) { float len; - len = VectorNormalize (sv_player->v.punchangle); + len = VectorNormalize (sv_player->v.v.punchangle); len -= 10 * host_frametime; if (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 // - 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++) wishvel[i] = forward[i] * cmd.forwardmove + right[i] * cmd.sidemove; @@ -328,12 +329,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 > sv_player->v.v.teleport_time || !sv_player->v.v.waterlevel) { + sv_player->v.v.flags = (int) sv_player->v.v.flags & ~FL_WATERJUMP; + sv_player->v.v.teleport_time = 0; } - sv_player->v.velocity[0] = sv_player->v.movedir[0]; - sv_player->v.velocity[1] = sv_player->v.movedir[1]; + sv_player->v.v.velocity[0] = sv_player->v.v.movedir[0]; + sv_player->v.v.velocity[1] = sv_player->v.v.movedir[1]; } @@ -350,19 +351,19 @@ SV_AirMove (void) vec3_t wishvel; float fmove, smove; - AngleVectors (sv_player->v.angles, forward, right, up); + AngleVectors (sv_player->v.v.angles, 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 < sv_player->v.v.teleport_time && 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) sv_player->v.v.movetype != MOVETYPE_WALK) wishvel[2] = cmd.upmove; else wishvel[2] = 0; @@ -374,7 +375,7 @@ SV_AirMove (void) wishspeed = sv_maxspeed->value; } - if (sv_player->v.movetype == MOVETYPE_NOCLIP) { // noclip + if (sv_player->v.v.movetype == MOVETYPE_NOCLIP) { // noclip VectorCopy (wishvel, velocity); } else if (onground) { SV_UserFriction (); @@ -399,44 +400,45 @@ SV_ClientThink (void) { vec3_t v_angle; - if (sv_player->v.movetype == MOVETYPE_NONE) + if (sv_player->v.v.movetype == MOVETYPE_NONE) return; - onground = (int) sv_player->v.flags & FL_ONGROUND; + onground = (int) sv_player->v.v.flags & FL_ONGROUND; - origin = sv_player->v.origin; - velocity = sv_player->v.velocity; + origin = sv_player->v.v.origin; + velocity = sv_player->v.v.velocity; DropPunchAngle (); // // if dead, behave differently // - if (sv_player->v.health <= 0) + if (sv_player->v.v.health <= 0) return; // // angles // show 1/3 the pitch angle and all the roll angle 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); - angles[ROLL] = V_CalcRoll (sv_player->v.angles, sv_player->v.velocity) * 4; - if (!sv_player->v.fixangle) { + VectorAdd (sv_player->v.v.v_angle, sv_player->v.v.punchangle, v_angle); + angles[ROLL] = + 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[YAW] = v_angle[YAW]; } - if ((int) sv_player->v.flags & FL_WATERJUMP) { + if ((int) sv_player->v.v.flags & FL_WATERJUMP) { SV_WaterJump (); return; } // // walk // - if ((sv_player->v.waterlevel >= 2) - && (sv_player->v.movetype != MOVETYPE_NOCLIP)) { + if ((sv_player->v.v.waterlevel >= 2) + && (sv_player->v.v.movetype != MOVETYPE_NOCLIP)) { SV_WaterMove (); return; } @@ -466,7 +468,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, host_client->edict->v.v.v_angle); // read movement move->forwardmove = MSG_ReadShort (net_message); @@ -475,16 +477,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; + host_client->edict->v.v.button0 = bits & 1; + host_client->edict->v.v.button2 = (bits & 2) >> 1; i = MSG_ReadByte (net_message); if (i) - host_client->edict->v.impulse = i; + host_client->edict->v.v.impulse = i; #ifdef QUAKE2 // 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 } diff --git a/nq/source/world.c b/nq/source/world.c index ffafce236..e92d97692 100644 --- a/nq/source/world.c +++ b/nq/source/world.c @@ -153,11 +153,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 (ent->v.v.solid == SOLID_BSP) { // explicit hulls in the BSP model + if (ent->v.v.movetype != 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) 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 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 // box sizes - VectorSubtract (ent->v.mins, maxs, hullmins); - VectorSubtract (ent->v.maxs, mins, hullmaxs); + VectorSubtract (ent->v.v.mins, maxs, hullmins); + VectorSubtract (ent->v.v.maxs, mins, 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); if (touch == ent) continue; - if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER) + if (!touch->v.v.touch || touch->v.v.solid != 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 (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]) continue; - old_self = pr_global_struct->self; - old_other = pr_global_struct->other; + old_self = sv_pr_state.pr_global_struct->self; + old_other = sv_pr_state.pr_global_struct->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_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); - pr_global_struct->self = old_self; - pr_global_struct->other = old_other; + sv_pr_state.pr_global_struct->self = old_self; + sv_pr_state.pr_global_struct->other = old_other; } // recurse down both sides if (node->axis == -1) return; - if (ent->v.absmax[node->axis] > node->dist) + if (ent->v.v.absmax[node->axis] > node->dist) 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]); } @@ -370,7 +371,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 (ent->v.v.absmin, ent->v.v.absmax, splitplane); // recurse down the contacted sides if (sides & 1) @@ -403,9 +404,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 (ent->v.v.solid == SOLID_BSP && + (ent->v.v.angles[0] || ent->v.v.angles[1] || ent->v.v.angles[2])) { // expand + // // for // rotation float max, v; @@ -413,50 +414,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 (ent->v.v.mins[i]); if (v > max) max = v; - v = fabs (ent->v.maxs[i]); + v = fabs (ent->v.v.maxs[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; + ent->v.v.absmin[i] = ent->v.v.origin[i] - max; + ent->v.v.absmax[i] = ent->v.v.origin[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 (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); } // // 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) 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; } 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; + 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; } // link to PVS leafs ent->num_leafs = 0; - if (ent->v.modelindex) + if (ent->v.v.modelindex) SV_FindTouchedLeafs (ent, sv.worldmodel->nodes); - if (ent->v.solid == SOLID_NOT) + if (ent->v.v.solid == SOLID_NOT) return; // find the first node that the ent's box crosses @@ -464,9 +465,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 (ent->v.v.absmin[node->axis] > node->dist) 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]; else break; // crosses the node @@ -474,7 +475,7 @@ SV_LinkEdict (edict_t *ent, qboolean touch_triggers) // link it in - if (ent->v.solid == SOLID_TRIGGER) + if (ent->v.v.solid == SOLID_TRIGGER) InsertLinkBefore (&ent->area, &node->trigger_edicts); else InsertLinkBefore (&ent->area, &node->solid_edicts); @@ -570,8 +571,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 (ent->v.v.origin, ent->v.v.mins, ent->v.v.maxs, ent->v.v.origin, + 0, ent); if (trace.startsolid) return sv.edicts; @@ -758,13 +759,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 (ent->v.v.solid == SOLID_BSP && + (ent->v.v.angles[0] || ent->v.v.angles[1] || ent->v.v.angles[2])) { vec3_t a; vec3_t forward, right, up; vec3_t temp; - AngleVectors (ent->v.angles, forward, right, up); + AngleVectors (ent->v.v.angles, forward, right, up); VectorCopy (start_l, temp); 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 // 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 (ent->v.v.solid == SOLID_BSP && + (ent->v.v.angles[0] || ent->v.v.angles[1] || ent->v.v.angles[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, ent->v.v.angles, a); AngleVectors (a, forward, right, up); 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) { next = l->next; touch = EDICT_FROM_AREA (l); - if (touch->v.solid == SOLID_NOT) + if (touch->v.v.solid == SOLID_NOT) continue; if (touch == clip->passedict) continue; - if (touch->v.solid == SOLID_TRIGGER) + if (touch->v.v.solid == SOLID_TRIGGER) 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; - 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] > 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]) 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 // 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, touch->v.v.owner) == + clip->passedict) continue; // don't clip against own + // missiles + 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 = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);