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

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

View file

@ -1,7 +1,7 @@
/*
progs.h
@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

View file

@ -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

View file

@ -137,8 +137,8 @@ client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_parse.c \
gib_interpret.c gib_modules.c gib_parse.c gib_stack.c vid.c
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)

View file

@ -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 ();

View file

@ -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);
}
/*

View file

@ -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);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,54 @@
/*
pr_offs.c
Quick QuakeC offset access
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "progs.h"
int
FindFieldOffset (progs_t *pr, char *field)
{
ddef_t *d;
d = ED_FindField (pr, field);
if (!d)
return 0;
return d->ofs * 4;
}
eval_t *
GETEDICTFIELDVALUE (edict_t *ed, int fieldoffset)
{
if (!fieldoffset)
return NULL;
return (eval_t *) ((char *) &ed->v + fieldoffset);
}

View file

@ -157,7 +157,7 @@ SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
return;
}
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;

View file

@ -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);
}
}

File diff suppressed because it is too large Load diff

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

@ -0,0 +1,160 @@
/*
sv_progs.c
Quick QuakeC server code
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
#include "string.h"
#endif
#ifdef HAVE_STRINGS_H
#include "strings.h"
#endif
#include "cmd.h"
#include "console.h"
#include "host.h"
#include "progs.h"
#include "server.h"
#include "world.h"
int eval_alpha, eval_scale, eval_glowsize, eval_glowcolor,
eval_colormod;
progs_t sv_pr_state;
cvar_t *r_skyname;
cvar_t *sv_progs;
func_t EndFrame;
func_t SpectatorConnect;
func_t SpectatorDisconnect;
func_t SpectatorThink;
void
FindEdictFieldOffsets (progs_t * pr)
{
dfunction_t *f;
if (pr == &sv_pr_state) {
// Zoid, find the spectator functions
SpectatorConnect = SpectatorThink = SpectatorDisconnect = 0;
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorConnect")) != NULL)
SpectatorConnect = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorThink")) != NULL)
SpectatorThink = (func_t) (f - sv_pr_state.pr_functions);
if ((f = ED_FindFunction (&sv_pr_state, "SpectatorDisconnect")) != NULL)
SpectatorDisconnect = (func_t) (f - sv_pr_state.pr_functions);
// 2000-01-02 EndFrame function by Maddes/FrikaC
EndFrame = 0;
if ((f = ED_FindFunction (&sv_pr_state, "EndFrame")) != NULL)
EndFrame = (func_t) (f - sv_pr_state.pr_functions);
eval_alpha = FindFieldOffset (&sv_pr_state, "alpha");
eval_scale = FindFieldOffset (&sv_pr_state, "scale");
eval_glowsize = FindFieldOffset (&sv_pr_state, "glow_size");
eval_glowcolor = FindFieldOffset (&sv_pr_state, "glow_color");
eval_colormod = FindFieldOffset (&sv_pr_state, "colormod");
}
}
void
ED_PrintEdicts_f (void)
{
ED_PrintEdicts (&sv_pr_state);
}
/*
ED_PrintEdict_f
For debugging, prints a single edicy
*/
void
ED_PrintEdict_f (void)
{
int i;
i = atoi (Cmd_Argv (1));
Con_Printf ("\n EDICT %i:\n", i);
ED_PrintNum (&sv_pr_state, i);
}
void
ED_Count_f (void)
{
ED_Count (&sv_pr_state);
}
void
PR_Profile_f (void)
{
PR_Profile (&sv_pr_state);
}
int
ED_Parse_Extra_Fields (progs_t * pr, char *key, char *value)
{
return 0;
}
void
SV_LoadProgs (void)
{
PR_LoadProgs (&sv_pr_state, sv_progs->string);
if (!sv_pr_state.progs)
Host_Error ("SV_LoadProgs: couldn't load %s", sv_progs->string);
}
void
SV_Progs_Init (void)
{
sv_pr_state.edicts = &sv.edicts;
sv_pr_state.num_edicts = &sv.num_edicts;
sv_pr_state.time = &sv.time;
sv_pr_state.unlink = SV_UnlinkEdict;
Cmd_AddCommand ("edict", ED_PrintEdict_f,
"Report information on a given edict in the game. (edict (edict number))");
Cmd_AddCommand ("edicts", ED_PrintEdicts_f,
"Display information on all edicts in the game.");
Cmd_AddCommand ("edictcount", ED_Count_f,
"Display summary information on the edicts in the game.");
Cmd_AddCommand ("profile", PR_Profile_f,
"FIXME: Report information about QuakeC Stuff (???) No Description");
}
void
SV_Progs_Init_Cvars (void)
{
r_skyname = Cvar_Get ("r_skyname", "", CVAR_SERVERINFO, "name of skybox");
sv_progs = Cvar_Get ("sv_progs", "progs.dat", CVAR_ROM,
"Allows selectable game progs if you have several "
"of them in the gamedir");
}

View file

@ -1,3 +1,4 @@
/*
sv_user.c
@ -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
}

View file

@ -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);